diff --git a/.github/desktop-tauri.jpeg b/.github/desktop-tauri.jpeg
new file mode 100644
index 00000000..cf4d691e
Binary files /dev/null and b/.github/desktop-tauri.jpeg differ
diff --git a/.gitignore b/.gitignore
index 4b772892..4f7e39cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
+.idea
.vscode
-__debug_bin
+!*.example
+dist/
config.yaml
*.log
-paopao-api
\ No newline at end of file
+paopao-ce*
diff --git a/Dockerfile b/Dockerfile
index f6034422..109cbea6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -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
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..4a23ba98
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,33 @@
+.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)
+TAGS = ""
+all: fmt build
+build:
+ @go mod download
+ @echo Build paopao-ce
+ bash build.sh paopao-ce
+run:
+ @go run -tags '$(TAGS)' -ldflags "-X 'main.version=${BUILD_VERSION}' -X 'main.buildDate=${BUILD_DATE}' -X 'main.commitID=${SHA_SHORT}'" .
+clean:
+ @go clean
+ @find ./dist -type f -exec rm -r {} +
+ @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 run: start api server"
+ @echo "make build: build executables"
+ @echo "make build: build executables"
+ @echo "make run TAGS='embed': start api server and serve embed web frontend"
+ @echo "make build TAGS='embed': build executables with embed web frontend"
+.EXPORT_ALL_VARIABLES:
+GO111MODULE = on
diff --git a/README.md b/README.md
index a9bead35..40ff3323 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
-
[![Go Report Card][goreport-shield]][goreport-url]
[![Forks][forks-shield]][forks-url]
@@ -28,22 +27,22 @@
+---
-
-## 1. 截图预览
-
+## 预览
+Web端:
[![明色主题][product-light-screenshot]](https://www.paopao.info)
[![暗色主题][product-dark-screenshot]](https://www.paopao.info)
-更多演示请前往[官网](https://www.paopao.info)体验(谢绝灌水)
+更多演示请前往[官网](https://www.paopao.info)体验(谢绝灌水)
-(back to top)
+桌面端:
+
-
-## 2. 快速开始
+(back to top)
-### 2.1 技术栈
+## 🛠 技术栈
PaoPao主要由以下优秀的开源项目/工具构建
@@ -54,61 +53,116 @@ PaoPao主要由以下优秀的开源项目/工具构建
* [Vue.js](https://vuejs.org/)
* [Vite.js](https://vitejs.dev/)
+
+## 🏗 快速开始
-### 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是一款轻量级全文搜索引擎,可以查阅 安装
以上环境版本为PaoPao官方的开发版本,仅供参考,其他版本的环境未进行充分测试
-
+### 安装说明
+
+***宝塔安装***
+
+我们为宝塔用户提供了超详细安装教程 [点此查看](https://www.rocs.me/archives/paopao_bt_install.html)
-### 3. 安装说明
+***普通安装***
克隆代码库
+
```sh
git clone https://github.com/rocboss/paopao-ce.git
```
-#### 3.1 后端
+
+#### 后端
1. 导入项目根目录下的 `paopao.sql` 文件至MySQL数据库
2. 拷贝项目根目录下 `config.yaml.sample` 文件至 `config.yaml`,按照注释完成配置编辑
-3. 编译后端
+3. 编译后端
+ 编译api服务:
```sh
- go mod download
- go build -o paopao-api .
+ make build
```
-4. 启动后端
+ 编译api服务、内嵌web前端ui; 注意此步骤需要先编译web前端。
```sh
- chmod +x paopao-api
- ./paopao-api
+ make build TAGS='embed'
```
+ 编译后在`dist`目录可以找到对应可执行文件。
-#### 3.2 前端
+4. 启动后端
+ 运行api服务:
+ ```sh
+ make run
+ ```
+ 运行api服务、web前端ui服务:
+ ```sh
+ make run TAGS='embed'
+ ```
+
+#### 前端
1. 进入前端目录 `web`,编辑 `.env` 文件中后端服务地址,下载依赖包
+
```sh
cd ./web
vim .env
yarn
```
+
2. 编译前端
+
```sh
yarn build
```
build完成后,可以在dist目录获取编译产出,配置nginx指向至该目录即可
-#### 3.3 其他
-建议后端服务使用 `supervisor` 守护进程,并通过nginx反向代理后,提供API给前端服务调用。
-短信通道使用的juhe数据,如果申请不下来,可以考虑替换其他服务商。
-代码结构比较简单,喜欢的朋友欢迎给个Star、贡献PR。
+#### 桌面端
+
+1. 进入前端目录 `web`,编辑 `.env` 文件中后端服务地址,下载依赖包
+
+ ```sh
+ cd ./web
+ vim .env
+ yarn
+ ```
+
+2. 编译前端
+
+ ```sh
+ yarn build
+ ```
+
+3. 构建桌面端
+ ```sh
+ yarn tauri build
+ ```
+ 桌面端是使用[Rust](https://www.rust-lang.org/) + [tauri](https://github.com/tauri-apps/tauri)编写
+ 的,需要Rust编译环境,具体安装指南请参考[https://www.rust-lang.org/tools/install](https://www.rust-lang.org/tools/install).
+
+### 其他说明
+
+建议后端服务使用 `supervisor` 守护进程,并通过 `nginx` 反向代理后,提供API给前端服务调用。
+
+短信通道使用的[聚合数据](https://www.juhe.cn/),如果申请不下来,可以考虑替换其他服务商。
+
+代码结构比较简单,很方便扩展
+
+## 👯♀️ 贡献
+
+喜欢的朋友欢迎给个Star、贡献PR。
+
+## License
+
+Distributed under the MIT License. See `LICENSE` for more information.
[contributors-shield]: https://img.shields.io/github/contributors/rocboss/paopao-ce?style=flat
@@ -125,4 +179,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
\ No newline at end of file
+[product-dark-screenshot]: https://cdn.rocs.me/static/paopao-dark.jpeg
diff --git a/comic.ttf b/assets/comic.ttf
similarity index 100%
rename from comic.ttf
rename to assets/comic.ttf
diff --git a/build.sh b/build.sh
new file mode 100644
index 00000000..f49c00c8
--- /dev/null
+++ b/build.sh
@@ -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}" -tags "${TAGS}" \
+ -ldflags "-X 'main.version=${BUILD_VERSION}' \
+ -X 'main.buildDate=${BUILD_DATE}' \
+ -X 'main.commitID=${SHA_SHORT}'\
+ -w -s"
+ else
+ go build -trimpath -o "${TARGET}" -tags "${TAGS}" \
+ -ldflags "-X 'main.version=${BUILD_VERSION}' \
+ -X 'main.buildDate=${BUILD_DATE}' \
+ -X 'main.commitID=${SHA_SHORT}'\
+ -w -s"
+ fi
+done
diff --git a/config.yaml.sample b/config.yaml.sample
index f666be2f..a44a84df 100644
--- a/config.yaml.sample
+++ b/config.yaml.sample
@@ -10,6 +10,8 @@ App: # APP基础设置项
SmsJuheTplVal: "#code#=%dm#=%d"
AlipayAppID:
AlipayPrivateKey:
+Runtime: # App运行时功能调节
+ DisablePhoneVerify: False # 禁止绑定手机号码时验证短信验证码,为true时任意验证码都可以通过验证
Server: # 服务设置
RunMode: debug
HttpIp: 0.0.0.0
diff --git a/global/setting.go b/global/setting.go
index 1e26d29c..ac463109 100644
--- a/global/setting.go
+++ b/global/setting.go
@@ -10,6 +10,7 @@ import (
var (
ServerSetting *setting.ServerSettingS
AppSetting *setting.AppSettingS
+ RuntimeSetting *setting.RuntimeSettingS
DatabaseSetting *setting.DatabaseSettingS
RedisSetting *setting.RedisSettingS
SearchSetting *setting.SearchSettingS
diff --git a/go.mod b/go.mod
index 3c326ad5..2fc783ce 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 29160250..9aaf5068 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
diff --git a/init.go b/init.go
index 9382471f..ac7a1178 100644
--- a/init.go
+++ b/init.go
@@ -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
diff --git a/internal/model/message.go b/internal/model/message.go
index 415e3ac4..89a4ae64 100644
--- a/internal/model/message.go
+++ b/internal/model/message.go
@@ -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{},
diff --git a/internal/routers/api/attachment.go b/internal/routers/api/attachment.go
index 6ff07630..37cdcec6 100644
--- a/internal/routers/api/attachment.go
+++ b/internal/routers/api/attachment.go
@@ -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)
diff --git a/internal/routers/api/comment.go b/internal/routers/api/comment.go
index 842e57b1..5aba10b5 100644
--- a/internal/routers/api/comment.go
+++ b/internal/routers/api/comment.go
@@ -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
}
diff --git a/internal/routers/api/home.go b/internal/routers/api/home.go
index fb48f07d..65b2ca2e 100644
--- a/internal/routers/api/home.go
+++ b/internal/routers/api/home.go
@@ -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)
diff --git a/internal/routers/api/message.go b/internal/routers/api/message.go
index 202e9a83..1242ff86 100644
--- a/internal/routers/api/message.go
+++ b/internal/routers/api/message.go
@@ -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)
diff --git a/internal/routers/api/post.go b/internal/routers/api/post.go
index a7beaaac..226c9c6a 100644
--- a/internal/routers/api/post.go
+++ b/internal/routers/api/post.go
@@ -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(¶m)
+ tags, err := service.GetPostTags(¶m)
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
diff --git a/internal/routers/api/user.go b/internal/routers/api/user.go
index 92ba4b72..dfbc5c8a 100644
--- a/internal/routers/api/user.go
+++ b/internal/routers/api/user.go
@@ -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(¶m)
+ user, err := service.DoLogin(c, ¶m)
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(¶m)
+ user, err := service.GetUserInfo(¶m)
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
}
diff --git a/internal/routers/router.go b/internal/routers/router.go
index 449f3e02..f735bc2a 100644
--- a/internal/routers/router.go
+++ b/internal/routers/router.go
@@ -10,16 +10,22 @@ import (
)
func NewRouter() *gin.Engine {
- r := gin.New()
- r.HandleMethodNotAllowed = true
- r.Use(gin.Logger())
- r.Use(gin.Recovery())
+ e := gin.New()
+ e.HandleMethodNotAllowed = true
+ e.Use(gin.Logger())
+ e.Use(gin.Recovery())
// 跨域配置
corsConfig := cors.DefaultConfig()
corsConfig.AllowAllOrigins = true
corsConfig.AddAllowHeaders("Authorization")
- r.Use(cors.New(corsConfig))
+ e.Use(cors.New(corsConfig))
+
+ // 按需注册静态资源路由
+ registerStatick(e)
+
+ // v1 group api
+ r := e.Group("/v1")
// 获取version
r.GET("/", api.Version)
@@ -163,18 +169,18 @@ func NewRouter() *gin.Engine {
}
// 默认404
- r.NoRoute(func(c *gin.Context) {
+ e.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{
"code": 404,
"msg": "Not Found",
})
})
// 默认405
- r.NoMethod(func(c *gin.Context) {
+ e.NoMethod(func(c *gin.Context) {
c.JSON(http.StatusMethodNotAllowed, gin.H{
"code": 405,
"msg": "Method Not Allowed",
})
})
- return r
+ return e
}
diff --git a/internal/routers/statick.go b/internal/routers/statick.go
new file mode 100644
index 00000000..c20d5059
--- /dev/null
+++ b/internal/routers/statick.go
@@ -0,0 +1,13 @@
+//go:build !embed
+// +build !embed
+
+package routers
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+// registerStatick stub function for register static asset route
+func registerStatick(e *gin.Engine) {
+ // empty
+}
diff --git a/internal/routers/statick_embed.go b/internal/routers/statick_embed.go
new file mode 100644
index 00000000..2ea56171
--- /dev/null
+++ b/internal/routers/statick_embed.go
@@ -0,0 +1,27 @@
+//go:build embed
+// +build embed
+
+package routers
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+ "github.com/rocboss/paopao-ce/web"
+)
+
+// registerStatick register static assets route
+func registerStatick(e *gin.Engine) {
+ routeStatic(e, "/", "/index.html", "/favicon.ico", "/assets/*filepath")
+}
+
+func routeStatic(e *gin.Engine, paths ...string) {
+ staticHandler := http.FileServer(web.NewFileSystem())
+ handler := func(c *gin.Context) {
+ staticHandler.ServeHTTP(c.Writer, c.Request)
+ }
+ for _, path := range paths {
+ e.GET(path, handler)
+ e.HEAD(path, handler)
+ }
+}
diff --git a/internal/service/attachment.go b/internal/service/attachment.go
index 2f4bfc88..053b555c 100644
--- a/internal/service/attachment.go
+++ b/internal/service/attachment.go
@@ -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)
}
diff --git a/internal/service/avatar.go b/internal/service/avatar.go
index 5c666133..3ac302e0 100644
--- a/internal/service/avatar.go
+++ b/internal/service/avatar.go
@@ -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))]
}
diff --git a/internal/service/comment.go b/internal/service/comment.go
index 9ef87f67..88cb917c 100644
--- a/internal/service/comment.go
+++ b/internal/service/comment.go
@@ -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
}
diff --git a/internal/service/message.go b/internal/service/message.go
index 2c420cd7..64e0cd4a 100644
--- a/internal/service/message.go
+++ b/internal/service/message.go
@@ -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
}
diff --git a/internal/service/post.go b/internal/service/post.go
index ea89dbc9..7554c2ed 100644
--- a/internal/service/post.go
+++ b/internal/service/post.go
@@ -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
}
diff --git a/internal/service/service.go b/internal/service/service.go
index e0b3db36..d9b91b40 100644
--- a/internal/service/service.go
+++ b/internal/service/service.go
@@ -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)
}
diff --git a/internal/service/sign.go b/internal/service/sign.go
index 53aa58e4..6d5ef510 100644
--- a/internal/service/sign.go
+++ b/internal/service/sign.go
@@ -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{}
diff --git a/internal/service/user.go b/internal/service/user.go
index 5cdbc208..e055d0f4 100644
--- a/internal/service/user.go
+++ b/internal/service/user.go
@@ -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
}
diff --git a/internal/service/wallet.go b/internal/service/wallet.go
index 60526937..8c5da819 100644
--- a/internal/service/wallet.go
+++ b/internal/service/wallet.go
@@ -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)
}
diff --git a/main.go b/main.go
index 3bf3441f..8aa7adf9 100644
--- a/main.go
+++ b/main.go
@@ -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()
}
diff --git a/paopao.sql b/paopao.sql
index c134f55d..d78496d5 100644
--- a/paopao.sql
+++ b/paopao.sql
@@ -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',
diff --git a/pkg/setting/settting.go b/pkg/setting/settting.go
index 216ada5a..bb22198b 100644
--- a/pkg/setting/settting.go
+++ b/pkg/setting/settting.go
@@ -51,6 +51,10 @@ type AppSettingS struct {
AlipayPrivateKey string
}
+type RuntimeSettingS struct {
+ DisablePhoneVerify bool
+}
+
type SearchSettingS struct {
ZincHost string
ZincIndex string
diff --git a/pkg/sign/sign.go b/pkg/sign/sign.go
index ebce41d1..717b8e54 100644
--- a/pkg/sign/sign.go
+++ b/pkg/sign/sign.go
@@ -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 签名交易
diff --git a/pkg/util/banner.go b/pkg/util/banner.go
new file mode 100644
index 00000000..d41b5ae1
--- /dev/null
+++ b/pkg/util/banner.go
@@ -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)
+}
diff --git a/pkg/util/ip.go b/pkg/util/ip.go
index 5e657944..3aaa13c1 100644
--- a/pkg/util/ip.go
+++ b/pkg/util/ip.go
@@ -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
}
diff --git a/pkg/util/iploc/iploc.go b/pkg/util/iploc/iploc.go
new file mode 100644
index 00000000..0a103738
--- /dev/null
+++ b/pkg/util/iploc/iploc.go
@@ -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
+}
diff --git a/pkg/util/iploc/iploc_test.go b/pkg/util/iploc/iploc_test.go
new file mode 100644
index 00000000..4754e86d
--- /dev/null
+++ b/pkg/util/iploc/iploc_test.go
@@ -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)
+ }
+ }
+}
diff --git a/qqwry.dat b/pkg/util/iploc/qqwry.dat
similarity index 100%
rename from qqwry.dat
rename to pkg/util/iploc/qqwry.dat
diff --git a/pkg/zinc/zinc.go b/pkg/zinc/zinc.go
index 7cf4c86e..a7d9cc8d 100644
--- a/pkg/zinc/zinc.go
+++ b/pkg/zinc/zinc.go
@@ -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{
diff --git a/version b/version
new file mode 100644
index 00000000..e69de29b
diff --git a/web/.gitignore b/web/.gitignore
index ba6b09ec..5e36b5b9 100644
--- a/web/.gitignore
+++ b/web/.gitignore
@@ -11,6 +11,7 @@ node_modules
dist
dist-ssr
*.local
+.env
# Editor directories and files
.vscode/*
diff --git a/web/embed.go b/web/embed.go
new file mode 100644
index 00000000..4866a53a
--- /dev/null
+++ b/web/embed.go
@@ -0,0 +1,19 @@
+//go:build embed
+// +build embed
+
+package web
+
+import (
+ "embed"
+ "io/fs"
+ "net/http"
+)
+
+//go:embed dist/*
+var files embed.FS
+
+// NewFileSystem get an embed static assets http.FileSystem instance.
+func NewFileSystem() http.FileSystem {
+ subfs, _ := fs.Sub(files, "dist")
+ return http.FS(subfs)
+}
diff --git a/web/package.json b/web/package.json
index 78bd809a..d93e4413 100644
--- a/web/package.json
+++ b/web/package.json
@@ -5,7 +5,8 @@
"scripts": {
"dev": "vite",
"build": "vite build",
- "preview": "vite preview"
+ "preview": "vite preview",
+ "tauri": "tauri"
},
"dependencies": {
"@vicons/carbon": "^0.12.0",
@@ -29,6 +30,7 @@
"vuex": "^4.0.2"
},
"devDependencies": {
+ "@tauri-apps/cli": "^1.0.0-rc.7",
"@types/node": "^17.0.35",
"@types/qrcode": "^1.4.2",
"@vitejs/plugin-vue": "^2.3.1",
diff --git a/web/src-tauri/.gitignore b/web/src-tauri/.gitignore
new file mode 100644
index 00000000..25279840
--- /dev/null
+++ b/web/src-tauri/.gitignore
@@ -0,0 +1,5 @@
+# Generated by Cargo
+# will have compiled files and executables
+/target/
+WixTools
+Cargo.lock
diff --git a/web/src-tauri/Cargo.toml b/web/src-tauri/Cargo.toml
new file mode 100644
index 00000000..f1f34a5d
--- /dev/null
+++ b/web/src-tauri/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "paopao"
+version = "0.1.0"
+description = "Paopao App"
+authors = ["Rocboss"]
+license = "MIT License"
+repository = "https://github.com/rocboss/paopao-ce"
+edition = "2021"
+rust-version = "1.57"
+
+[build-dependencies]
+tauri-build = { version = "1.0.0-rc.4", features = [] }
+
+[dependencies]
+tauri = { version = "1.0.0-rc.4", features = ["api-all"] }
+
+[features]
+# by default Tauri runs in production mode
+# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
+default = [ "custom-protocol" ]
+# this feature is used used for production builds where `devPath` points to the filesystem
+# DO NOT remove this
+custom-protocol = [ "tauri/custom-protocol" ]
diff --git a/web/src-tauri/build.rs b/web/src-tauri/build.rs
new file mode 100644
index 00000000..d860e1e6
--- /dev/null
+++ b/web/src-tauri/build.rs
@@ -0,0 +1,3 @@
+fn main() {
+ tauri_build::build()
+}
diff --git a/web/src-tauri/icons/128x128.png b/web/src-tauri/icons/128x128.png
new file mode 100644
index 00000000..8976d45d
Binary files /dev/null and b/web/src-tauri/icons/128x128.png differ
diff --git a/web/src-tauri/icons/128x128@2x.png b/web/src-tauri/icons/128x128@2x.png
new file mode 100644
index 00000000..826a74fc
Binary files /dev/null and b/web/src-tauri/icons/128x128@2x.png differ
diff --git a/web/src-tauri/icons/32x32.png b/web/src-tauri/icons/32x32.png
new file mode 100644
index 00000000..96e054be
Binary files /dev/null and b/web/src-tauri/icons/32x32.png differ
diff --git a/web/src-tauri/icons/icon.icns b/web/src-tauri/icons/icon.icns
new file mode 100644
index 00000000..80eebbf3
Binary files /dev/null and b/web/src-tauri/icons/icon.icns differ
diff --git a/web/src-tauri/icons/icon.ico b/web/src-tauri/icons/icon.ico
new file mode 100644
index 00000000..92783607
Binary files /dev/null and b/web/src-tauri/icons/icon.ico differ
diff --git a/web/src-tauri/src/main.rs b/web/src-tauri/src/main.rs
new file mode 100644
index 00000000..6c858d61
--- /dev/null
+++ b/web/src-tauri/src/main.rs
@@ -0,0 +1,52 @@
+#![cfg_attr(
+ all(not(debug_assertions), target_os = "windows"),
+ windows_subsystem = "windows"
+)]
+
+use tauri::api::shell;
+use tauri::{CustomMenuItem, Manager, Menu, MenuEntry, MenuItem, Submenu};
+
+fn main() {
+ let _ctx = tauri::generate_context!();
+
+ tauri::Builder::default()
+ .menu(Menu::with_items([
+ #[cfg(target_os = "macos")]
+ MenuEntry::Submenu(Submenu::new(
+ &_ctx.package_info().name,
+ Menu::with_items([
+ MenuItem::Separator.into(),
+ MenuItem::Services.into(),
+ MenuItem::Separator.into(),
+ MenuItem::Hide.into(),
+ MenuItem::HideOthers.into(),
+ MenuItem::ShowAll.into(),
+ MenuItem::Separator.into(),
+ MenuItem::Quit.into(),
+ ]),
+ )),
+ MenuEntry::Submenu(Submenu::new(
+ "Window",
+ Menu::with_items([MenuItem::Minimize.into(), MenuItem::Zoom.into()]),
+ )),
+ // You should always have a Help menu on macOS because it will automatically
+ // show a menu search field
+ MenuEntry::Submenu(Submenu::new(
+ "Help",
+ Menu::with_items([CustomMenuItem::new("Learn More", "Learn More").into()]),
+ )),
+ ]))
+ .on_menu_event(|event| {
+ let event_name = event.menu_item_id();
+ event.window().emit("menu", event_name).unwrap();
+ match event_name {
+ "Learn More" => {
+ let link = "https://github.com/rocboss/paopao-ce".to_string();
+ shell::open(&event.window().shell_scope(), link, None).unwrap();
+ }
+ _ => {}
+ }
+ })
+ .run(tauri::generate_context!())
+ .expect("error while running tauri application");
+}
diff --git a/web/src-tauri/tauri.conf.json b/web/src-tauri/tauri.conf.json
new file mode 100644
index 00000000..e28b7816
--- /dev/null
+++ b/web/src-tauri/tauri.conf.json
@@ -0,0 +1,74 @@
+{
+ "package": {
+ "productName": "Paopao",
+ "version": "0.1.0"
+ },
+ "build": {
+ "distDir": "../dist",
+ "beforeDevCommand": "",
+ "beforeBuildCommand": "",
+ "withGlobalTauri": true
+ },
+ "tauri": {
+ "bundle": {
+ "active": true,
+ "targets": "all",
+ "identifier": "tauri.paopao.info",
+ "icon": [
+ "icons/32x32.png",
+ "icons/128x128.png",
+ "icons/128x128@2x.png",
+ "icons/icon.icns",
+ "icons/icon.ico"
+ ],
+ "resources": [],
+ "externalBin": [],
+ "copyright": "",
+ "category": "Social Networking",
+ "shortDescription": "",
+ "longDescription": "",
+ "deb": {
+ "depends": []
+ },
+ "macOS": {
+ "frameworks": [],
+ "minimumSystemVersion": "",
+ "exceptionDomain": "",
+ "signingIdentity": null,
+ "providerShortName": null,
+ "entitlements": null
+ },
+ "windows": {
+ "certificateThumbprint": null,
+ "digestAlgorithm": "sha256",
+ "timestampUrl": ""
+ }
+ },
+ "updater": {
+ "active": false
+ },
+ "allowlist": {
+ "all": true,
+ "http": {
+ "all": true,
+ "request": true,
+ "scope": ["https://**", "http://**"]
+ },
+ "notification": {
+ "all": true
+ }
+ },
+ "windows": [
+ {
+ "title": "泡泡 - 闲了,冒个泡",
+ "width": 1080,
+ "height": 800,
+ "resizable": true,
+ "fullscreen": false
+ }
+ ],
+ "security": {
+ "csp": null
+ }
+ }
+}
diff --git a/web/src/api/auth.ts b/web/src/api/auth.ts
index e6513e92..4d5a066d 100644
--- a/web/src/api/auth.ts
+++ b/web/src/api/auth.ts
@@ -1,62 +1,39 @@
-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 => {
return request({
method: 'post',
- url: '/auth/login',
+ url: '/v1/auth/login',
data: params,
- }) as unknown as Promise;
+ });
};
-/**
- * 注册用户
- * @param {Object} params
- * - @param {string} username
- * - @param {string} password
- * @returns Promise
- */
-export const userRegister = (params = {}) => {
+/** 注册用户 */
+export const userRegister = (params: NetParams.AuthUserRegister): Promise => {
return request({
method: 'post',
- url: '/auth/register',
+ url: '/v1/auth/register',
data: params,
});
};
-/**
- * 用户信息
- * @param {Object} params
- * @returns Promise
- */
-export const userInfo = (token = '') => {
+/** 用户信息 */
+export const userInfo = (token: NetParams.AuthUserInfo = ""): Promise => {
return request({
method: 'get',
- url: '/user/info',
+ url: '/v1/user/info',
headers: {
Authorization: `Bearer ${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 => {
return request({
method: 'post',
- url: '/api/user/password',
+ url: '/v1/api/user/password',
data,
});
};
diff --git a/web/src/api/post.ts b/web/src/api/post.ts
index 3488eed5..7f2bc408 100644
--- a/web/src/api/post.ts
+++ b/web/src/api/post.ts
@@ -1,222 +1,145 @@
-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 => {
return request({
method: 'get',
- url: '/posts',
+ url: '/v1/posts',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取标签列表
- * @param {Object} params
- * @returns Promise
- */
-export const getTags = (params: NetParams.PostGetTags) => {
+/** 获取标签列表 */
+export const getTags = (params: NetParams.PostGetTags): Promise => {
return request({
method: 'get',
- url: '/tags',
+ url: '/v1/tags',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取动态详情
- * @param {Object} params
- * @returns Promise
- */
-export const getPost = (params: NetParams.PostGetPost) => {
+/** 获取动态详情 */
+export const getPost = (params: NetParams.PostGetPost): Promise => {
return request({
method: 'get',
- url: '/post',
+ url: '/v1/post',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取动态点赞状态
- * @param {Object} params
- * @returns Promise
- */
-export const getPostStar = (params: NetParams.PostPostStar) => {
+/** 获取动态点赞状态 */
+export const getPostStar = (params: NetParams.PostPostStar): Promise => {
return request({
method: 'get',
- url: '/post/star',
+ url: '/v1/post/star',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 动态点赞
- * @param {Object} data
- * @returns Promise
- */
-export const postStar = (data: NetParams.PostPostStar) => {
+/** 动态点赞 */
+export const postStar = (data: NetParams.PostPostStar): Promise => {
return request({
method: 'post',
- url: '/post/star',
+ url: '/v1/post/star',
data
- }) as unknown as Promise;
+ });
};
-/**
- * 获取动态收藏状态
- * @param {Object} params
- * @returns Promise
- */
-export const getPostCollection = (params: NetParams.PostGetPostCollection) => {
+/** 获取动态收藏状态 */
+export const getPostCollection = (params: NetParams.PostGetPostCollection): Promise => {
return request({
method: 'get',
- url: '/post/collection',
+ url: '/v1/post/collection',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 动态收藏
- * @param {Object} data
- * @returns Promise
- */
-export const postCollection = (data: NetParams.PostPostCollection) => {
+/** 动态收藏 */
+export const postCollection = (data: NetParams.PostPostCollection): Promise => {
return request({
method: 'post',
- url: '/post/collection',
+ url: '/v1/post/collection',
data
- }) as unknown as Promise;
+ });
};
-/**
- * 获取动态评论列表
- * @param {Object} params
- * @returns Promise
- */
-export const getPostComments = (params: NetParams.PostGetPostComments) => {
+/** 获取动态评论列表 */
+export const getPostComments = (params: NetParams.PostGetPostComments): Promise => {
return request({
method: 'get',
- url: '/post/comments',
+ url: '/v1/post/comments',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 发布动态
- * @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 => {
return request({
method: 'post',
- url: '/post',
+ url: '/v1/post',
data
- }) as unknown as Promise;
+ });
};
-/**
- * 删除动态
- * @param {Object} data
- * - @param {number} id
- * @returns Promise
- */
-export const deletePost = (data: any) => {
+/** 删除动态 */
+export const deletePost = (data: NetParams.PostDeletePost): Promise => {
return request({
method: 'delete',
- url: '/post',
+ url: '/v1/post',
data
});
};
-/**
- * 锁定/解锁动态
- * @param {Object} data
- * - @param {number} id
- * @returns Promise
- */
-export const lockPost = (data: NetParams.PostLockPost) => {
+/** 锁定/解锁动态 */
+export const lockPost = (data: NetParams.PostLockPost): Promise => {
return request({
method: 'post',
- url: '/post/lock',
+ url: '/v1/post/lock',
data
- }) as unknown as Promise;
+ });
};
-/**
- * 置顶/取消置顶动态
- * @param {Object} data
- * - @param {number} id
- * @returns Promise
- */
-export const stickPost = (data: NetParams.PostStickPost) => {
+/** 置顶/取消置顶动态 */
+export const stickPost = (data: NetParams.PostStickPost): Promise => {
return request({
method: 'post',
- url: '/post/stick',
+ url: '/v1/post/stick',
data
- }) as unknown as Promise;
+ });
};
-/**
- * 发布动态评论
- * @param {Object} data
- * - @param {array} contents 内容
- * - @param {array} users at用户
- * @returns Promise
- */
-export const createComment = (data: any) => {
+/** 发布动态评论 */
+export const createComment = (data: NetParams.PostCreateComment): Promise => {
return request({
method: 'post',
- url: '/post/comment',
+ url: '/v1/post/comment',
data
});
};
-/**
- * 删除评论
- * @param {Object} data
- * - @param {number} id
- * @returns Promise
- */
-export const deleteComment = (data: any) => {
+/** 删除评论 */
+export const deleteComment = (data: NetParams.PostDeleteComment): Promise => {
return request({
method: 'delete',
- url: '/post/comment',
+ url: '/v1/post/comment',
data
});
};
-/**
- * 发布评论回复
- * @param {Object} data
- * - @param {string} content 内容
- * - @param {number} comment_id 评论ID
- * - @param {number} at_user_id at用户ID
- * @returns Promise
- */
-export const createCommentReply = (data: any) => {
+/** 发布评论回复 */
+export const createCommentReply = (data: NetParams.PostCreateCommentReply): Promise => {
return request({
method: 'post',
- url: '/post/comment/reply',
+ url: '/v1/post/comment/reply',
data
});
};
-/**
- * 删除评论回复
- * @param {Object} data
- * - @param {number} id 评论ID
- * @returns Promise
- */
-export const deleteCommentReply = (data: any) => {
+/** 删除评论回复 */
+export const deleteCommentReply = (data: NetParams.PostDeleteCommentReply): Promise => {
return request({
method: 'delete',
- url: '/post/comment/reply',
+ url: '/v1/post/comment/reply',
data
});
-};
\ No newline at end of file
+};
diff --git a/web/src/api/user.ts b/web/src/api/user.ts
index 46cfe889..ea6c1adf 100644
--- a/web/src/api/user.ts
+++ b/web/src/api/user.ts
@@ -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 => {
return request({
method: 'get',
- url: '/captcha',
+ url: '/v1/captcha',
params
- }) as unknown as Promise;
+ });
};
/**
@@ -21,7 +17,7 @@ export const getCaptcha = (params: NetParams.UserGetCaptcha = {}) => {
export const sendCaptcha = (data: any) => {
return request({
method: 'post',
- url: '/captcha',
+ url: '/v1/captcha',
data
});
};
@@ -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 => {
return request({
method: 'post',
- url: '/user/whisper',
+ url: '/v1/user/whisper',
data
- }) as unknown as Promise;
+ });
};
/**
@@ -44,36 +40,28 @@ export const sendUserWhisper = (data: NetParams.UserWhisper) => {
* @param {Object} data
* @returns Promise
*/
-export const bindUserPhone = (data: NetParams.UserBindUserPhone) => {
+export const bindUserPhone = (data: NetParams.UserBindUserPhone): Promise => {
return request({
method: 'post',
- url: '/user/phone',
+ url: '/v1/user/phone',
data
- }) as unknown as Promise;
+ });
};
-/**
- * 更改密码
- * @param {Object} data
- * @returns Promise
- */
-export const changePassword = (data: any) => {
+/** 更改密码 */
+export const changePassword = (data: NetParams.UserChangePassword): Promise => {
return request({
method: 'post',
- url: '/user/password',
+ url: '/v1/user/password',
data
});
};
-/**
- * 更改昵称
- * @param {Object} data
- * @returns Promise
- */
-export const changeNickname = (data: any) => {
+/** 更改昵称 */
+export const changeNickname = (data: NetParams.UserChangeNickname): Promise => {
return request({
method: 'post',
- url: '/user/nickname',
+ url: '/v1/user/nickname',
data
});
};
@@ -86,35 +74,27 @@ export const changeNickname = (data: any) => {
export const changeAvatar = (data: any) => {
return request({
method: 'post',
- url: '/user/avatar',
+ url: '/v1/user/avatar',
data
});
};
-/**
- * 获取未读消息数
- * @param {Object} params
- * @returns Promise
- */
-export const getUnreadMsgCount = (params: NetParams.UserGetUnreadMsgCount = {}) => {
+/** 获取未读消息数 */
+export const getUnreadMsgCount = (params: NetParams.UserGetUnreadMsgCount = {}): Promise => {
return request({
method: 'get',
- url: '/user/msgcount/unread',
+ url: '/v1/user/msgcount/unread',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取消息列表
- * @param {Object} params
- * @returns Promise
- */
-export const getMessages = (params: NetParams.UserGetMessages) => {
+/** 获取消息列表 */
+export const getMessages = (params: NetParams.UserGetMessages): Promise => {
return request({
method: 'get',
- url: '/user/messages',
+ url: '/v1/user/messages',
params
- }) as unknown as Promise;
+ });
};
/**
@@ -125,74 +105,54 @@ export const getMessages = (params: NetParams.UserGetMessages) => {
export const readMessage = (data: any) => {
return request({
method: 'post',
- url: '/user/message/read',
+ url: '/v1/user/message/read',
data
});
};
-/**
- * 获取收藏列表
- * @param {Object} params
- * @returns Promise
- */
-export const getCollections = (params: NetParams.UserGetCollections) => {
+/** 获取收藏列表 */
+export const getCollections = (params: NetParams.UserGetCollections): Promise => {
return request({
method: 'get',
- url: '/user/collections',
+ url: '/v1/user/collections',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取点赞列表
- * @param {Object} params
- * @returns Promise
- */
-export const getStars = (params: NetParams.UserGetStars) => {
+/** 获取点赞列表 */
+export const getStars = (params: NetParams.UserGetStars): Promise => {
return request({
method: 'get',
- url: '/user/stars',
+ url: '/v1/user/stars',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取用户基础信息
- * @param {Object} params
- * @returns Promise
- */
-export const getUserProfile = (params: NetParams.UserGetUserProfile) => {
+/** 获取用户基础信息 */
+export const getUserProfile = (params: NetParams.UserGetUserProfile): Promise => {
return request({
method: 'get',
- url: '/user/profile',
+ url: '/v1/user/profile',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取点赞列表
- * @param {Object} params
- * @returns Promise
- */
-export const getUserPosts = (params: NetParams.UserGetUserPosts) => {
+/** 获取用户帖子列表 */
+export const getUserPosts = (params: NetParams.UserGetUserPosts): Promise => {
return request({
method: 'get',
- url: '/user/posts',
+ url: '/v1/user/posts',
params
- }) as unknown as Promise;
+ });
};
-/**
- * 获取账单列表
- * @param {Object} params
- * @returns Promise
- */
-export const getBills = (params: NetParams.UserGetBills) => {
+/** 获取账单列表 */
+export const getBills = (params: NetParams.UserGetBills): Promise => {
return request({
method: 'get',
- url: '/user/wallet/bills',
+ url: '/v1/user/wallet/bills',
params
- }) as unknown as Promise;
+ });
};
/**
@@ -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 => {
return request({
method: 'post',
- url: '/user/recharge',
+ url: '/v1/user/recharge',
data
- }) as unknown as Promise;
+ });
};
/**
@@ -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 => {
return request({
method: 'get',
- url: '/user/recharge',
+ url: '/v1/user/recharge',
params
- }) as unknown as Promise;
+ });
};
/**
@@ -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 => {
return request({
method: 'get',
- url: '/suggest/users',
+ url: '/v1/suggest/users',
params
- }) as unknown as Promise;
+ });
};
/**
@@ -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 => {
return request({
method: 'get',
- url: '/suggest/tags',
+ url: '/v1/suggest/tags',
params
- }) as unknown as Promise;
+ });
};
/**
@@ -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 => {
return request({
method: 'get',
- url: '/attachment/precheck',
+ url: '/v1/attachment/precheck',
params
- }) as unknown as Promise;
+ });
};
/**
@@ -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 => {
return request({
method: 'get',
- url: '/attachment',
+ url: '/v1/attachment',
params
- }) as unknown as Promise;
+ });
};
diff --git a/web/src/components/comment-item.vue b/web/src/components/comment-item.vue
index ad93562a..c5b4f2ee 100644
--- a/web/src/components/comment-item.vue
+++ b/web/src/components/comment-item.vue
@@ -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);
diff --git a/web/src/components/compose-comment.vue b/web/src/components/compose-comment.vue
index 3bcb36fd..e6c9fded 100644
--- a/web/src/components/compose-comment.vue
+++ b/web/src/components/compose-comment.vue
@@ -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) {
diff --git a/web/src/components/compose-reply.vue b/web/src/components/compose-reply.vue
index 2f19810e..cc22b195 100644
--- a/web/src/components/compose-reply.vue
+++ b/web/src/components/compose-reply.vue
@@ -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();
const showReply = ref(false);
diff --git a/web/src/components/compose.vue b/web/src/components/compose.vue
index 7fa46214..db8fca0c 100644
--- a/web/src/components/compose.vue
+++ b/web/src/components/compose.vue
@@ -265,7 +265,7 @@ const uploadType = ref('public/image');
const fileQueue = ref([]);
const imageContents = ref([]);
const videoContents = ref([]);
-const attachmentContents = ref([]);
+const attachmentContents = ref([]);
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) {
diff --git a/web/src/components/message-item.vue b/web/src/components/message-item.vue
index bb873603..e01f6a71 100644
--- a/web/src/components/message-item.vue
+++ b/web/src/components/message-item.vue
@@ -46,11 +46,11 @@
-
- {{ message.breif }}
+
+ {{ message.brief }}
{
}
}
- .breif-wrap {
+ .brief-wrap {
margin-top: 10px;
- .breif-content {
+ .brief-content {
display: flex;
width: 100%;
}
diff --git a/web/src/components/post-attachment.vue b/web/src/components/post-attachment.vue
index c806ac9f..a3d01bf8 100644
--- a/web/src/components/post-attachment.vue
+++ b/web/src/components/post-attachment.vue
@@ -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('');
const attachmentID = ref(0);
-const download = (attachment: Item.AttachmentProps) => {
+const download = (attachment: Item.PostItemProps) => {
showDownloadModal.value = true;
attachmentID.value = attachment.id;
diff --git a/web/src/components/post-detail.vue b/web/src/components/post-detail.vue
index 5bfc9a43..af283e9c 100644
--- a/web/src/components/post-detail.vue
+++ b/web/src/components/post-detail.vue
@@ -197,7 +197,7 @@ const emit = defineEmits<{
const post = computed({
get: () => {
- let post: Required = Object.assign(
+ let post: Item.PostComponentProps = Object.assign(
{
texts: [],
imgs: [],
diff --git a/web/src/components/post-image.vue b/web/src/components/post-image.vue
index 3a136b6e..179ed462 100644
--- a/web/src/components/post-image.vue
+++ b/web/src/components/post-image.vue
@@ -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: () => []
});
diff --git a/web/src/components/post-item.vue b/web/src/components/post-item.vue
index 9ae3ad55..06dfd018 100644
--- a/web/src/components/post-item.vue
+++ b/web/src/components/post-item.vue
@@ -101,7 +101,7 @@ const props = withDefaults(defineProps<{
}>(), {});
const post = computed(() => {
- let post: Required = Object.assign(
+ let post: Item.PostComponentProps = Object.assign(
{
texts: [],
imgs: [],
diff --git a/web/src/components/post-link.vue b/web/src/components/post-link.vue
index b5713695..16864089 100644
--- a/web/src/components/post-link.vue
+++ b/web/src/components/post-link.vue
@@ -17,7 +17,7 @@