Merge pull request #47 from injet-zhou/dev

test: add convert unit test
pull/52/head
ROC 2 years ago committed by GitHub
commit 755cc07f9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

6
.gitignore vendored

@ -1,5 +1,7 @@
.idea
.vscode
__debug_bin
!*.example
dist/
config.yaml
*.log
paopao-api
paopao-ce*

@ -1,9 +1,9 @@
# build app
FROM golang AS build-env
ADD . /paopao-api
ADD . /paopao-ce
WORKDIR /paopao-api
WORKDIR /paopao-ce
RUN CGO_ENABLED=0 go build .
@ -14,14 +14,13 @@ ENV TZ=Asia/Shanghai
RUN apk update && apk add --no-cache ca-certificates && update-ca-certificates
COPY --from=build-env /paopao-api/paopao-api /usr/bin/paopao-api
COPY --from=build-env /paopao-api/comic.ttf /comic.ttf
COPY --from=build-env /paopao-api/qqwry.dat /qqwry.dat
COPY --from=build-env /paopao-api/configs /configs
COPY --from=build-env /paopao-ce/paopao-ce /usr/bin/paopao-ce
COPY --from=build-env /paopao-ce/assets/comic.ttf /assets/comic.ttf
COPY --from=build-env /paopao-ce/configs /configs
EXPOSE 8000
CMD ["paopao-api"]
CMD ["paopao-ce"]
# HEALTHCHECK
HEALTHCHECK --interval=5s --timeout=3s --retries=3 CMD ps -ef | grep paopao-api || exit 1
HEALTHCHECK --interval=5s --timeout=3s --retries=3 CMD ps -ef | grep paopao-ce || exit 1

@ -0,0 +1,28 @@
.PHONY: all build run clean fmt help
BUILD_VERSION := $(shell cat version)
BUILD_DATE := $(shell date +'%Y-%m-%d %H:%M:%S')
SHA_SHORT := $(shell git rev-parse --short HEAD)
all: fmt build
build:
@go mod download
@echo Build paopao-ce
bash build.sh paopao-ce
run:
@go run -ldflags "-X 'main.version=${BUILD_VERSION}' -X 'main.buildDate=${BUILD_DATE}' -X 'main.commitID=${SHA_SHORT}'" .
clean:
@go clean
@find ./dist -type f -exec rm -r {} +
@find ./tmp -type f -exec rm -r {} +
fmt:
@echo Formatting...
@go fmt ./global/...
@go fmt ./internal/...
@go fmt ./pkg/...
@go vet -composites=false ./global/...
@go vet -composites=false ./internal/...
@go vet -composites=false ./pkg/...
help:
@echo "make: make"
@echo "make build: build executables"
.EXPORT_ALL_VARIABLES:
GO111MODULE = on

@ -1,6 +1,5 @@
<div id="top"></div>
<!-- PROJECT SHIELDS -->
[![Go Report Card][goreport-shield]][goreport-url]
[![Forks][forks-shield]][forks-url]
@ -28,9 +27,9 @@
</p>
</div>
---
## 1. 截图预览
## 预览
[![明色主题][product-light-screenshot]](https://www.paopao.info)
@ -40,10 +39,7 @@
<p align="right">(<a href="#top">back to top</a>)</p>
<!-- GETTING STARTED -->
## 2. 快速开始
### 2.1 技术栈
## 🛠 技术栈
PaoPao主要由以下优秀的开源项目/工具构建
@ -54,22 +50,22 @@ PaoPao主要由以下优秀的开源项目/工具构建
* [Vue.js](https://vuejs.org/)
* [Vite.js](https://vitejs.dev/)
<!-- GETTING STARTED -->
## 🏗 快速开始
### 2.2 环境要求
### 环境要求
- Go (1.17+)
- Node.js (14+)
- MySQL (5.7+)
- Redis
- Zinc
* Go (1.17+)
* Node.js (14+)
* MySQL (5.7+)
* Redis
* Zinc
\* Zinc是一款轻量级全文搜索引擎可以查阅 https://zincsearch.com/ 安装
\* Zinc是一款轻量级全文搜索引擎可以查阅 <https://zincsearch.com/> 安装
以上环境版本为PaoPao官方的开发版本仅供参考其他版本的环境未进行充分测试
<br />
### 3. 安装说明
### 安装说明
***宝塔安装***
@ -78,45 +74,62 @@ PaoPao主要由以下优秀的开源项目/工具构建
***普通安装***
克隆代码库
```sh
git clone https://github.com/rocboss/paopao-ce.git
```
#### 3.1 后端
#### 后端
1. 导入项目根目录下的 `paopao.sql` 文件至MySQL数据库
2. 拷贝项目根目录下 `config.yaml.sample` 文件至 `config.yaml`,按照注释完成配置编辑
3. 编译后端
```sh
go mod download
go build .
go build -o paopao-api .
```
4. 启动后端
```sh
chmod +x paopao-api
./paopao-api
```
#### 3.2 前端
#### 前端
1. 进入前端目录 `web`,编辑 `.env` 文件中后端服务地址,下载依赖包
```sh
cd ./web
vim .env
yarn
```
2. 编译前端
```sh
yarn build
```
build完成后可以在dist目录获取编译产出配置nginx指向至该目录即可
#### 3.3 其他
建议后端服务使用 `supervisor` 守护进程并通过nginx反向代理后提供API给前端服务调用。
### 其他说明
建议后端服务使用 `supervisor` 守护进程,并通过 `nginx` 反向代理后提供API给前端服务调用。
短信通道使用的[聚合数据](https://www.juhe.cn/),如果申请不下来,可以考虑替换其他服务商。
代码结构比较简单,很方便扩展
## 👯‍♀️ 贡献
喜欢的朋友欢迎给个Star、贡献PR。
短信通道使用的聚合数据(juhe.cn),如果申请不下来,可以考虑替换其他服务商。
## License
代码结构比较简单很方便扩展喜欢的朋友欢迎给个Star、贡献PR。
Distributed under the MIT License. See `LICENSE` for more information.
<!-- MARKDOWN LINKS & IMAGES -->
[contributors-shield]: https://img.shields.io/github/contributors/rocboss/paopao-ce?style=flat
@ -133,4 +146,4 @@ PaoPao主要由以下优秀的开源项目/工具构建
[license-url]: https://github.com/rocboss/paopao-ce/blob/master/LICENSE.txt
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat&logo=linkedin&colorB=555
[product-light-screenshot]: https://cdn.rocs.me/static/paopao-light.jpeg
[product-dark-screenshot]: https://cdn.rocs.me/static/paopao-dark.jpeg
[product-dark-screenshot]: https://cdn.rocs.me/static/paopao-dark.jpeg

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# shellcheck disable=SC2155
set -e
DIST_PREFIX=${1}
DEBUG_MODE=${2}
TARGET_DIR="dist"
PLATFORMS="darwin/amd64 darwin/arm64 linux/amd64 windows/amd64"
rm -rf ${TARGET_DIR}
mkdir ${TARGET_DIR}
for pl in ${PLATFORMS}; do
export CGO_ENABLED=0
export GOOS=$(echo "${pl}" | cut -d'/' -f1)
export GOARCH=$(echo "${pl}" | cut -d'/' -f2)
export TARGET=${TARGET_DIR}/${DIST_PREFIX}_${GOOS}_${GOARCH}
if [ "${GOOS}" == "windows" ]; then
export TARGET=${TARGET_DIR}/${DIST_PREFIX}_${GOOS}_${GOARCH}.exe
fi
echo "build => ${TARGET}"
if [ "${DEBUG_MODE}" == "debug" ]; then
go build -trimpath -gcflags "all=-N -l" -o "${TARGET}" \
-ldflags "-X 'main.version=${BUILD_VERSION}' \
-X 'main.buildDate=${BUILD_DATE}' \
-X 'main.commitID=${SHA_SHORT}'\
-w -s"
else
go build -trimpath -o "${TARGET}" \
-ldflags "-X 'main.version=${BUILD_VERSION}' \
-X 'main.buildDate=${BUILD_DATE}' \
-X 'main.commitID=${SHA_SHORT}'\
-w -s"
fi
done

@ -10,6 +10,8 @@ App: # APP基础设置项
SmsJuheTplVal: "#code#=%d&#m#=%d"
AlipayAppID:
AlipayPrivateKey:
Runtime: # App运行时功能调节
DisablePhoneVerify: False # 禁止绑定手机号码时验证短信验证码为true时任意验证码都可以通过验证
Server: # 服务设置
RunMode: debug
HttpIp: 0.0.0.0

@ -10,6 +10,7 @@ import (
var (
ServerSetting *setting.ServerSettingS
AppSetting *setting.AppSettingS
RuntimeSetting *setting.RuntimeSettingS
DatabaseSetting *setting.DatabaseSettingS
RedisSetting *setting.RedisSettingS
SearchSetting *setting.SearchSettingS

@ -9,6 +9,7 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/disintegration/imaging v1.6.2
github.com/ethereum/go-ethereum v1.10.16
github.com/fatih/color v1.13.0
github.com/fbsobreira/gotron-sdk v0.0.0-20211102183839-58a64f4da5f4
github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.7.7
@ -16,19 +17,18 @@ require (
github.com/go-redis/redis/v8 v8.11.4
github.com/go-resty/resty/v2 v2.7.0
github.com/gofrs/uuid v3.3.0+incompatible
github.com/golang/protobuf v1.5.2
github.com/google/go-cmp v0.5.7 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sirupsen/logrus v1.8.1
github.com/smartwalle/alipay/v3 v3.1.7
github.com/spf13/viper v1.10.1
github.com/ugorji/go v1.2.7 // indirect
github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc // indirect
github.com/yinheli/qqwry v0.0.0-20160229183603-f50680010f4a
github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 // indirect
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect
google.golang.org/protobuf v1.27.1
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/resty.v1 v1.12.0
gorm.io/driver/mysql v1.3.2

@ -201,6 +201,7 @@ github.com/ethereum/go-ethereum v1.10.16 h1:3oPrumn0bCW/idjcxMn5YYVCdK7VzJYIvwGZ
github.com/ethereum/go-ethereum v1.10.16/go.mod h1:Anj6cxczl+AHy63o4X9O8yWNHuN5wMpfb8MAnHkWn7Y=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fbsobreira/gotron-sdk v0.0.0-20211102183839-58a64f4da5f4 h1:zlN+of+l+or/Y6CYgpX99wwaTf4zN0myVj6YAXiE3xk=
@ -485,6 +486,7 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
@ -675,8 +677,6 @@ github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6Ut
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc h1:7VHQaaNwHymWbj8lAcXMYX1qopebSBHwYC3ceXLWONU=
github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc/go.mod h1:Pcc297eVCbkDBBVq8FbnI+qDUeIMrHy4Bo7nveAuCAs=
github.com/yinheli/qqwry v0.0.0-20160229183603-f50680010f4a h1:VUPXGL4N1B5xqomxI4vZn0momgleh0hcH0PE/oIOsAI=
github.com/yinheli/qqwry v0.0.0-20160229183603-f50680010f4a/go.mod h1:Zva9ErVtC2arl+9xtHwiXujgejX1S3VpOYExADJ9kio=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

@ -8,8 +8,10 @@ import (
"github.com/go-redis/redis/v8"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/service"
"github.com/rocboss/paopao-ce/pkg/logger"
"github.com/rocboss/paopao-ce/pkg/setting"
"github.com/rocboss/paopao-ce/pkg/zinc"
)
func init() {
@ -25,6 +27,8 @@ func init() {
if err != nil {
log.Fatalf("init.setupDBEngine err: %v", err)
}
client := zinc.NewClient(global.SearchSetting)
service.Initialize(global.DBEngine, client)
}
func setupSetting() error {
@ -41,6 +45,10 @@ func setupSetting() error {
if err != nil {
return err
}
err = setting.ReadSection("Runtime", &global.RuntimeSetting)
if err != nil {
return err
}
err = setting.ReadSection("Log", &global.LoggerSetting)
if err != nil {
return err

@ -20,7 +20,7 @@ type Message struct {
SenderUserID int64 `json:"sender_user_id"`
ReceiverUserID int64 `json:"receiver_user_id"`
Type MessageT `json:"type"`
Breif string `json:"breif"`
Brief string `json:"brief"`
Content string `json:"content"`
PostID int64 `json:"post_id"`
CommentID int64 `json:"comment_id"`
@ -34,7 +34,7 @@ type MessageFormated struct {
SenderUser *UserFormated `json:"sender_user"`
ReceiverUserID int64 `json:"receiver_user_id"`
Type MessageT `json:"type"`
Breif string `json:"breif"`
Brief string `json:"brief"`
Content string `json:"content"`
PostID int64 `json:"post_id"`
Post *PostFormated `json:"post"`
@ -57,7 +57,7 @@ func (m *Message) Format() *MessageFormated {
SenderUser: &UserFormated{},
ReceiverUserID: m.ReceiverUserID,
Type: m.Type,
Breif: m.Breif,
Brief: m.Brief,
Content: m.Content,
PostID: m.PostID,
Post: &PostFormated{},

@ -53,9 +53,23 @@ func GetImageSize(img image.Rectangle) (int, int) {
return width, height
}
func fileCheck(uploadType string, size int64) error {
if uploadType != "public/video" &&
uploadType != "public/image" &&
uploadType != "public/avatar" &&
uploadType != "attachment" {
return errcode.InvalidParams
}
if size > 1024*1024*100 {
return errcode.FileInvalidSize.WithDetails("最大允许100MB")
}
return nil
}
func UploadAttachment(c *gin.Context) {
response := app.NewResponse(c)
svc := service.New(c)
uploadType := c.Request.FormValue("type")
file, fileHeader, err := c.Request.FormFile("file")
@ -66,16 +80,9 @@ func UploadAttachment(c *gin.Context) {
}
defer file.Close()
if uploadType != "public/video" &&
uploadType != "public/image" &&
uploadType != "public/avatar" &&
uploadType != "attachment" {
response.ToErrorResponse(errcode.InvalidParams)
return
}
if fileHeader.Size > 1024*1024*100 {
response.ToErrorResponse(errcode.FileInvalidSize.WithDetails("最大允许100MB"))
if err = fileCheck(uploadType, fileHeader.Size); err != nil {
cErr, _ := err.(*errcode.Error)
response.ToErrorResponse(cErr)
return
}
@ -129,24 +136,25 @@ func UploadAttachment(c *gin.Context) {
attachment.UserID = userID.(int64)
}
if uploadType == "public/image" || uploadType == "public/avatar" {
attachment.Type = model.ATTACHMENT_TYPE_IMAGE
var uploadAttachmentTypeMap = map[string]model.AttachmentType{
"public/image": model.ATTACHMENT_TYPE_IMAGE,
"public/avatar": model.ATTACHMENT_TYPE_IMAGE,
"public/video": model.ATTACHMENT_TYPE_VIDEO,
"attachment": model.ATTACHMENT_TYPE_OTHER,
}
src, err := imaging.Decode(file)
attachment.Type = uploadAttachmentTypeMap[uploadType]
if attachment.Type == model.ATTACHMENT_TYPE_IMAGE {
var src image.Image
src, err = imaging.Decode(file)
if err == nil {
attachment.ImgWidth, attachment.ImgHeight = GetImageSize(src.Bounds())
}
}
if uploadType == "public/video" {
attachment.Type = model.ATTACHMENT_TYPE_VIDEO
}
if uploadType == "attachment" {
attachment.Type = model.ATTACHMENT_TYPE_OTHER
}
attachment, err = svc.CreateAttachment(attachment)
attachment, err = service.CreateAttachment(attachment)
if err != nil {
global.Logger.Errorf("svc.CreateAttachment err: %v", err)
global.Logger.Errorf("service.CreateAttachment err: %v", err)
response.ToErrorResponse(errcode.FileUploadFailed)
}
@ -155,21 +163,20 @@ func UploadAttachment(c *gin.Context) {
func DownloadAttachmentPrecheck(c *gin.Context) {
response := app.NewResponse(c)
svc := service.New(c)
contentID := convert.StrTo(c.Query("id")).MustInt64()
// 加载content
content, err := svc.GetPostContentByID(contentID)
content, err := service.GetPostContentByID(contentID)
if err != nil {
global.Logger.Errorf("svc.GetPostContentByID err: %v", err)
global.Logger.Errorf("service.GetPostContentByID err: %v", err)
response.ToErrorResponse(errcode.InvalidDownloadReq)
}
user, _ := c.Get("USER")
if content.Type == model.CONTENT_TYPE_CHARGE_ATTACHMENT {
// 加载post
post, err := svc.GetPost(content.PostID)
post, err := service.GetPost(content.PostID)
if err != nil {
global.Logger.Errorf("svc.GetPost err: %v", err)
global.Logger.Errorf("service.GetPost err: %v", err)
response.ToResponse(gin.H{
"paid": false,
})
@ -186,7 +193,7 @@ func DownloadAttachmentPrecheck(c *gin.Context) {
// 检测是否有购买记录
response.ToResponse(gin.H{
"paid": svc.CheckPostAttachmentIsPaid(post.ID, user.(*model.User).ID),
"paid": service.CheckPostAttachmentIsPaid(post.ID, user.(*model.User).ID),
})
return
}
@ -197,14 +204,13 @@ func DownloadAttachmentPrecheck(c *gin.Context) {
func DownloadAttachment(c *gin.Context) {
response := app.NewResponse(c)
svc := service.New(c)
contentID := convert.StrTo(c.Query("id")).MustInt64()
// 加载content
content, err := svc.GetPostContentByID(contentID)
content, err := service.GetPostContentByID(contentID)
if err != nil {
global.Logger.Errorf("svc.GetPostContentByID err: %v", err)
global.Logger.Errorf("service.GetPostContentByID err: %v", err)
response.ToErrorResponse(errcode.InvalidDownloadReq)
}
@ -213,9 +219,9 @@ func DownloadAttachment(c *gin.Context) {
user, _ := c.Get("USER")
// 加载post
post, err := svc.GetPost(content.PostID)
post, err := service.GetPost(content.PostID)
if err != nil {
global.Logger.Errorf("svc.GetPost err: %v", err)
global.Logger.Errorf("service.GetPost err: %v", err)
response.ToResponse(gin.H{
"paid": false,
})
@ -230,13 +236,13 @@ func DownloadAttachment(c *gin.Context) {
}
// 检测是否有购买记录
if svc.CheckPostAttachmentIsPaid(post.ID, user.(*model.User).ID) {
if service.CheckPostAttachmentIsPaid(post.ID, user.(*model.User).ID) {
paidFlag = true
}
if !paidFlag {
// 未购买,则尝试购买
err := svc.BuyPostAttachment(&model.Post{
err := service.BuyPostAttachment(&model.Post{
Model: &model.Model{
ID: post.ID,
},
@ -244,7 +250,7 @@ func DownloadAttachment(c *gin.Context) {
AttachmentPrice: post.AttachmentPrice,
}, user.(*model.User))
if err != nil {
global.Logger.Errorf("svc.BuyPostAttachment err: %v", err)
global.Logger.Errorf("service.BuyPostAttachment err: %v", err)
if err == errcode.InsuffientDownloadMoney {
response.ToErrorResponse(errcode.InsuffientDownloadMoney)

@ -11,15 +11,13 @@ import (
)
func GetPostComments(c *gin.Context) {
postID := convert.StrTo(c.Query("id")).MustInt64()
response := app.NewResponse(c)
svc := service.New(c)
contents, totalRows, err := svc.GetPostComments(postID, "id ASC", 0, 0)
contents, totalRows, err := service.GetPostComments(postID, "id ASC", 0, 0)
if err != nil {
global.Logger.Errorf("svc.GetPostComments err: %v\n", err)
global.Logger.Errorf("service.GetPostComments err: %v\n", err)
response.ToErrorResponse(errcode.GetCommentsFailed)
return
}
@ -38,14 +36,13 @@ func CreatePostComment(c *gin.Context) {
}
userID, _ := c.Get("UID")
svc := service.New(c)
comment, err := svc.CreatePostComment(userID.(int64), param)
comment, err := service.CreatePostComment(c, userID.(int64), param)
if err != nil {
if err == errcode.MaxCommentCount {
response.ToErrorResponse(errcode.MaxCommentCount)
} else {
global.Logger.Errorf("svc.CreatePostComment err: %v\n", err)
global.Logger.Errorf("service.CreatePostComment err: %v\n", err)
response.ToErrorResponse(errcode.CreateCommentFailed)
}
return
@ -64,11 +61,10 @@ func DeletePostComment(c *gin.Context) {
return
}
user, _ := c.Get("USER")
svc := service.New(c)
comment, err := svc.GetPostComment(param.ID)
comment, err := service.GetPostComment(param.ID)
if err != nil {
global.Logger.Errorf("svc.GetPostComment err: %v\n", err)
global.Logger.Errorf("service.GetPostComment err: %v\n", err)
response.ToErrorResponse(errcode.GetCommentFailed)
return
}
@ -79,9 +75,9 @@ func DeletePostComment(c *gin.Context) {
}
// 执行删除
err = svc.DeletePostComment(comment)
err = service.DeletePostComment(comment)
if err != nil {
global.Logger.Errorf("svc.DeletePostComment err: %v\n", err)
global.Logger.Errorf("service.DeletePostComment err: %v\n", err)
response.ToErrorResponse(errcode.DeleteCommentFailed)
return
}
@ -99,11 +95,10 @@ func CreatePostCommentReply(c *gin.Context) {
return
}
user, _ := c.Get("USER")
svc := service.New(c)
comment, err := svc.CreatePostCommentReply(param.CommentID, param.Content, user.(*model.User).ID, param.AtUserID)
comment, err := service.CreatePostCommentReply(c, param.CommentID, param.Content, user.(*model.User).ID, param.AtUserID)
if err != nil {
global.Logger.Errorf("svc.CreatePostCommentReply err: %v\n", err)
global.Logger.Errorf("service.CreatePostCommentReply err: %v\n", err)
response.ToErrorResponse(errcode.CreateReplyFailed)
return
}
@ -122,11 +117,10 @@ func DeletePostCommentReply(c *gin.Context) {
}
user, _ := c.Get("USER")
svc := service.New(c)
reply, err := svc.GetPostCommentReply(param.ID)
reply, err := service.GetPostCommentReply(param.ID)
if err != nil {
global.Logger.Errorf("svc.GetPostCommentReply err: %v\n", err)
global.Logger.Errorf("service.GetPostCommentReply err: %v\n", err)
response.ToErrorResponse(errcode.GetReplyFailed)
return
}
@ -137,9 +131,9 @@ func DeletePostCommentReply(c *gin.Context) {
}
// 执行删除
err = svc.DeletePostCommentReply(reply)
err = service.DeletePostCommentReply(reply)
if err != nil {
global.Logger.Errorf("svc.DeletePostCommentReply err: %v\n", err)
global.Logger.Errorf("service.DeletePostCommentReply err: %v\n", err)
response.ToErrorResponse(errcode.DeleteCommentFailed)
return
}

@ -30,12 +30,11 @@ func Version(c *gin.Context) {
func SyncSearchIndex(c *gin.Context) {
response := app.NewResponse(c)
svc := service.New(c)
user, _ := c.Get("USER")
if user.(*model.User).IsAdmin {
go svc.PushPostsToSearch()
go service.PushPostsToSearch(c)
}
response.ToResponse(nil)
@ -44,7 +43,7 @@ func SyncSearchIndex(c *gin.Context) {
func GetCaptcha(c *gin.Context) {
cap := captcha.New()
if err := cap.SetFont("comic.ttf"); err != nil {
if err := cap.SetFont("assets/comic.ttf"); err != nil {
panic(err.Error())
}
@ -77,7 +76,6 @@ func PostCaptcha(c *gin.Context) {
response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
return
}
svc := service.New(c)
// 验证图片验证码
if res, err := global.Redis.Get(c.Request.Context(), "PaoPaoCaptcha:"+param.ImgCaptchaID).Result(); err != nil || res != param.ImgCaptcha {
@ -92,7 +90,7 @@ func PostCaptcha(c *gin.Context) {
return
}
err := svc.SendPhoneCaptcha(param.Phone)
err := service.SendPhoneCaptcha(c, param.Phone)
if err != nil {
global.Logger.Errorf("app.SendPhoneCaptcha errs: %v", errs)
response.ToErrorResponse(errcode.GetPhoneCaptchaError)

@ -16,9 +16,8 @@ func GetUnreadMsgCount(c *gin.Context) {
if u, exists := c.Get("USER"); exists {
user = u.(*model.User)
}
svc := service.New(c)
count, _ := svc.GetUnreadCount(user.ID)
count, _ := service.GetUnreadCount(user.ID)
response.ToResponse(gin.H{
"count": count,
@ -29,11 +28,10 @@ func GetMessages(c *gin.Context) {
response := app.NewResponse(c)
userID, _ := c.Get("UID")
svc := service.New(c)
messages, totalRows, err := svc.GetMessages(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
messages, totalRows, err := service.GetMessages(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
if err != nil {
global.Logger.Errorf("svc.GetMessages err: %v\n", err)
global.Logger.Errorf("service.GetMessages err: %v\n", err)
response.ToErrorResponse(errcode.GetMessagesFailed)
return
}
@ -52,10 +50,9 @@ func ReadMessage(c *gin.Context) {
}
userID, _ := c.Get("UID")
svc := service.New(c)
err := svc.ReadMessage(param.ID, userID.(int64))
err := service.ReadMessage(param.ID, userID.(int64))
if err != nil {
global.Logger.Errorf("svc.ReadMessage err: %v\n", err)
global.Logger.Errorf("service.ReadMessage err: %v\n", err)
response.ToErrorResponse(errcode.ReadMessageFailed)
return
}
@ -81,17 +78,16 @@ func SendUserWhisper(c *gin.Context) {
return
}
svc := service.New(c)
_, err := svc.CreateWhisper(&model.Message{
_, err := service.CreateWhisper(c, &model.Message{
SenderUserID: userID.(int64),
ReceiverUserID: param.UserID,
Type: model.MESSAGE_WHISPER,
Breif: "给你发送新私信了",
Brief: "给你发送新私信了",
Content: param.Content,
})
if err != nil {
global.Logger.Errorf("svc.CreateWhisper err: %v\n", err)
global.Logger.Errorf("service.CreateWhisper err: %v\n", err)
if err == errcode.TooManyWhisperNum {
response.ToErrorResponse(errcode.TooManyWhisperNum)

@ -22,10 +22,9 @@ func GetPostList(c *gin.Context) {
q.Type = "tag"
}
svc := service.New(c)
if q.Query == "" && q.Type == "search" {
// 直接读库
posts, err := svc.GetPostList(&service.PostListReq{
posts, err := service.GetPostList(&service.PostListReq{
Conditions: &model.ConditionsT{
"ORDER": "is_top DESC, latest_replied_on DESC",
},
@ -33,20 +32,20 @@ func GetPostList(c *gin.Context) {
Limit: app.GetPageSize(c),
})
if err != nil {
global.Logger.Errorf("svc.GetPostList err: %v\n", err)
global.Logger.Errorf("service.GetPostList err: %v\n", err)
response.ToErrorResponse(errcode.GetPostsFailed)
return
}
totalRows, _ := svc.GetPostCount(&model.ConditionsT{
totalRows, _ := service.GetPostCount(&model.ConditionsT{
"ORDER": "latest_replied_on DESC",
})
response.ToResponseList(posts, totalRows)
} else {
posts, totalRows, err := svc.GetPostListFromSearch(q, (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
posts, totalRows, err := service.GetPostListFromSearch(q, (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
if err != nil {
global.Logger.Errorf("svc.GetPostListFromSearch err: %v\n", err)
global.Logger.Errorf("service.GetPostListFromSearch err: %v\n", err)
response.ToErrorResponse(errcode.GetPostsFailed)
return
}
@ -58,11 +57,10 @@ func GetPost(c *gin.Context) {
postID := convert.StrTo(c.Query("id")).MustInt64()
response := app.NewResponse(c)
svc := service.New(c)
postFormated, err := svc.GetPost(postID)
postFormated, err := service.GetPost(postID)
if err != nil {
global.Logger.Errorf("svc.GetPost err: %v\n", err)
global.Logger.Errorf("service.GetPost err: %v\n", err)
response.ToErrorResponse(errcode.GetPostFailed)
return
}
@ -81,11 +79,10 @@ func CreatePost(c *gin.Context) {
}
userID, _ := c.Get("UID")
svc := service.New(c)
post, err := svc.CreatePost(userID.(int64), param)
post, err := service.CreatePost(c, userID.(int64), param)
if err != nil {
global.Logger.Errorf("svc.CreatePost err: %v\n", err)
global.Logger.Errorf("service.CreatePost err: %v\n", err)
response.ToErrorResponse(errcode.CreatePostFailed)
return
}
@ -104,12 +101,11 @@ func DeletePost(c *gin.Context) {
}
user, _ := c.Get("USER")
svc := service.New(c)
// 获取Post
postFormated, err := svc.GetPost(param.ID)
postFormated, err := service.GetPost(param.ID)
if err != nil {
global.Logger.Errorf("svc.GetPost err: %v\n", err)
global.Logger.Errorf("service.GetPost err: %v\n", err)
response.ToErrorResponse(errcode.GetPostFailed)
return
}
@ -119,9 +115,9 @@ func DeletePost(c *gin.Context) {
return
}
err = svc.DeletePost(param.ID)
err = service.DeletePost(param.ID)
if err != nil {
global.Logger.Errorf("svc.DeletePost err: %v\n", err)
global.Logger.Errorf("service.DeletePost err: %v\n", err)
response.ToErrorResponse(errcode.DeletePostFailed)
return
}
@ -133,10 +129,9 @@ func GetPostStar(c *gin.Context) {
postID := convert.StrTo(c.Query("id")).MustInt64()
response := app.NewResponse(c)
svc := service.New(c)
userID, _ := c.Get("UID")
_, err := svc.GetPostStar(postID, userID.(int64))
_, err := service.GetPostStar(postID, userID.(int64))
if err != nil {
response.ToResponse(gin.H{
"status": false,
@ -160,18 +155,17 @@ func PostStar(c *gin.Context) {
return
}
svc := service.New(c)
userID, _ := c.Get("UID")
status := false
star, err := svc.GetPostStar(param.ID, userID.(int64))
star, err := service.GetPostStar(param.ID, userID.(int64))
if err != nil {
// 创建Star
svc.CreatePostStar(param.ID, userID.(int64))
service.CreatePostStar(param.ID, userID.(int64))
status = true
} else {
// 取消Star
svc.DeletePostStar(star)
service.DeletePostStar(star)
}
response.ToResponse(gin.H{
@ -183,10 +177,9 @@ func GetPostCollection(c *gin.Context) {
postID := convert.StrTo(c.Query("id")).MustInt64()
response := app.NewResponse(c)
svc := service.New(c)
userID, _ := c.Get("UID")
_, err := svc.GetPostCollection(postID, userID.(int64))
_, err := service.GetPostCollection(postID, userID.(int64))
if err != nil {
response.ToResponse(gin.H{
"status": false,
@ -210,18 +203,17 @@ func PostCollection(c *gin.Context) {
return
}
svc := service.New(c)
userID, _ := c.Get("UID")
status := false
collection, err := svc.GetPostCollection(param.ID, userID.(int64))
collection, err := service.GetPostCollection(param.ID, userID.(int64))
if err != nil {
// 创建collection
svc.CreatePostCollection(param.ID, userID.(int64))
service.CreatePostCollection(param.ID, userID.(int64))
status = true
} else {
// 取消Star
svc.DeletePostCollection(collection)
service.DeletePostCollection(collection)
}
response.ToResponse(gin.H{
@ -240,12 +232,11 @@ func LockPost(c *gin.Context) {
}
user, _ := c.Get("USER")
svc := service.New(c)
// 获取Post
postFormated, err := svc.GetPost(param.ID)
postFormated, err := service.GetPost(param.ID)
if err != nil {
global.Logger.Errorf("svc.GetPost err: %v\n", err)
global.Logger.Errorf("service.GetPost err: %v\n", err)
response.ToErrorResponse(errcode.GetPostFailed)
return
}
@ -254,9 +245,9 @@ func LockPost(c *gin.Context) {
response.ToErrorResponse(errcode.NoPermission)
return
}
err = svc.LockPost(param.ID)
err = service.LockPost(param.ID)
if err != nil {
global.Logger.Errorf("svc.LockPost err: %v\n", err)
global.Logger.Errorf("service.LockPost err: %v\n", err)
response.ToErrorResponse(errcode.LockPostFailed)
return
}
@ -277,12 +268,11 @@ func StickPost(c *gin.Context) {
}
user, _ := c.Get("USER")
svc := service.New(c)
// 获取Post
postFormated, err := svc.GetPost(param.ID)
postFormated, err := service.GetPost(param.ID)
if err != nil {
global.Logger.Errorf("svc.GetPost err: %v\n", err)
global.Logger.Errorf("service.GetPost err: %v\n", err)
response.ToErrorResponse(errcode.GetPostFailed)
return
}
@ -291,9 +281,9 @@ func StickPost(c *gin.Context) {
response.ToErrorResponse(errcode.NoPermission)
return
}
err = svc.StickPost(param.ID)
err = service.StickPost(param.ID)
if err != nil {
global.Logger.Errorf("svc.StickPost err: %v\n", err)
global.Logger.Errorf("service.StickPost err: %v\n", err)
response.ToErrorResponse(errcode.LockPostFailed)
return
}
@ -313,11 +303,9 @@ func GetPostTags(c *gin.Context) {
return
}
svc := service.New(c)
tags, err := svc.GetPostTags(&param)
tags, err := service.GetPostTags(&param)
if err != nil {
global.Logger.Errorf("svc.GetPostTags err: %v\n", err)
global.Logger.Errorf("service.GetPostTags err: %v\n", err)
response.ToErrorResponse(errcode.GetPostTagsFailed)
return

@ -16,7 +16,7 @@ import (
"github.com/smartwalle/alipay/v3"
)
// 用户登录
// Login 用户登录
func Login(c *gin.Context) {
param := service.AuthRequest{}
response := app.NewResponse(c)
@ -27,10 +27,9 @@ func Login(c *gin.Context) {
return
}
svc := service.New(c)
user, err := svc.DoLogin(&param)
user, err := service.DoLogin(c, &param)
if err != nil {
global.Logger.Errorf("svc.DoLogin err: %v", err)
global.Logger.Errorf("service.DoLogin err: %v", err)
response.ToErrorResponse(err.(*errcode.Error))
return
}
@ -47,7 +46,7 @@ func Login(c *gin.Context) {
})
}
// 用户注册
// Register 用户注册
func Register(c *gin.Context) {
param := service.RegisterRequest{}
@ -59,31 +58,29 @@ func Register(c *gin.Context) {
return
}
svc := service.New(c)
// 用户名检查
err := svc.ValidUsername(param.Username)
err := service.ValidUsername(param.Username)
if err != nil {
global.Logger.Errorf("svc.Register err: %v", err)
global.Logger.Errorf("service.Register err: %v", err)
response.ToErrorResponse(err.(*errcode.Error))
return
}
// 密码检查
err = svc.CheckPassword(param.Password)
err = service.CheckPassword(param.Password)
if err != nil {
global.Logger.Errorf("svc.Register err: %v", err)
global.Logger.Errorf("service.Register err: %v", err)
response.ToErrorResponse(err.(*errcode.Error))
return
}
user, err := svc.Register(
user, err := service.Register(
param.Username,
param.Password,
)
if err != nil {
global.Logger.Errorf("svc.Register err: %v", err)
global.Logger.Errorf("service.Register err: %v", err)
response.ToErrorResponse(errcode.UserRegisterFailed)
return
}
@ -98,13 +95,12 @@ func Register(c *gin.Context) {
func GetUserInfo(c *gin.Context) {
param := service.AuthRequest{}
response := app.NewResponse(c)
svc := service.New(c)
if username, exists := c.Get("USERNAME"); exists {
param.Username = username.(string)
}
user, err := svc.GetUserInfo(&param)
user, err := service.GetUserInfo(&param)
if err != nil {
response.ToErrorResponse(errcode.UnauthorizedAuthNotExist)
@ -143,25 +139,23 @@ func ChangeUserPassword(c *gin.Context) {
user = u.(*model.User)
}
svc := service.New(c)
// 密码检查
err := svc.CheckPassword(param.Password)
err := service.CheckPassword(param.Password)
if err != nil {
global.Logger.Errorf("svc.Register err: %v", err)
global.Logger.Errorf("service.Register err: %v", err)
response.ToErrorResponse(err.(*errcode.Error))
return
}
// 旧密码校验
if !svc.ValidPassword(user.Password, param.OldPassword, user.Salt) {
if !service.ValidPassword(user.Password, param.OldPassword, user.Salt) {
response.ToErrorResponse(errcode.ErrorOldPassword)
return
}
// 更新入库
user.Password, user.Salt = svc.EncryptPasswordAndSalt(param.Password)
svc.UpdateUserInfo(user)
user.Password, user.Salt = service.EncryptPasswordAndSalt(param.Password)
service.UpdateUserInfo(user)
response.ToResponse(nil)
}
@ -181,7 +175,6 @@ func ChangeNickname(c *gin.Context) {
if u, exists := c.Get("USER"); exists {
user = u.(*model.User)
}
svc := service.New(c)
if utf8.RuneCountInString(param.Nickname) < 2 || utf8.RuneCountInString(param.Nickname) > 12 {
response.ToErrorResponse(errcode.NicknameLengthLimit)
@ -190,7 +183,7 @@ func ChangeNickname(c *gin.Context) {
// 执行绑定
user.Nickname = param.Nickname
svc.UpdateUserInfo(user)
service.UpdateUserInfo(user)
response.ToResponse(nil)
}
@ -210,7 +203,6 @@ func ChangeAvatar(c *gin.Context) {
if u, exists := c.Get("USER"); exists {
user = u.(*model.User)
}
svc := service.New(c)
if strings.Index(param.Avatar, "https://"+global.AliossSetting.AliossDomain) != 0 {
response.ToErrorResponse(errcode.InvalidParams)
@ -219,7 +211,7 @@ func ChangeAvatar(c *gin.Context) {
// 执行绑定
user.Avatar = param.Avatar
svc.UpdateUserInfo(user)
service.UpdateUserInfo(user)
response.ToResponse(nil)
}
@ -239,25 +231,25 @@ func BindUserPhone(c *gin.Context) {
if u, exists := c.Get("USER"); exists {
user = u.(*model.User)
}
svc := service.New(c)
// 手机重复性检查
if svc.CheckPhoneExist(user.ID, param.Phone) {
if service.CheckPhoneExist(user.ID, param.Phone) {
response.ToErrorResponse(errcode.ExistedUserPhone)
return
}
// 验证短信验证码
err := svc.CheckPhoneCaptcha(param.Phone, param.Captcha)
if err != nil {
global.Logger.Errorf("svc.CheckPhoneCaptcha err: %v\n", err)
response.ToErrorResponse(err)
return
if !global.RuntimeSetting.DisablePhoneVerify {
if err := service.CheckPhoneCaptcha(param.Phone, param.Captcha); err != nil {
global.Logger.Errorf("service.CheckPhoneCaptcha err: %v\n", err)
response.ToErrorResponse(err)
return
}
}
// 执行绑定
user.Phone = param.Phone
svc.UpdateUserInfo(user)
service.UpdateUserInfo(user)
response.ToResponse(nil)
}
@ -266,10 +258,9 @@ func GetUserProfile(c *gin.Context) {
response := app.NewResponse(c)
username := c.Query("username")
svc := service.New(c)
user, err := svc.GetUserByUsername(username)
user, err := service.GetUserByUsername(username)
if err != nil {
global.Logger.Errorf("svc.GetUserByUsername err: %v\n", err)
global.Logger.Errorf("service.GetUserByUsername err: %v\n", err)
response.ToErrorResponse(errcode.NoExistUsername)
return
}
@ -288,10 +279,9 @@ func GetUserPosts(c *gin.Context) {
response := app.NewResponse(c)
username := c.Query("username")
svc := service.New(c)
user, err := svc.GetUserByUsername(username)
user, err := service.GetUserByUsername(username)
if err != nil {
global.Logger.Errorf("svc.GetUserByUsername err: %v\n", err)
global.Logger.Errorf("service.GetUserByUsername err: %v\n", err)
response.ToErrorResponse(errcode.NoExistUsername)
return
}
@ -301,17 +291,17 @@ func GetUserPosts(c *gin.Context) {
"ORDER": "latest_replied_on DESC",
}
posts, err := svc.GetPostList(&service.PostListReq{
posts, err := service.GetPostList(&service.PostListReq{
Conditions: conditions,
Offset: (app.GetPage(c) - 1) * app.GetPageSize(c),
Limit: app.GetPageSize(c),
})
if err != nil {
global.Logger.Errorf("svc.GetPostList err: %v\n", err)
global.Logger.Errorf("service.GetPostList err: %v\n", err)
response.ToErrorResponse(errcode.GetPostsFailed)
return
}
totalRows, _ := svc.GetPostCount(conditions)
totalRows, _ := service.GetPostCount(conditions)
response.ToResponseList(posts, totalRows)
}
@ -320,11 +310,10 @@ func GetUserCollections(c *gin.Context) {
response := app.NewResponse(c)
userID, _ := c.Get("UID")
svc := service.New(c)
posts, totalRows, err := svc.GetUserCollections(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
posts, totalRows, err := service.GetUserCollections(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
if err != nil {
global.Logger.Errorf("svc.GetUserCollections err: %v\n", err)
global.Logger.Errorf("service.GetUserCollections err: %v\n", err)
response.ToErrorResponse(errcode.GetCollectionsFailed)
return
}
@ -336,10 +325,9 @@ func GetUserStars(c *gin.Context) {
response := app.NewResponse(c)
userID, _ := c.Get("UID")
svc := service.New(c)
posts, totalRows, err := svc.GetUserStars(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
posts, totalRows, err := service.GetUserStars(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
if err != nil {
global.Logger.Errorf("svc.GetUserStars err: %v\n", err)
global.Logger.Errorf("service.GetUserStars err: %v\n", err)
response.ToErrorResponse(errcode.GetCollectionsFailed)
return
}
@ -351,10 +339,9 @@ func GetSuggestUsers(c *gin.Context) {
keyword := c.Query("k")
response := app.NewResponse(c)
svc := service.New(c)
usernames, err := svc.GetSuggestUsers(keyword)
usernames, err := service.GetSuggestUsers(keyword)
if err != nil {
global.Logger.Errorf("svc.GetSuggestUsers err: %v\n", err)
global.Logger.Errorf("service.GetSuggestUsers err: %v\n", err)
response.ToErrorResponse(errcode.GetCollectionsFailed)
return
}
@ -366,10 +353,9 @@ func GetSuggestTags(c *gin.Context) {
keyword := c.Query("k")
response := app.NewResponse(c)
svc := service.New(c)
tags, err := svc.GetSuggestTags(keyword)
tags, err := service.GetSuggestTags(keyword)
if err != nil {
global.Logger.Errorf("svc.GetSuggestTags err: %v\n", err)
global.Logger.Errorf("service.GetSuggestTags err: %v\n", err)
response.ToErrorResponse(errcode.GetCollectionsFailed)
return
}
@ -389,10 +375,9 @@ func GetUserRechargeLink(c *gin.Context) {
// 下单
userID, _ := c.Get("UID")
svc := service.New(c)
recharge, err := svc.CreateRecharge(userID.(int64), param.Amount)
recharge, err := service.CreateRecharge(userID.(int64), param.Amount)
if err != nil {
global.Logger.Errorf("svc.CreateRecharge err: %v\n", err)
global.Logger.Errorf("service.CreateRecharge err: %v\n", err)
response.ToErrorResponse(errcode.RechargeReqFail)
return
@ -456,8 +441,7 @@ func GetUserRechargeResult(c *gin.Context) {
id := c.Query("id")
userID, _ := c.Get("UID")
svc := service.New(c)
recharge, err := svc.GetRechargeByID(convert.StrTo(id).MustInt64())
recharge, err := service.GetRechargeByID(convert.StrTo(id).MustInt64())
if err != nil {
response.ToErrorResponse(errcode.GetRechargeFailed)
return
@ -514,15 +498,14 @@ func AlipayNotify(c *gin.Context) {
return
}
svc := service.New(c)
id := c.Request.Form.Get("out_trade_no")
tradeNo := c.Request.Form.Get("trade_no")
tradeStatus := c.Request.Form.Get("trade_status")
if tradeStatus == "TRADE_SUCCESS" {
// 交易支付成功
err = svc.FinishRecharge(convert.StrTo(id).MustInt64(), tradeNo)
err = service.FinishRecharge(c, convert.StrTo(id).MustInt64(), tradeNo)
if err != nil {
global.Logger.Errorf("svc.FinishRecharge err: %v\n", err)
global.Logger.Errorf("service.FinishRecharge err: %v\n", err)
response.ToErrorResponse(errcode.RechargeNotifyError)
return
}
@ -534,11 +517,10 @@ func GetUserWalletBills(c *gin.Context) {
response := app.NewResponse(c)
userID, _ := c.Get("UID")
svc := service.New(c)
bills, totalRows, err := svc.GetUserWalletBills(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
bills, totalRows, err := service.GetUserWalletBills(userID.(int64), (app.GetPage(c)-1)*app.GetPageSize(c), app.GetPageSize(c))
if err != nil {
global.Logger.Errorf("svc.GetUserWalletBills err: %v\n", err)
global.Logger.Errorf("service.GetUserWalletBills err: %v\n", err)
response.ToErrorResponse(errcode.GetCollectionsFailed)
return
}

@ -2,6 +2,6 @@ package service
import "github.com/rocboss/paopao-ce/internal/model"
func (svc *Service) CreateAttachment(attachment *model.Attachment) (*model.Attachment, error) {
return svc.dao.CreateAttachment(attachment)
func CreateAttachment(attachment *model.Attachment) (*model.Attachment, error) {
return myDao.CreateAttachment(attachment)
}

@ -58,7 +58,7 @@ var defaultAvatars = []string{
"https://assets.paopao.info/public/avatar/default/abigail.png",
}
func (s *Service) GetRandomAvatar() string {
func GetRandomAvatar() string {
rand.Seed(time.Now().UnixMicro())
return defaultAvatars[rand.Intn(len(defaultAvatars))]
}

@ -4,6 +4,7 @@ import (
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/errcode"
@ -28,12 +29,12 @@ type ReplyDelReq struct {
ID int64 `json:"id" binding:"required"`
}
func (svc *Service) GetPostComments(postID int64, sort string, offset, limit int) ([]*model.CommentFormated, int64, error) {
func GetPostComments(postID int64, sort string, offset, limit int) ([]*model.CommentFormated, int64, error) {
conditions := &model.ConditionsT{
"post_id": postID,
"ORDER": sort,
}
comments, err := svc.dao.GetComments(conditions, offset, limit)
comments, err := myDao.GetComments(conditions, offset, limit)
if err != nil {
return nil, 0, err
@ -46,17 +47,17 @@ func (svc *Service) GetPostComments(postID int64, sort string, offset, limit int
commentIDs = append(commentIDs, comment.ID)
}
users, err := svc.dao.GetUsersByIDs(userIDs)
users, err := myDao.GetUsersByIDs(userIDs)
if err != nil {
return nil, 0, err
}
contents, err := svc.dao.GetCommentContentsByIDs(commentIDs)
contents, err := myDao.GetCommentContentsByIDs(commentIDs)
if err != nil {
return nil, 0, err
}
replies, err := svc.dao.GetCommentRepliesByID(commentIDs)
replies, err := myDao.GetCommentRepliesByID(commentIDs)
if err != nil {
return nil, 0, err
}
@ -84,14 +85,14 @@ func (svc *Service) GetPostComments(postID int64, sort string, offset, limit int
}
// 获取总量
totalRows, _ := svc.dao.GetCommentCount(conditions)
totalRows, _ := myDao.GetCommentCount(conditions)
return commentsFormated, totalRows, nil
}
func (svc *Service) CreatePostComment(userID int64, param CommentCreationReq) (*model.Comment, error) {
func CreatePostComment(ctx *gin.Context, userID int64, param CommentCreationReq) (*model.Comment, error) {
// 加载Post
post, err := svc.dao.GetPostByID(param.PostID)
post, err := myDao.GetPostByID(param.PostID)
if err != nil {
return nil, err
@ -100,14 +101,14 @@ func (svc *Service) CreatePostComment(userID int64, param CommentCreationReq) (*
if post.CommentCount >= global.AppSetting.MaxCommentCount {
return nil, errcode.MaxCommentCount
}
ip := svc.ctx.ClientIP()
ip := ctx.ClientIP()
comment := &model.Comment{
PostID: post.ID,
UserID: userID,
IP: ip,
IPLoc: util.GetIPLoc(ip),
}
comment, err = svc.dao.CreateComment(comment)
comment, err = myDao.CreateComment(comment)
if err != nil {
return nil, err
}
@ -127,41 +128,41 @@ func (svc *Service) CreatePostComment(userID int64, param CommentCreationReq) (*
Type: item.Type,
Sort: item.Sort,
}
svc.dao.CreateCommentContent(postContent)
myDao.CreateCommentContent(postContent)
}
// 更新Post回复数
post.CommentCount++
post.LatestRepliedOn = time.Now().Unix()
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
// 更新索引
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
// 创建用户消息提醒
postMaster, err := svc.dao.GetUserByID(post.UserID)
postMaster, err := myDao.GetUserByID(post.UserID)
if err == nil && postMaster.ID != userID {
go svc.dao.CreateMessage(&model.Message{
go myDao.CreateMessage(&model.Message{
SenderUserID: userID,
ReceiverUserID: postMaster.ID,
Type: model.MESSAGE_COMMENT,
Breif: "在泡泡中评论了你",
Brief: "在泡泡中评论了你",
PostID: post.ID,
CommentID: comment.ID,
})
}
for _, u := range param.Users {
user, err := svc.dao.GetUserByUsername(u)
user, err := myDao.GetUserByUsername(u)
if err != nil || user.ID == userID || user.ID == postMaster.ID {
continue
}
// 创建消息提醒
go svc.dao.CreateMessage(&model.Message{
go myDao.CreateMessage(&model.Message{
SenderUserID: userID,
ReceiverUserID: user.ID,
Type: model.MESSAGE_COMMENT,
Breif: "在泡泡评论中@了你",
Brief: "在泡泡评论中@了你",
PostID: post.ID,
CommentID: comment.ID,
})
@ -170,37 +171,38 @@ func (svc *Service) CreatePostComment(userID int64, param CommentCreationReq) (*
return comment, nil
}
func (svc *Service) GetPostComment(id int64) (*model.Comment, error) {
return svc.dao.GetCommentByID(id)
func GetPostComment(id int64) (*model.Comment, error) {
return myDao.GetCommentByID(id)
}
func (svc *Service) DeletePostComment(comment *model.Comment) error {
func DeletePostComment(comment *model.Comment) error {
// 加载post
post, err := svc.dao.GetPostByID(comment.PostID)
post, err := myDao.GetPostByID(comment.PostID)
if err == nil {
// 更新post回复数
post.CommentCount--
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
}
return svc.dao.DeleteComment(comment)
return myDao.DeleteComment(comment)
}
func (svc *Service) CreatePostCommentReply(commentID int64, content string, userID, atUserID int64) (*model.CommentReply, error) {
func createPostPreHandler(commentID int64, userID, atUserID int64) (*model.Post, *model.Comment, int64,
error) {
// 加载Comment
comment, err := svc.dao.GetCommentByID(commentID)
comment, err := myDao.GetCommentByID(commentID)
if err != nil {
return nil, err
return nil, nil, atUserID, err
}
// 加载comment的post
post, err := svc.dao.GetPostByID(comment.PostID)
post, err := myDao.GetPostByID(comment.PostID)
if err != nil {
return nil, err
return nil, nil, atUserID, err
}
if post.CommentCount >= global.AppSetting.MaxCommentCount {
return nil, errcode.MaxCommentCount
return nil, nil, atUserID, errcode.MaxCommentCount
}
if userID == atUserID {
@ -209,14 +211,27 @@ func (svc *Service) CreatePostCommentReply(commentID int64, content string, user
if atUserID > 0 {
// 检测目前用户是否存在
users, _ := svc.dao.GetUsersByIDs([]int64{atUserID})
users, _ := myDao.GetUsersByIDs([]int64{atUserID})
if len(users) == 0 {
atUserID = 0
}
}
return post, comment, atUserID, nil
}
func CreatePostCommentReply(ctx *gin.Context, commentID int64, content string, userID, atUserID int64) (*model.CommentReply, error) {
var (
post *model.Post
comment *model.Comment
err error
)
if post, comment, atUserID, err = createPostPreHandler(commentID, userID, atUserID); err != nil {
return nil, err
}
// 创建评论
ip := svc.ctx.ClientIP()
ip := ctx.ClientIP()
reply := &model.CommentReply{
CommentID: commentID,
UserID: userID,
@ -226,7 +241,7 @@ func (svc *Service) CreatePostCommentReply(commentID int64, content string, user
IPLoc: util.GetIPLoc(ip),
}
reply, err = svc.dao.CreateCommentReply(reply)
reply, err = myDao.CreateCommentReply(reply)
if err != nil {
return nil, err
}
@ -234,45 +249,45 @@ func (svc *Service) CreatePostCommentReply(commentID int64, content string, user
// 更新Post回复数
post.CommentCount++
post.LatestRepliedOn = time.Now().Unix()
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
// 更新索引
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
// 创建用户消息提醒
commentMaster, err := svc.dao.GetUserByID(comment.UserID)
commentMaster, err := myDao.GetUserByID(comment.UserID)
if err == nil && commentMaster.ID != userID {
go svc.dao.CreateMessage(&model.Message{
go myDao.CreateMessage(&model.Message{
SenderUserID: userID,
ReceiverUserID: commentMaster.ID,
Type: model.MESSAGE_REPLY,
Breif: "在泡泡评论下回复了你",
Brief: "在泡泡评论下回复了你",
PostID: post.ID,
CommentID: comment.ID,
ReplyID: reply.ID,
})
}
postMaster, err := svc.dao.GetUserByID(post.UserID)
postMaster, err := myDao.GetUserByID(post.UserID)
if err == nil && postMaster.ID != userID && commentMaster.ID != postMaster.ID {
go svc.dao.CreateMessage(&model.Message{
go myDao.CreateMessage(&model.Message{
SenderUserID: userID,
ReceiverUserID: postMaster.ID,
Type: model.MESSAGE_REPLY,
Breif: "在泡泡评论下发布了新回复",
Brief: "在泡泡评论下发布了新回复",
PostID: post.ID,
CommentID: comment.ID,
ReplyID: reply.ID,
})
}
if atUserID > 0 {
user, err := svc.dao.GetUserByID(atUserID)
user, err := myDao.GetUserByID(atUserID)
if err == nil && user.ID != userID && commentMaster.ID != user.ID && postMaster.ID != user.ID {
// 创建消息提醒
go svc.dao.CreateMessage(&model.Message{
go myDao.CreateMessage(&model.Message{
SenderUserID: userID,
ReceiverUserID: user.ID,
Type: model.MESSAGE_REPLY,
Breif: "在泡泡评论的回复中@了你",
Brief: "在泡泡评论的回复中@了你",
PostID: post.ID,
CommentID: comment.ID,
ReplyID: reply.ID,
@ -283,24 +298,24 @@ func (svc *Service) CreatePostCommentReply(commentID int64, content string, user
return reply, nil
}
func (svc *Service) GetPostCommentReply(id int64) (*model.CommentReply, error) {
return svc.dao.GetCommentReplyByID(id)
func GetPostCommentReply(id int64) (*model.CommentReply, error) {
return myDao.GetCommentReplyByID(id)
}
func (svc *Service) DeletePostCommentReply(reply *model.CommentReply) error {
err := svc.dao.DeleteCommentReply(reply)
func DeletePostCommentReply(reply *model.CommentReply) error {
err := myDao.DeleteCommentReply(reply)
if err != nil {
return err
}
// 加载Comment
comment, err := svc.dao.GetCommentByID(reply.CommentID)
comment, err := myDao.GetCommentByID(reply.CommentID)
if err != nil {
return err
}
// 加载comment的post
post, err := svc.dao.GetPostByID(comment.PostID)
post, err := myDao.GetPostByID(comment.PostID)
if err != nil {
return err
}
@ -308,10 +323,10 @@ func (svc *Service) DeletePostCommentReply(reply *model.CommentReply) error {
// 更新Post回复数
post.CommentCount--
post.LatestRepliedOn = time.Now().Unix()
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
// 更新索引
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
return nil
}

@ -4,13 +4,14 @@ import (
"fmt"
"time"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/convert"
"github.com/rocboss/paopao-ce/pkg/errcode"
)
// 当日单用户私信总数限制TODO 配置化、积分兑换等)
// MAX_WHISPER_NUM_DAILY 当日单用户私信总数限制TODO 配置化、积分兑换等)
const MAX_WHISPER_NUM_DAILY = 20
type ReadMessageReq struct {
@ -21,37 +22,37 @@ type WhisperReq struct {
Content string `json:"content" binding:"required"`
}
// 创建私信
func (svc *Service) CreateWhisper(msg *model.Message) (*model.Message, error) {
// CreateWhisper 创建私信
func CreateWhisper(c *gin.Context, msg *model.Message) (*model.Message, error) {
whisperKey := fmt.Sprintf("WhisperTimes:%d", msg.SenderUserID)
// 今日频次限制
if res, _ := global.Redis.Get(svc.ctx, whisperKey).Result(); convert.StrTo(res).MustInt() >= MAX_WHISPER_NUM_DAILY {
if res, _ := global.Redis.Get(c, whisperKey).Result(); convert.StrTo(res).MustInt() >= MAX_WHISPER_NUM_DAILY {
return nil, errcode.TooManyWhisperNum
}
// 创建私信
msg, err := svc.dao.CreateMessage(msg)
msg, err := myDao.CreateMessage(msg)
if err != nil {
return nil, err
}
// 写入当日(自然日)计数缓存
global.Redis.Incr(svc.ctx, whisperKey).Result()
global.Redis.Incr(c, whisperKey).Result()
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
global.Redis.Expire(svc.ctx, whisperKey, endTime.Sub(currentTime))
global.Redis.Expire(c, whisperKey, endTime.Sub(currentTime))
return msg, err
}
func (svc *Service) GetUnreadCount(userID int64) (int64, error) {
return svc.dao.GetUnreadCount(userID)
func GetUnreadCount(userID int64) (int64, error) {
return myDao.GetUnreadCount(userID)
}
func (svc *Service) ReadMessage(id, userID int64) error {
func ReadMessage(id, userID int64) error {
// 获取message
message, err := svc.dao.GetMessageByID(id)
message, err := myDao.GetMessageByID(id)
if err != nil {
return err
}
@ -61,20 +62,20 @@ func (svc *Service) ReadMessage(id, userID int64) error {
}
// 已读消息
return svc.dao.ReadMessage(message)
return myDao.ReadMessage(message)
}
func (svc *Service) GetMessages(userID int64, offset, limit int) ([]*model.MessageFormated, int64, error) {
func GetMessages(userID int64, offset, limit int) ([]*model.MessageFormated, int64, error) {
conditions := &model.ConditionsT{
"receiver_user_id": userID,
"ORDER": "id DESC",
}
messages, err := svc.dao.GetMessages(conditions, offset, limit)
messages, err := myDao.GetMessages(conditions, offset, limit)
for _, mf := range messages {
if mf.SenderUserID > 0 {
user, err := svc.dao.GetUserByID(mf.SenderUserID)
user, err := myDao.GetUserByID(mf.SenderUserID)
if err == nil {
mf.SenderUser = user.Format()
}
@ -82,17 +83,17 @@ func (svc *Service) GetMessages(userID int64, offset, limit int) ([]*model.Messa
}
if mf.PostID > 0 {
post, err := svc.GetPost(mf.PostID)
post, err := GetPost(mf.PostID)
if err == nil {
mf.Post = post
if mf.CommentID > 0 {
comment, err := svc.GetPostComment(mf.CommentID)
comment, err := GetPostComment(mf.CommentID)
if err == nil {
mf.Comment = comment
if mf.ReplyID > 0 {
reply, err := svc.GetPostCommentReply(mf.ReplyID)
reply, err := GetPostCommentReply(mf.ReplyID)
if err == nil {
mf.Reply = reply
}
@ -108,7 +109,7 @@ func (svc *Service) GetMessages(userID int64, offset, limit int) ([]*model.Messa
}
// 获取总量
totalRows, _ := svc.dao.GetMessageCount(conditions)
totalRows, _ := myDao.GetMessageCount(conditions)
return messages, totalRows, nil
}

@ -7,6 +7,7 @@ import (
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/dao"
"github.com/rocboss/paopao-ce/internal/model"
@ -39,26 +40,50 @@ type PostCreationReq struct {
type PostDelReq struct {
ID int64 `json:"id" binding:"required"`
}
type PostLockReq struct {
ID int64 `json:"id" binding:"required"`
}
type PostStickReq struct {
ID int64 `json:"id" binding:"required"`
}
type PostStarReq struct {
ID int64 `json:"id" binding:"required"`
}
type PostCollectionReq struct {
ID int64 `json:"id" binding:"required"`
}
type PostContentItem struct {
Content string `json:"content" binding:"required"`
Type model.PostContentT `json:"type" binding:"required"`
Sort int64 `json:"sort" binding:"required"`
}
func (svc *Service) CreatePost(userID int64, param PostCreationReq) (*model.Post, error) {
ip := svc.ctx.ClientIP()
// Check 检查PostContentItem属性
func (p *PostContentItem) Check() error {
// 检查附件是否是本站资源
if p.Type == model.CONTENT_TYPE_IMAGE || p.Type == model.CONTENT_TYPE_VIDEO || p.Type == model.
CONTENT_TYPE_ATTACHMENT {
if strings.Index(p.Content, "https://"+global.AliossSetting.AliossDomain) != 0 {
return fmt.Errorf("附件非本站资源")
}
}
// 检查链接是否合法
if p.Type == model.CONTENT_TYPE_LINK {
if strings.Index(p.Content, "http://") != 0 && strings.Index(p.Content, "https://") != 0 {
return fmt.Errorf("链接不合法")
}
}
return nil
}
func CreatePost(c *gin.Context, userID int64, param PostCreationReq) (*model.Post, error) {
ip := c.ClientIP()
post := &model.Post{
UserID: userID,
@ -67,7 +92,7 @@ func (svc *Service) CreatePost(userID int64, param PostCreationReq) (*model.Post
IPLoc: util.GetIPLoc(ip),
AttachmentPrice: param.AttachmentPrice,
}
post, err := svc.dao.CreatePost(post)
post, err := myDao.CreatePost(post)
if err != nil {
return nil, err
}
@ -78,22 +103,13 @@ func (svc *Service) CreatePost(userID int64, param PostCreationReq) (*model.Post
UserID: userID,
Tag: t,
}
svc.dao.CreateTag(tag)
myDao.CreateTag(tag)
}
for _, item := range param.Contents {
// 检查附件是否是本站资源
if item.Type == model.CONTENT_TYPE_IMAGE || item.Type == model.CONTENT_TYPE_VIDEO || item.Type == model.CONTENT_TYPE_ATTACHMENT {
if strings.Index(item.Content, "https://"+global.AliossSetting.AliossDomain) != 0 {
continue
}
}
// 检查链接是否合法
if item.Type == model.CONTENT_TYPE_LINK {
if strings.Index(item.Content, "http://") != 0 && strings.Index(item.Content, "https://") != 0 {
continue
}
if err = item.Check(); err != nil {
// 属性非法
continue
}
if item.Type == model.CONTENT_TYPE_ATTACHMENT && param.AttachmentPrice > 0 {
@ -107,25 +123,25 @@ func (svc *Service) CreatePost(userID int64, param PostCreationReq) (*model.Post
Type: item.Type,
Sort: item.Sort,
}
svc.dao.CreatePostContent(postContent)
myDao.CreatePostContent(postContent)
}
// 推送Search
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
// 创建用户消息提醒
for _, u := range param.Users {
user, err := svc.dao.GetUserByUsername(u)
user, err := myDao.GetUserByUsername(u)
if err != nil || user.ID == userID {
continue
}
// 创建消息提醒
go svc.dao.CreateMessage(&model.Message{
go myDao.CreateMessage(&model.Message{
SenderUserID: userID,
ReceiverUserID: user.ID,
Type: model.MESSAGE_POST,
Breif: "在新发布的泡泡动态中@了你",
Brief: "在新发布的泡泡动态中@了你",
PostID: post.ID,
})
}
@ -133,8 +149,8 @@ func (svc *Service) CreatePost(userID int64, param PostCreationReq) (*model.Post
return post, nil
}
func (svc *Service) DeletePost(id int64) error {
post, _ := svc.dao.GetPostByID(id)
func DeletePost(id int64) error {
post, _ := myDao.GetPostByID(id)
// tag删除
tags := strings.Split(post.Tags, ",")
@ -143,25 +159,25 @@ func (svc *Service) DeletePost(id int64) error {
tag := &model.Tag{
Tag: t,
}
svc.dao.DeleteTag(tag)
myDao.DeleteTag(tag)
}
err := svc.dao.DeletePost(post)
err := myDao.DeletePost(post)
if err != nil {
return err
}
// 删除索引
go svc.DeleteSearchPost(post)
go DeleteSearchPost(post)
return nil
}
func (svc *Service) LockPost(id int64) error {
post, _ := svc.dao.GetPostByID(id)
func LockPost(id int64) error {
post, _ := myDao.GetPostByID(id)
err := svc.dao.LockPost(post)
err := myDao.LockPost(post)
if err != nil {
return err
@ -170,10 +186,10 @@ func (svc *Service) LockPost(id int64) error {
return nil
}
func (svc *Service) StickPost(id int64) error {
post, _ := svc.dao.GetPostByID(id)
func StickPost(id int64) error {
post, _ := myDao.GetPostByID(id)
err := svc.dao.StickPost(post)
err := myDao.StickPost(post)
if err != nil {
return err
@ -182,109 +198,109 @@ func (svc *Service) StickPost(id int64) error {
return nil
}
func (svc *Service) GetPostStar(postID, userID int64) (*model.PostStar, error) {
return svc.dao.GetUserPostStar(postID, userID)
func GetPostStar(postID, userID int64) (*model.PostStar, error) {
return myDao.GetUserPostStar(postID, userID)
}
func (svc *Service) CreatePostStar(postID, userID int64) (*model.PostStar, error) {
func CreatePostStar(postID, userID int64) (*model.PostStar, error) {
// 加载Post
post, err := svc.dao.GetPostByID(postID)
post, err := myDao.GetPostByID(postID)
if err != nil {
return nil, err
}
star, err := svc.dao.CreatePostStar(postID, userID)
star, err := myDao.CreatePostStar(postID, userID)
if err != nil {
return nil, err
}
// 更新Post点赞数
post.UpvoteCount++
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
// 更新索引
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
return star, nil
}
func (svc *Service) DeletePostStar(star *model.PostStar) error {
err := svc.dao.DeletePostStar(star)
func DeletePostStar(star *model.PostStar) error {
err := myDao.DeletePostStar(star)
if err != nil {
return err
}
// 加载Post
post, err := svc.dao.GetPostByID(star.PostID)
post, err := myDao.GetPostByID(star.PostID)
if err != nil {
return err
}
// 更新Post点赞数
post.UpvoteCount--
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
// 更新索引
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
return nil
}
func (svc *Service) GetPostCollection(postID, userID int64) (*model.PostCollection, error) {
return svc.dao.GetUserPostCollection(postID, userID)
func GetPostCollection(postID, userID int64) (*model.PostCollection, error) {
return myDao.GetUserPostCollection(postID, userID)
}
func (svc *Service) CreatePostCollection(postID, userID int64) (*model.PostCollection, error) {
func CreatePostCollection(postID, userID int64) (*model.PostCollection, error) {
// 加载Post
post, err := svc.dao.GetPostByID(postID)
post, err := myDao.GetPostByID(postID)
if err != nil {
return nil, err
}
collection, err := svc.dao.CreatePostCollection(postID, userID)
collection, err := myDao.CreatePostCollection(postID, userID)
if err != nil {
return nil, err
}
// 更新Post点赞数
post.CollectionCount++
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
// 更新索引
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
return collection, nil
}
func (svc *Service) DeletePostCollection(collection *model.PostCollection) error {
err := svc.dao.DeletePostCollection(collection)
func DeletePostCollection(collection *model.PostCollection) error {
err := myDao.DeletePostCollection(collection)
if err != nil {
return err
}
// 加载Post
post, err := svc.dao.GetPostByID(collection.PostID)
post, err := myDao.GetPostByID(collection.PostID)
if err != nil {
return err
}
// 更新Post点赞数
post.CollectionCount--
svc.dao.UpdatePost(post)
myDao.UpdatePost(post)
// 更新索引
go svc.PushPostToSearch(post)
go PushPostToSearch(post)
return nil
}
func (svc *Service) GetPost(id int64) (*model.PostFormated, error) {
post, err := svc.dao.GetPostByID(id)
func GetPost(id int64) (*model.PostFormated, error) {
post, err := myDao.GetPostByID(id)
if err != nil {
return nil, err
}
postContents, err := svc.dao.GetPostContentsByIDs([]int64{post.ID})
postContents, err := myDao.GetPostContentsByIDs([]int64{post.ID})
if err != nil {
return nil, err
}
users, err := svc.dao.GetUsersByIDs([]int64{post.UserID})
users, err := myDao.GetUsersByIDs([]int64{post.UserID})
if err != nil {
return nil, err
}
@ -302,21 +318,21 @@ func (svc *Service) GetPost(id int64) (*model.PostFormated, error) {
return postFormated, nil
}
func (svc *Service) GetPostContentByID(id int64) (*model.PostContent, error) {
return svc.dao.GetPostContentByID(id)
func GetPostContentByID(id int64) (*model.PostContent, error) {
return myDao.GetPostContentByID(id)
}
func (svc *Service) GetPostList(req *PostListReq) ([]*model.PostFormated, error) {
posts, err := svc.dao.GetPosts(req.Conditions, req.Offset, req.Limit)
func GetPostList(req *PostListReq) ([]*model.PostFormated, error) {
posts, err := myDao.GetPosts(req.Conditions, req.Offset, req.Limit)
if err != nil {
return nil, err
}
return svc.FormatPosts(posts)
return FormatPosts(posts)
}
func (svc *Service) FormatPosts(posts []*model.Post) ([]*model.PostFormated, error) {
func FormatPosts(posts []*model.Post) ([]*model.PostFormated, error) {
postIds := []int64{}
userIds := []int64{}
for _, post := range posts {
@ -324,12 +340,12 @@ func (svc *Service) FormatPosts(posts []*model.Post) ([]*model.PostFormated, err
userIds = append(userIds, post.UserID)
}
postContents, err := svc.dao.GetPostContentsByIDs(postIds)
postContents, err := myDao.GetPostContentsByIDs(postIds)
if err != nil {
return nil, err
}
users, err := svc.dao.GetUsersByIDs(userIds)
users, err := myDao.GetUsersByIDs(userIds)
if err != nil {
return nil, err
}
@ -356,17 +372,17 @@ func (svc *Service) FormatPosts(posts []*model.Post) ([]*model.PostFormated, err
return postsFormated, nil
}
func (svc *Service) GetPostCount(conditions *model.ConditionsT) (int64, error) {
return svc.dao.GetPostCount(conditions)
func GetPostCount(conditions *model.ConditionsT) (int64, error) {
return myDao.GetPostCount(conditions)
}
func (svc *Service) GetPostListFromSearch(q *dao.QueryT, offset, limit int) ([]*model.PostFormated, int64, error) {
queryResult, err := svc.dao.QueryAll(q, global.SearchSetting.ZincIndex, offset, limit)
func GetPostListFromSearch(q *dao.QueryT, offset, limit int) ([]*model.PostFormated, int64, error) {
queryResult, err := myDao.QueryAll(q, global.SearchSetting.ZincIndex, offset, limit)
if err != nil {
return nil, 0, err
}
posts, err := svc.FormatZincPost(queryResult)
posts, err := FormatZincPost(queryResult)
if err != nil {
return nil, 0, err
}
@ -374,13 +390,13 @@ func (svc *Service) GetPostListFromSearch(q *dao.QueryT, offset, limit int) ([]*
return posts, queryResult.Hits.Total.Value, nil
}
func (svc *Service) GetPostListFromSearchByQuery(query string, offset, limit int) ([]*model.PostFormated, int64, error) {
queryResult, err := svc.dao.QuerySearch(global.SearchSetting.ZincIndex, query, offset, limit)
func GetPostListFromSearchByQuery(query string, offset, limit int) ([]*model.PostFormated, int64, error) {
queryResult, err := myDao.QuerySearch(global.SearchSetting.ZincIndex, query, offset, limit)
if err != nil {
return nil, 0, err
}
posts, err := svc.FormatZincPost(queryResult)
posts, err := FormatZincPost(queryResult)
if err != nil {
return nil, 0, err
}
@ -388,14 +404,14 @@ func (svc *Service) GetPostListFromSearchByQuery(query string, offset, limit int
return posts, queryResult.Hits.Total.Value, nil
}
func (svc *Service) PushPostToSearch(post *model.Post) {
func PushPostToSearch(post *model.Post) {
indexName := global.SearchSetting.ZincIndex
postFormated := post.Format()
postFormated.User = &model.UserFormated{
ID: post.UserID,
}
contents, _ := svc.dao.GetPostContentsByIDs([]int64{post.ID})
contents, _ := myDao.GetPostContentsByIDs([]int64{post.ID})
for _, content := range contents {
postFormated.Contents = append(postFormated.Contents, content.Format())
}
@ -436,31 +452,31 @@ func (svc *Service) PushPostToSearch(post *model.Post) {
"modified_on": post.ModifiedOn,
})
svc.dao.BulkPushDoc(data)
myDao.BulkPushDoc(data)
}
func (svc *Service) DeleteSearchPost(post *model.Post) error {
func DeleteSearchPost(post *model.Post) error {
indexName := global.SearchSetting.ZincIndex
return svc.dao.DelDoc(indexName, fmt.Sprintf("%d", post.ID))
return myDao.DelDoc(indexName, fmt.Sprintf("%d", post.ID))
}
func (svc *Service) PushPostsToSearch() {
if ok, _ := global.Redis.SetNX(svc.ctx, "JOB_PUSH_TO_SEARCH", 1, time.Hour).Result(); ok {
func PushPostsToSearch(c *gin.Context) {
if ok, _ := global.Redis.SetNX(c, "JOB_PUSH_TO_SEARCH", 1, time.Hour).Result(); ok {
splitNum := 1000
totalRows, _ := svc.GetPostCount(&model.ConditionsT{})
totalRows, _ := GetPostCount(&model.ConditionsT{})
pages := math.Ceil(float64(totalRows) / float64(splitNum))
nums := int(pages)
indexName := global.SearchSetting.ZincIndex
// 创建索引
svc.dao.CreateSearchIndex(indexName)
myDao.CreateSearchIndex(indexName)
for i := 0; i < nums; i++ {
data := []map[string]interface{}{}
posts, _ := svc.GetPostList(&PostListReq{
posts, _ := GetPostList(&PostListReq{
Conditions: &model.ConditionsT{},
Offset: i * splitNum,
Limit: splitNum,
@ -499,15 +515,15 @@ func (svc *Service) PushPostsToSearch() {
}
if len(data) > 0 {
svc.dao.BulkPushDoc(data)
myDao.BulkPushDoc(data)
}
}
global.Redis.Del(svc.ctx, "JOB_PUSH_TO_SEARCH")
global.Redis.Del(c, "JOB_PUSH_TO_SEARCH")
}
}
func (svc *Service) FormatZincPost(queryResult *zinc.QueryResultT) ([]*model.PostFormated, error) {
func FormatZincPost(queryResult *zinc.QueryResultT) ([]*model.PostFormated, error) {
posts := []*model.PostFormated{}
for _, hit := range queryResult.Hits.Hits {
item := &model.PostFormated{}
@ -525,12 +541,12 @@ func (svc *Service) FormatZincPost(queryResult *zinc.QueryResultT) ([]*model.Pos
postIds = append(postIds, post.ID)
userIds = append(userIds, post.UserID)
}
postContents, err := svc.dao.GetPostContentsByIDs(postIds)
postContents, err := myDao.GetPostContentsByIDs(postIds)
if err != nil {
return nil, err
}
users, err := svc.dao.GetUsersByIDs(userIds)
users, err := myDao.GetUsersByIDs(userIds)
if err != nil {
return nil, err
}
@ -555,7 +571,7 @@ func (svc *Service) FormatZincPost(queryResult *zinc.QueryResultT) ([]*model.Pos
return posts, nil
}
func (svc *Service) GetPostTags(param *PostTagsReq) ([]*model.TagFormated, error) {
func GetPostTags(param *PostTagsReq) ([]*model.TagFormated, error) {
num := param.Num
if num > global.AppSetting.MaxPageSize {
num = global.AppSetting.MaxPageSize
@ -575,7 +591,7 @@ func (svc *Service) GetPostTags(param *PostTagsReq) ([]*model.TagFormated, error
}
}
tags, err := svc.dao.GetTags(conditions, 0, num)
tags, err := myDao.GetTags(conditions, 0, num)
if err != nil {
return nil, err
}
@ -586,7 +602,7 @@ func (svc *Service) GetPostTags(param *PostTagsReq) ([]*model.TagFormated, error
userIds = append(userIds, tag.UserID)
}
users, _ := svc.dao.GetUsersByIDs(userIds)
users, _ := myDao.GetUsersByIDs(userIds)
tagsFormated := []*model.TagFormated{}
for _, tag := range tags {
@ -602,8 +618,8 @@ func (svc *Service) GetPostTags(param *PostTagsReq) ([]*model.TagFormated, error
return tagsFormated, nil
}
func (svc *Service) CheckPostAttachmentIsPaid(postID, userID int64) bool {
bill, err := svc.dao.GetPostAttatchmentBill(postID, userID)
func CheckPostAttachmentIsPaid(postID, userID int64) bool {
bill, err := myDao.GetPostAttatchmentBill(postID, userID)
return err == nil && bill.Model != nil && bill.ID > 0
}

@ -1,26 +1,15 @@
package service
import (
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/dao"
"github.com/rocboss/paopao-ce/pkg/zinc"
"gorm.io/gorm"
)
type Service struct {
ctx *gin.Context
dao *dao.Dao
}
func New(ctx *gin.Context) Service {
svc := Service{ctx: ctx}
svc.dao = dao.New(global.DBEngine, &zinc.ZincClient{
ZincClientConfig: &zinc.ZincClientConfig{
ZincHost: global.SearchSetting.ZincHost,
ZincUser: global.SearchSetting.ZincUser,
ZincPassword: global.SearchSetting.ZincPassword,
},
})
var (
myDao *dao.Dao
)
return svc
func Initialize(engine *gorm.DB, client *zinc.ZincClient) {
myDao = dao.New(engine, client)
}

@ -8,7 +8,7 @@ import (
"github.com/rocboss/paopao-ce/pkg/util"
)
func (svc *Service) GetParamSign(param map[string]interface{}, secretKey string) string {
func GetParamSign(param map[string]interface{}, secretKey string) string {
signRaw := ""
rawStrs := []string{}

@ -7,6 +7,7 @@ import (
"time"
"unicode/utf8"
"github.com/gin-gonic/gin"
"github.com/gofrs/uuid"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/model"
@ -32,6 +33,7 @@ type AuthRequest struct {
Username string `json:"username" form:"username" binding:"required"`
Password string `json:"password" form:"password" binding:"required"`
}
type RegisterRequest struct {
Username string `json:"username" form:"username" binding:"required"`
Password string `json:"password" form:"password" binding:"required"`
@ -41,9 +43,11 @@ type ChangePasswordReq struct {
Password string `json:"password" form:"password" binding:"required"`
OldPassword string `json:"old_password" form:"old_password" binding:"required"`
}
type ChangeNicknameReq struct {
Nickname string `json:"nickname" form:"nickname" binding:"required"`
}
type ChangeAvatarReq struct {
Avatar string `json:"avatar" form:"avatar" binding:"required"`
}
@ -51,36 +55,36 @@ type ChangeAvatarReq struct {
const LOGIN_ERR_KEY = "PaoPaoUserLoginErr"
const MAX_LOGIN_ERR_TIMES = 10
// 用户认证
func (svc *Service) DoLogin(param *AuthRequest) (*model.User, error) {
user, err := svc.dao.GetUserByUsername(param.Username)
// DoLogin 用户认证
func DoLogin(ctx *gin.Context, param *AuthRequest) (*model.User, error) {
user, err := myDao.GetUserByUsername(param.Username)
if err != nil {
return nil, errcode.UnauthorizedAuthNotExist
}
if user.Model != nil && user.ID > 0 {
if errTimes, err := global.Redis.Get(svc.ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID)).Result(); err == nil {
if errTimes, err := global.Redis.Get(ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID)).Result(); err == nil {
if convert.StrTo(errTimes).MustInt() >= MAX_LOGIN_ERR_TIMES {
return nil, errcode.TooManyLoginError
}
}
// 对比密码是否正确
if svc.ValidPassword(user.Password, param.Password, user.Salt) {
if ValidPassword(user.Password, param.Password, user.Salt) {
if user.Status == model.UserStatusClosed {
return nil, errcode.UserHasBeenBanned
}
// 清空登录计数
global.Redis.Del(svc.ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID))
global.Redis.Del(ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID))
return user, nil
}
// 登录错误计数
_, err = global.Redis.Incr(svc.ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID)).Result()
_, err = global.Redis.Incr(ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID)).Result()
if err == nil {
global.Redis.Expire(svc.ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID), time.Hour).Result()
global.Redis.Expire(ctx, fmt.Sprintf("%s:%d", LOGIN_ERR_KEY, user.ID), time.Hour).Result()
}
return nil, errcode.UnauthorizedAuthFailed
@ -89,18 +93,18 @@ func (svc *Service) DoLogin(param *AuthRequest) (*model.User, error) {
return nil, errcode.UnauthorizedAuthNotExist
}
// 检查密码是否一致
func (svc *Service) ValidPassword(dbPassword, password, salt string) bool {
// ValidPassword 检查密码是否一致
func ValidPassword(dbPassword, password, salt string) bool {
return strings.Compare(dbPassword, util.EncodeMD5(util.EncodeMD5(password)+salt)) == 0
}
// 检测用户权限
func (svc *Service) CheckStatus(user *model.User) bool {
// CheckStatus 检测用户权限
func CheckStatus(user *model.User) bool {
return user.Status == model.UserStatusNormal
}
// 验证用户
func (svc *Service) ValidUsername(username string) error {
// ValidUsername 验证用户
func ValidUsername(username string) error {
// 检测用户是否合规
if utf8.RuneCountInString(username) < 3 || utf8.RuneCountInString(username) > 12 {
return errcode.UsernameLengthLimit
@ -111,7 +115,7 @@ func (svc *Service) ValidUsername(username string) error {
}
// 重复检查
user, _ := svc.dao.GetUserByUsername(username)
user, _ := myDao.GetUserByUsername(username)
if user.Model != nil && user.ID > 0 {
return errcode.UsernameHasExisted
@ -120,8 +124,8 @@ func (svc *Service) ValidUsername(username string) error {
return nil
}
// 密码检查
func (svc *Service) CheckPassword(password string) error {
// CheckPassword 密码检查
func CheckPassword(password string) error {
// 检测用户是否合规
if utf8.RuneCountInString(password) < 6 || utf8.RuneCountInString(password) > 16 {
return errcode.PasswordLengthLimit
@ -130,9 +134,9 @@ func (svc *Service) CheckPassword(password string) error {
return nil
}
// 验证手机验证码
func (svc *Service) CheckPhoneCaptcha(phone, captcha string) *errcode.Error {
c, err := svc.dao.GetLatestPhoneCaptcha(phone)
// CheckPhoneCaptcha 验证手机验证码
func CheckPhoneCaptcha(phone, captcha string) *errcode.Error {
c, err := myDao.GetLatestPhoneCaptcha(phone)
if err != nil {
return errcode.ErrorPhoneCaptcha
}
@ -150,14 +154,14 @@ func (svc *Service) CheckPhoneCaptcha(phone, captcha string) *errcode.Error {
}
// 更新检测次数
svc.dao.UsePhoneCaptcha(c)
myDao.UsePhoneCaptcha(c)
return nil
}
// 检测手机号是否存在
func (svc *Service) CheckPhoneExist(uid int64, phone string) bool {
u, err := svc.dao.GetUserByPhone(phone)
// CheckPhoneExist 检测手机号是否存在
func CheckPhoneExist(uid int64, phone string) bool {
u, err := myDao.GetUserByPhone(phone)
if err != nil {
return false
}
@ -173,28 +177,28 @@ func (svc *Service) CheckPhoneExist(uid int64, phone string) bool {
return true
}
// 密码加密&生成salt
func (svc *Service) EncryptPasswordAndSalt(password string) (string, string) {
// EncryptPasswordAndSalt 密码加密&生成salt
func EncryptPasswordAndSalt(password string) (string, string) {
salt := uuid.Must(uuid.NewV4()).String()[:8]
password = util.EncodeMD5(util.EncodeMD5(password) + salt)
return password, salt
}
// 用户注册
func (svc *Service) Register(username, password string) (*model.User, error) {
password, salt := svc.EncryptPasswordAndSalt(password)
// Register 用户注册
func Register(username, password string) (*model.User, error) {
password, salt := EncryptPasswordAndSalt(password)
user := &model.User{
Nickname: username,
Username: username,
Password: password,
Avatar: svc.GetRandomAvatar(),
Avatar: GetRandomAvatar(),
Salt: salt,
Status: model.UserStatusNormal,
}
user, err := svc.dao.CreateUser(user)
user, err := myDao.CreateUser(user)
if err != nil {
return nil, err
}
@ -202,9 +206,9 @@ func (svc *Service) Register(username, password string) (*model.User, error) {
return user, nil
}
// 获取用户信息
func (svc *Service) GetUserInfo(param *AuthRequest) (*model.User, error) {
user, err := svc.dao.GetUserByUsername(param.Username)
// GetUserInfo 获取用户信息
func GetUserInfo(param *AuthRequest) (*model.User, error) {
user, err := myDao.GetUserByUsername(param.Username)
if err != nil {
return nil, err
@ -217,8 +221,8 @@ func (svc *Service) GetUserInfo(param *AuthRequest) (*model.User, error) {
return nil, errcode.UnauthorizedAuthNotExist
}
func (svc *Service) GetUserByUsername(username string) (*model.User, error) {
user, err := svc.dao.GetUserByUsername(username)
func GetUserByUsername(username string) (*model.User, error) {
user, err := myDao.GetUserByUsername(username)
if err != nil {
return nil, err
@ -231,18 +235,18 @@ func (svc *Service) GetUserByUsername(username string) (*model.User, error) {
return nil, errcode.NoExistUsername
}
// 更新用户信息
func (svc *Service) UpdateUserInfo(user *model.User) error {
return svc.dao.UpdateUser(user)
// UpdateUserInfo 更新用户信息
func UpdateUserInfo(user *model.User) error {
return myDao.UpdateUser(user)
}
// 获取用户收藏列表
func (svc *Service) GetUserCollections(userID int64, offset, limit int) ([]*model.PostFormated, int64, error) {
collections, err := svc.dao.GetUserPostCollections(userID, offset, limit)
// GetUserCollections 获取用户收藏列表
func GetUserCollections(userID int64, offset, limit int) ([]*model.PostFormated, int64, error) {
collections, err := myDao.GetUserPostCollections(userID, offset, limit)
if err != nil {
return nil, 0, err
}
totalRows, err := svc.dao.GetUserPostCollectionCount(userID)
totalRows, err := myDao.GetUserPostCollectionCount(userID)
if err != nil {
return nil, 0, err
}
@ -252,7 +256,7 @@ func (svc *Service) GetUserCollections(userID int64, offset, limit int) ([]*mode
}
// 获取Posts
posts, err := svc.dao.GetPosts(&model.ConditionsT{
posts, err := myDao.GetPosts(&model.ConditionsT{
"id IN ?": postIDs,
"ORDER": "id DESC",
}, 0, 0)
@ -260,7 +264,7 @@ func (svc *Service) GetUserCollections(userID int64, offset, limit int) ([]*mode
return nil, 0, err
}
postsFormated, err := svc.FormatPosts(posts)
postsFormated, err := FormatPosts(posts)
if err != nil {
return nil, 0, err
}
@ -268,13 +272,13 @@ func (svc *Service) GetUserCollections(userID int64, offset, limit int) ([]*mode
return postsFormated, totalRows, nil
}
// 获取用户点赞列表
func (svc *Service) GetUserStars(userID int64, offset, limit int) ([]*model.PostFormated, int64, error) {
stars, err := svc.dao.GetUserPostStars(userID, offset, limit)
// GetUserStars 获取用户点赞列表
func GetUserStars(userID int64, offset, limit int) ([]*model.PostFormated, int64, error) {
stars, err := myDao.GetUserPostStars(userID, offset, limit)
if err != nil {
return nil, 0, err
}
totalRows, err := svc.dao.GetUserPostStarCount(userID)
totalRows, err := myDao.GetUserPostStarCount(userID)
if err != nil {
return nil, 0, err
}
@ -284,7 +288,7 @@ func (svc *Service) GetUserStars(userID int64, offset, limit int) ([]*model.Post
}
// 获取Posts
posts, err := svc.dao.GetPosts(&model.ConditionsT{
posts, err := myDao.GetPosts(&model.ConditionsT{
"id IN ?": postIDs,
"ORDER": "id DESC",
}, 0, 0)
@ -292,7 +296,7 @@ func (svc *Service) GetUserStars(userID int64, offset, limit int) ([]*model.Post
return nil, 0, err
}
postsFormated, err := svc.FormatPosts(posts)
postsFormated, err := FormatPosts(posts)
if err != nil {
return nil, 0, err
}
@ -300,13 +304,13 @@ func (svc *Service) GetUserStars(userID int64, offset, limit int) ([]*model.Post
return postsFormated, totalRows, nil
}
// 获取用户账单列表
func (svc *Service) GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, int64, error) {
bills, err := svc.dao.GetUserWalletBills(userID, offset, limit)
// GetUserWalletBills 获取用户账单列表
func GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, int64, error) {
bills, err := myDao.GetUserWalletBills(userID, offset, limit)
if err != nil {
return nil, 0, err
}
totalRows, err := svc.dao.GetUserWalletBillCount(userID)
totalRows, err := myDao.GetUserWalletBillCount(userID)
if err != nil {
return nil, 0, err
}
@ -314,28 +318,28 @@ func (svc *Service) GetUserWalletBills(userID int64, offset, limit int) ([]*mode
return bills, totalRows, nil
}
// 发送短信验证码
func (svc *Service) SendPhoneCaptcha(phone string) error {
// SendPhoneCaptcha 发送短信验证码
func SendPhoneCaptcha(ctx *gin.Context, phone string) error {
err := svc.dao.SendPhoneCaptcha(phone)
err := myDao.SendPhoneCaptcha(phone)
if err != nil {
return err
}
// 写入计数缓存
global.Redis.Incr(svc.ctx, "PaoPaoSmsCaptcha:"+phone).Result()
global.Redis.Incr(ctx, "PaoPaoSmsCaptcha:"+phone).Result()
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
global.Redis.Expire(svc.ctx, "PaoPaoSmsCaptcha:"+phone, endTime.Sub(currentTime))
global.Redis.Expire(ctx, "PaoPaoSmsCaptcha:"+phone, endTime.Sub(currentTime))
return nil
}
// 根据关键词获取用户推荐
func (svc *Service) GetSuggestUsers(keyword string) ([]string, error) {
users, err := svc.dao.GetUsersByKeyword(keyword)
// GetSuggestUsers 根据关键词获取用户推荐
func GetSuggestUsers(keyword string) ([]string, error) {
users, err := myDao.GetUsersByKeyword(keyword)
if err != nil {
return nil, err
}
@ -348,9 +352,9 @@ func (svc *Service) GetSuggestUsers(keyword string) ([]string, error) {
return usernames, nil
}
// 根据关键词获取标签推荐
func (svc *Service) GetSuggestTags(keyword string) ([]string, error) {
tags, err := svc.dao.GetTagsByKeyword(keyword)
// GetSuggestTags 根据关键词获取标签推荐
func GetSuggestTags(keyword string) ([]string, error) {
tags, err := myDao.GetTagsByKeyword(keyword)
if err != nil {
return nil, err
}

@ -3,6 +3,7 @@ package service
import (
"time"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/errcode"
@ -12,17 +13,17 @@ type RechargeReq struct {
Amount int64 `json:"amount" form:"amount" binding:"required"`
}
func (svc *Service) GetRechargeByID(id int64) (*model.WalletRecharge, error) {
return svc.dao.GetRechargeByID(id)
func GetRechargeByID(id int64) (*model.WalletRecharge, error) {
return myDao.GetRechargeByID(id)
}
func (svc *Service) CreateRecharge(userID, amount int64) (*model.WalletRecharge, error) {
return svc.dao.CreateRecharge(userID, amount)
func CreateRecharge(userID, amount int64) (*model.WalletRecharge, error) {
return myDao.CreateRecharge(userID, amount)
}
func (svc *Service) FinishRecharge(id int64, tradeNo string) error {
if ok, _ := global.Redis.SetNX(svc.ctx, "PaoPaoRecharge:"+tradeNo, 1, time.Second*5).Result(); ok {
recharge, err := svc.dao.GetRechargeByID(id)
func FinishRecharge(ctx *gin.Context, id int64, tradeNo string) error {
if ok, _ := global.Redis.SetNX(ctx, "PaoPaoRecharge:"+tradeNo, 1, time.Second*5).Result(); ok {
recharge, err := myDao.GetRechargeByID(id)
if err != nil {
return err
}
@ -30,8 +31,8 @@ func (svc *Service) FinishRecharge(id int64, tradeNo string) error {
if recharge.TradeStatus != "TRADE_SUCCESS" {
// 标记为已付款
err := svc.dao.HandleRechargeSuccess(recharge, tradeNo)
defer global.Redis.Del(svc.ctx, "PaoPaoRecharge:"+tradeNo)
err := myDao.HandleRechargeSuccess(recharge, tradeNo)
defer global.Redis.Del(ctx, "PaoPaoRecharge:"+tradeNo)
if err != nil {
return err
@ -43,11 +44,11 @@ func (svc *Service) FinishRecharge(id int64, tradeNo string) error {
return nil
}
func (svc *Service) BuyPostAttachment(post *model.Post, user *model.User) error {
func BuyPostAttachment(post *model.Post, user *model.User) error {
if user.Balance < post.AttachmentPrice {
return errcode.InsuffientDownloadMoney
}
// 执行购买
return svc.dao.HandlePostAttachmentBought(post, user)
return myDao.HandlePostAttachmentBought(post, user)
}

@ -4,9 +4,15 @@ import (
"fmt"
"net/http"
"github.com/fatih/color"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/routers"
"github.com/rocboss/paopao-ce/pkg/util"
)
var (
version, buildDate, commitID string
)
func main() {
@ -21,6 +27,9 @@ func main() {
MaxHeaderBytes: 1 << 20,
}
fmt.Printf("\x1b[36m%s\x1b[0m\n", "PaoPao service listen on http://"+global.ServerSetting.HttpIp+":"+global.ServerSetting.HttpPort)
util.PrintHelloBanner(fmt.Sprintf("paopao %s (build:%s %s)", version, commitID, buildDate))
fmt.Fprintf(color.Output, "PaoPao service listen on %s\n",
color.GreenString(fmt.Sprintf("http://%s:%s", global.ServerSetting.HttpIp, global.ServerSetting.HttpPort)),
)
s.ListenAndServe()
}

@ -111,7 +111,7 @@ CREATE TABLE `p_message` (
`sender_user_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '发送方用户ID',
`receiver_user_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '接收方用户ID',
`type` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '通知类型1动态2评论3回复4私信99系统通知',
`breif` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '摘要说明',
`brief` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '摘要说明',
`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '详细内容',
`post_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '动态ID',
`comment_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '评论ID',

@ -0,0 +1,117 @@
package convert
import (
"testing"
)
func TestStrTo_String(t *testing.T) {
type fields struct {
Str string
}
tests := []struct {
name string
fields fields
want string
}{
{
name: "test",
fields: fields{Str: "test"},
want: "test",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := StrTo(tt.fields.Str)
if got := s.String(); got != tt.want {
t.Errorf("StrTo.String() = %v, want %v", got, tt.want)
}
})
}
}
func TestStrTo_Int(t *testing.T) {
var s StrTo = "123"
i, err := s.Int()
if err != nil {
t.Errorf("s.Int() error: %v", err)
}
if i != 123 {
t.Errorf("s.Int() should be 123")
}
}
func TestStrTo_MustInt(t *testing.T) {
var s StrTo = "123"
i := s.MustInt()
if i != 123 {
t.Errorf("s.MustInt() should be 123")
}
}
func TestStrTo_UInt32(t *testing.T) {
var s StrTo = "123"
i, err := s.UInt32()
if err != nil {
t.Errorf("s.UInt32() error: %v", err)
}
if i != 123 {
t.Errorf("s.UInt32() should be 123")
}
}
func TestStrTo_UInt32_2(t *testing.T) {
var s StrTo = "-123"
i, err := s.UInt32()
if err != nil {
t.Errorf("s.UInt32() error: %v", err)
}
if i == 123 {
t.Errorf("s.UInt32() should not be 123")
}
}
func TestStrTo_MustUInt32(t *testing.T) {
var s StrTo = "123"
i := s.MustUInt32()
if i != 123 {
t.Errorf("s.MustUInt32() should be 123")
}
}
func TestStrTo_Int64(t *testing.T) {
var s StrTo = "123"
i, err := s.Int64()
if err != nil {
t.Errorf("s.Int64() error: %v", err)
}
if i != 123 {
t.Errorf("s.Int64() should be 123")
}
}
func TestStrTo_MustInt64(t *testing.T) {
var s StrTo = "123"
i := s.MustInt64()
if i != 123 {
t.Errorf("s.MustInt64() should be 123")
}
}
func TestStrTo_Float64(t *testing.T) {
var s StrTo = "123.456"
f, err := s.Float64()
if err != nil {
t.Errorf("s.Float64() error: %v", err)
}
if f != 123.456 {
t.Errorf("s.Float64() should be 123.456")
}
}
func TestStrTo_MustFloat64(t *testing.T) {
var s StrTo = "123.456"
f := s.MustFloat64()
if f != 123.456 {
t.Errorf("s.MustFloat64() should be 123.456")
}
}

@ -51,6 +51,10 @@ type AppSettingS struct {
AlipayPrivateKey string
}
type RuntimeSettingS struct {
DisablePhoneVerify bool
}
type SearchSettingS struct {
ZincHost string
ZincIndex string

@ -6,8 +6,8 @@ import (
"time"
"github.com/fbsobreira/gotron-sdk/pkg/proto/core"
"github.com/golang/protobuf/proto"
"github.com/rocboss/paopao-ce/pkg/crypto"
"google.golang.org/protobuf/proto"
)
// SignTransaction 签名交易

@ -0,0 +1,12 @@
package util
import "fmt"
func PrintHelloBanner(text string) {
fmt.Println(" ____ __ __ ____ __ __ ")
fmt.Println("( _ \\ / _\\ / \\( _ \\ / _\\ / \\ ")
fmt.Println(" ) __// \\( O )) __// \\( O )")
fmt.Println("(__) \\_/\\_/ \\__/(__) \\_/\\_/ \\__/ ")
fmt.Println(text)
}

@ -1,12 +1,8 @@
package util
import (
"github.com/yinheli/qqwry"
)
import "github.com/rocboss/paopao-ce/pkg/util/iploc"
func GetIPLoc(ip string) string {
q := qqwry.NewQQwry("qqwry.dat")
q.Find(ip)
return q.Country
country, _ := iploc.Find(ip)
return country
}

@ -0,0 +1,128 @@
package iploc
import (
_ "embed"
"encoding/binary"
"net"
"github.com/yinheli/mahonia"
)
// Note: This file is a modified version of https://github.com/yinheli/qqwry.
//go:embed qqwry.dat
var qqwry []byte
const (
cIndexLen = 7
cRedirectMode1 = 0x01
cRedirectMode2 = 0x02
)
// Find get country and city base ip
func Find(ip string) (string, string) {
offset := searchIndex(binary.BigEndian.Uint32(net.ParseIP(ip).To4()))
if offset <= 0 {
return "", ""
}
var country, area []byte
mode := readMode(offset + 4)
if mode == cRedirectMode1 {
countryOffset := readUInt24(offset + 5)
mode = readMode(countryOffset)
if mode == cRedirectMode2 {
c := readUInt24(countryOffset + 1)
country = readString(c)
countryOffset += 4
} else {
country = readString(countryOffset)
countryOffset += uint32(len(country) + 1)
}
area = readArea(countryOffset)
} else if mode == cRedirectMode2 {
countryOffset := readUInt24(offset + 5)
country = readString(countryOffset)
area = readArea(offset + 8)
} else {
country = readString(offset + 4)
area = readArea(offset + uint32(5+len(country)))
}
enc := mahonia.NewDecoder("gbk")
Country := enc.ConvertString(string(country))
City := enc.ConvertString(string(area))
return Country, City
}
func readMode(offset uint32) byte {
return qqwry[offset]
}
func readArea(offset uint32) []byte {
mode := readMode(offset)
if mode == cRedirectMode1 || mode == cRedirectMode2 {
areaOffset := readUInt24(offset + 1)
if areaOffset == 0 {
return []byte("")
} else {
return readString(areaOffset)
}
} else {
return readString(offset)
}
}
func readString(offset uint32) []byte {
data := make([]byte, 0, 30)
for {
if qqwry[offset] == 0 {
break
}
data = append(data, qqwry[offset])
offset++
}
return data
}
func searchIndex(ip uint32) uint32 {
header := qqwry[:8]
start := binary.LittleEndian.Uint32(header[:4])
end := binary.LittleEndian.Uint32(header[4:])
for {
mid := getMiddleOffset(start, end)
buf := qqwry[mid : mid+cIndexLen]
ipaddr := binary.LittleEndian.Uint32(buf[:4])
if end-start == cIndexLen {
offset := byte3ToUInt32(buf[4:])
// TODO: 这里可能有bug需要优化
if ip < binary.LittleEndian.Uint32(qqwry[end:end+4]) {
return offset
} else {
return 0
}
}
// 找到的比较大,向前移
if ipaddr > ip {
end = mid
} else if ipaddr < ip { // 找到的比较小,向后移
start = mid
} else {
return byte3ToUInt32(buf[4:])
}
}
}
func readUInt24(offset uint32) uint32 {
return byte3ToUInt32(qqwry[offset : offset+3])
}
func getMiddleOffset(start uint32, end uint32) uint32 {
records := ((end - start) / cIndexLen) >> 1
return start + records*cIndexLen
}
func byte3ToUInt32(data []byte) uint32 {
i := uint32(data[0]) & 0xff
i |= (uint32(data[1]) << 8) & 0xff00
i |= (uint32(data[2]) << 16) & 0xff0000
return i
}

@ -0,0 +1,25 @@
package iploc
import (
"testing"
)
func TestFind(t *testing.T) {
for _, data := range []struct {
ip string
country string
city string
}{
{ip: "127.0.0.1", country: "本机地址", city: " CZ88.NET"},
{ip: "180.89.94.9", country: "北京市", city: "鹏博士宽带"},
} {
country, city := Find(data.ip)
t.Logf("ip:%v, country:%v, city:%v", data.ip, country, city)
if country != data.country {
t.Errorf("find ip:%s expect country: %s got: %s", data.ip, data.country, country)
}
if city != data.city {
t.Errorf("find ip:%s expect city: %s got: %s", data.ip, data.city, city)
}
}
}

@ -8,6 +8,7 @@ import (
"time"
"github.com/go-resty/resty/v2"
"github.com/rocboss/paopao-ce/pkg/setting"
)
type ZincClient struct {
@ -49,14 +50,17 @@ type QueryResultT struct {
TimedOut bool `json:"timed_out"`
Hits *HitsResultT `json:"hits"`
}
type HitsResultT struct {
Total *HitsResultTotalT `json:"total"`
MaxScore float64 `json:"max_score"`
Hits []*HitItem `json:"hits"`
}
type HitsResultTotalT struct {
Value int64 `json:"value"`
}
type HitItem struct {
Index string `json:"_index"`
Type string `json:"_type"`
@ -66,6 +70,17 @@ type HitItem struct {
Source interface{} `json:"_source"`
}
// NewClient 获取ZincClient新实例
func NewClient(conf *setting.SearchSettingS) *ZincClient {
return &ZincClient{
ZincClientConfig: &ZincClientConfig{
ZincHost: conf.ZincHost,
ZincUser: conf.ZincUser,
ZincPassword: conf.ZincPassword,
},
}
}
// 创建索引
func (c *ZincClient) CreateIndex(name string, p *ZincIndexProperty) bool {
data := &ZincIndex{

@ -1,29 +1,16 @@
import request from '@/utils/request';
import { request } from '@/utils/request';
/**
*
* @param {Object} params
* - @param {string} username
* - @param {string} password
* @returns Promise
*/
export const userLogin = (params: NetParams.AuthUserLogin = {}) => {
/** 用户登录 */
export const userLogin = (params: NetParams.AuthUserLogin): Promise<NetReq.AuthUserLogin> => {
return request({
method: 'post',
url: '/auth/login',
data: params,
}) as unknown as Promise<NetReq.AuthUserLogin>;
});
};
/**
*
* @param {Object} params
* - @param {string} username
* - @param {string} password
* @returns Promise
*/
export const userRegister = (params = {}) => {
/** 注册用户 */
export const userRegister = (params: NetParams.AuthUserRegister): Promise<NetReq.AuthUserRegister> => {
return request({
method: 'post',
url: '/auth/register',
@ -31,12 +18,8 @@ export const userRegister = (params = {}) => {
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const userInfo = (token = '') => {
/** 用户信息 */
export const userInfo = (token: NetParams.AuthUserInfo = ""): Promise<NetReq.AuthUserInfo> => {
return request({
method: 'get',
url: '/user/info',
@ -46,14 +29,8 @@ export const userInfo = (token = '') => {
});
};
/**
*
* @param {Object} params
* - @param {string} password
* - @param {string} old_password
* @returns Promise
*/
export const updateUserPassword = (data: any) => {
/** 修改用户密码,该接口暂时未使用 */
export const updateUserPassword = (data: NetParams.AuthUpdateUserPassword): Promise<NetReq.AuthUpdateUserPassword> => {
return request({
method: 'post',
url: '/api/user/password',

@ -1,132 +1,88 @@
import request from '@/utils/request';
import { request } from '@/utils/request';
/**
*
* @param {Object} params
* @returns Promise
*/
export const getPosts = (params: NetParams.PostGetPosts) => {
/** 获取动态列表 */
export const getPosts = (params: NetParams.PostGetPosts): Promise<NetReq.PostGetPosts> => {
return request({
method: 'get',
url: '/posts',
params
}) as unknown as Promise<NetReq.PostGetPosts>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getTags = (params: NetParams.PostGetTags) => {
/** 获取标签列表 */
export const getTags = (params: NetParams.PostGetTags): Promise<NetReq.PostGetTags> => {
return request({
method: 'get',
url: '/tags',
params
}) as unknown as Promise<NetReq.PostGetTags>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getPost = (params: NetParams.PostGetPost) => {
/** 获取动态详情 */
export const getPost = (params: NetParams.PostGetPost): Promise<NetReq.PostGetPost> => {
return request({
method: 'get',
url: '/post',
params
}) as unknown as Promise<NetReq.PostGetPost>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getPostStar = (params: NetParams.PostPostStar) => {
/** 获取动态点赞状态 */
export const getPostStar = (params: NetParams.PostPostStar): Promise<NetReq.PostGetPostStar> => {
return request({
method: 'get',
url: '/post/star',
params
}) as unknown as Promise<NetReq.PostGetPostStar>;
});
};
/**
*
* @param {Object} data
* @returns Promise
*/
export const postStar = (data: NetParams.PostPostStar) => {
/** 动态点赞 */
export const postStar = (data: NetParams.PostPostStar): Promise<NetReq.PostPostStar> => {
return request({
method: 'post',
url: '/post/star',
data
}) as unknown as Promise<NetReq.PostPostStar>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getPostCollection = (params: NetParams.PostGetPostCollection) => {
/** 获取动态收藏状态 */
export const getPostCollection = (params: NetParams.PostGetPostCollection): Promise<NetReq.PostGetPostCollection> => {
return request({
method: 'get',
url: '/post/collection',
params
}) as unknown as Promise<NetReq.PostGetPostCollection>;
});
};
/**
*
* @param {Object} data
* @returns Promise
*/
export const postCollection = (data: NetParams.PostPostCollection) => {
/** 动态收藏 */
export const postCollection = (data: NetParams.PostPostCollection): Promise<NetReq.PostPostCollection> => {
return request({
method: 'post',
url: '/post/collection',
data
}) as unknown as Promise<NetReq.PostPostCollection>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getPostComments = (params: NetParams.PostGetPostComments) => {
/** 获取动态评论列表 */
export const getPostComments = (params: NetParams.PostGetPostComments): Promise<NetReq.PostGetPostComments> => {
return request({
method: 'get',
url: '/post/comments',
params
}) as unknown as Promise<NetReq.PostGetPostComments>;
});
};
/**
*
* @param {Object} data
* - @param {array} contents
* - @param {array} users at
* - @param {array} tags
* @returns Promise
*/
export const createPost = (data: NetParams.PostCreatePost) => {
/** 发布动态 */
export const createPost = (data: NetParams.PostCreatePost): Promise<NetReq.PostCreatePost> => {
return request({
method: 'post',
url: '/post',
data
}) as unknown as Promise<NetReq.PostCreatePost>;
});
};
/**
*
* @param {Object} data
* - @param {number} id
* @returns Promise
*/
export const deletePost = (data: any) => {
/** 删除动态 */
export const deletePost = (data: NetParams.PostDeletePost): Promise<NetReq.PostDeletePost> => {
return request({
method: 'delete',
url: '/post',
@ -134,42 +90,26 @@ export const deletePost = (data: any) => {
});
};
/**
* /
* @param {Object} data
* - @param {number} id
* @returns Promise
*/
export const lockPost = (data: NetParams.PostLockPost) => {
/** 锁定/解锁动态 */
export const lockPost = (data: NetParams.PostLockPost): Promise<NetReq.PostLockPost> => {
return request({
method: 'post',
url: '/post/lock',
data
}) as unknown as Promise<NetReq.PostLockPost>;
});
};
/**
* /
* @param {Object} data
* - @param {number} id
* @returns Promise
*/
export const stickPost = (data: NetParams.PostStickPost) => {
/** 置顶/取消置顶动态 */
export const stickPost = (data: NetParams.PostStickPost): Promise<NetReq.PostStickPost> => {
return request({
method: 'post',
url: '/post/stick',
data
}) as unknown as Promise<NetReq.PostStickPost>;
});
};
/**
*
* @param {Object} data
* - @param {array} contents
* - @param {array} users at
* @returns Promise
*/
export const createComment = (data: any) => {
/** 发布动态评论 */
export const createComment = (data: NetParams.PostCreateComment): Promise<NetReq.PostCreateComment> => {
return request({
method: 'post',
url: '/post/comment',
@ -177,13 +117,8 @@ export const createComment = (data: any) => {
});
};
/**
*
* @param {Object} data
* - @param {number} id
* @returns Promise
*/
export const deleteComment = (data: any) => {
/** 删除评论 */
export const deleteComment = (data: NetParams.PostDeleteComment): Promise<NetReq.PostDeleteComment> => {
return request({
method: 'delete',
url: '/post/comment',
@ -191,15 +126,8 @@ export const deleteComment = (data: any) => {
});
};
/**
*
* @param {Object} data
* - @param {string} content
* - @param {number} comment_id ID
* - @param {number} at_user_id atID
* @returns Promise
*/
export const createCommentReply = (data: any) => {
/** 发布评论回复 */
export const createCommentReply = (data: NetParams.PostCreateCommentReply): Promise<NetReq.PostCreateCommentReply> => {
return request({
method: 'post',
url: '/post/comment/reply',
@ -207,16 +135,11 @@ export const createCommentReply = (data: any) => {
});
};
/**
*
* @param {Object} data
* - @param {number} id ID
* @returns Promise
*/
export const deleteCommentReply = (data: any) => {
/** 删除评论回复 */
export const deleteCommentReply = (data: NetParams.PostDeleteCommentReply): Promise<NetReq.PostDeleteCommentReply> => {
return request({
method: 'delete',
url: '/post/comment/reply',
data
});
};
};

@ -1,16 +1,12 @@
import request from '@/utils/request';
import { request } from '@/utils/request';
/**
*
* @param {Object} params
* @returns Promise
*/
export const getCaptcha = (params: NetParams.UserGetCaptcha = {}) => {
/** 获取验证码 */
export const getCaptcha = (params: NetParams.UserGetCaptcha = {}): Promise<NetReq.UserGetCaptcha> => {
return request({
method: 'get',
url: '/captcha',
params
}) as unknown as Promise<NetReq.UserGetCaptcha>;
});
};
/**
@ -31,12 +27,12 @@ export const sendCaptcha = (data: any) => {
* @param {Object} data
* @returns Promise
*/
export const sendUserWhisper = (data: NetParams.UserWhisper) => {
export const sendUserWhisper = (data: NetParams.UserWhisper): Promise<NetParams.UserWhisper> => {
return request({
method: 'post',
url: '/user/whisper',
data
}) as unknown as Promise<NetParams.UserWhisper>;
});
};
/**
@ -44,20 +40,16 @@ export const sendUserWhisper = (data: NetParams.UserWhisper) => {
* @param {Object} data
* @returns Promise
*/
export const bindUserPhone = (data: NetParams.UserBindUserPhone) => {
export const bindUserPhone = (data: NetParams.UserBindUserPhone): Promise<NetParams.UserBindUserPhone> => {
return request({
method: 'post',
url: '/user/phone',
data
}) as unknown as Promise<NetParams.UserBindUserPhone>;
});
};
/**
*
* @param {Object} data
* @returns Promise
*/
export const changePassword = (data: any) => {
/** 更改密码 */
export const changePassword = (data: NetParams.UserChangePassword): Promise<NetReq.UserChangePassword> => {
return request({
method: 'post',
url: '/user/password',
@ -65,12 +57,8 @@ export const changePassword = (data: any) => {
});
};
/**
*
* @param {Object} data
* @returns Promise
*/
export const changeNickname = (data: any) => {
/** 更改昵称 */
export const changeNickname = (data: NetParams.UserChangeNickname): Promise<NetReq.UserChangeNickname> => {
return request({
method: 'post',
url: '/user/nickname',
@ -91,30 +79,22 @@ export const changeAvatar = (data: any) => {
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getUnreadMsgCount = (params: NetParams.UserGetUnreadMsgCount = {}) => {
/** 获取未读消息数 */
export const getUnreadMsgCount = (params: NetParams.UserGetUnreadMsgCount = {}): Promise<NetReq.UserGetUnreadMsgCount> => {
return request({
method: 'get',
url: '/user/msgcount/unread',
params
}) as unknown as Promise<NetReq.UserGetUnreadMsgCount>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getMessages = (params: NetParams.UserGetMessages) => {
/** 获取消息列表 */
export const getMessages = (params: NetParams.UserGetMessages): Promise<NetReq.UserGetMessages> => {
return request({
method: 'get',
url: '/user/messages',
params
}) as unknown as Promise<NetReq.UserGetMessages>;
});
};
/**
@ -130,69 +110,49 @@ export const readMessage = (data: any) => {
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getCollections = (params: NetParams.UserGetCollections) => {
/** 获取收藏列表 */
export const getCollections = (params: NetParams.UserGetCollections): Promise<NetReq.UserGetCollections> => {
return request({
method: 'get',
url: '/user/collections',
params
}) as unknown as Promise<NetReq.UserGetCollections>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getStars = (params: NetParams.UserGetStars) => {
/** 获取点赞列表 */
export const getStars = (params: NetParams.UserGetStars): Promise<NetReq.UserGetStars> => {
return request({
method: 'get',
url: '/user/stars',
params
}) as unknown as Promise<NetReq.UserGetStars>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getUserProfile = (params: NetParams.UserGetUserProfile) => {
/** 获取用户基础信息 */
export const getUserProfile = (params: NetParams.UserGetUserProfile): Promise<NetReq.UserGetUserProfile> => {
return request({
method: 'get',
url: '/user/profile',
params
}) as unknown as Promise<NetReq.UserGetUserProfile>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getUserPosts = (params: NetParams.UserGetUserPosts) => {
/** 获取用户帖子列表 */
export const getUserPosts = (params: NetParams.UserGetUserPosts): Promise<NetReq.UserGetUserPosts> => {
return request({
method: 'get',
url: '/user/posts',
params
}) as unknown as Promise<NetReq.UserGetUserPosts>;
});
};
/**
*
* @param {Object} params
* @returns Promise
*/
export const getBills = (params: NetParams.UserGetBills) => {
/** 获取账单列表 */
export const getBills = (params: NetParams.UserGetBills): Promise<NetReq.UserGetBills> => {
return request({
method: 'get',
url: '/user/wallet/bills',
params
}) as unknown as Promise<NetReq.UserGetBills>;
});
};
/**
@ -200,12 +160,12 @@ export const getBills = (params: NetParams.UserGetBills) => {
* @param {Object} data
* @returns Promise
*/
export const reqRecharge = (data: NetParams.UserReqRecharge) => {
export const reqRecharge = (data: NetParams.UserReqRecharge): Promise<NetReq.UserReqRecharge> => {
return request({
method: 'post',
url: '/user/recharge',
data
}) as unknown as Promise<NetReq.UserReqRecharge>;
});
};
/**
@ -213,12 +173,12 @@ export const reqRecharge = (data: NetParams.UserReqRecharge) => {
* @param {Object} params
* @returns Promise
*/
export const getRecharge = (params: NetParams.UserGetRecharge) => {
export const getRecharge = (params: NetParams.UserGetRecharge): Promise<NetReq.UserGetRecharge> => {
return request({
method: 'get',
url: '/user/recharge',
params
}) as unknown as Promise<NetReq.UserGetRecharge>;
});
};
/**
@ -226,12 +186,12 @@ export const getRecharge = (params: NetParams.UserGetRecharge) => {
* @param {Object} params
* @returns Promise
*/
export const getSuggestUsers = (params: { k: string }) => {
export const getSuggestUsers = (params: { k: string }): Promise<NetReq.UserGetSuggestUsers> => {
return request({
method: 'get',
url: '/suggest/users',
params
}) as unknown as Promise<NetReq.UserGetSuggestUsers>;
});
};
/**
@ -239,12 +199,12 @@ export const getSuggestUsers = (params: { k: string }) => {
* @param {Object} params
* @returns Promise
*/
export const getSuggestTags = (params: { k: string }) => {
export const getSuggestTags = (params: { k: string }): Promise<NetReq.UserGetSuggestTags> => {
return request({
method: 'get',
url: '/suggest/tags',
params
}) as unknown as Promise<NetReq.UserGetSuggestTags>;
});
};
/**
@ -252,12 +212,12 @@ export const getSuggestTags = (params: { k: string }) => {
* @param {Object} params
* @returns Promise
*/
export const precheckAttachment = (params: NetParams.UserPrecheckAttachment) => {
export const precheckAttachment = (params: NetParams.UserPrecheckAttachment): Promise<NetReq.UserPrecheckAttachment> => {
return request({
method: 'get',
url: '/attachment/precheck',
params
}) as unknown as Promise<NetReq.UserPrecheckAttachment>;
});
};
/**
@ -265,10 +225,10 @@ export const precheckAttachment = (params: NetParams.UserPrecheckAttachment) =>
* @param {Object} params
* @returns Promise
*/
export const getAttachment = (params: NetParams.UserGetAttachment) => {
export const getAttachment = (params: NetParams.UserGetAttachment): Promise<NetReq.UserGetAttachment> => {
return request({
method: 'get',
url: '/attachment',
params
}) as unknown as Promise<NetReq.UserGetAttachment>;
});
};

@ -1,3 +1,8 @@
:root {
// 如果要变更中间栏的大小,修改此处即可
--content-main: 500px;
}
.app-container {
margin: 0;
@ -16,7 +21,7 @@
.content-wrap {
width: 100%;
max-width: 500px;
max-width: var(--content-main);
position: relative;
}

@ -113,20 +113,20 @@ const replyAtUsername = ref('');
const replyComposeRef = ref();
const emit = defineEmits<{
(e: "reload"): void
(e: 'reload'): void
}>();
const props = withDefaults(defineProps<{
comment: Item.CommentProps
}>(), {})
const comment = computed(() => {
let comment = Object.assign(
let comment: Item.CommentComponentProps = Object.assign(
{
texts: [],
imgs: [],
},
props.comment
) as {texts: Item.CommentProps[], imgs: Item.CommentProps[]} & Item.CommentProps;
);
comment.contents.map((content :any) => {
if (+content.type === 1 || +content.type === 2) {
comment.texts.push(content);

@ -170,7 +170,7 @@ import { parsePostTag } from '@/utils/content';
import type { MentionOption, UploadFileInfo, UploadInst } from 'naive-ui';
const emit = defineEmits<{
(e: "post-success"): void
(e: 'post-success'): void
}>();
const props = withDefaults(defineProps<{
lock: number,
@ -265,7 +265,7 @@ const finishUpload = ({ file, event }: any): any => {
imageContents.value.push({
id: file.id,
content: data.data.content,
});
} as Item.CommentItemProps);
}
}
} catch (error) {

@ -50,11 +50,11 @@ const props = withDefaults(defineProps<{
}>(), {
commentId: 0,
atUserid: 0,
atUsername: ""
atUsername: ''
});
const emit = defineEmits<{
(e: "reload"): void,
(e: "reset"): void
(e: 'reload'): void,
(e: 'reset'): void
}>();
const inputInstRef = ref<InputInst>();
const showReply = ref(false);

@ -265,7 +265,7 @@ const uploadType = ref('public/image');
const fileQueue = ref<UploadFileInfo[]>([]);
const imageContents = ref<Item.CommentItemProps[]>([]);
const videoContents = ref<Item.CommentItemProps[]>([]);
const attachmentContents = ref<Item.CommentItemProps[]>([]);
const attachmentContents = ref<Item.AttachmentProps[]>([]);
const uploadGateway = import.meta.env.VITE_HOST + '/attachment';
const uploadToken = ref();
@ -402,19 +402,19 @@ const finishUpload = ({ file, event }: any): any => {
imageContents.value.push({
id: file.id,
content: data.data.content,
});
} as Item.CommentItemProps);
}
if (uploadType.value === 'public/video') {
videoContents.value.push({
id: file.id,
content: data.data.content,
});
} as Item.CommentItemProps);
}
if (uploadType.value === 'attachment') {
attachmentContents.value.push({
id: file.id,
content: data.data.content,
});
} as Item.AttachmentProps);
}
}
} catch (error) {

@ -46,11 +46,11 @@
<template #description>
<n-alert
:show-icon="false"
class="breif-wrap"
class="brief-wrap"
:type="message.is_read > 0 ? 'default' : 'success'"
>
<div class="breif-content">
{{ message.breif }}
<div class="brief-content">
{{ message.brief }}
<span
v-if="message.type !== 4"
@click.stop="viewDetail(message)"
@ -146,9 +146,9 @@ const handleReadMessage = (message: Item.MessageProps) => {
}
}
.breif-wrap {
.brief-wrap {
margin-top: 10px;
.breif-content {
.brief-content {
display: flex;
width: 100%;
}

@ -42,7 +42,7 @@ import { precheckAttachment, getAttachment } from '@/api/user';
const props = withDefaults(
defineProps<{
attachments: Item.AttachmentProps[];
attachments: Item.PostItemProps[];
price?: number;
}>(),
{
@ -54,7 +54,7 @@ const showDownloadModal = ref(false);
const downloadTip = ref<any>('');
const attachmentID = ref(0);
const download = (attachment: Item.AttachmentProps) => {
const download = (attachment: Item.PostItemProps) => {
showDownloadModal.value = true;
attachmentID.value = attachment.id;

@ -197,7 +197,7 @@ const emit = defineEmits<{
const post = computed({
get: () => {
let post: Required<Item.PostProps> = Object.assign(
let post: Item.PostComponentProps = Object.assign(
{
texts: [],
imgs: [],

@ -230,7 +230,7 @@ const defaultImg =
const thumbnail =
'?x-oss-process=image/resize,m_fill,w_300,h_300,limit_0/auto-orient,1/format,png';
const props = withDefaults(defineProps<{
imgs: Item.PostProps[],
imgs: Item.PostItemProps[],
}>(), {
imgs: () => []
});

@ -101,7 +101,7 @@ const props = withDefaults(defineProps<{
}>(), {});
const post = computed(() => {
let post: Required<Item.PostProps> = Object.assign(
let post: Item.PostComponentProps = Object.assign(
{
texts: [],
imgs: [],

@ -17,7 +17,7 @@
<script setup lang="ts">
import { LinkOutline } from '@vicons/ionicons5';
const props = withDefaults(defineProps<{
links: Item.PostProps[]
links: Item.PostItemProps[]
}>(), {
links: () => []
});

@ -22,7 +22,7 @@ import NVideo from 'nonesir-video';
const props = withDefaults(
defineProps<{
videos: Item.PostProps[];
videos: Item.PostItemProps[];
full?: boolean;
}>(),
{

@ -76,8 +76,8 @@ const props = withDefaults(defineProps<{
}>(), {});
const store = useStore();
const emit = defineEmits<{
(e: "focusReply", reply: Item.ReplyProps): void,
(e: "reload"): void
(e: 'focusReply', reply: Item.ReplyProps): void,
(e: 'reload'): void
}>();
const focusReply = () => {

@ -119,7 +119,7 @@ onMounted(() => {
.rightbar-wrap {
width: 240px;
position: fixed;
left: calc(50% + 260px);
left: calc(50% + var(--content-main) / 2 + 10px);
.search-wrap {
margin: 12px 0;
}

@ -279,7 +279,7 @@ window.$message = useMessage();
width: 200px;
height: 100vh;
position: fixed;
right: calc(50% + 260px);
right: calc(50% + var(--content-main) / 2 + 10px);
padding: 12px 0;
box-sizing: border-box;
.n-menu .n-menu-item-content::before {

@ -1,8 +1,26 @@
declare module NetParams {
interface AuthUserLogin {
username?: string,
password?: string
/** 用户名 */
username: string,
/** 密码 */
password: string
}
interface AuthUserRegister {
/** 用户名 */
username: string,
/** 密码 */
password: string
}
type AuthUserInfo = string
interface AuthUpdateUserPassword {
/** 新密码 */
password: string,
/** 旧密码 */
old_password: string
}
interface UserGetCollections {
@ -28,6 +46,7 @@ declare module NetParams {
}
interface UserGetUserPosts {
/** 用户名 */
username: string,
page: number,
page_size: number
@ -69,13 +88,25 @@ declare module NetParams {
content: string
}
interface UserChangePassword {
/** 新密码 */
password: string,
/** 旧密码 */
old_password: string
}
interface UserChangeNickname {
/** 昵称 */
nickname: string
}
interface PostGetPost {
id: number
}
interface PostGetPosts {
query: string | null,
type: number,
type: string,
page: number,
page_size: number
}
@ -92,11 +123,11 @@ declare module NetParams {
id: number
}
interface PostGetPostCollection {
interface PostPostStar {
id: number
}
interface PostPostStar {
interface PostGetPostCollection {
id: number
}
@ -105,7 +136,7 @@ declare module NetParams {
}
interface PostGetTags {
type: "hot" | string,
type: 'hot' | string,
num: number
}
@ -114,14 +145,44 @@ declare module NetParams {
}
interface PostCreatePost {
contents: {
content: string,
type: number,
sort: number
}[],
/** 帖子内容列表 */
contents: Partial<Item.PostItemProps>[],
/** 标签列表 */
tags: string[],
/** 艾特用户列表 */
users: string[],
/** 附件价格 */
attachment_price: number
}
}
interface PostDeletePost {
id: number
}
interface PostCreateComment {
/** 内容ID */
post_id: number,
/** 帖子内容列表 */
contents: Partial<Item.CommentItemProps>[],
/** 艾特用户列表 */
users: string[]
}
interface PostDeleteComment {
id: number
}
interface PostCreateCommentReply {
/** 艾特的用户UID */
at_user_id: number,
/** 回复的评论ID */
comment_id: number,
/** 回复内容 */
content: string
}
interface PostDeleteCommentReply{
id: number
}
}

@ -1,12 +1,27 @@
declare module NetReq {
interface AuthUserLogin {
token?: string
token: string
}
interface AuthUserRegister {
/** 用户UID */
id: number,
/** 用户名 */
username: string
}
type AuthUserInfo = Item.UserInfo
interface AuthUpdateUserPassword {
}
interface UserGetCollections {
list: any[],
pager: AnyObject
/** 帖子列表 */
list: Item.PostProps[],
/** 页码信息 */
pager: Item.PagerProps
}
type UserGetSuggestUsers = string[]
@ -23,17 +38,23 @@ declare module NetReq {
}
interface UserGetMessages {
/** 消息列表 */
list: Item.MessageProps[],
/** 页码信息 */
pager: Item.PagerProps
}
interface UserGetUserPosts {
/** 帖子列表 */
list: Item.PostProps[],
/** 页码信息 */
pager: Item.PagerProps
}
interface UserGetStars {
/** 帖子列表 */
list: Item.PostProps[],
/** 页码信息 */
pager: Item.PagerProps
}
@ -41,6 +62,7 @@ declare module NetReq {
interface UserGetBills {
list: Item.BillProps[],
/** 页码信息 */
pager: Item.PagerProps
}
@ -59,33 +81,46 @@ declare module NetReq {
interface UserGetCaptcha {
id: string,
/** 头像图片 base64 */
b64s: string
}
interface UserChangeNickname {
}
interface UserChangePassword {
}
type PostGetPost = Item.PostProps
interface PostGetPosts {
/** 帖子列表 */
list: Item.PostProps[],
/** 页码信息 */
pager: Item.PagerProps
}
interface PostLockPost {
lock_status: number
/** 锁定状态0为未锁定1为锁定 */
lock_status: 0 | 1
}
interface PostStickPost {
top_status: number
/** 置顶状态0为未置顶1为置顶 */
top_status: 0 | 1
}
interface PostGetPostStar {
status: boolean
}
interface PostGetPostCollection {
interface PostPostStar {
status: boolean
}
interface PostPostStar {
interface PostGetPostCollection {
status: boolean
}
@ -96,9 +131,28 @@ declare module NetReq {
type PostGetTags = Item.TagProps[]
interface PostGetPostComments {
list: Item.PostProps[]
/** 评论列表 */
list: Item.CommentProps[],
/** 页码信息 */
pager: Item.PagerProps
}
type PostCreatePost = Item.PostProps
}
interface PostDeletePost {
}
type PostCreateComment = Item.CommentProps
interface PostDeleteComment {
}
type PostCreateCommentReply = Item.ReplyProps
interface PostDeleteCommentReply{
}
}

@ -1,85 +1,282 @@
declare module Item {
interface UserInfo {
/** 用户UID */
id: number,
/** 用户名 */
username: string,
/** 用户昵称 */
nickname: string,
avatar: string
/** 用户头像 */
avatar: string,
/** 用户手机号 */
phone?: string,
/** 是否为管理员 */
is_admin: boolean,
/** 用户余额(分) */
balance?: number,
/** 用户状态 */
status?: 0 | 1
}
/** 评论内容 */
interface CommentItemProps {
id: number | string,
content: string
/** 内容ID */
id: number,
/** 评论ID */
comment_id: number,
/** 评论者UID */
user_id: number,
/** 类别1为标题2为文字段落3为图片地址4为视频地址5为语音地址6为链接地址 */
type: number,
/** 内容 */
content: string,
/** 排序,越小越靠前 */
sort: number,
/** 创建时间 */
created_on: number,
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1
}
interface CommentProps extends CommentItemProps {
type: number,
/** 评论数据 */
interface CommentProps {
id: number,
post_id: number,
/** 评论者UID */
user_id: number,
/** 评论者用户信息 */
user: UserInfo,
contents: CommentProps[],
/** 评论内容 */
contents: CommentItemProps[],
/** 回复列表 */
replies: ReplyProps[],
/** 评论者IP地址 */
ip?: string,
/** 评论者城市地址 */
ip_loc: string,
created_on: number
/** 创建时间 */
created_on: number,
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1
}
interface CommentComponentProps extends CommentProps {
/** 文字评论列表 */
texts: CommentItemProps[],
/** 图片评论列表 */
imgs: CommentItemProps[]
}
/** 回复内容 */
interface ReplyProps {
/** 内容ID */
id: number,
/** 评论ID */
comment_id: number,
/** 回复人ID */
user_id: number,
/** 回复人用户数据 */
user: UserInfo,
/** 艾特人ID */
at_user_id: number,
/** 艾特人用户数据 */
at_user: UserInfo,
/** 内容 */
content: string,
/** 回复人IP地址 */
ip?: string,
/** 回复人城市地址 */
ip_loc: string,
created_on: number
/** 创建时间 */
created_on: number,
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1
}
interface PostProps {
/** 帖子内容 */
interface PostItemProps {
/** 内容ID */
id: number,
/** 类型1为标题2为文字段落3为图片地址4为视频地址5为语音地址6为链接地址7为附件资源8为收费资源 */
type: number,
/** POST ID */
post_id: number,
/** 内容 */
content: string,
/** 排序,越小越靠前 */
sort: number,
/** 用户UID */
user_id?: number,
/** 创建时间 */
created_on: number,
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1,
}
/** 帖子 */
interface PostProps {
id: number,
/** 发帖人UID */
user_id: number,
/** 发帖人用户数据 */
user: UserInfo,
/** 附件价格(分) */
attachment_price: number,
/** 发帖时IP地址 */
ip?: string,
/** 发帖时城市地址 */
ip_loc: string,
created_on: number,
/** 最新回复时间 */
latest_replied_on: number,
/** 创建时间 */
created_on: number,
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 点赞数 */
upvote_count: number,
/** 评论数 */
comment_count: number,
/** 收藏数 */
collection_count: number,
content: string,
contents: PostProps[],
/** 内容列表 */
contents: PostItemProps[],
/** 标签列表 */
tags: {[key: string]: number} | string,
/** 是否锁定 */
is_lock: number,
/** 是否置顶 */
is_top: number,
texts?: PostProps[],
imgs?: PostProps[],
videos?: PostProps[],
links?: PostProps[],
attachments?: PostProps[],
charge_attachments?: PostProps[]
/** 是否精华 */
is_essence: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1
}
/** 组件用帖子 */
interface PostComponentProps extends PostProps {
/** 文字段落列表 */
texts: PostItemProps[],
/** 图片列表 */
imgs: PostItemProps[],
/** 视频列表 */
videos: PostItemProps[],
/** 链接列表 */
links: PostItemProps[],
/** 附件列表 */
attachments: PostItemProps[],
/** 收费附件列表 */
charge_attachments: PostItemProps[]
}
interface MessageProps {
id: number,
type: number,
is_read: number,
sender_user: UserInfo
post: PostProps,
/** 类型1为动态2为评论3为回复4为私信99为系统通知 */
type: 1 | 2 | 3 | 4 | 99,
/** 摘要说明 */
brief: string,
/** 详细内容 */
content: string,
/** 是否已读0为未读1为已读 */
is_read: 0 | 1,
/** 发送人UID */
sender_user_id: number,
/** 发送人用户数据 */
sender_user: UserInfo,
/** 接收方UID */
receiver_user_id: number,
/** 帖子ID */
post_id: number,
/** 帖子内容 */
post: PostProps,
/** 评论ID */
comment_id: number,
/** 评论内容 */
comment: CommentProps,
/** 回复ID */
reply_id: number,
/** 回复内容 */
replay: ReplyProps,
/** 创建时间 */
created_on: number,
breif: string
content?: string
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1
}
interface AttachmentProps {
id: number,
type: number
/** 类别1为图片2为视频3为其他附件 */
type: 1 | 2 | 3,
/** 发布者用户UID */
user_id: number,
/** 发布者用户数据 */
user: UserInfo,
/** 文件大小 */
file_size: number,
/** 图片宽度 */
img_width?: number,
/** 图片高度 */
img_height?: number,
/** 内容 */
content: string,
/** 创建时间 */
created_on: number,
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1
}
interface TagProps {
id: number,
quote_num: number,
/** 创建者UID */
user_id: number,
/** 创建者用户数据 */
user: UserInfo,
/** 标签名 */
tag: string,
user: UserInfo
/** 引用数 */
quote_num: number,
/** 创建时间 */
created_on: number,
/** 修改时间 */
modified_on?: number,
/** 删除时间 */
deleted_on?: number,
/** 是否删除0为未删除1为已删除 */
is_del?: 0 | 1
}
interface PagerProps {
/** 当前页码 */
page: number,
/** 每页条数 */
page_size: number,
/** 总条数 */
total_rows: number
}

@ -1,4 +1,4 @@
import axios from 'axios';
import axios, { AxiosRequestConfig, AxiosRequestHeaders, Method } from 'axios';
const service = axios.create({
baseURL: import.meta.env.VITE_HOST,
@ -48,3 +48,7 @@ service.interceptors.response.use(
);
export default service;
export function request<T, R>(config: AxiosRequestConfig<T>): Promise<R> {
return service(config) as unknown as Promise<R>;
}

@ -67,7 +67,7 @@ const loadPosts = () => {
loading.value = true;
getPosts({
query: route.query.q ? decodeURIComponent(route.query.q as string) : null,
type: +(route.query.t as string),
type: route.query.t as string,
page: page.value,
page_size: pageSize.value,
})

@ -54,7 +54,7 @@ const route = useRoute();
const post = ref<Item.PostProps>({} as Item.PostProps);
const loading = ref(false);
const commentLoading = ref(false);
const comments = ref<Item.PostProps[]>([]);
const comments = ref<Item.CommentProps[]>([]);
const postId = computed(() => +(route.query.id as string));
const loadPost = () => {

@ -285,9 +285,9 @@ const modelData = reactive({
imgCaptcha: '',
phone: '',
phone_captcha: '',
password: null,
old_password: null,
reenteredPassword: null,
password: '',
old_password: '',
reenteredPassword: '',
});
const beforeUpload = async (data: any) => {

Loading…
Cancel
Save