Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28b9866c42 | ||
|
|
8e026de20b | ||
|
|
718ecc2372 | ||
|
|
56d46722f4 | ||
|
|
b6463cd715 | ||
|
|
bd3ae0cbfe | ||
|
|
83c3aa894f | ||
|
|
1b88d26fea | ||
|
|
588287fdb4 | ||
|
|
688e544b07 | ||
|
|
3e3f812e83 | ||
|
|
b551c7abe4 | ||
|
|
6d1e7a4c05 | ||
|
|
3341a4bc8e | ||
|
|
1c84980d36 | ||
|
|
833b25881d | ||
|
|
9dbf58903c | ||
|
|
ad007f0d91 | ||
|
|
4b06973a52 | ||
|
|
159a67f15d | ||
|
|
7c03b9953b | ||
|
|
f90987de8d | ||
|
|
70e4ff7820 | ||
|
|
a99356f54b | ||
|
|
c5bc9534cc | ||
|
|
a40733424f | ||
|
|
a937efc60e | ||
|
|
6adb0e8415 | ||
|
|
ff9ffb2f12 | ||
|
|
9be4f472ae | ||
|
|
8581d74b08 | ||
|
|
dafe9bd6b6 | ||
|
|
3ae5772360 | ||
|
|
4628dbccfb | ||
|
|
572b1d4c14 | ||
|
|
bdb70e9859 | ||
|
|
38bda17271 | ||
|
|
455e1d2e5b | ||
|
|
89cd724bab | ||
|
|
b9109b4d0e | ||
|
|
945958f552 | ||
|
|
78eb0d5c06 | ||
|
|
bc6eae711e | ||
|
|
f0a4bf6164 | ||
|
|
fc3b5e3ac3 | ||
|
|
f7235ac847 | ||
|
|
231f4ddb7f | ||
|
|
3cad3994cb | ||
|
|
8c97cc8686 | ||
|
|
7ae976ee5d | ||
|
|
e91b53eb32 | ||
|
|
90311536a7 | ||
|
|
e951b7f2f9 | ||
|
|
e0f94b62cf | ||
|
|
8cb701ec85 | ||
|
|
9afd11e3b8 | ||
|
|
a1d495f2db | ||
|
|
652fa93910 | ||
|
|
ef414855f0 | ||
|
|
76cf35cdf0 | ||
|
|
9d7aa05032 | ||
|
|
62a22c697d | ||
|
|
be497a5aa7 | ||
|
|
fc3e16bc63 | ||
|
|
df35912461 | ||
|
|
0ddc66a854 | ||
|
|
716d557d66 | ||
|
|
f9edcb9d47 | ||
|
|
d4623c5bc9 | ||
|
|
02ba4a3330 | ||
|
|
a72d4eaf78 | ||
|
|
4d3abb2dc0 | ||
|
|
ad6a8d1f7a | ||
|
|
a5c8c2ac97 | ||
|
|
1237004cb1 | ||
|
|
c2bcd17df7 | ||
|
|
bb49cbdd50 | ||
|
|
6ad770a824 | ||
|
|
593eeb3ac3 | ||
|
|
6a7be3ef84 |
190
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*' # 当推送带有版本号的 tag(例如 v1.0.0)时触发工作流
|
||||
- 'test*'
|
||||
|
||||
env:
|
||||
LATEST_TAG: latest
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { platform: "amd64", goos: "linux" }
|
||||
- { platform: "arm64", goos: "linux" }
|
||||
- { platform: "amd64", goos: "windows" }
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go environment
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22' # 选择 Go 版本
|
||||
|
||||
- name: Set up npm
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
|
||||
- name: build rustdesk-api-web
|
||||
run: |
|
||||
git clone https://github.com/lejianwen/rustdesk-api-web
|
||||
cd rustdesk-api-web
|
||||
npm install
|
||||
npm run build
|
||||
mkdir ../resources/admin/ -p
|
||||
cp -ar dist/* ../resources/admin/
|
||||
|
||||
- name: tidy
|
||||
run: go mod tidy
|
||||
|
||||
- name: swag
|
||||
run: |
|
||||
go install github.com/swaggo/swag/cmd/swag@latest
|
||||
swag init -g cmd/apimain.go --output docs/api --instanceName api --exclude http/controller/admin
|
||||
swag init -g cmd/apimain.go --output docs/admin --instanceName admin --exclude http/controller/api
|
||||
|
||||
- name: Build for ${{ matrix.job.goos }}-${{ matrix.job.platform }}
|
||||
run: |
|
||||
mkdir release -p
|
||||
cp -ar resources release/
|
||||
cp -ar docs release/
|
||||
cp -ar conf release/
|
||||
mkdir -p release/data
|
||||
mkdir -p release/runtime
|
||||
if [ "${{ matrix.job.goos }}" = "windows" ]; then
|
||||
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
|
||||
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
|
||||
zip -r ${{ matrix.job.goos}}-${{ matrix.job.platform }}.zip ./release
|
||||
else
|
||||
if [ "${{ matrix.job.platform }}" = "arm64" ]; then
|
||||
wget https://musl.cc/aarch64-linux-musl-cross.tgz
|
||||
tar -xf aarch64-linux-musl-cross.tgz
|
||||
export PATH=$PATH:$PWD/aarch64-linux-musl-cross/bin
|
||||
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=aarch64-linux-musl-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain ./cmd/apimain.go
|
||||
else
|
||||
sudo apt-get install musl musl-dev musl-tools -y
|
||||
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=musl-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain ./cmd/apimain.go
|
||||
fi
|
||||
tar -czf ${{ matrix.job.goos}}-${{ matrix.job.platform }}.tar.gz ./release
|
||||
fi
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
|
||||
path: |
|
||||
${{ matrix.job.goos}}-${{ matrix.job.platform }}.tar.gz
|
||||
${{ matrix.job.goos}}-${{ matrix.job.platform }}.zip
|
||||
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
${{ matrix.job.goos}}-${{ matrix.job.platform }}.tar.gz
|
||||
${{ matrix.job.goos}}-${{ matrix.job.platform }}.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
docker:
|
||||
name: Push Docker Image
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { platform: "amd64", goos: "linux", docker_platform: "linux/amd64" }
|
||||
- { platform: "arm64", goos: "linux", docker_platform: "linux/arm64" }
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
|
||||
- name: Extract version from tag
|
||||
id: vars
|
||||
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: lejianwen/rustdesk-api
|
||||
|
||||
- name: Download binaries
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
|
||||
path: ./
|
||||
|
||||
- name: Unzip binaries
|
||||
run: |
|
||||
mkdir -p ${{ matrix.job.platform }}
|
||||
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
|
||||
file ${{ matrix.job.platform }}/apimain
|
||||
|
||||
- name: Build and push Docker image ${{ matrix.job.platform }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: "."
|
||||
file: ./Dockerfile
|
||||
platforms: ${{ matrix.job.docker_platform }}
|
||||
push: true
|
||||
provenance: false
|
||||
build-args: |
|
||||
BUILDARCH=${{ matrix.job.platform }}
|
||||
tags: |
|
||||
lejianwen/rustdesk-api:${{ env.LATEST_TAG }}-${{ matrix.job.platform }}
|
||||
lejianwen/rustdesk-api:${{ env.TAG }}-${{ matrix.job.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
#
|
||||
docker-manifest:
|
||||
name: Push Docker Manifest
|
||||
needs: docker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Extract version from tag
|
||||
id: vars
|
||||
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
|
||||
- name: Create and push manifest (:version)
|
||||
uses: Noelware/docker-manifest-action@master
|
||||
with:
|
||||
base-image: lejianwen/rustdesk-api:${{ env.TAG }}
|
||||
extra-images: lejianwen/rustdesk-api:${{ env.TAG }}-amd64,lejianwen/rustdesk-api:${{ env.TAG }}-arm64
|
||||
push: true
|
||||
|
||||
- name: Create and push manifest (:latest)
|
||||
uses: Noelware/docker-manifest-action@master
|
||||
with:
|
||||
base-image: lejianwen/rustdesk-api:latest
|
||||
extra-images: lejianwen/rustdesk-api:latest-amd64,lejianwen/rustdesk-api:latest-arm64
|
||||
push: true
|
||||
95
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
name: Build and Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# tags:
|
||||
# - 'v*.*.*' # 当推送带有版本号的 tag(例如 v1.0.0)时触发工作流
|
||||
#on:
|
||||
# push:
|
||||
# branches: [ "master" ]
|
||||
# pull_request:
|
||||
# branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
goos: [ linux, windows ] # 指定要构建的操作系统
|
||||
goarch: [ amd64 ] # 指定架构
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go environment
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.22' # 选择 Go 版本
|
||||
|
||||
- name: Set up npm
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: install gcc zip musl
|
||||
run: |
|
||||
if [ "${{ matrix.goos }}" = "windows" ]; then
|
||||
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
|
||||
else
|
||||
sudo apt-get install musl musl-dev musl-tools -y
|
||||
fi
|
||||
|
||||
|
||||
- name: build rustdesk-api-web
|
||||
run: |
|
||||
git clone https://github.com/lejianwen/rustdesk-api-web
|
||||
cd rustdesk-api-web
|
||||
npm install
|
||||
npm run build
|
||||
mkdir ../resources/admin/ -p
|
||||
cp -ar dist/* ../resources/admin/
|
||||
|
||||
- name: tidy
|
||||
run: go mod tidy
|
||||
|
||||
|
||||
- name: swag
|
||||
run: |
|
||||
go install github.com/swaggo/swag/cmd/swag@latest
|
||||
swag init -g cmd/apimain.go --output docs/api --instanceName api --exclude http/controller/admin
|
||||
swag init -g cmd/apimain.go --output docs/admin --instanceName admin --exclude http/controller/api
|
||||
|
||||
- name: Build for ${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
run: |
|
||||
mkdir release -p
|
||||
cp -ar resources release/
|
||||
cp -ar docs release/
|
||||
cp -ar conf release/
|
||||
mkdir -p release/data
|
||||
mkdir -p release/runtime
|
||||
if [ "${{ matrix.goos }}" = "windows" ]; then
|
||||
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
|
||||
zip -r ${{ matrix.goos}}-${{ matrix.goarch }}.zip ./release
|
||||
else
|
||||
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} CC=musl-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain ./cmd/apimain.go
|
||||
tar -czf ${{ matrix.goos}}-${{ matrix.goarch }}.tar.gz ./release
|
||||
fi
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: myapp-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
path: |
|
||||
${{ matrix.goos}}-${{ matrix.goarch }}.tar.gz
|
||||
${{ matrix.goos}}-${{ matrix.goarch }}.zip
|
||||
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
${{ matrix.goos}}-${{ matrix.goarch }}.tar.gz
|
||||
${{ matrix.goos}}-${{ matrix.goarch }}.zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
1
.gitignore
vendored
@@ -5,5 +5,6 @@ go.sum
|
||||
resources/*
|
||||
!resources/public/upload/.gitignore
|
||||
!resources/web
|
||||
!resources/i18n
|
||||
release
|
||||
data
|
||||
40
Dockerfile
@@ -1,39 +1,11 @@
|
||||
FROM golang:1.22-alpine as builder
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache git gcc build-base sqlite-dev npm nodejs; \
|
||||
git clone https://github.com/lejianwen/rustdesk-api-web; \
|
||||
git clone https://github.com/lejianwen/rustdesk-api; \
|
||||
#先编译后台
|
||||
cd rustdesk-api-web; \
|
||||
npm install; \
|
||||
npm run build; \
|
||||
cd ..; \
|
||||
mkdir -p rustdesk-api/resources/admin; \
|
||||
cp -ar rustdesk-api-web/dist/* rustdesk-api/resources/admin; \
|
||||
cd rustdesk-api; \
|
||||
go mod tidy; \
|
||||
go install github.com/swaggo/swag/cmd/swag@latest; \
|
||||
swag init -g cmd/apimain.go --output docs/api --instanceName api --exclude http/controller/admin; \
|
||||
swag init -g cmd/apimain.go --output docs/admin --instanceName admin --exclude http/controller/api; \
|
||||
go env -w GO111MODULE=on;\
|
||||
go env -w CGO_ENABLED=1;\
|
||||
go env -w GOOS=linux;\
|
||||
go env -w GOARCH=amd64;\
|
||||
go env -w CGO_LDFLAGS="-static"; \
|
||||
go build -o release/apimain cmd/apimain.go; \
|
||||
cp -ar resources release/; \
|
||||
mkdir -p release/resources/public; \
|
||||
cp -ar docs release/; \
|
||||
cp -ar conf release/; \
|
||||
mkdir -p release/data; \
|
||||
mkdir -p release/runtime;
|
||||
|
||||
VOLUME /app/data
|
||||
FROM alpine
|
||||
|
||||
ARG BUILDARCH
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache tzdata
|
||||
COPY --from=builder /go/rustdesk-api/release /app/
|
||||
RUN apk add --no-cache tzdata file
|
||||
COPY ./${BUILDARCH}/release /app/
|
||||
RUN file /app/apimain
|
||||
VOLUME /app/data
|
||||
|
||||
EXPOSE 21114
|
||||
CMD ["./apimain"]
|
||||
|
||||
130
README.md
@@ -2,15 +2,39 @@
|
||||
|
||||
[English Doc](README_EN.md)
|
||||
|
||||
本项目使用 Go 实现了 RustDesk 的 API,并包含了 Web UI 和 Web 客户端。RustDesk 是一个远程桌面软件,提供了自托管的解决方案。
|
||||
本项目使用 Go 实现了 RustDesk 的 API,并包含了 Web Admin 和 Web 客户端。RustDesk 是一个远程桌面软件,提供了自托管的解决方案。
|
||||
|
||||
<div align=center>
|
||||
<img src="https://img.shields.io/badge/golang-1.22-blue"/>
|
||||
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
||||
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
||||
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
||||
</div>
|
||||
|
||||
# 特性
|
||||
|
||||
- PC端API
|
||||
- 个人版API
|
||||
- 登录
|
||||
- 地址簿
|
||||
- 群组
|
||||
- 授权登录,支持`github`和`google`登录,支持`web后台`授权登录
|
||||
- i18n
|
||||
- Web Admin
|
||||
- 用户管理
|
||||
- 设备管理
|
||||
- 地址簿管理
|
||||
- 标签管理
|
||||
- 群组管理
|
||||
- Oauth 管理
|
||||
- 快速使用web client
|
||||
- i18n
|
||||
- Web Client
|
||||
- 自动获取API server
|
||||
- 自动获取ID服务器和KEY
|
||||
- 自动获取地址簿
|
||||
|
||||
## 使用前准备
|
||||
|
||||
### [Rustdesk](https://github.com/rustdesk/rustdesk)
|
||||
@@ -32,7 +56,7 @@
|
||||
|
||||
## 功能
|
||||
|
||||
### API 服务: 基本实现了PC端基础的接口。
|
||||
### API 服务: 基本实现了PC端基础的接口。支持Personal版本接口,可以通过配置文件`rustdesk.personal`或环境变量`RUSTDESK_API_RUSTDESK_PERSONAL`来控制是否启用
|
||||
|
||||
#### 登录
|
||||
|
||||
@@ -45,13 +69,13 @@
|
||||
|
||||

|
||||
|
||||
#### 群组,群组分为`共享组`和`普通组`,共享组中所有人都能看到小组成员的地址,普通组只有管理员能看到所有小组成员的地址
|
||||
#### 群组,群组分为`共享组`和`普通组`,共享组中所有人都能看到小组成员的设备,普通组只有管理员能看到所有小组成员的设备
|
||||
|
||||

|
||||
|
||||
### **Web UI**: 使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。
|
||||
### Web Admin:
|
||||
|
||||
***前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)***
|
||||
***使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)***
|
||||
|
||||
***后台访问地址是`http://<your server>[:port]/_admin/`初次安装管理员为用户名密码为`admin` `admin`,请即时更改密码***
|
||||
|
||||
@@ -59,21 +83,21 @@
|
||||

|
||||
2. 普通用户界面
|
||||

|
||||
3. 右上角也可以更改密码
|
||||
右上角也可以更改密码
|
||||

|
||||
|
||||
4. 分组可以自定义,方便管理,暂时支持两种类型: `共享组` 和 `普通组`
|
||||
3. 分组可以自定义,方便管理,暂时支持两种类型: `共享组` 和 `普通组`
|
||||

|
||||
5. 可以直接打开webclient,方便使用
|
||||
4. 可以直接打开webclient,方便使用
|
||||

|
||||
6. Oauth,暂时只支持了`Github`和`Google`, 需要创建一个`OAuth App`,然后配置到后台
|
||||
5. Oauth,暂时只支持了`Github`和`Google`, 需要创建一个`OAuth App`,然后配置到后台
|
||||

|
||||
- `github oauth app`在`Settings`->`Developer settings`->`OAuth Apps`->`New OAuth App`
|
||||
中创建,地址 [https://github.com/settings/developers](https://github.com/settings/developers)
|
||||
- `Authorization callback URL`填写`http://<your server[:port]>/api/oauth/callback`
|
||||
,比如`http://127.0.0.1:21114/api/oauth/callback`
|
||||
|
||||
### **Web Client**:
|
||||
### Web Client:
|
||||
|
||||
1. 如果已经登录了后台,web client将自动直接登录
|
||||
2. 如果没登录后台,点击右上角登录即可,api server已经自动配置好了
|
||||
@@ -81,19 +105,22 @@
|
||||
3. 登录后,会自动同步ID服务器和KEY
|
||||
4. 登录后,会将地址簿自动保存到web client中,方便使用
|
||||
|
||||
### **自动化文档**: 使用 Swag 生成 API 文档,方便开发者理解和使用 API。
|
||||
### 自动化文档: 使用 Swag 生成 API 文档,方便开发者理解和使用 API。
|
||||
|
||||
1. 后台文档 `<youer server>/admin/swagger/index.html`
|
||||
2. PC端文档 `<youer server>/swagger/index.html`
|
||||
1. 后台文档 `<youer server[:port]>/admin/swagger/index.html`
|
||||
2. PC端文档 `<youer server[:port]>/swagger/index.html`
|
||||

|
||||
|
||||
## 安装与运行
|
||||
|
||||
### 相关配置
|
||||
|
||||
* 参考`conf/config.yaml`配置文件,修改相关配置。如果`gorm.type`是`sqlite`,则不需要配置mysql相关配置。
|
||||
* 参考`conf/config.yaml`配置文件,修改相关配置。
|
||||
* 如果`gorm.type`是`sqlite`,则不需要配置mysql相关配置。
|
||||
* 语言如果不设置默认为`zh-CN`
|
||||
|
||||
```yaml
|
||||
lang: "en"
|
||||
gin:
|
||||
api-addr: "0.0.0.0:21114"
|
||||
mode: "release"
|
||||
@@ -113,20 +140,23 @@ rustdesk:
|
||||
relay-server: "192.168.1.66:21117"
|
||||
api-server: "http://192.168.1.66:21114"
|
||||
key: "123456789"
|
||||
personal: 1
|
||||
```
|
||||
|
||||
* 环境变量,变量名前缀是RUSTDESK_API,环境变量如果存在将覆盖配置文件中的配置
|
||||
|
||||
| 变量名 | 说明 | 示例 |
|
||||
|:------------------------------------|:-------------------------------------|-----------------------------|
|
||||
|-------------------------------------|--------------------------------------|-----------------------------|
|
||||
| TZ | 时区 | Asia/Shanghai |
|
||||
| RUSTDESK_API_LANG | 语言 | `en`,`zh-CN` |
|
||||
| -----GIN配置----- | ---------- | ---------- |
|
||||
| RUSTDESK_API_GIN_TRUST_PROXY | 信任的代理IP列表,以`,`分割,默认信任所有 | 192.168.1.2,192.168.1.3 |
|
||||
| -----------GORM配置------------------ | ------------------------------------ | --------------------------- |
|
||||
| RUSTDESK_API_GORM_TYPE | 数据库类型sqlite或者mysql,默认sqlite | sqlite |
|
||||
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | 数据库最大空闲连接数 | 10 |
|
||||
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | 数据库最大打开连接数 | 100 |
|
||||
| -----MYSQL配置----- | -----数据库类型为sqlite时不用填----- | ---------- |
|
||||
| RUSTDESK_API_RUSTDESK_PERSONAL | 是否启用个人版API, 1:启用,0:不启用; 默认启用 | 1 |
|
||||
| -----MYSQL配置----- | ---------- | ---------- |
|
||||
| RUSTDESK_API_MYSQL_USERNAME | mysql用户名 | root |
|
||||
| RUSTDESK_API_MYSQL_PASSWORD | mysql密码 | 111111 |
|
||||
| RUSTDESK_API_MYSQL_ADDR | mysql地址 | 192.168.1.66:3306 |
|
||||
@@ -240,6 +270,72 @@ lejianwen/rustdesk-api
|
||||
|
||||
```
|
||||
|
||||
- 如果使用的是S6的镜像,会需要修改启动脚本,覆盖镜像中的`/etc/s6-overlay/s6-rc.d/hbbr/run`
|
||||
和`/etc/s6-overlay/s6-rc.d/hbbr/run`
|
||||
|
||||
1. 创建`hbbr/run`
|
||||
|
||||
```bash
|
||||
#!/command/with-contenv sh
|
||||
cd /data
|
||||
PARAMS=
|
||||
[ "${ENCRYPTED_ONLY}" = "1" ] && PARAMS="-k ${KEY}"
|
||||
/usr/bin/hbbr $PARAMS
|
||||
```
|
||||
|
||||
2. 创建`hbbs/run`
|
||||
```bash
|
||||
#!/command/with-contenv sh
|
||||
sleep 2
|
||||
cd /data
|
||||
PARAMS=
|
||||
[ "${ENCRYPTED_ONLY}" = "1" ] && PARAMS="-k ${KEY}"
|
||||
/usr/bin/hbbs -r $RELAY $PARAMS
|
||||
```
|
||||
3. 修改`docker-compose.yml`中的`s6`部分
|
||||
|
||||
```
|
||||
networks:
|
||||
rustdesk-net:
|
||||
external: false
|
||||
services:
|
||||
rustdesk-server:
|
||||
container_name: rustdesk-server
|
||||
ports:
|
||||
- 21115:21115
|
||||
- 21116:21116
|
||||
- 21116:21116/udp
|
||||
- 21117:21117
|
||||
- 21118:21118
|
||||
- 21119:21119
|
||||
image: rustdesk/rustdesk-server-s6:latest
|
||||
environment:
|
||||
- RELAY=192.168.1.66:21117
|
||||
- ENCRYPTED_ONLY=1
|
||||
- KEY=abc123456789
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./hbbr/run:/etc/s6-overlay/s6-rc.d/hbbr/run
|
||||
- ./hbbs/run:/etc/s6-overlay/s6-rc.d/hbbs/run
|
||||
restart: unless-stopped
|
||||
rustdesk-api:
|
||||
container_name: rustdesk-api
|
||||
ports:
|
||||
- 21114:21114
|
||||
image: lejianwen/rustdesk-api
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116
|
||||
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117
|
||||
- RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114
|
||||
- RUSTDESK_API_RUSTDESK_KEY=abc123456789
|
||||
volumes:
|
||||
- /data/rustdesk/api:/app/data #将数据库挂载
|
||||
networks:
|
||||
- rustdesk-net
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
#### 下载release直接运行
|
||||
|
||||
下载地址[release](https://github.com/lejianwen/rustdesk-api/releases)
|
||||
@@ -280,7 +376,7 @@ lejianwen/rustdesk-api
|
||||
5. 编译,如果想自己编译,先cd到项目根目录,然后windows下直接运行`build.bat`,linux下运行`build.sh`,编译后会在`release`
|
||||
目录下生成对应的可执行文件。直接运行编译后的可执行文件即可。
|
||||
|
||||
6. 打开浏览器访问`http://<your server>:21114/_admin/`,默认用户名密码为`admin`,请及时更改密码。
|
||||
6. 打开浏览器访问`http://<your server[:port]>/_admin/`,默认用户名密码为`admin`,请及时更改密码。
|
||||
|
||||
## 其他
|
||||
|
||||
|
||||
156
README_EN.md
@@ -8,8 +8,32 @@ desktop software that provides self-hosted solutions.
|
||||
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
||||
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
||||
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
||||
</div>
|
||||
|
||||
# Features
|
||||
|
||||
- PC API
|
||||
- Personal API
|
||||
- Login
|
||||
- Address Book
|
||||
- Groups
|
||||
- Authorized login, supports `GitHub` and `Google` login, supports `web admin` authorized login
|
||||
- i18n
|
||||
- Web Admin
|
||||
- User Management
|
||||
- Device Management
|
||||
- Address Book Management
|
||||
- Tag Management
|
||||
- Group Management
|
||||
- OAuth Management
|
||||
- Quick access to web client
|
||||
- i18n
|
||||
- Web Client
|
||||
- Automatically obtain API server
|
||||
- Automatically obtain ID server and KEY
|
||||
- Automatically obtain address book
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### [Rustdesk](https://github.com/rustdesk/rustdesk)
|
||||
@@ -30,52 +54,54 @@ desktop software that provides self-hosted solutions.
|
||||
hbbr -k abc1234567
|
||||
```
|
||||
|
||||
## Features
|
||||
## Overview
|
||||
|
||||
### API Service: Basic implementation of the PC client's primary interfaces.
|
||||
### API Service: Basic implementation of the PC client's primary interfaces.Supports the Personal version api, which can be enabled by configuring the `rustdesk.personal` file or the `RUSTDESK_API_RUSTDESK_PERSONAL` environment variable.
|
||||
|
||||
#### Login
|
||||
|
||||
- Added `GitHub` and `Google` login, which can be used after configuration in the admin panel. See the OAuth configuration section
|
||||
for details.
|
||||
- Added `GitHub` and `Google` login, which can be used after configuration in the admin panel. See the OAuth
|
||||
configuration section for details.
|
||||
- Added authorization login for the web admin panel.
|
||||
|
||||

|
||||

|
||||
|
||||
#### Address Book
|
||||
|
||||

|
||||

|
||||
|
||||
#### Groups: Groups are divided into `shared groups` and `regular groups`. In shared groups, everyone can see the addresses of all group members, while in regular groups, only administrators can see all members' addresses.
|
||||
#### Groups: Groups are divided into `shared groups` and `regular groups`. In shared groups, everyone can see the peers of all group members, while in regular groups, only administrators can see all members' peers.
|
||||
|
||||

|
||||

|
||||
|
||||
### **Web UI**: The frontend and backend are separated to provide a user-friendly management interface, primarily for managing and displaying data.
|
||||
### Web Admin
|
||||
|
||||
***Frontend code is available at [rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)***
|
||||
***The frontend and backend are separated to provide a user-friendly management interface, primarily for managing and
|
||||
displaying data.Frontend code is available at [rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)***
|
||||
|
||||
***Admin panel URL: `http://<your server>[:port]/_admin/`. The default username and password for the initial
|
||||
***Admin panel URL: `http://<your server[:port]>/_admin/`. The default username and password for the initial
|
||||
installation are `admin` `admin`, please change the password immediately.***
|
||||
|
||||
1. Admin interface:
|
||||

|
||||

|
||||
2. Regular user interface:
|
||||

|
||||
3. You can change your password from the top right corner:
|
||||

|
||||
4. Groups can be customized for easy management. Currently, two types are supported: `shared group` and `regular group`.
|
||||

|
||||
5. You can open the web client directly for convenience:
|
||||

|
||||
6. OAuth support: Currently, `GitHub` and `Google` is supported. You need to create an `OAuth App` and configure it in the admin
|
||||

|
||||
You can change your password from the top right corner:
|
||||

|
||||
3. Groups can be customized for easy management. Currently, two types are supported: `shared group` and `regular group`.
|
||||

|
||||
4. You can open the web client directly for convenience:
|
||||

|
||||
5. OAuth support: Currently, `GitHub` and `Google` is supported. You need to create an `OAuth App` and configure it in
|
||||
the admin
|
||||
panel.
|
||||

|
||||

|
||||
- Create a `GitHub OAuth App`
|
||||
at `Settings` -> `Developer settings` -> `OAuth Apps` -> `New OAuth App` [here](https://github.com/settings/developers).
|
||||
- Set the `Authorization callback URL` to `http://<your server[:port]>/api/oauth/callback`,
|
||||
e.g., `http://127.0.0.1:21114/api/oauth/callback`.
|
||||
|
||||
### **Web Client**:
|
||||
### Web Client:
|
||||
|
||||
1. If you're already logged into the admin panel, the web client will log in automatically.
|
||||
2. If you're not logged in, simply click the login button at the top right corner, and the API server will be
|
||||
@@ -84,20 +110,22 @@ installation are `admin` `admin`, please change the password immediately.***
|
||||
3. After logging in, the ID server and key will be automatically synced.
|
||||
4. The address book will also be automatically saved to the web client for convenient use.
|
||||
|
||||
### **Automated Documentation** : API documentation is generated using Swag, making it easier for developers to understand and use the API.
|
||||
### Automated Documentation : API documentation is generated using Swag, making it easier for developers to understand and use the API.
|
||||
|
||||
1. Admin panel docs: `<your server>/admin/swagger/index.html`
|
||||
2. PC client docs: `<your server>/swagger/index.html`
|
||||
1. Admin panel docs: `<your server[:port]>/admin/swagger/index.html`
|
||||
2. PC client docs: `<your server[:port]>/swagger/index.html`
|
||||

|
||||
|
||||
## Installation and Setup
|
||||
|
||||
### Configuration
|
||||
|
||||
* Modify the configuration in `conf/config.yaml`. If `gorm.type` is set to `sqlite`, MySQL-related configurations are
|
||||
not required.
|
||||
* Modify the configuration in `conf/config.yaml`.
|
||||
* If `gorm.type` is set to `sqlite`, MySQL-related configurations are not required.
|
||||
* Language support: `en` and `zh-CN` are supported. The default is `zh-CN`.
|
||||
|
||||
```yaml
|
||||
lang: "en"
|
||||
gin:
|
||||
api-addr: "0.0.0.0:21114"
|
||||
mode: "release"
|
||||
@@ -117,19 +145,24 @@ rustdesk:
|
||||
relay-server: "192.168.1.66:21117"
|
||||
api-server: "http://192.168.1.66:21114"
|
||||
key: "123456789"
|
||||
personal: 1
|
||||
```
|
||||
|
||||
* Environment variables, with the prefix `RUSTDESK_API`, will override the settings in the configuration file if
|
||||
* Environment variables, with the prefix `RUSTDESK_API_RUSTDESK_PERSONAL`, will override the settings in the
|
||||
configuration file if
|
||||
present.
|
||||
|
||||
| Variable Name | Description | Example |
|
||||
|------------------------------------|-----------------------------------------------------------|--------------------------------|
|
||||
| TZ | timezone | Asia/Shanghai |
|
||||
| RUSTDESK_API_LANG | Language | `en`,`zh-CN` |
|
||||
| ----- GIN Configuration ----- | --------------------------------------- | ------------------------------ |
|
||||
| RUSTDESK_API_GIN_TRUST_PROXY | Trusted proxy IPs, separated by commas. | 192.168.1.2,192.168.1.3 |
|
||||
| ----- GORM Configuration ----- | --------------------------------------- | ------------------------------ |
|
||||
| RUSTDESK_API_GORM_TYPE | Database type (`sqlite` or `mysql`). Default is `sqlite`. | sqlite |
|
||||
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | Maximum idle connections | 10 |
|
||||
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | Maximum open connections | 100 |
|
||||
| RUSTDESK_API_RUSTDESK_PERSONAL | Open Personal Api 1:Enable,0:Disable | 1 |
|
||||
| ----- MYSQL Configuration ----- | --------------------------------------- | ------------------------------ |
|
||||
| RUSTDESK_API_MYSQL_USERNAME | MySQL username | root |
|
||||
| RUSTDESK_API_MYSQL_PASSWORD | MySQL password | 111111 |
|
||||
@@ -151,6 +184,7 @@ rustdesk:
|
||||
```bash
|
||||
docker run -d --name rustdesk-api -p 21114:21114 \
|
||||
-v /data/rustdesk/api:/app/data \
|
||||
-e RUSTDESK_API_LANG=en \
|
||||
-e RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116 \
|
||||
-e RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117 \
|
||||
-e RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114 \
|
||||
@@ -241,6 +275,70 @@ lejianwen/rustdesk-api
|
||||
restart: unless-stopped
|
||||
|
||||
```
|
||||
- If you are using an S6 image, you need to modify the startup script `/etc/s6-overlay/s6-rc.d/hbbr/run`
|
||||
and `/etc/s6-overlay/s6-rc.d/hbbr/run`
|
||||
|
||||
1. create `hbbr/run`
|
||||
|
||||
```bash
|
||||
#!/command/with-contenv sh
|
||||
cd /data
|
||||
PARAMS=
|
||||
[ "${ENCRYPTED_ONLY}" = "1" ] && PARAMS="-k ${KEY}"
|
||||
/usr/bin/hbbr $PARAMS
|
||||
```
|
||||
|
||||
2. create `hbbs/run`
|
||||
```bash
|
||||
#!/command/with-contenv sh
|
||||
sleep 2
|
||||
cd /data
|
||||
PARAMS=
|
||||
[ "${ENCRYPTED_ONLY}" = "1" ] && PARAMS="-k ${KEY}"
|
||||
/usr/bin/hbbs -r $RELAY $PARAMS
|
||||
```
|
||||
3. edit `docker-compose.yml`
|
||||
```
|
||||
networks:
|
||||
rustdesk-net:
|
||||
external: false
|
||||
services:
|
||||
rustdesk-server:
|
||||
container_name: rustdesk-server
|
||||
ports:
|
||||
- 21115:21115
|
||||
- 21116:21116
|
||||
- 21116:21116/udp
|
||||
- 21117:21117
|
||||
- 21118:21118
|
||||
- 21119:21119
|
||||
image: rustdesk/rustdesk-server-s6:latest
|
||||
environment:
|
||||
- RELAY=192.168.1.66:21117
|
||||
- ENCRYPTED_ONLY=1
|
||||
- KEY=abc123456789
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./hbbr/run:/etc/s6-overlay/s6-rc.d/hbbr/run
|
||||
- ./hbbs/run:/etc/s6-overlay/s6-rc.d/hbbs/run
|
||||
restart: unless-stopped
|
||||
rustdesk-api:
|
||||
container_name: rustdesk-api
|
||||
ports:
|
||||
- 21114:21114
|
||||
image: lejianwen/rustdesk-api
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- RUSTDESK_API_RUSTDESK_ID_SERVER=192.168.1.66:21116
|
||||
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=192.168.1.66:21117
|
||||
- RUSTDESK_API_RUSTDESK_API_SERVER=http://192.168.1.66:21114
|
||||
- RUSTDESK_API_RUSTDESK_KEY=abc123456789
|
||||
volumes:
|
||||
- /data/rustdesk/api:/app/data #将数据库挂载
|
||||
networks:
|
||||
- rustdesk-net
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
#### Running from Release
|
||||
|
||||
@@ -286,7 +384,7 @@ Download the release from [release](https://github.com/lejianwen/rustdesk-api/re
|
||||
compiling, the corresponding executables will be generated in the `release` directory. Run the compiled executables
|
||||
directly.
|
||||
|
||||
6. Open your browser and visit `http://<your server>:21114/_admin/`, with default credentials `admin admin`. Please
|
||||
6. Open your browser and visit `http://<your server[:port]>/_admin/`, with default credentials `admin admin`. Please
|
||||
change the password promptly.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
115
cmd/apimain.go
@@ -12,12 +12,18 @@ import (
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"fmt"
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/locales/en"
|
||||
"github.com/go-playground/locales/zh_Hans_CN"
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
en_translations "github.com/go-playground/validator/v10/translations/en"
|
||||
zh_translations "github.com/go-playground/validator/v10/translations/zh"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/text/language"
|
||||
nethttp "net/http"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@@ -42,6 +48,8 @@ func main() {
|
||||
ReportCaller: global.Config.Logger.ReportCaller,
|
||||
})
|
||||
|
||||
InitI18n()
|
||||
|
||||
//redis
|
||||
global.Redis = redis.NewClient(&redis.Options{
|
||||
Addr: global.Config.Redis.Addr,
|
||||
@@ -105,15 +113,25 @@ func main() {
|
||||
|
||||
func ApiInitValidator() {
|
||||
validate := validator.New()
|
||||
|
||||
// 定义不同的语言翻译
|
||||
enT := en.New()
|
||||
cn := zh_Hans_CN.New()
|
||||
|
||||
uni := ut.New(enT, cn)
|
||||
trans, _ := uni.GetTranslator("cn")
|
||||
err := zh_translations.RegisterDefaultTranslations(validate, trans)
|
||||
|
||||
enTrans, _ := uni.GetTranslator("en")
|
||||
zhTrans, _ := uni.GetTranslator("zh_Hans_CN")
|
||||
|
||||
err := zh_translations.RegisterDefaultTranslations(validate, zhTrans)
|
||||
if err != nil {
|
||||
//退出
|
||||
panic(err)
|
||||
}
|
||||
err = en_translations.RegisterDefaultTranslations(validate, enTrans)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
|
||||
label := field.Tag.Get("label")
|
||||
if label == "" {
|
||||
@@ -122,10 +140,16 @@ func ApiInitValidator() {
|
||||
return label
|
||||
})
|
||||
global.Validator.Validate = validate
|
||||
global.Validator.VTrans = trans
|
||||
global.Validator.UT = uni // 存储 Universal Translator
|
||||
global.Validator.VTrans = zhTrans
|
||||
|
||||
global.Validator.ValidStruct = func(i interface{}) []string {
|
||||
global.Validator.ValidStruct = func(ctx *gin.Context, i interface{}) []string {
|
||||
err := global.Validator.Validate.Struct(i)
|
||||
lang := ctx.GetHeader("Accept-Language")
|
||||
if lang == "" {
|
||||
lang = global.Config.Lang
|
||||
}
|
||||
trans := getTranslatorForLang(lang)
|
||||
errList := make([]string, 0, 10)
|
||||
if err != nil {
|
||||
if _, ok := err.(*validator.InvalidValidationError); ok {
|
||||
@@ -133,14 +157,18 @@ func ApiInitValidator() {
|
||||
return errList
|
||||
}
|
||||
for _, err2 := range err.(validator.ValidationErrors) {
|
||||
errList = append(errList, err2.Translate(global.Validator.VTrans))
|
||||
errList = append(errList, err2.Translate(trans))
|
||||
}
|
||||
}
|
||||
return errList
|
||||
}
|
||||
global.Validator.ValidVar = func(field interface{}, tag string) []string {
|
||||
global.Validator.ValidVar = func(ctx *gin.Context, field interface{}, tag string) []string {
|
||||
err := global.Validator.Validate.Var(field, tag)
|
||||
fmt.Println(err)
|
||||
lang := ctx.GetHeader("Accept-Language")
|
||||
if lang == "" {
|
||||
lang = global.Config.Lang
|
||||
}
|
||||
trans := getTranslatorForLang(lang)
|
||||
errList := make([]string, 0, 10)
|
||||
if err != nil {
|
||||
if _, ok := err.(*validator.InvalidValidationError); ok {
|
||||
@@ -148,16 +176,31 @@ func ApiInitValidator() {
|
||||
return errList
|
||||
}
|
||||
for _, err2 := range err.(validator.ValidationErrors) {
|
||||
errList = append(errList, err2.Translate(global.Validator.VTrans))
|
||||
errList = append(errList, err2.Translate(trans))
|
||||
}
|
||||
}
|
||||
return errList
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func getTranslatorForLang(lang string) ut.Translator {
|
||||
switch lang {
|
||||
case "zh_CN":
|
||||
fallthrough
|
||||
case "zh-CN":
|
||||
fallthrough
|
||||
case "zh":
|
||||
trans, _ := global.Validator.UT.GetTranslator("zh_Hans_CN")
|
||||
return trans
|
||||
case "en":
|
||||
fallthrough
|
||||
default:
|
||||
trans, _ := global.Validator.UT.GetTranslator("en")
|
||||
return trans
|
||||
}
|
||||
}
|
||||
func DatabaseAutoUpdate() {
|
||||
version := 103
|
||||
version := 212
|
||||
|
||||
db := global.DB
|
||||
|
||||
@@ -227,13 +270,23 @@ func Migrate(version uint) {
|
||||
var vc int64
|
||||
global.DB.Model(&model.Version{}).Count(&vc)
|
||||
if vc == 1 {
|
||||
localizer := global.Localizer(&gin.Context{
|
||||
Request: &nethttp.Request{},
|
||||
})
|
||||
defaultGroup, _ := localizer.LocalizeMessage(&i18n.Message{
|
||||
ID: "DefaultGroup",
|
||||
})
|
||||
group := &model.Group{
|
||||
Name: "默认组",
|
||||
Name: defaultGroup,
|
||||
Type: model.GroupTypeDefault,
|
||||
}
|
||||
service.AllService.GroupService.Create(group)
|
||||
|
||||
shareGroup, _ := localizer.LocalizeMessage(&i18n.Message{
|
||||
ID: "ShareGroup",
|
||||
})
|
||||
groupShare := &model.Group{
|
||||
Name: "共享组",
|
||||
Name: shareGroup,
|
||||
Type: model.GroupTypeShare,
|
||||
}
|
||||
service.AllService.GroupService.Create(groupShare)
|
||||
@@ -241,7 +294,7 @@ func Migrate(version uint) {
|
||||
is_admin := true
|
||||
admin := &model.User{
|
||||
Username: "admin",
|
||||
Nickname: "管理员",
|
||||
Nickname: "Admin",
|
||||
Status: model.COMMON_STATUS_ENABLE,
|
||||
IsAdmin: &is_admin,
|
||||
GroupId: 1,
|
||||
@@ -251,3 +304,37 @@ func Migrate(version uint) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func InitI18n() {
|
||||
bundle := i18n.NewBundle(language.English)
|
||||
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
|
||||
bundle.LoadMessageFile(global.Config.Gin.ResourcesPath + "/i18n/en.toml")
|
||||
bundle.LoadMessageFile(global.Config.Gin.ResourcesPath + "/i18n/zh_CN.toml")
|
||||
global.Localizer = func(ctx *gin.Context) *i18n.Localizer {
|
||||
lang := ctx.GetHeader("Accept-Language")
|
||||
if lang == "" {
|
||||
lang = global.Config.Lang
|
||||
}
|
||||
if lang == "en" {
|
||||
return i18n.NewLocalizer(bundle, "en")
|
||||
} else {
|
||||
return i18n.NewLocalizer(bundle, lang, "en")
|
||||
}
|
||||
}
|
||||
|
||||
//personUnreadEmails := localizer.MustLocalize(&i18n.LocalizeConfig{
|
||||
// DefaultMessage: &i18n.Message{
|
||||
// ID: "PersonUnreadEmails",
|
||||
// },
|
||||
// PluralCount: 6,
|
||||
// TemplateData: map[string]interface{}{
|
||||
// "Name": "LE",
|
||||
// "PluralCount": 6,
|
||||
// },
|
||||
//})
|
||||
//personUnreadEmails, err := global.Localizer.LocalizeMessage(&i18n.Message{
|
||||
// ID: "ParamsError",
|
||||
//})
|
||||
//fmt.Println(err, personUnreadEmails)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
lang: "zh-CN"
|
||||
gin:
|
||||
api-addr: "0.0.0.0:21114"
|
||||
mode: "release" #release,debug,test
|
||||
@@ -17,6 +18,7 @@ rustdesk:
|
||||
relay-server: "192.168.1.66:21117"
|
||||
api-server: "http://192.168.1.66:21114"
|
||||
key: "123456789"
|
||||
personal: 1
|
||||
logger:
|
||||
path: "./runtime/log.txt"
|
||||
level: "warn" #trace,debug,info,warn,error,fatal
|
||||
|
||||
@@ -15,6 +15,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Lang string `mapstructure:"lang"`
|
||||
Gorm Gorm
|
||||
Mysql Mysql
|
||||
Gin Gin
|
||||
|
||||
@@ -5,4 +5,5 @@ type Rustdesk struct {
|
||||
RelayServer string `mapstructure:"relay-server"`
|
||||
ApiServer string `mapstructure:"api-server"`
|
||||
Key string `mapstructure:"key"`
|
||||
Personal int `mapstructure:"personal"`
|
||||
}
|
||||
|
||||
@@ -1185,7 +1185,7 @@ const docTemplateadmin = `{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "创建机器",
|
||||
"description": "创建设备",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1193,12 +1193,12 @@ const docTemplateadmin = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "创建机器",
|
||||
"summary": "创建设备",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "机器信息",
|
||||
"description": "设备信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -1242,7 +1242,7 @@ const docTemplateadmin = `{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器删除",
|
||||
"description": "设备删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1250,12 +1250,12 @@ const docTemplateadmin = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器删除",
|
||||
"summary": "设备删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "机器信息",
|
||||
"description": "设备信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -1287,7 +1287,7 @@ const docTemplateadmin = `{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器详情",
|
||||
"description": "设备详情",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1295,9 +1295,9 @@ const docTemplateadmin = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器详情",
|
||||
"summary": "设备详情",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
@@ -1342,7 +1342,7 @@ const docTemplateadmin = `{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器列表",
|
||||
"description": "设备列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1350,9 +1350,9 @@ const docTemplateadmin = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器列表",
|
||||
"summary": "设备列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
@@ -1402,7 +1402,7 @@ const docTemplateadmin = `{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器编辑",
|
||||
"description": "设备编辑",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1410,12 +1410,12 @@ const docTemplateadmin = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器编辑",
|
||||
"summary": "设备编辑",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "机器信息",
|
||||
"description": "设备信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -2266,7 +2266,7 @@ const docTemplateadmin = `{
|
||||
"alias": {
|
||||
"type": "string"
|
||||
},
|
||||
"force_always_relay": {
|
||||
"forceAlwaysRelay": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"hash": {
|
||||
@@ -2278,7 +2278,7 @@ const docTemplateadmin = `{
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"login_name": {
|
||||
"loginName": {
|
||||
"type": "string"
|
||||
},
|
||||
"online": {
|
||||
@@ -2290,16 +2290,16 @@ const docTemplateadmin = `{
|
||||
"platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"rdp_port": {
|
||||
"rdpPort": {
|
||||
"type": "string"
|
||||
},
|
||||
"rdp_username": {
|
||||
"rdpUsername": {
|
||||
"type": "string"
|
||||
},
|
||||
"row_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"same_server": {
|
||||
"sameServer": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tags": {
|
||||
@@ -2434,8 +2434,7 @@ const docTemplateadmin = `{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"color",
|
||||
"name",
|
||||
"user_id"
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"color": {
|
||||
@@ -2456,7 +2455,6 @@ const docTemplateadmin = `{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"group_id",
|
||||
"nickname",
|
||||
"status",
|
||||
"username"
|
||||
],
|
||||
@@ -2761,6 +2759,9 @@ const docTemplateadmin = `{
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"last_online_time": {
|
||||
"type": "integer"
|
||||
},
|
||||
"memory": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -1178,7 +1178,7 @@
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "创建机器",
|
||||
"description": "创建设备",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1186,12 +1186,12 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "创建机器",
|
||||
"summary": "创建设备",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "机器信息",
|
||||
"description": "设备信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -1235,7 +1235,7 @@
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器删除",
|
||||
"description": "设备删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1243,12 +1243,12 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器删除",
|
||||
"summary": "设备删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "机器信息",
|
||||
"description": "设备信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -1280,7 +1280,7 @@
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器详情",
|
||||
"description": "设备详情",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1288,9 +1288,9 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器详情",
|
||||
"summary": "设备详情",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
@@ -1335,7 +1335,7 @@
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器列表",
|
||||
"description": "设备列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1343,9 +1343,9 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器列表",
|
||||
"summary": "设备列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
@@ -1395,7 +1395,7 @@
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "机器编辑",
|
||||
"description": "设备编辑",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -1403,12 +1403,12 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"机器"
|
||||
"设备"
|
||||
],
|
||||
"summary": "机器编辑",
|
||||
"summary": "设备编辑",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "机器信息",
|
||||
"description": "设备信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
@@ -2259,7 +2259,7 @@
|
||||
"alias": {
|
||||
"type": "string"
|
||||
},
|
||||
"force_always_relay": {
|
||||
"forceAlwaysRelay": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"hash": {
|
||||
@@ -2271,7 +2271,7 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"login_name": {
|
||||
"loginName": {
|
||||
"type": "string"
|
||||
},
|
||||
"online": {
|
||||
@@ -2283,16 +2283,16 @@
|
||||
"platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"rdp_port": {
|
||||
"rdpPort": {
|
||||
"type": "string"
|
||||
},
|
||||
"rdp_username": {
|
||||
"rdpUsername": {
|
||||
"type": "string"
|
||||
},
|
||||
"row_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"same_server": {
|
||||
"sameServer": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tags": {
|
||||
@@ -2427,8 +2427,7 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"color",
|
||||
"name",
|
||||
"user_id"
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"color": {
|
||||
@@ -2449,7 +2448,6 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"group_id",
|
||||
"nickname",
|
||||
"status",
|
||||
"username"
|
||||
],
|
||||
@@ -2754,6 +2752,9 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"last_online_time": {
|
||||
"type": "integer"
|
||||
},
|
||||
"memory": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ definitions:
|
||||
properties:
|
||||
alias:
|
||||
type: string
|
||||
force_always_relay:
|
||||
forceAlwaysRelay:
|
||||
type: boolean
|
||||
hash:
|
||||
type: string
|
||||
@@ -24,7 +24,7 @@ definitions:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
login_name:
|
||||
loginName:
|
||||
type: string
|
||||
online:
|
||||
type: boolean
|
||||
@@ -32,13 +32,13 @@ definitions:
|
||||
type: string
|
||||
platform:
|
||||
type: string
|
||||
rdp_port:
|
||||
rdpPort:
|
||||
type: string
|
||||
rdp_username:
|
||||
rdpUsername:
|
||||
type: string
|
||||
row_id:
|
||||
type: integer
|
||||
same_server:
|
||||
sameServer:
|
||||
type: boolean
|
||||
tags:
|
||||
items:
|
||||
@@ -141,7 +141,6 @@ definitions:
|
||||
required:
|
||||
- color
|
||||
- name
|
||||
- user_id
|
||||
type: object
|
||||
admin.UserForm:
|
||||
properties:
|
||||
@@ -166,7 +165,6 @@ definitions:
|
||||
type: string
|
||||
required:
|
||||
- group_id
|
||||
- nickname
|
||||
- status
|
||||
- username
|
||||
type: object
|
||||
@@ -348,6 +346,8 @@ definitions:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
last_online_time:
|
||||
type: integer
|
||||
memory:
|
||||
type: string
|
||||
os:
|
||||
@@ -1163,9 +1163,9 @@ paths:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 创建机器
|
||||
description: 创建设备
|
||||
parameters:
|
||||
- description: 机器信息
|
||||
- description: 设备信息
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
@@ -1189,16 +1189,16 @@ paths:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 创建机器
|
||||
summary: 创建设备
|
||||
tags:
|
||||
- 机器
|
||||
- 设备
|
||||
/admin/peer/delete:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 机器删除
|
||||
description: 设备删除
|
||||
parameters:
|
||||
- description: 机器信息
|
||||
- description: 设备信息
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
@@ -1217,14 +1217,14 @@ paths:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 机器删除
|
||||
summary: 设备删除
|
||||
tags:
|
||||
- 机器
|
||||
- 设备
|
||||
/admin/peer/detail/{id}:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 机器详情
|
||||
description: 设备详情
|
||||
parameters:
|
||||
- description: ID
|
||||
in: path
|
||||
@@ -1249,14 +1249,14 @@ paths:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 机器详情
|
||||
summary: 设备详情
|
||||
tags:
|
||||
- 机器
|
||||
- 设备
|
||||
/admin/peer/list:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 机器列表
|
||||
description: 设备列表
|
||||
parameters:
|
||||
- description: 页码
|
||||
in: query
|
||||
@@ -1284,16 +1284,16 @@ paths:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 机器列表
|
||||
summary: 设备列表
|
||||
tags:
|
||||
- 机器
|
||||
- 设备
|
||||
/admin/peer/update:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 机器编辑
|
||||
description: 设备编辑
|
||||
parameters:
|
||||
- description: 机器信息
|
||||
- description: 设备信息
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
@@ -1317,9 +1317,9 @@ paths:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 机器编辑
|
||||
summary: 设备编辑
|
||||
tags:
|
||||
- 机器
|
||||
- 设备
|
||||
/admin/server-config:
|
||||
get:
|
||||
consumes:
|
||||
|
||||
@@ -136,7 +136,7 @@ const docTemplateapi = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址"
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签添加",
|
||||
"responses": {
|
||||
@@ -155,14 +155,14 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/personal": {
|
||||
"/ab/peer/add/{guid}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "个人信息",
|
||||
"description": "添加地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -170,9 +170,136 @@ const docTemplateapi = `{
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户"
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "个人信息",
|
||||
"summary": "添加地址",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "删除地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "删除地址",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/peer/update/{guid}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "更新地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "更新地址",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/peers": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "地址列表",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
@@ -199,6 +326,283 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/personal": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "个人地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "个人地址",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
"name": "string",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/settings": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "设置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "设置",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
"name": "string",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/shared/profiles": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "共享",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "共享地址簿",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
"name": "string",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tag/rename/{guid}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签重命名",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tag/update/{guid}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签修改颜色",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tag/{guid}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签删除",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tags/{guid}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.TagList"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -389,35 +793,6 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/oauth/login": {
|
||||
"get": {
|
||||
"description": "WebOauthLogin",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Oauth"
|
||||
],
|
||||
"summary": "WebOauthLogin",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/oidc/auth": {
|
||||
"post": {
|
||||
"description": "OidcAuth",
|
||||
@@ -882,6 +1257,26 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.TagList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.Tag"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
"page_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.DataResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址"
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签添加",
|
||||
"responses": {
|
||||
@@ -148,14 +148,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/personal": {
|
||||
"/ab/peer/add/{guid}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "个人信息",
|
||||
"description": "添加地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -163,9 +163,136 @@
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户"
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "个人信息",
|
||||
"summary": "添加地址",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "删除地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "删除地址",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/peer/update/{guid}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "更新地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "更新地址",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/peers": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "地址列表",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
@@ -192,6 +319,283 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/personal": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "个人地址",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "个人地址",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
"name": "string",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/settings": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "设置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "设置",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
"name": "string",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/shared/profiles": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "共享",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "共享地址簿",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "string valid",
|
||||
"name": "string",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tag/rename/{guid}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签重命名",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tag/update/{guid}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签修改颜色",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tag/{guid}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签删除",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ab/tags/{guid}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址[Personal]"
|
||||
],
|
||||
"summary": "标签",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.TagList"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -382,35 +786,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/oauth/login": {
|
||||
"get": {
|
||||
"description": "WebOauthLogin",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Oauth"
|
||||
],
|
||||
"summary": "WebOauthLogin",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/oidc/auth": {
|
||||
"post": {
|
||||
"description": "OidcAuth",
|
||||
@@ -875,6 +1250,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.TagList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.Tag"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
"page_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.DataResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -103,6 +103,19 @@ definitions:
|
||||
user_id:
|
||||
type: integer
|
||||
type: object
|
||||
model.TagList:
|
||||
properties:
|
||||
list:
|
||||
items:
|
||||
$ref: '#/definitions/model.Tag'
|
||||
type: array
|
||||
page:
|
||||
type: integer
|
||||
page_size:
|
||||
type: integer
|
||||
total:
|
||||
type: integer
|
||||
type: object
|
||||
response.DataResponse:
|
||||
properties:
|
||||
data: {}
|
||||
@@ -215,12 +228,92 @@ paths:
|
||||
- BearerAuth: []
|
||||
summary: 标签添加
|
||||
tags:
|
||||
- 地址
|
||||
/ab/personal:
|
||||
- 地址[Personal]
|
||||
/ab/peer/add/{guid}:
|
||||
delete:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 删除地址
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 删除地址
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 个人信息
|
||||
description: 添加地址
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 添加地址
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/peer/update/{guid}:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 更新地址
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 更新地址
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/peers:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 地址
|
||||
parameters:
|
||||
- description: string valid
|
||||
in: body
|
||||
@@ -240,9 +333,180 @@ paths:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 个人信息
|
||||
summary: 地址列表
|
||||
tags:
|
||||
- 用户
|
||||
- 地址[Personal]
|
||||
/ab/personal:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 个人地址
|
||||
parameters:
|
||||
- description: string valid
|
||||
in: body
|
||||
name: string
|
||||
schema:
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 个人地址
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/settings:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 设置
|
||||
parameters:
|
||||
- description: string valid
|
||||
in: body
|
||||
name: string
|
||||
schema:
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 设置
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/shared/profiles:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 共享
|
||||
parameters:
|
||||
- description: string valid
|
||||
in: body
|
||||
name: string
|
||||
schema:
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 共享地址簿
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/tag/{guid}:
|
||||
delete:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 标签
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 标签删除
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/tag/rename/{guid}:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 标签
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 标签重命名
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/tag/update/{guid}:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 标签
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 标签修改颜色
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/ab/tags/{guid}:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 标签
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/model.TagList'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 标签
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/api:
|
||||
get:
|
||||
consumes:
|
||||
@@ -366,25 +630,6 @@ paths:
|
||||
summary: OauthCallback
|
||||
tags:
|
||||
- Oauth
|
||||
/oauth/login:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: WebOauthLogin
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
type: string
|
||||
summary: WebOauthLogin
|
||||
tags:
|
||||
- Oauth
|
||||
/oidc/auth:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
BIN
docs/en_img/admin_webclient.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
docs/en_img/pc_ab.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
docs/en_img/pc_gr.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
docs/en_img/pc_login.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
docs/en_img/web_admin.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
docs/en_img/web_admin_gr.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
docs/en_img/web_admin_oauth.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
docs/en_img/web_admin_user.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/en_img/web_resetpwd.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.3 KiB |
@@ -6,9 +6,11 @@ import (
|
||||
"Gwen/lib/jwt"
|
||||
"Gwen/lib/lock"
|
||||
"Gwen/lib/upload"
|
||||
"github.com/gin-gonic/gin"
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"gorm.io/gorm"
|
||||
@@ -23,11 +25,13 @@ var (
|
||||
Cache cache.Handler
|
||||
Validator struct {
|
||||
Validate *validator.Validate
|
||||
UT *ut.UniversalTranslator
|
||||
VTrans ut.Translator
|
||||
ValidStruct func(interface{}) []string
|
||||
ValidVar func(field interface{}, tag string) []string
|
||||
ValidStruct func(*gin.Context, interface{}) []string
|
||||
ValidVar func(ctx *gin.Context, field interface{}, tag string) []string
|
||||
}
|
||||
Oss *upload.Oss
|
||||
Jwt *jwt.Jwt
|
||||
Lock lock.Locker
|
||||
Localizer func(ctx *gin.Context) *i18n.Localizer
|
||||
)
|
||||
|
||||
8
go.mod
@@ -3,6 +3,7 @@ module Gwen
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.1
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
|
||||
@@ -12,12 +13,14 @@ require (
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/go-redis/redis/v8 v8.11.4
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/viper v1.9.0
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.3
|
||||
golang.org/x/oauth2 v0.23.0
|
||||
golang.org/x/text v0.18.0
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.7
|
||||
@@ -64,10 +67,9 @@ require (
|
||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.63.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
_ "encoding/json"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -31,14 +32,14 @@ func (ct *AddressBook) Detail(c *gin.Context) {
|
||||
t := service.AllService.AddressBookService.InfoByRowId(uint(iid))
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if !service.AllService.UserService.IsAdmin(u) && t.UserId != u.Id {
|
||||
response.Fail(c, 101, "无权限")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
if t.RowId > 0 {
|
||||
response.Success(c, t)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -56,10 +57,10 @@ func (ct *AddressBook) Detail(c *gin.Context) {
|
||||
func (ct *AddressBook) Create(c *gin.Context) {
|
||||
f := &admin.AddressBookForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -69,14 +70,72 @@ func (ct *AddressBook) Create(c *gin.Context) {
|
||||
if !service.AllService.UserService.IsAdmin(u) || t.UserId == 0 {
|
||||
t.UserId = u.Id
|
||||
}
|
||||
ex := service.AllService.AddressBookService.InfoByUserIdAndId(t.UserId, t.Id)
|
||||
if ex.RowId > 0 {
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemExist"))
|
||||
return
|
||||
}
|
||||
|
||||
err := service.AllService.AddressBookService.Create(t)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "创建失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, u)
|
||||
}
|
||||
|
||||
// BatchCreate 批量创建地址簿
|
||||
// @Tags 地址簿
|
||||
// @Summary 批量创建地址簿
|
||||
// @Description 批量创建地址簿
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body admin.AddressBookForm true "地址簿信息"
|
||||
// @Success 200 {object} response.Response{data=model.AddressBook}
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /admin/address_book/create [post]
|
||||
// @Security token
|
||||
func (ct *AddressBook) BatchCreate(c *gin.Context) {
|
||||
f := &admin.AddressBookForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
}
|
||||
|
||||
//创建标签
|
||||
for _, fu := range f.UserIds {
|
||||
if fu == 0 {
|
||||
continue
|
||||
}
|
||||
for _, ft := range f.Tags {
|
||||
exTag := service.AllService.TagService.InfoByUserIdAndName(fu, ft)
|
||||
if exTag.Id == 0 {
|
||||
service.AllService.TagService.Create(&model.Tag{
|
||||
UserId: fu,
|
||||
Name: ft,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
ts := f.ToAddressBooks()
|
||||
for _, t := range ts {
|
||||
if t.UserId == 0 {
|
||||
continue
|
||||
}
|
||||
ex := service.AllService.AddressBookService.InfoByUserIdAndId(t.UserId, t.Id)
|
||||
if ex.RowId == 0 {
|
||||
service.AllService.AddressBookService.Create(t)
|
||||
}
|
||||
}
|
||||
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
// List 列表
|
||||
// @Tags 地址簿
|
||||
// @Summary 地址簿列表
|
||||
@@ -94,7 +153,7 @@ func (ct *AddressBook) Create(c *gin.Context) {
|
||||
func (ct *AddressBook) List(c *gin.Context) {
|
||||
query := &admin.AddressBookQuery{}
|
||||
if err := c.ShouldBindQuery(query); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
@@ -102,9 +161,18 @@ func (ct *AddressBook) List(c *gin.Context) {
|
||||
query.UserId = int(u.Id)
|
||||
}
|
||||
res := service.AllService.AddressBookService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
|
||||
if query.Id != "" {
|
||||
tx.Where("id like ?", "%"+query.Id+"%")
|
||||
}
|
||||
if query.UserId > 0 {
|
||||
tx.Where("user_id = ?", query.UserId)
|
||||
}
|
||||
if query.Username != "" {
|
||||
tx.Where("username like ?", "%"+query.Username+"%")
|
||||
}
|
||||
if query.Hostname != "" {
|
||||
tx.Where("hostname like ?", "%"+query.Hostname+"%")
|
||||
}
|
||||
})
|
||||
response.Success(c, res)
|
||||
}
|
||||
@@ -123,27 +191,27 @@ func (ct *AddressBook) List(c *gin.Context) {
|
||||
func (ct *AddressBook) Update(c *gin.Context) {
|
||||
f := &admin.AddressBookForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
}
|
||||
if f.RowId == 0 {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
t := f.ToAddressBook()
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if !service.AllService.UserService.IsAdmin(u) && t.UserId != u.Id {
|
||||
response.Fail(c, 101, "无权限")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
err := service.AllService.AddressBookService.Update(t)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
@@ -163,11 +231,11 @@ func (ct *AddressBook) Update(c *gin.Context) {
|
||||
func (ct *AddressBook) Delete(c *gin.Context) {
|
||||
f := &admin.AddressBookForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "系统错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
id := f.RowId
|
||||
errList := global.Validator.ValidVar(id, "required,gt=0")
|
||||
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -175,7 +243,7 @@ func (ct *AddressBook) Delete(c *gin.Context) {
|
||||
t := service.AllService.AddressBookService.InfoByRowId(f.RowId)
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if !service.AllService.UserService.IsAdmin(u) && t.UserId != u.Id {
|
||||
response.Fail(c, 101, "无权限")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
if u.Id > 0 {
|
||||
@@ -184,8 +252,8 @@ func (ct *AddressBook) Delete(c *gin.Context) {
|
||||
response.Success(c, nil)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, err.Error())
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func (ct *Group) Detail(c *gin.Context) {
|
||||
response.Success(c, u)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -49,10 +49,10 @@ func (ct *Group) Detail(c *gin.Context) {
|
||||
func (ct *Group) Create(c *gin.Context) {
|
||||
f := &admin.GroupForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -60,7 +60,7 @@ func (ct *Group) Create(c *gin.Context) {
|
||||
u := f.ToGroup()
|
||||
err := service.AllService.GroupService.Create(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "创建失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, u)
|
||||
@@ -81,7 +81,7 @@ func (ct *Group) Create(c *gin.Context) {
|
||||
func (ct *Group) List(c *gin.Context) {
|
||||
query := &admin.PageQuery{}
|
||||
if err := c.ShouldBindQuery(query); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
res := service.AllService.GroupService.List(query.Page, query.PageSize, nil)
|
||||
@@ -102,14 +102,14 @@ func (ct *Group) List(c *gin.Context) {
|
||||
func (ct *Group) Update(c *gin.Context) {
|
||||
f := &admin.GroupForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
if f.Id == 0 {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -117,7 +117,7 @@ func (ct *Group) Update(c *gin.Context) {
|
||||
u := f.ToGroup()
|
||||
err := service.AllService.GroupService.Update(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
@@ -137,11 +137,11 @@ func (ct *Group) Update(c *gin.Context) {
|
||||
func (ct *Group) Delete(c *gin.Context) {
|
||||
f := &admin.GroupForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "系统错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
id := f.Id
|
||||
errList := global.Validator.ValidVar(id, "required,gt=0")
|
||||
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -153,8 +153,8 @@ func (ct *Group) Delete(c *gin.Context) {
|
||||
response.Success(c, nil)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, err.Error())
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@ func (ct *Login) Login(c *gin.Context) {
|
||||
f := &admin.Login{}
|
||||
err := c.ShouldBindJSON(f)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -40,7 +40,7 @@ func (ct *Login) Login(c *gin.Context) {
|
||||
u := service.AllService.UserService.InfoByUsernamePassword(f.Username, f.Password)
|
||||
|
||||
if u.Id == 0 {
|
||||
response.Fail(c, 101, "用户名或密码错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "UsernameOrPasswordError"))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ func (ct *LoginLog) Detail(c *gin.Context) {
|
||||
response.Success(c, u)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (ct *LoginLog) Detail(c *gin.Context) {
|
||||
func (ct *LoginLog) List(c *gin.Context) {
|
||||
query := &admin.LoginLogQuery{}
|
||||
if err := c.ShouldBindQuery(query); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
@@ -82,11 +82,11 @@ func (ct *LoginLog) List(c *gin.Context) {
|
||||
func (ct *LoginLog) Delete(c *gin.Context) {
|
||||
f := &model.LoginLog{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "系统错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
id := f.Id
|
||||
errList := global.Validator.ValidVar(id, "required,gt=0")
|
||||
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -94,7 +94,7 @@ func (ct *LoginLog) Delete(c *gin.Context) {
|
||||
l := service.AllService.LoginLogService.InfoById(f.Id)
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if !service.AllService.UserService.IsAdmin(u) && l.UserId != u.Id {
|
||||
response.Fail(c, 101, "无权限")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
if l.Id > 0 {
|
||||
@@ -106,5 +106,5 @@ func (ct *LoginLog) Delete(c *gin.Context) {
|
||||
response.Fail(c, 101, err.Error())
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ type Oauth struct {
|
||||
func (o *Oauth) Info(c *gin.Context) {
|
||||
code := c.Query("code")
|
||||
if code == "" {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
v := service.AllService.OauthService.GetOauthCache(code)
|
||||
if v == nil {
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
response.Success(c, v)
|
||||
@@ -33,20 +33,20 @@ func (o *Oauth) ToBind(c *gin.Context) {
|
||||
f := &adminReq.BindOauthForm{}
|
||||
err := c.ShouldBindJSON(f)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
|
||||
utr := service.AllService.UserService.UserThirdInfo(u.Id, f.Op)
|
||||
if utr.Id > 0 {
|
||||
response.Fail(c, 101, "已绑定过了")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OauthHasBindOtherUser"))
|
||||
return
|
||||
}
|
||||
|
||||
err, code, url := service.AllService.OauthService.BeginAuth(f.Op)
|
||||
if err != nil {
|
||||
response.Error(c, err.Error())
|
||||
response.Error(c, response.TranslateMsg(c, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -89,22 +89,22 @@ func (o *Oauth) BindConfirm(c *gin.Context) {
|
||||
j := &adminReq.OauthConfirmForm{}
|
||||
err := c.ShouldBindJSON(j)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "参数错误"+err.Error())
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
if j.Code == "" {
|
||||
response.Fail(c, 101, "参数错误: code 不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
v := service.AllService.OauthService.GetOauthCache(j.Code)
|
||||
if v == nil {
|
||||
response.Fail(c, 101, "授权已过期")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OauthExpired"))
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
err = service.AllService.OauthService.BindGithubUser(v.ThirdOpenId, v.ThirdOpenId, u.Id)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "绑定失败,请重试")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "BindFail"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -117,22 +117,30 @@ func (o *Oauth) Unbind(c *gin.Context) {
|
||||
f := &adminReq.UnBindOauthForm{}
|
||||
err := c.ShouldBindJSON(f)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
utr := service.AllService.UserService.UserThirdInfo(u.Id, f.Op)
|
||||
if utr.Id == 0 {
|
||||
response.Fail(c, 101, "未绑定")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
if f.Op == model.OauthTypeGithub {
|
||||
err = service.AllService.OauthService.UnBindGithubUser(u.Id)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "解绑失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
if f.Op == model.OauthTypeGoogle {
|
||||
err = service.AllService.OauthService.UnBindGoogleUser(u.Id)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
@@ -155,7 +163,7 @@ func (o *Oauth) Detail(c *gin.Context) {
|
||||
response.Success(c, u)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -173,10 +181,10 @@ func (o *Oauth) Detail(c *gin.Context) {
|
||||
func (o *Oauth) Create(c *gin.Context) {
|
||||
f := &admin.OauthForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误"+err.Error())
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -184,14 +192,14 @@ func (o *Oauth) Create(c *gin.Context) {
|
||||
|
||||
ex := service.AllService.OauthService.InfoByOp(f.Op)
|
||||
if ex.Id > 0 {
|
||||
response.Fail(c, 101, "已存在"+f.Op)
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemExists"))
|
||||
return
|
||||
}
|
||||
|
||||
u := f.ToOauth()
|
||||
err := service.AllService.OauthService.Create(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "创建失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, u)
|
||||
@@ -212,7 +220,7 @@ func (o *Oauth) Create(c *gin.Context) {
|
||||
func (o *Oauth) List(c *gin.Context) {
|
||||
query := &admin.PageQuery{}
|
||||
if err := c.ShouldBindQuery(query); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
res := service.AllService.OauthService.List(query.Page, query.PageSize, nil)
|
||||
@@ -233,14 +241,14 @@ func (o *Oauth) List(c *gin.Context) {
|
||||
func (o *Oauth) Update(c *gin.Context) {
|
||||
f := &admin.OauthForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
if f.Id == 0 {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -248,7 +256,7 @@ func (o *Oauth) Update(c *gin.Context) {
|
||||
u := f.ToOauth()
|
||||
err := service.AllService.OauthService.Update(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
@@ -268,11 +276,11 @@ func (o *Oauth) Update(c *gin.Context) {
|
||||
func (o *Oauth) Delete(c *gin.Context) {
|
||||
f := &admin.OauthForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "系统错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
id := f.Id
|
||||
errList := global.Validator.ValidVar(id, "required,gt=0")
|
||||
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -287,5 +295,5 @@ func (o *Oauth) Delete(c *gin.Context) {
|
||||
response.Fail(c, 101, err.Error())
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
}
|
||||
|
||||
@@ -6,16 +6,18 @@ import (
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Peer struct {
|
||||
}
|
||||
|
||||
// Detail 机器
|
||||
// @Tags 机器
|
||||
// @Summary 机器详情
|
||||
// @Description 机器详情
|
||||
// Detail 设备
|
||||
// @Tags 设备
|
||||
// @Summary 设备详情
|
||||
// @Description 设备详情
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path int true "ID"
|
||||
@@ -31,17 +33,17 @@ func (ct *Peer) Detail(c *gin.Context) {
|
||||
response.Success(c, u)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
|
||||
// Create 创建机器
|
||||
// @Tags 机器
|
||||
// @Summary 创建机器
|
||||
// @Description 创建机器
|
||||
// Create 创建设备
|
||||
// @Tags 设备
|
||||
// @Summary 创建设备
|
||||
// @Description 创建设备
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body admin.PeerForm true "机器信息"
|
||||
// @Param body body admin.PeerForm true "设备信息"
|
||||
// @Success 200 {object} response.Response{data=model.Peer}
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /admin/peer/create [post]
|
||||
@@ -49,10 +51,10 @@ func (ct *Peer) Detail(c *gin.Context) {
|
||||
func (ct *Peer) Create(c *gin.Context) {
|
||||
f := &admin.PeerForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -60,41 +62,51 @@ func (ct *Peer) Create(c *gin.Context) {
|
||||
u := f.ToPeer()
|
||||
err := service.AllService.PeerService.Create(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "创建失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, u)
|
||||
}
|
||||
|
||||
// List 列表
|
||||
// @Tags 机器
|
||||
// @Summary 机器列表
|
||||
// @Description 机器列表
|
||||
// @Tags 设备
|
||||
// @Summary 设备列表
|
||||
// @Description 设备列表
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param page query int false "页码"
|
||||
// @Param page_size query int false "页大小"
|
||||
// @Param time_ago query int false "时间"
|
||||
// @Success 200 {object} response.Response{data=model.PeerList}
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /admin/peer/list [get]
|
||||
// @Security token
|
||||
func (ct *Peer) List(c *gin.Context) {
|
||||
query := &admin.PageQuery{}
|
||||
query := &admin.PeerQuery{}
|
||||
if err := c.ShouldBindQuery(query); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
res := service.AllService.PeerService.List(query.Page, query.PageSize, nil)
|
||||
res := service.AllService.PeerService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
|
||||
if query.TimeAgo > 0 {
|
||||
lt := time.Now().Unix() - int64(query.TimeAgo)
|
||||
tx.Where("last_online_time < ?", lt)
|
||||
}
|
||||
if query.TimeAgo < 0 {
|
||||
lt := time.Now().Unix() + int64(query.TimeAgo)
|
||||
tx.Where("last_online_time > ?", lt)
|
||||
}
|
||||
})
|
||||
response.Success(c, res)
|
||||
}
|
||||
|
||||
// Update 编辑
|
||||
// @Tags 机器
|
||||
// @Summary 机器编辑
|
||||
// @Description 机器编辑
|
||||
// @Tags 设备
|
||||
// @Summary 设备编辑
|
||||
// @Description 设备编辑
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body admin.PeerForm true "机器信息"
|
||||
// @Param body body admin.PeerForm true "设备信息"
|
||||
// @Success 200 {object} response.Response{data=model.Peer}
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /admin/peer/update [post]
|
||||
@@ -102,14 +114,14 @@ func (ct *Peer) List(c *gin.Context) {
|
||||
func (ct *Peer) Update(c *gin.Context) {
|
||||
f := &admin.PeerForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
if f.RowId == 0 {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -117,19 +129,19 @@ func (ct *Peer) Update(c *gin.Context) {
|
||||
u := f.ToPeer()
|
||||
err := service.AllService.PeerService.Update(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
// @Tags 机器
|
||||
// @Summary 机器删除
|
||||
// @Description 机器删除
|
||||
// @Tags 设备
|
||||
// @Summary 设备删除
|
||||
// @Description 设备删除
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body admin.PeerForm true "机器信息"
|
||||
// @Param body body admin.PeerForm true "设备信息"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /admin/peer/delete [post]
|
||||
@@ -137,11 +149,11 @@ func (ct *Peer) Update(c *gin.Context) {
|
||||
func (ct *Peer) Delete(c *gin.Context) {
|
||||
f := &admin.PeerForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "系统错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
id := f.RowId
|
||||
errList := global.Validator.ValidVar(id, "required,gt=0")
|
||||
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -153,8 +165,37 @@ func (ct *Peer) Delete(c *gin.Context) {
|
||||
response.Success(c, nil)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, err.Error())
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除
|
||||
// @Tags 设备
|
||||
// @Summary 批量设备删除
|
||||
// @Description 批量设备删除
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body admin.PeerBatchDeleteForm true "设备id"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /admin/peer/delete [post]
|
||||
// @Security token
|
||||
func (ct *Peer) BatchDelete(c *gin.Context) {
|
||||
f := &admin.PeerBatchDeleteForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
if len(f.RowIds) == 0 {
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
err := service.AllService.PeerService.BatchDelete(f.RowIds)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
@@ -30,14 +30,14 @@ func (ct *Tag) Detail(c *gin.Context) {
|
||||
t := service.AllService.TagService.InfoById(uint(iid))
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if !service.AllService.UserService.IsAdmin(u) && t.UserId != u.Id {
|
||||
response.Fail(c, 101, "无权限")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
if t.Id > 0 {
|
||||
response.Success(c, t)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -55,10 +55,10 @@ func (ct *Tag) Detail(c *gin.Context) {
|
||||
func (ct *Tag) Create(c *gin.Context) {
|
||||
f := &admin.TagForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -70,7 +70,7 @@ func (ct *Tag) Create(c *gin.Context) {
|
||||
}
|
||||
err := service.AllService.TagService.Create(t)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "创建失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, u)
|
||||
@@ -93,7 +93,7 @@ func (ct *Tag) Create(c *gin.Context) {
|
||||
func (ct *Tag) List(c *gin.Context) {
|
||||
query := &admin.TagQuery{}
|
||||
if err := c.ShouldBindQuery(query); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
@@ -122,27 +122,27 @@ func (ct *Tag) List(c *gin.Context) {
|
||||
func (ct *Tag) Update(c *gin.Context) {
|
||||
f := &admin.TagForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
}
|
||||
if f.Id == 0 {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
t := f.ToTag()
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if !service.AllService.UserService.IsAdmin(u) && t.UserId != u.Id {
|
||||
response.Fail(c, 101, "无权限")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
err := service.AllService.TagService.Update(t)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
@@ -162,11 +162,11 @@ func (ct *Tag) Update(c *gin.Context) {
|
||||
func (ct *Tag) Delete(c *gin.Context) {
|
||||
f := &admin.TagForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "系统错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
id := f.Id
|
||||
errList := global.Validator.ValidVar(id, "required,gt=0")
|
||||
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -174,7 +174,7 @@ func (ct *Tag) Delete(c *gin.Context) {
|
||||
t := service.AllService.TagService.InfoById(f.Id)
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if !service.AllService.UserService.IsAdmin(u) && t.UserId != u.Id {
|
||||
response.Fail(c, 101, "无权限")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
if u.Id > 0 {
|
||||
@@ -186,5 +186,5 @@ func (ct *Tag) Delete(c *gin.Context) {
|
||||
response.Fail(c, 101, err.Error())
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func (ct *User) Detail(c *gin.Context) {
|
||||
response.Success(c, u)
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -51,10 +51,10 @@ func (ct *User) Detail(c *gin.Context) {
|
||||
func (ct *User) Create(c *gin.Context) {
|
||||
f := &admin.UserForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -62,7 +62,7 @@ func (ct *User) Create(c *gin.Context) {
|
||||
u := f.ToUser()
|
||||
err := service.AllService.UserService.Create(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "创建失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, u)
|
||||
@@ -84,7 +84,7 @@ func (ct *User) Create(c *gin.Context) {
|
||||
func (ct *User) List(c *gin.Context) {
|
||||
query := &admin.UserQuery{}
|
||||
if err := c.ShouldBindQuery(query); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
res := service.AllService.UserService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
|
||||
@@ -109,14 +109,14 @@ func (ct *User) List(c *gin.Context) {
|
||||
func (ct *User) Update(c *gin.Context) {
|
||||
f := &admin.UserForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误:"+err.Error())
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
if f.Id == 0 {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -124,7 +124,7 @@ func (ct *User) Update(c *gin.Context) {
|
||||
u := f.ToUser()
|
||||
err := service.AllService.UserService.Update(u)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
@@ -144,11 +144,11 @@ func (ct *User) Update(c *gin.Context) {
|
||||
func (ct *User) Delete(c *gin.Context) {
|
||||
f := &admin.UserForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "系统错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
id := f.Id
|
||||
errList := global.Validator.ValidVar(id, "required,gt=0")
|
||||
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -163,7 +163,7 @@ func (ct *User) Delete(c *gin.Context) {
|
||||
response.Fail(c, 101, err.Error())
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
}
|
||||
|
||||
// UpdatePassword 修改密码
|
||||
@@ -180,22 +180,22 @@ func (ct *User) Delete(c *gin.Context) {
|
||||
func (ct *User) UpdatePassword(c *gin.Context) {
|
||||
f := &admin.UserPasswordForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.InfoById(f.Id)
|
||||
if u.Id == 0 {
|
||||
response.Fail(c, 101, "信息不存在")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
err := service.AllService.UserService.UpdatePassword(u, f.Password)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
@@ -237,11 +237,11 @@ func (ct *User) Current(c *gin.Context) {
|
||||
func (ct *User) ChangeCurPwd(c *gin.Context) {
|
||||
f := &admin.ChangeCurPasswordForm{}
|
||||
if err := c.ShouldBindJSON(f); err != nil {
|
||||
response.Fail(c, 101, "参数错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Fail(c, 101, errList[0])
|
||||
return
|
||||
@@ -249,12 +249,12 @@ func (ct *User) ChangeCurPwd(c *gin.Context) {
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
oldPwd := service.AllService.UserService.EncryptPassword(f.OldPassword)
|
||||
if u.Password != oldPwd {
|
||||
response.Fail(c, 101, "旧密码错误")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OldPasswordError"))
|
||||
return
|
||||
}
|
||||
err := service.AllService.UserService.UpdatePassword(u, f.NewPassword)
|
||||
if err != nil {
|
||||
response.Fail(c, 101, "更新失败")
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
requstform "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
"Gwen/http/response/api"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Ab struct {
|
||||
@@ -65,37 +68,30 @@ func (a *Ab) UpAb(c *gin.Context) {
|
||||
abf := &requstform.AddressBookForm{}
|
||||
err := c.ShouldBindJSON(&abf)
|
||||
if err != nil {
|
||||
response.Error(c, "参数错误")
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
abd := &requstform.AddressBookFormData{}
|
||||
err = json.Unmarshal([]byte(abf.Data), abd)
|
||||
if err != nil {
|
||||
response.Error(c, "系统错误")
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
tc := map[string]uint{}
|
||||
err = json.Unmarshal([]byte(abd.TagColors), &tc)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
//fmt.Println(abd)
|
||||
//for _, peer := range abd.Peers {
|
||||
// fmt.Println(peer)
|
||||
//}
|
||||
|
||||
user := service.AllService.UserService.CurUser(c)
|
||||
|
||||
err = service.AllService.AddressBookService.UpdateAddressBook(abd.Peers, user.Id)
|
||||
if err != nil {
|
||||
c.Abort()
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
tc := map[string]uint{}
|
||||
err = json.Unmarshal([]byte(abd.TagColors), &tc)
|
||||
if err != nil {
|
||||
response.Error(c, "系统错误")
|
||||
return
|
||||
} else {
|
||||
service.AllService.TagService.UpdateTags(user.Id, tc)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, nil)
|
||||
}
|
||||
@@ -118,7 +114,7 @@ func (a *Ab) Tags(c *gin.Context) {
|
||||
}
|
||||
|
||||
// TagAdd
|
||||
// @Tags 地址
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 标签添加
|
||||
// @Description 标签
|
||||
// @Accept json
|
||||
@@ -131,16 +127,361 @@ func (a *Ab) TagAdd(c *gin.Context) {
|
||||
t := &model.Tag{}
|
||||
err := c.ShouldBindJSON(t)
|
||||
if err != nil {
|
||||
response.Error(c, "参数错误")
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
tag := service.AllService.TagService.InfoByUserIdAndName(u.Id, t.Name)
|
||||
if tag != nil && tag.Id != 0 {
|
||||
response.Error(c, response.TranslateMsg(c, "ItemExists"))
|
||||
return
|
||||
}
|
||||
t.UserId = u.Id
|
||||
err = service.AllService.TagService.Create(t)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
// TagRename
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 标签重命名
|
||||
// @Description 标签
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /ab/tag/rename/{guid} [put]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) TagRename(c *gin.Context) {
|
||||
t := &requstform.TagRenameForm{}
|
||||
err := c.ShouldBindJSON(t)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
tag := service.AllService.TagService.InfoByUserIdAndName(u.Id, t.Old)
|
||||
if tag == nil || tag.Id == 0 {
|
||||
response.Error(c, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
ntag := service.AllService.TagService.InfoByUserIdAndName(u.Id, t.New)
|
||||
if ntag != nil && ntag.Id != 0 {
|
||||
response.Error(c, response.TranslateMsg(c, "ItemExists"))
|
||||
return
|
||||
}
|
||||
tag.Name = t.New
|
||||
err = service.AllService.TagService.Update(tag)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
// TagUpdate
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 标签修改颜色
|
||||
// @Description 标签
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /ab/tag/update/{guid} [put]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) TagUpdate(c *gin.Context) {
|
||||
t := &requstform.TagColorForm{}
|
||||
err := c.ShouldBindJSON(t)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
tag := service.AllService.TagService.InfoByUserIdAndName(u.Id, t.Name)
|
||||
if tag == nil || tag.Id == 0 {
|
||||
response.Error(c, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
tag.Color = t.Color
|
||||
err = service.AllService.TagService.Update(tag)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
// TagDel
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 标签删除
|
||||
// @Description 标签
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /ab/tag/{guid} [delete]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) TagDel(c *gin.Context) {
|
||||
t := &[]string{}
|
||||
err := c.ShouldBind(t)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
//fmt.Println(t)
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
for _, name := range *t {
|
||||
tag := service.AllService.TagService.InfoByUserIdAndName(u.Id, name)
|
||||
if tag == nil || tag.Id == 0 {
|
||||
response.Error(c, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
err = service.AllService.TagService.Delete(tag)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
// Personal
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 个人地址
|
||||
// @Description 个人地址
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param string body string false "string valid"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /ab/personal [post]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) Personal(c *gin.Context) {
|
||||
user := service.AllService.UserService.CurUser(c)
|
||||
/**
|
||||
guid = json['guid'] ?? '',
|
||||
name = json['name'] ?? '',
|
||||
owner = json['owner'] ?? '',
|
||||
note = json['note'] ?? '',
|
||||
rule = json['rule'] ?? 0;
|
||||
*/
|
||||
if global.Config.Rustdesk.Personal == 1 {
|
||||
guid := strconv.Itoa(int(user.GroupId)) + "-" + strconv.Itoa(int(user.Id))
|
||||
//如果返回了guid,后面的请求会有变化
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"guid": guid,
|
||||
"name": user.Username,
|
||||
"rule": 0,
|
||||
})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, nil)
|
||||
}
|
||||
|
||||
}
|
||||
//u := service.AllService.UserService.CurUser(c)
|
||||
|
||||
//err = service.AllService.TagService.UpdateTags(t.Name, t.Color, user.Id)
|
||||
//if err != nil {
|
||||
// response.Error(c, "操作失败")
|
||||
// Settings
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 设置
|
||||
// @Description 设置
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param string body string false "string valid"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /ab/settings [post]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) Settings(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"max_peer_one_ab": 0, //最大peer数,0表示不限制
|
||||
})
|
||||
}
|
||||
|
||||
// SharedProfiles
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 共享地址簿
|
||||
// @Description 共享
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param string body string false "string valid"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /ab/shared/profiles [post]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) SharedProfiles(c *gin.Context) {
|
||||
//AbProfile.fromJson(Map<String, dynamic> json)
|
||||
//: guid = json['guid'] ?? '',
|
||||
// name = json['name'] ?? '',
|
||||
// owner = json['owner'] ?? '',
|
||||
// note = json['note'] ?? '',
|
||||
// rule = json['rule'] ?? 0;
|
||||
//暂时没必要返回数据,可能是为了共享地址簿
|
||||
/*item := map[string]interface{}{
|
||||
"guid": "1",
|
||||
"name": "admin",
|
||||
"owner": "admin",
|
||||
"note": "admin11",
|
||||
"rule": 0,
|
||||
}
|
||||
item2 := map[string]interface{}{
|
||||
"guid": "2",
|
||||
"name": "admin2",
|
||||
"owner": "admin2",
|
||||
"note": "admin22",
|
||||
"rule": 0,
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"total": 2,
|
||||
"data": []interface{}{item, item2},
|
||||
})*/
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"total": 0,
|
||||
"data": nil,
|
||||
})
|
||||
}
|
||||
|
||||
// Peers
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 地址列表
|
||||
// @Description 地址
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param string body string false "string valid"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /ab/peers [post]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) Peers(c *gin.Context) {
|
||||
user := service.AllService.UserService.CurUser(c)
|
||||
al := service.AllService.AddressBookService.ListByUserId(user.Id, 1, 1000)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"total": al.Total,
|
||||
"data": al.AddressBooks,
|
||||
"licensed_devices": 99999,
|
||||
})
|
||||
}
|
||||
|
||||
// PTags
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 标签
|
||||
// @Description 标签
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "id"
|
||||
// @Success 200 {object} model.TagList
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /ab/tags/{guid} [post]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) PTags(c *gin.Context) {
|
||||
user := service.AllService.UserService.CurUser(c)
|
||||
|
||||
tags := service.AllService.TagService.ListByUserId(user.Id)
|
||||
c.JSON(http.StatusOK, tags.Tags)
|
||||
}
|
||||
|
||||
// PeerAdd
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 添加地址
|
||||
// @Description 添加地址
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "id"
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /ab/peer/add/{guid} [post]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) PeerAdd(c *gin.Context) {
|
||||
// forceAlwaysRelay永远是字符串"false",真是坑
|
||||
//f := &gin.H{}
|
||||
f := &requstform.PersonalAddressBookForm{}
|
||||
err := c.ShouldBindJSON(f)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Println(f)
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
f.UserId = u.Id
|
||||
ab := f.ToAddressBook()
|
||||
err = service.AllService.AddressBookService.AddAddressBook(ab)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
// PeerDel
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 删除地址
|
||||
// @Description 删除地址
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "id"
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /ab/peer/add/{guid} [delete]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) PeerDel(c *gin.Context) {
|
||||
f := &[]string{}
|
||||
err := c.ShouldBind(f)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
for _, id := range *f {
|
||||
ab := service.AllService.AddressBookService.InfoByUserIdAndId(u.Id, id)
|
||||
if ab == nil || ab.RowId == 0 {
|
||||
response.Error(c, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
err = service.AllService.AddressBookService.Delete(ab)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
// PeerUpdate
|
||||
// @Tags 地址[Personal]
|
||||
// @Summary 更新地址
|
||||
// @Description 更新地址
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "id"
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /ab/peer/update/{guid} [put]
|
||||
// @Security BearerAuth
|
||||
func (a *Ab) PeerUpdate(c *gin.Context) {
|
||||
//f := &gin.H{}
|
||||
f := &requstform.PersonalAddressBookForm{}
|
||||
err := c.ShouldBindJSON(f)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
//fmt.Println(f)
|
||||
//return
|
||||
//}
|
||||
c.JSON(http.StatusOK, "")
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
ab := service.AllService.AddressBookService.InfoByUserIdAndId(u.Id, f.Id)
|
||||
if ab == nil || ab.RowId == 0 {
|
||||
response.Error(c, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
nab := f.ToAddressBook()
|
||||
nab.RowId = ab.RowId
|
||||
err = service.AllService.AddressBookService.Update(nab)
|
||||
if err != nil {
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
c.String(http.StatusOK, "")
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func (g *Group) Users(c *gin.Context) {
|
||||
if !*u.IsAdmin {
|
||||
gr := service.AllService.GroupService.InfoById(u.GroupId)
|
||||
if gr.Type != model.GroupTypeShare {
|
||||
response.Error(c, "不是管理员也不在分享组")
|
||||
response.Error(c, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ func (g *Group) Peers(c *gin.Context) {
|
||||
if !*u.IsAdmin {
|
||||
gr := service.AllService.GroupService.InfoById(u.GroupId)
|
||||
if gr.Type != model.GroupTypeShare {
|
||||
response.Error(c, "不是管理员也不在分享组")
|
||||
response.Error(c, response.TranslateMsg(c, "NoAccess"))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -96,15 +96,15 @@ func (g *Group) Peers(c *gin.Context) {
|
||||
namesById[user.Id] = user.Username
|
||||
userIds = append(userIds, user.Id)
|
||||
}
|
||||
peerList := service.AllService.AddressBookService.ListByUserIds(userIds, q.Page, q.PageSize)
|
||||
peerList := service.AllService.PeerService.ListByUserIds(userIds, q.Page, q.PageSize)
|
||||
var data []*apiResp.GroupPeerPayload
|
||||
for _, ab := range peerList.AddressBooks {
|
||||
uname, ok := namesById[ab.UserId]
|
||||
for _, peer := range peerList.Peers {
|
||||
uname, ok := namesById[peer.UserId]
|
||||
if !ok {
|
||||
uname = ""
|
||||
}
|
||||
pp := &apiResp.GroupPeerPayload{}
|
||||
pp.FromAddressBook(ab, uname)
|
||||
pp.FromPeer(peer, uname)
|
||||
data = append(data, pp)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
requstform "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Index struct {
|
||||
@@ -35,5 +38,22 @@ func (i *Index) Index(c *gin.Context) {
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /heartbeat [post]
|
||||
func (i *Index) Heartbeat(c *gin.Context) {
|
||||
info := &requstform.PeerInfoInHeartbeat{}
|
||||
err := c.ShouldBindJSON(info)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
return
|
||||
}
|
||||
if info.Uuid == "" {
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
return
|
||||
}
|
||||
peer := service.AllService.PeerService.FindByUuid(info.Uuid)
|
||||
if peer == nil {
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
return
|
||||
}
|
||||
peer.LastOnlineTime = time.Now().Unix()
|
||||
service.AllService.PeerService.Update(peer)
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ func (l *Login) Login(c *gin.Context) {
|
||||
err := c.ShouldBindJSON(f)
|
||||
//fmt.Println(f)
|
||||
if err != nil {
|
||||
response.Error(c, "参数错误")
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
errList := global.Validator.ValidStruct(f)
|
||||
errList := global.Validator.ValidStruct(c, f)
|
||||
if len(errList) > 0 {
|
||||
response.Error(c, errList[0])
|
||||
return
|
||||
@@ -43,7 +43,7 @@ func (l *Login) Login(c *gin.Context) {
|
||||
u := service.AllService.UserService.InfoByUsernamePassword(f.Username, f.Password)
|
||||
|
||||
if u.Id == 0 {
|
||||
response.Error(c, "用户名或密码错误")
|
||||
response.Error(c, response.TranslateMsg(c, "UsernameOrPasswordError"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func (l *Login) LoginOptions(c *gin.Context) {
|
||||
}
|
||||
common, err := json.Marshal(oidcItems)
|
||||
if err != nil {
|
||||
response.Error(c, "参数错误")
|
||||
response.Error(c, response.TranslateMsg(c, "SystemError")+err.Error())
|
||||
return
|
||||
}
|
||||
var res []string
|
||||
|
||||
@@ -29,17 +29,17 @@ func (o *Oauth) OidcAuth(c *gin.Context) {
|
||||
f := &api.OidcAuthRequest{}
|
||||
err := c.ShouldBindJSON(&f)
|
||||
if err != nil {
|
||||
response.Error(c, "参数错误")
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
if f.Op != model.OauthTypeWebauth && f.Op != model.OauthTypeGoogle && f.Op != model.OauthTypeGithub {
|
||||
response.Error(c, "参数错误")
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError"))
|
||||
return
|
||||
}
|
||||
|
||||
err, code, url := service.AllService.OauthService.BeginAuth(f.Op)
|
||||
if err != nil {
|
||||
response.Error(c, err.Error())
|
||||
response.Error(c, response.TranslateMsg(c, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -72,12 +72,12 @@ func (o *Oauth) OidcAuthQuery(c *gin.Context) {
|
||||
q := &api.OidcAuthQuery{}
|
||||
err := c.ShouldBindQuery(q)
|
||||
if err != nil {
|
||||
response.Error(c, "参数错误")
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
v := service.AllService.OauthService.GetOauthCache(q.Code)
|
||||
if v == nil {
|
||||
response.Error(c, "授权已过期,请重新授权")
|
||||
response.Error(c, response.TranslateMsg(c, "OauthExpired"))
|
||||
return
|
||||
}
|
||||
if v.UserId == 0 {
|
||||
@@ -87,7 +87,6 @@ func (o *Oauth) OidcAuthQuery(c *gin.Context) {
|
||||
}
|
||||
u := service.AllService.UserService.InfoById(v.UserId)
|
||||
//fmt.Println("auth success u", u)
|
||||
if u.Id > 0 {
|
||||
service.AllService.OauthService.DeleteOauthCache(q.Code)
|
||||
ut := service.AllService.UserService.Login(u, &model.LoginLog{
|
||||
UserId: u.Id,
|
||||
@@ -102,9 +101,6 @@ func (o *Oauth) OidcAuthQuery(c *gin.Context) {
|
||||
Type: "access_token",
|
||||
User: *(&apiResp.UserPayload{}).FromUser(u),
|
||||
})
|
||||
return
|
||||
}
|
||||
response.Error(c, "用户不存在")
|
||||
}
|
||||
|
||||
// OauthCallback 回调
|
||||
@@ -119,7 +115,7 @@ func (o *Oauth) OidcAuthQuery(c *gin.Context) {
|
||||
func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||
state := c.Query("state")
|
||||
if state == "" {
|
||||
c.String(http.StatusInternalServerError, "state为空")
|
||||
c.String(http.StatusInternalServerError, response.TranslateParamMsg(c, "ParamIsEmpty", "state"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -127,7 +123,7 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||
//从缓存中获取
|
||||
v := service.AllService.OauthService.GetOauthCache(cacheKey)
|
||||
if v == nil {
|
||||
c.String(http.StatusInternalServerError, "授权已过期,请重新授权")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthExpired"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -138,34 +134,34 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||
code := c.Query("code")
|
||||
err, userData := service.AllService.OauthService.GithubCallback(code)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "授权失败:"+err.Error())
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthFailed")+response.TranslateMsg(c, err.Error()))
|
||||
return
|
||||
}
|
||||
if ac == service.OauthActionTypeBind {
|
||||
//fmt.Println("bind", ty, userData)
|
||||
utr := service.AllService.OauthService.UserThirdInfo(ty, strconv.Itoa(userData.Id))
|
||||
if utr.UserId > 0 {
|
||||
c.String(http.StatusInternalServerError, "已经绑定其他账号")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthHasBindOtherUser"))
|
||||
return
|
||||
}
|
||||
//绑定
|
||||
u := service.AllService.UserService.InfoById(v.UserId)
|
||||
if u == nil {
|
||||
c.String(http.StatusInternalServerError, "用户不存在")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
//绑定github
|
||||
err = service.AllService.OauthService.BindGithubUser(strconv.Itoa(userData.Id), userData.Login, v.UserId)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "绑定失败")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "BindFail"))
|
||||
return
|
||||
}
|
||||
c.String(http.StatusOK, "绑定成功")
|
||||
c.String(http.StatusOK, response.TranslateMsg(c, "BindSuccess"))
|
||||
return
|
||||
} else if ac == service.OauthActionTypeLogin {
|
||||
//登录
|
||||
if v.UserId != 0 {
|
||||
c.String(http.StatusInternalServerError, "授权已经成功")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthHasBeenSuccess"))
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.InfoByGithubId(strconv.Itoa(userData.Id))
|
||||
@@ -183,19 +179,16 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||
//自动注册
|
||||
u = service.AllService.UserService.RegisterByGithub(userData.Login, strconv.Itoa(userData.Id))
|
||||
if u.Id == 0 {
|
||||
c.String(http.StatusInternalServerError, "注册失败")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthRegisterFailed"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
v.UserId = u.Id
|
||||
service.AllService.OauthService.SetOauthCache(cacheKey, v, 0)
|
||||
c.String(http.StatusOK, "授权成功")
|
||||
c.String(http.StatusOK, response.TranslateMsg(c, "OauthSuccess"))
|
||||
return
|
||||
}
|
||||
//返回js
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
c.String(http.StatusOK, "授权错误")
|
||||
|
||||
}
|
||||
|
||||
@@ -203,7 +196,7 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||
code := c.Query("code")
|
||||
err, userData := service.AllService.OauthService.GoogleCallback(code)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "授权失败:"+err.Error())
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthFailed")+response.TranslateMsg(c, err.Error()))
|
||||
return
|
||||
}
|
||||
//将空格替换成_
|
||||
@@ -212,26 +205,26 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||
//fmt.Println("bind", ty, userData)
|
||||
utr := service.AllService.OauthService.UserThirdInfo(ty, userData.Email)
|
||||
if utr.UserId > 0 {
|
||||
c.String(http.StatusInternalServerError, "已经绑定其他账号")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthHasBindOtherUser"))
|
||||
return
|
||||
}
|
||||
//绑定
|
||||
u := service.AllService.UserService.InfoById(v.UserId)
|
||||
if u == nil {
|
||||
c.String(http.StatusInternalServerError, "用户不存在")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "ItemNotFound"))
|
||||
return
|
||||
}
|
||||
//绑定
|
||||
err = service.AllService.OauthService.BindGoogleUser(userData.Email, googleName, v.UserId)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "绑定失败")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "BindFail"))
|
||||
return
|
||||
}
|
||||
c.String(http.StatusOK, "绑定成功")
|
||||
c.String(http.StatusOK, response.TranslateMsg(c, "BindSuccess"))
|
||||
return
|
||||
} else if ac == service.OauthActionTypeLogin {
|
||||
if v.UserId != 0 {
|
||||
c.String(http.StatusInternalServerError, "授权已经成功")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthHasBeenSuccess"))
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.InfoByGoogleEmail(userData.Email)
|
||||
@@ -250,30 +243,17 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||
//自动注册
|
||||
u = service.AllService.UserService.RegisterByGoogle(googleName, userData.Email)
|
||||
if u.Id == 0 {
|
||||
c.String(http.StatusInternalServerError, "注册失败")
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthRegisterFailed"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
v.UserId = u.Id
|
||||
service.AllService.OauthService.SetOauthCache(cacheKey, v, 0)
|
||||
c.String(http.StatusOK, "授权成功")
|
||||
c.String(http.StatusOK, response.TranslateMsg(c, "OauthSuccess"))
|
||||
return
|
||||
}
|
||||
}
|
||||
c.String(http.StatusInternalServerError, "授权配置错误,请联系管理员")
|
||||
|
||||
}
|
||||
|
||||
// WebOauthLogin
|
||||
// @Tags Oauth
|
||||
// @Summary WebOauthLogin
|
||||
// @Description WebOauthLogin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {string} string
|
||||
// @Router /oauth/login [get]
|
||||
func (o *Oauth) WebOauthLogin(c *gin.Context) {
|
||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "SystemError"))
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func (p *Peer) SysInfo(c *gin.Context) {
|
||||
f := &requstform.PeerForm{}
|
||||
err := c.ShouldBindBodyWith(f, binding.JSON)
|
||||
if err != nil {
|
||||
response.Error(c, err.Error())
|
||||
response.Error(c, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func (p *Peer) SysInfo(c *gin.Context) {
|
||||
pe = f.ToPeer()
|
||||
err = service.AllService.PeerService.Create(pe)
|
||||
if err != nil {
|
||||
response.Error(c, err.Error())
|
||||
response.Error(c, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package api
|
||||
import (
|
||||
apiResp "Gwen/http/response/api"
|
||||
"Gwen/service"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
@@ -42,33 +41,3 @@ func (u *User) Info(c *gin.Context) {
|
||||
up := (&apiResp.UserPayload{}).FromUser(user)
|
||||
c.JSON(http.StatusOK, up)
|
||||
}
|
||||
|
||||
// Personal
|
||||
// @Tags 用户
|
||||
// @Summary 个人信息
|
||||
// @Description 个人信息
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param string body string false "string valid"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /ab/personal [post]
|
||||
// @Security BearerAuth
|
||||
func (u *User) Personal(c *gin.Context) {
|
||||
//打印全部body
|
||||
fmt.Println(c.Request.Body)
|
||||
|
||||
/**
|
||||
guid = json['guid'] ?? '',
|
||||
name = json['name'] ?? '',
|
||||
owner = json['owner'] ?? '',
|
||||
note = json['note'] ?? '',
|
||||
rule = json['rule'] ?? 0;
|
||||
*/
|
||||
//如果返回了guid,后面的请求会有变化
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
//"guid": "123456",
|
||||
//"name": "admindddd",
|
||||
//"rule": 1,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,10 +8,23 @@ import (
|
||||
type Index struct {
|
||||
}
|
||||
|
||||
func (i *Index) Index(c *gin.Context) {
|
||||
c.Redirect(302, "/_admin/")
|
||||
}
|
||||
|
||||
func (i *Index) ConfigJs(c *gin.Context) {
|
||||
apiServer := global.Config.Rustdesk.ApiServer
|
||||
|
||||
tmp := `
|
||||
function stringToUint8Array(str){
|
||||
var arr = [];
|
||||
for (var i = 0, j = str.length; i < j; ++i) {
|
||||
arr.push(str.charCodeAt(i));
|
||||
}
|
||||
|
||||
var tmpUint8Array = new Uint8Array(arr);
|
||||
return tmpUint8Array
|
||||
}
|
||||
window._gwen = {}
|
||||
window._gwen.kv = {}
|
||||
function getQueryVariable() {
|
||||
@@ -54,12 +67,25 @@ const autoWriteServer = () => {
|
||||
|
||||
if (res.data.peers) {
|
||||
oldPeers = JSON.parse(localStorage.getItem('peers')) || {}
|
||||
let needUpdate = false
|
||||
Object.keys(res.data.peers).forEach(k => {
|
||||
if(!oldPeers[k]) {
|
||||
oldPeers[k] = res.data.peers[k]
|
||||
needUpdate = true
|
||||
}else{
|
||||
oldPeers[k].info = res.data.peers[k].info
|
||||
}
|
||||
if (oldPeers[k].info && oldPeers[k].info.hash&&!oldPeers[k].password ) {
|
||||
let p1 = window.atob(oldPeers[k].info.hash)
|
||||
const pwd = stringToUint8Array(p1)
|
||||
oldPeers[k].password = pwd.toString()
|
||||
oldPeers[k].remember = true
|
||||
}
|
||||
})
|
||||
localStorage.setItem('peers', JSON.stringify(oldPeers))
|
||||
if(needUpdate) {
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
func RustAuth() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
|
||||
//fmt.Println(c.Request.Header)
|
||||
//获取HTTP_AUTHORIZATION
|
||||
token := c.GetHeader("Authorization")
|
||||
if token == "" {
|
||||
|
||||
@@ -16,12 +16,13 @@ type AddressBookForm struct {
|
||||
Tags []string `json:"tags"`
|
||||
Hash string `json:"hash"`
|
||||
UserId uint `json:"user_id"`
|
||||
ForceAlwaysRelay bool `json:"force_always_relay"`
|
||||
RdpPort string `json:"rdp_port"`
|
||||
RdpUsername string `json:"rdp_username"`
|
||||
UserIds []uint `json:"user_ids"`
|
||||
ForceAlwaysRelay bool `json:"forceAlwaysRelay"`
|
||||
RdpPort string `json:"rdpPort"`
|
||||
RdpUsername string `json:"rdpUsername"`
|
||||
Online bool `json:"online"`
|
||||
LoginName string `json:"login_name" `
|
||||
SameServer bool `json:"same_server"`
|
||||
LoginName string `json:"loginName" `
|
||||
SameServer bool `json:"sameServer"`
|
||||
}
|
||||
|
||||
func (a AddressBookForm) ToAddressBook() *model.AddressBook {
|
||||
@@ -48,9 +49,39 @@ func (a AddressBookForm) ToAddressBook() *model.AddressBook {
|
||||
}
|
||||
|
||||
}
|
||||
func (a AddressBookForm) ToAddressBooks() []*model.AddressBook {
|
||||
//tags转换
|
||||
tags, _ := json.Marshal(a.Tags)
|
||||
|
||||
abs := make([]*model.AddressBook, 0, len(a.UserIds))
|
||||
for _, userId := range a.UserIds {
|
||||
abs = append(abs, &model.AddressBook{
|
||||
RowId: a.RowId,
|
||||
Id: a.Id,
|
||||
Username: a.Username,
|
||||
Password: a.Password,
|
||||
Hostname: a.Hostname,
|
||||
Alias: a.Alias,
|
||||
Platform: a.Platform,
|
||||
Tags: tags,
|
||||
Hash: a.Hash,
|
||||
UserId: userId,
|
||||
ForceAlwaysRelay: a.ForceAlwaysRelay,
|
||||
RdpPort: a.RdpPort,
|
||||
RdpUsername: a.RdpUsername,
|
||||
Online: a.Online,
|
||||
LoginName: a.LoginName,
|
||||
SameServer: a.SameServer,
|
||||
})
|
||||
}
|
||||
return abs
|
||||
}
|
||||
|
||||
type AddressBookQuery struct {
|
||||
UserId int `form:"user_id"`
|
||||
IsMy int `form:"is_my"`
|
||||
Username string `form:"username"`
|
||||
Hostname string `form:"hostname"`
|
||||
Id string `form:"id"`
|
||||
PageQuery
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ type PeerForm struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type PeerBatchDeleteForm struct {
|
||||
RowIds []uint `json:"row_ids" validate:"required"`
|
||||
}
|
||||
|
||||
// ToPeer
|
||||
func (f *PeerForm) ToPeer() *model.Peer {
|
||||
return &model.Peer{
|
||||
@@ -28,3 +32,8 @@ func (f *PeerForm) ToPeer() *model.Peer {
|
||||
Version: f.Version,
|
||||
}
|
||||
}
|
||||
|
||||
type PeerQuery struct {
|
||||
PageQuery
|
||||
TimeAgo int `json:"time_ago" form:"time_ago"`
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ type UserForm struct {
|
||||
Id uint `json:"id"`
|
||||
Username string `json:"username" validate:"required,gte=4,lte=10"`
|
||||
//Password string `json:"password" validate:"required,gte=4,lte=20"`
|
||||
Nickname string `json:"nickname" validate:"required"`
|
||||
Nickname string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
GroupId uint `json:"group_id" validate:"required"`
|
||||
IsAdmin *bool `json:"is_admin" `
|
||||
|
||||
@@ -35,3 +35,45 @@ func (pf *PeerForm) ToPeer() *model.Peer {
|
||||
Version: pf.Version,
|
||||
}
|
||||
}
|
||||
|
||||
// PersonalAddressBookForm 个人地址簿表单
|
||||
type PersonalAddressBookForm struct {
|
||||
model.AddressBook
|
||||
ForceAlwaysRelay string `json:"forceAlwaysRelay"`
|
||||
}
|
||||
|
||||
func (pabf *PersonalAddressBookForm) ToAddressBook() *model.AddressBook {
|
||||
return &model.AddressBook{
|
||||
RowId: pabf.RowId,
|
||||
Id: pabf.Id,
|
||||
Username: pabf.Username,
|
||||
Password: pabf.Password,
|
||||
Hostname: pabf.Hostname,
|
||||
Alias: pabf.Alias,
|
||||
Platform: pabf.Platform,
|
||||
Tags: pabf.Tags,
|
||||
Hash: pabf.Hash,
|
||||
UserId: pabf.UserId,
|
||||
ForceAlwaysRelay: pabf.ForceAlwaysRelay == "true",
|
||||
RdpPort: pabf.RdpPort,
|
||||
RdpUsername: pabf.RdpUsername,
|
||||
Online: pabf.Online,
|
||||
LoginName: pabf.LoginName,
|
||||
SameServer: pabf.SameServer,
|
||||
}
|
||||
}
|
||||
|
||||
type TagRenameForm struct {
|
||||
Old string `json:"old"`
|
||||
New string `json:"new"`
|
||||
}
|
||||
type TagColorForm struct {
|
||||
Name string `json:"name"`
|
||||
Color uint `json:"color"`
|
||||
}
|
||||
|
||||
type PeerInfoInHeartbeat struct {
|
||||
Id string `json:"id"`
|
||||
Uuid string `json:"uuid"`
|
||||
Ver int `json:"ver"`
|
||||
}
|
||||
|
||||
@@ -59,16 +59,13 @@ func (gpp *GroupPeerPayload) FromAddressBook(a *model.AddressBook, username stri
|
||||
gpp.UserName = username
|
||||
}
|
||||
|
||||
//func (gpp *GroupPeerPayload) FromPeer(p *model.Peer) {
|
||||
// gpp.Id = p.Id
|
||||
// gpp.Info = &PeerPayloadInfo{
|
||||
// DeviceName: p.Hostname,
|
||||
// Os: p.Os,
|
||||
// Username: p.Username,
|
||||
// }
|
||||
// gpp.Note = ""
|
||||
// if p.User.Id != 0 {
|
||||
// //gpp.User = p.User.Username
|
||||
// gpp.UserName = p.User.Username
|
||||
// }
|
||||
//}
|
||||
func (gpp *GroupPeerPayload) FromPeer(p *model.Peer, username string) {
|
||||
gpp.Id = p.Id
|
||||
gpp.Info = &PeerPayloadInfo{
|
||||
DeviceName: p.Hostname,
|
||||
Os: p.Os,
|
||||
Username: p.Username,
|
||||
}
|
||||
gpp.Note = ""
|
||||
gpp.UserName = username
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ type WebClientPeerInfoPayload struct {
|
||||
Username string `json:"username"`
|
||||
Hostname string `json:"hostname"`
|
||||
Platform string `json:"platform"`
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
func (wcpp *WebClientPeerPayload) FromAddressBook(a *model.AddressBook) {
|
||||
@@ -25,5 +26,6 @@ func (wcpp *WebClientPeerPayload) FromAddressBook(a *model.AddressBook) {
|
||||
Username: a.Username,
|
||||
Hostname: a.Hostname,
|
||||
Platform: a.Platform,
|
||||
Hash: a.Hash,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@@ -51,3 +54,48 @@ type ServerConfigResponse struct {
|
||||
RelayServer string `json:"relay_server"`
|
||||
ApiServer string `json:"api_server"`
|
||||
}
|
||||
|
||||
func TranslateMsg(c *gin.Context, messageId string) string {
|
||||
localizer := global.Localizer(c)
|
||||
errMsg, err := localizer.LocalizeMessage(&i18n.Message{
|
||||
ID: messageId,
|
||||
})
|
||||
if err != nil {
|
||||
global.Logger.Warn("LocalizeMessage Error: " + err.Error())
|
||||
errMsg = messageId
|
||||
}
|
||||
return errMsg
|
||||
}
|
||||
func TranslateTempMsg(c *gin.Context, messageId string, templateData map[string]interface{}) string {
|
||||
localizer := global.Localizer(c)
|
||||
errMsg, err := localizer.Localize(&i18n.LocalizeConfig{
|
||||
DefaultMessage: &i18n.Message{
|
||||
ID: messageId,
|
||||
},
|
||||
TemplateData: templateData,
|
||||
})
|
||||
if err != nil {
|
||||
global.Logger.Warn("LocalizeMessage Error: " + err.Error())
|
||||
errMsg = messageId
|
||||
}
|
||||
return errMsg
|
||||
}
|
||||
func TranslateParamMsg(c *gin.Context, messageId string, params ...string) string {
|
||||
localizer := global.Localizer(c)
|
||||
templateData := make(map[string]interface{})
|
||||
for i, v := range params {
|
||||
k := fmt.Sprintf("P%d", i)
|
||||
templateData[k] = v
|
||||
}
|
||||
errMsg, err := localizer.Localize(&i18n.LocalizeConfig{
|
||||
DefaultMessage: &i18n.Message{
|
||||
ID: messageId,
|
||||
},
|
||||
TemplateData: templateData,
|
||||
})
|
||||
if err != nil {
|
||||
global.Logger.Warn("LocalizeMessage Error: " + err.Error())
|
||||
errMsg = messageId
|
||||
}
|
||||
return errMsg
|
||||
}
|
||||
|
||||
@@ -93,6 +93,9 @@ func AddressBookBind(rg *gin.RouterGroup) {
|
||||
aR.POST("/create", cont.Create)
|
||||
aR.POST("/update", cont.Update)
|
||||
aR.POST("/delete", cont.Delete)
|
||||
|
||||
arp := aR.Use(middleware.AdminPrivilege())
|
||||
arp.POST("/batchCreate", cont.BatchCreate)
|
||||
}
|
||||
}
|
||||
func PeerBind(rg *gin.RouterGroup) {
|
||||
@@ -104,6 +107,9 @@ func PeerBind(rg *gin.RouterGroup) {
|
||||
aR.POST("/create", cont.Create)
|
||||
aR.POST("/update", cont.Update)
|
||||
aR.POST("/delete", cont.Delete)
|
||||
|
||||
arp := aR.Use(middleware.AdminPrivilege())
|
||||
arp.POST("/batchDelete", cont.BatchDelete)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,38 @@ func ApiInit(g *gin.Engine) {
|
||||
//更新地址
|
||||
frg.POST("/ab", ab.UpAb)
|
||||
}
|
||||
|
||||
PersonalRoutes(frg)
|
||||
//访问静态文件
|
||||
g.StaticFS("/upload", http.Dir(global.Config.Gin.ResourcesPath+"/public/upload"))
|
||||
}
|
||||
|
||||
func PersonalRoutes(frg *gin.RouterGroup) {
|
||||
{
|
||||
ab := &api.Ab{}
|
||||
frg.POST("/ab/personal", ab.Personal)
|
||||
//[method:POST] [uri:/api/ab/settings] Request
|
||||
frg.POST("/ab/settings", ab.Settings)
|
||||
// [method:POST] [uri:/api/ab/shared/profiles?current=1&pageSize=100]
|
||||
frg.POST("/ab/shared/profiles", ab.SharedProfiles)
|
||||
//[method:POST] [uri:/api/ab/peers?current=1&pageSize=100&ab=1]
|
||||
frg.POST("/ab/peers", ab.Peers)
|
||||
// [method:POST] [uri:/api/ab/tags/1]
|
||||
frg.POST("/ab/tags/:guid", ab.PTags)
|
||||
//[method:POST] api/ab/peer/add/1
|
||||
frg.POST("/ab/peer/add/:guid", ab.PeerAdd)
|
||||
//[method:DELETE] [uri:/api/ab/peer/1]
|
||||
frg.DELETE("/ab/peer/:guid", ab.PeerDel)
|
||||
//[method:PUT] [uri:/api/ab/peer/update/1]
|
||||
frg.PUT("/ab/peer/update/:guid", ab.PeerUpdate)
|
||||
//[method:POST] [uri:/api/ab/tag/add/1]
|
||||
frg.POST("/ab/tag/add/:guid", ab.TagAdd)
|
||||
//[method:PUT] [uri:/api/ab/tag/rename/1]
|
||||
frg.PUT("/ab/tag/rename/:guid", ab.TagRename)
|
||||
//[method:PUT] [uri:/api/ab/tag/update/1]
|
||||
frg.PUT("/ab/tag/update/:guid", ab.TagUpdate)
|
||||
//[method:DELETE] [uri:/api/ab/tag/1]
|
||||
frg.DELETE("/ab/tag/:guid", ab.TagDel)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
func WebInit(g *gin.Engine) {
|
||||
i := &web.Index{}
|
||||
g.GET("/", i.Index)
|
||||
g.GET("/webclient-config/index.js", i.ConfigJs)
|
||||
g.StaticFS("/webclient", http.Dir(global.Config.Gin.ResourcesPath+"/web"))
|
||||
g.StaticFS("/_admin", http.Dir(global.Config.Gin.ResourcesPath+"/admin"))
|
||||
|
||||
@@ -12,6 +12,7 @@ type Peer struct {
|
||||
Version string `json:"version" gorm:"default:'';not null;"`
|
||||
UserId uint `json:"user_id" gorm:"default:0;not null;index"`
|
||||
User User `json:"user,omitempty" gorm:""`
|
||||
LastOnlineTime int64 `json:"last_online_time" gorm:"default:0;not null;"`
|
||||
TimeModel
|
||||
}
|
||||
|
||||
|
||||
121
resources/i18n/en.toml
Normal file
@@ -0,0 +1,121 @@
|
||||
[Test]
|
||||
description = "test"
|
||||
one = "test1 "
|
||||
other = "Test2 {{.P0}}"
|
||||
|
||||
[ParamsError]
|
||||
description = "Params validation failed."
|
||||
one = "Params validation failed."
|
||||
other = "Params validation failed."
|
||||
|
||||
[OperationFailed]
|
||||
description = "OperationFailed."
|
||||
one = "the operation failed."
|
||||
other = "the operation failed."
|
||||
|
||||
[OperationSuccess]
|
||||
description = "OperationSuccess."
|
||||
one = "the operation success."
|
||||
other = "the operation success."
|
||||
|
||||
[ItemExists]
|
||||
description = "Item already exists."
|
||||
one = "Item already exists."
|
||||
other = "Item already exists."
|
||||
|
||||
[ItemNotFound]
|
||||
description = "Item not found."
|
||||
one = "Item not found."
|
||||
other = "Item not found."
|
||||
|
||||
[NoAccess]
|
||||
description = "No access."
|
||||
one = "No access."
|
||||
other = "No access."
|
||||
|
||||
[UsernameOrPasswordError]
|
||||
description = "Username or password error."
|
||||
one = "Username or password error."
|
||||
other = "Username or password error."
|
||||
|
||||
[SystemError]
|
||||
description = "System error."
|
||||
one = "System error."
|
||||
other = "System error."
|
||||
|
||||
[ConfigNotFound]
|
||||
description = "Config not found."
|
||||
one = "Config not found."
|
||||
other = "Config not found."
|
||||
|
||||
[OauthExpired]
|
||||
description = "Oauth expired."
|
||||
one = "Oauth expired, please try again."
|
||||
other = "Oauth expired,please try again."
|
||||
|
||||
[OauthFailed]
|
||||
description = "Oauth failed."
|
||||
one = "Oauth failed."
|
||||
other = "Oauth failed."
|
||||
|
||||
[OauthHasBindOtherUser]
|
||||
description = "Oauth has bind other user."
|
||||
one = "Oauth has bind other user."
|
||||
other = "Oauth has bind other user."
|
||||
|
||||
[ParamIsEmpty]
|
||||
description = "Param is empty."
|
||||
one = "{{.P0}} is empty."
|
||||
other = "{{.P0}} is empty."
|
||||
|
||||
[BindFail]
|
||||
description = "Bind fail."
|
||||
one = "Bind fail."
|
||||
other = "Bind fail."
|
||||
[BindSuccess]
|
||||
description = "Bind success."
|
||||
one = "Bind success."
|
||||
other = "Bind success."
|
||||
[OauthHasBeenSuccess]
|
||||
description = "Oauth has been success."
|
||||
one = "Oauth has been success."
|
||||
other = "Oauth has been success."
|
||||
[OauthSuccess]
|
||||
description = "Oauth success."
|
||||
one = "Oauth success."
|
||||
other = "Oauth success."
|
||||
[OauthRegisterSuccess]
|
||||
description = "Oauth register success."
|
||||
one = "Oauth register success."
|
||||
other = "Oauth register success."
|
||||
[OauthRegisterFailed]
|
||||
description = "Oauth register failed."
|
||||
one = "Oauth register failed."
|
||||
other = "Oauth register failed."
|
||||
[GetOauthTokenError]
|
||||
description = "Get oauth token error."
|
||||
one = "Get oauth token error."
|
||||
other = "Get oauth token error."
|
||||
[GetOauthUserInfoError]
|
||||
description = "Get oauth user info error."
|
||||
one = "Get oauth user info error."
|
||||
other = "Get oauth user info error."
|
||||
[DecodeOauthUserInfoError]
|
||||
description = "Decode oauth user info error."
|
||||
one = "Decode oauth user info error."
|
||||
other = "Decode oauth user info error."
|
||||
|
||||
[OldPasswordError]
|
||||
description = "Old password error."
|
||||
one = "Old password error."
|
||||
other = "Old password error."
|
||||
|
||||
[DefaultGroup]
|
||||
description = "Default group"
|
||||
one = "Default Group"
|
||||
other = "Default Group"
|
||||
|
||||
[ShareGroup]
|
||||
description = "Share group"
|
||||
one = "Share Group"
|
||||
other = "Share Group"
|
||||
123
resources/i18n/zh_CN.toml
Normal file
@@ -0,0 +1,123 @@
|
||||
[Test]
|
||||
description = "test"
|
||||
one = "测试1 {{.P0}}"
|
||||
other = "测试2 {{.P0}}"
|
||||
|
||||
[ParamsError]
|
||||
description = "Params validation failed."
|
||||
one = "参数错误。"
|
||||
other = "参数错误。"
|
||||
|
||||
[OperationFailed]
|
||||
description = "OperationFailed."
|
||||
one = "操作失败。"
|
||||
other = "操作失败。"
|
||||
|
||||
[OperationSuccess]
|
||||
description = "OperationSuccess."
|
||||
one = "操作成功。"
|
||||
other = "操作成功。"
|
||||
|
||||
[ItemExists]
|
||||
description = "Item already exists."
|
||||
one = "数据已存在。"
|
||||
other = "数据已存在。"
|
||||
|
||||
[ItemNotFound]
|
||||
description = "Item not found."
|
||||
one = "数据不存在。"
|
||||
other = "数据不存在。"
|
||||
|
||||
[NoAccess]
|
||||
description = "No access."
|
||||
one = "无权限。"
|
||||
other = "无权限。"
|
||||
|
||||
[UsernameOrPasswordError]
|
||||
description = "Username or password error."
|
||||
one = "用户名或密码错误。"
|
||||
other = "用户名或密码错误。"
|
||||
|
||||
[SystemError]
|
||||
description = "System error."
|
||||
one = "系统错误。"
|
||||
other = "系统错误。"
|
||||
|
||||
[ConfigNotFound]
|
||||
description = "Config not found."
|
||||
one = "配置不存在。"
|
||||
other = "配置不存在。"
|
||||
|
||||
#授权过期
|
||||
[OauthExpired]
|
||||
description = "Oauth expired."
|
||||
one = "授权过期,请重新授权。"
|
||||
other = "授权过期,请重新授权。"
|
||||
|
||||
[OauthFailed]
|
||||
description = "Oauth failed."
|
||||
one = "授权失败。"
|
||||
other = "授权失败。"
|
||||
|
||||
[OauthHasBindOtherUser]
|
||||
description = "Oauth has bind other user."
|
||||
one = "授权已绑定其他用户。"
|
||||
other = "授权已绑定其他用户。"
|
||||
|
||||
[ParamIsEmpty]
|
||||
description = "Param is empty."
|
||||
one = "{{.P0}} 为空。"
|
||||
other = "{{.P0}} 为空。"
|
||||
|
||||
[BindFail]
|
||||
description = "Bind fail."
|
||||
one = "绑定失败。"
|
||||
other = "绑定失败。"
|
||||
[BindSuccess]
|
||||
description = "Bind success."
|
||||
one = "绑定成功。"
|
||||
other = "绑定成功。"
|
||||
[OauthHasBeenSuccess]
|
||||
description = "Oauth has been success."
|
||||
one = "授权已成功。"
|
||||
other = "授权已成功。"
|
||||
[OauthSuccess]
|
||||
description = "Oauth success."
|
||||
one = "授权成功。"
|
||||
other = "授权成功。"
|
||||
[OauthRegisterSuccess]
|
||||
description = "Oauth register success."
|
||||
one = "授权注册成功。"
|
||||
other = "授权注册成功。"
|
||||
[OauthRegisterFailed]
|
||||
description = "Oauth register failed."
|
||||
one = "授权注册失败。"
|
||||
other = "授权注册失败。"
|
||||
[GetOauthTokenError]
|
||||
description = "Get oauth token error."
|
||||
one = "获取授权token失败。"
|
||||
other = "获取授权token失败。"
|
||||
[GetOauthUserInfoError]
|
||||
description = "Get oauth user info error."
|
||||
one = "获取授权用户信息失败。"
|
||||
other = "获取授权用户信息失败。"
|
||||
[DecodeOauthUserInfoError]
|
||||
description = "Decode oauth user info error."
|
||||
one = "解析授权用户信息失败。"
|
||||
other = "解析授权用户信息失败。"
|
||||
|
||||
[OldPasswordError]
|
||||
description = "Old password error."
|
||||
one = "旧密码错误。"
|
||||
other = "旧密码错误。"
|
||||
|
||||
|
||||
[DefaultGroup]
|
||||
description = "Default group."
|
||||
one = "默认组"
|
||||
other = "默认组"
|
||||
|
||||
[ShareGroup]
|
||||
description = "Share group."
|
||||
one = "共享组"
|
||||
other = "共享组"
|
||||
@@ -9,11 +9,17 @@ import (
|
||||
type AddressBookService struct {
|
||||
}
|
||||
|
||||
func (s *AddressBookService) Info(id uint) *model.AddressBook {
|
||||
func (s *AddressBookService) Info(id string) *model.AddressBook {
|
||||
p := &model.AddressBook{}
|
||||
global.DB.Where("id = ?", id).First(p)
|
||||
return p
|
||||
}
|
||||
|
||||
func (s *AddressBookService) InfoByUserIdAndId(userid uint, id string) *model.AddressBook {
|
||||
p := &model.AddressBook{}
|
||||
global.DB.Where("user_id = ? and id = ?", userid, id).First(p)
|
||||
return p
|
||||
}
|
||||
func (s *AddressBookService) InfoByRowId(id uint) *model.AddressBook {
|
||||
p := &model.AddressBook{}
|
||||
global.DB.Where("row_id = ?", id).First(p)
|
||||
|
||||
@@ -133,7 +133,7 @@ func (os *OauthService) BeginAuth(op string) (error error, code, url string) {
|
||||
return err, code, conf.AuthCodeURL(code)
|
||||
}
|
||||
|
||||
return errors.New("op错误"), code, ""
|
||||
return err, code, ""
|
||||
}
|
||||
|
||||
// GetOauthConfig 获取配置
|
||||
@@ -141,7 +141,7 @@ func (os *OauthService) GetOauthConfig(op string) (error, *oauth2.Config) {
|
||||
if op == model.OauthTypeGithub {
|
||||
g := os.InfoByOp(model.OauthTypeGithub)
|
||||
if g.Id == 0 || g.ClientId == "" || g.ClientSecret == "" || g.RedirectUrl == "" {
|
||||
return errors.New("配置不存在"), nil
|
||||
return errors.New("ConfigNotFound"), nil
|
||||
}
|
||||
return nil, &oauth2.Config{
|
||||
ClientID: g.ClientId,
|
||||
@@ -154,7 +154,7 @@ func (os *OauthService) GetOauthConfig(op string) (error, *oauth2.Config) {
|
||||
if op == model.OauthTypeGoogle {
|
||||
g := os.InfoByOp(model.OauthTypeGoogle)
|
||||
if g.Id == 0 || g.ClientId == "" || g.ClientSecret == "" || g.RedirectUrl == "" {
|
||||
return errors.New("配置不存在"), nil
|
||||
return errors.New("ConfigNotFound"), nil
|
||||
}
|
||||
return nil, &oauth2.Config{
|
||||
ClientID: g.ClientId,
|
||||
@@ -164,7 +164,7 @@ func (os *OauthService) GetOauthConfig(op string) (error, *oauth2.Config) {
|
||||
Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"},
|
||||
}
|
||||
}
|
||||
return errors.New("op错误"), nil
|
||||
return errors.New("ConfigNotFound"), nil
|
||||
}
|
||||
|
||||
func (os *OauthService) GithubCallback(code string) (error error, userData *GithubUserdata) {
|
||||
@@ -175,7 +175,7 @@ func (os *OauthService) GithubCallback(code string) (error error, userData *Gith
|
||||
token, err := oauthConfig.Exchange(context.Background(), code)
|
||||
if err != nil {
|
||||
global.Logger.Warn(fmt.Printf("oauthConfig.Exchange() failed: %s\n", err))
|
||||
error = errors.New("获取token失败")
|
||||
error = errors.New("GetOauthTokenError")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ func (os *OauthService) GithubCallback(code string) (error error, userData *Gith
|
||||
resp, err := client.Get("https://api.github.com/user")
|
||||
if err != nil {
|
||||
global.Logger.Warn("failed getting user info: %s\n", err)
|
||||
error = errors.New("获取user info失败")
|
||||
error = errors.New("GetOauthUserInfoError")
|
||||
return
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
@@ -197,7 +197,7 @@ func (os *OauthService) GithubCallback(code string) (error error, userData *Gith
|
||||
// 在这里处理 GitHub 用户信息
|
||||
if err = json.NewDecoder(resp.Body).Decode(&userData); err != nil {
|
||||
global.Logger.Warn("failed decoding user info: %s\n", err)
|
||||
error = errors.New("解析user info失败")
|
||||
error = errors.New("DecodeOauthUserInfoError")
|
||||
return
|
||||
}
|
||||
return
|
||||
@@ -208,7 +208,7 @@ func (os *OauthService) GoogleCallback(code string) (error error, userData *Goog
|
||||
token, err := oauthConfig.Exchange(context.Background(), code)
|
||||
if err != nil {
|
||||
global.Logger.Warn(fmt.Printf("oauthConfig.Exchange() failed: %s\n", err))
|
||||
error = errors.New("获取token失败")
|
||||
error = errors.New("GetOauthTokenError")
|
||||
return
|
||||
}
|
||||
// 创建 HTTP 客户端,并将 access_token 添加到 Authorization 头中
|
||||
@@ -216,7 +216,7 @@ func (os *OauthService) GoogleCallback(code string) (error error, userData *Goog
|
||||
resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo")
|
||||
if err != nil {
|
||||
global.Logger.Warn("failed getting user info: %s\n", err)
|
||||
error = errors.New("获取user info失败: " + err.Error())
|
||||
error = errors.New("GetOauthUserInfoError")
|
||||
return
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
@@ -228,7 +228,7 @@ func (os *OauthService) GoogleCallback(code string) (error error, userData *Goog
|
||||
|
||||
if err = json.NewDecoder(resp.Body).Decode(&userData); err != nil {
|
||||
global.Logger.Warn("failed decoding user info: %s\n", err)
|
||||
error = errors.New("解析user info失败:" + err.Error())
|
||||
error = errors.New("DecodeOauthUserInfoError")
|
||||
return
|
||||
}
|
||||
return
|
||||
@@ -258,7 +258,13 @@ func (os *OauthService) BindOauthUser(thirdType, openid, username string, userId
|
||||
}
|
||||
|
||||
func (os *OauthService) UnBindGithubUser(userid uint) error {
|
||||
return global.DB.Where("user_id = ? and third_type = ?", userid, model.OauthTypeGithub).Delete(&model.UserThird{}).Error
|
||||
return os.UnBindThird(model.OauthTypeGithub, userid)
|
||||
}
|
||||
func (os *OauthService) UnBindGoogleUser(userid uint) error {
|
||||
return os.UnBindThird(model.OauthTypeGoogle, userid)
|
||||
}
|
||||
func (os *OauthService) UnBindThird(thirdType string, userid uint) error {
|
||||
return global.DB.Where("user_id = ? and third_type = ?", userid, thirdType).Delete(&model.UserThird{}).Error
|
||||
}
|
||||
|
||||
// InfoById 根据id取用户信息
|
||||
|
||||
@@ -15,24 +15,38 @@ func (ps *PeerService) FindById(id string) *model.Peer {
|
||||
global.DB.Where("id = ?", id).First(p)
|
||||
return p
|
||||
}
|
||||
func (ps *PeerService) FindByUuid(uuid string) *model.Peer {
|
||||
p := &model.Peer{}
|
||||
global.DB.Where("uuid = ?", uuid).First(p)
|
||||
return p
|
||||
}
|
||||
func (ps *PeerService) InfoByRowId(id uint) *model.Peer {
|
||||
p := &model.Peer{}
|
||||
global.DB.Where("row_id = ?", id).First(p)
|
||||
return p
|
||||
}
|
||||
|
||||
//// ListByUserIds 根据用户id取列表
|
||||
//func (ps *PeerService) ListByUserIds(userIds []uint, page, pageSize uint) (res *model.PeerList) {
|
||||
// res = &model.PeerList{}
|
||||
// res.Page = int64(page)
|
||||
// res.PageSize = int64(pageSize)
|
||||
// tx := global.DB.Model(&model.Peer{}).Preload("User")
|
||||
// tx.Where("user_id in (?)", userIds)
|
||||
// tx.Count(&res.Total)
|
||||
// tx.Scopes(Paginate(page, pageSize))
|
||||
// tx.Find(&res.Peers)
|
||||
// return
|
||||
//}
|
||||
// UuidBindUserId 绑定用户id
|
||||
func (ps *PeerService) UuidBindUserId(uuid string, userId uint) {
|
||||
peer := ps.FindByUuid(uuid)
|
||||
if peer.RowId > 0 {
|
||||
peer.UserId = userId
|
||||
ps.Update(peer)
|
||||
}
|
||||
}
|
||||
|
||||
// ListByUserIds 根据用户id取列表
|
||||
func (ps *PeerService) ListByUserIds(userIds []uint, page, pageSize uint) (res *model.PeerList) {
|
||||
res = &model.PeerList{}
|
||||
res.Page = int64(page)
|
||||
res.PageSize = int64(pageSize)
|
||||
tx := global.DB.Model(&model.Peer{})
|
||||
tx.Where("user_id in (?)", userIds)
|
||||
tx.Count(&res.Total)
|
||||
tx.Scopes(Paginate(page, pageSize))
|
||||
tx.Find(&res.Peers)
|
||||
return
|
||||
}
|
||||
|
||||
func (ps *PeerService) List(page, pageSize uint, where func(tx *gorm.DB)) (res *model.PeerList) {
|
||||
res = &model.PeerList{}
|
||||
@@ -57,6 +71,11 @@ func (ps *PeerService) Delete(u *model.Peer) error {
|
||||
return global.DB.Delete(u).Error
|
||||
}
|
||||
|
||||
// BatchDelete
|
||||
func (ps *PeerService) BatchDelete(ids []uint) error {
|
||||
return global.DB.Where("row_id in (?)", ids).Delete(&model.Peer{}).Error
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (ps *PeerService) Update(u *model.Peer) error {
|
||||
return global.DB.Model(u).Updates(u).Error
|
||||
|
||||
@@ -14,6 +14,11 @@ func (s *TagService) Info(id uint) *model.Tag {
|
||||
global.DB.Where("id = ?", id).First(p)
|
||||
return p
|
||||
}
|
||||
func (s *TagService) InfoByUserIdAndName(userid uint, name string) *model.Tag {
|
||||
p := &model.Tag{}
|
||||
global.DB.Where("user_id = ? and name = ?", userid, name).First(p)
|
||||
return p
|
||||
}
|
||||
|
||||
func (s *TagService) ListByUserId(userId uint) (res *model.TagList) {
|
||||
res = s.List(1, 1000, func(tx *gorm.DB) {
|
||||
|
||||
@@ -66,6 +66,9 @@ func (us *UserService) Login(u *model.User, llog *model.LoginLog) *model.UserTok
|
||||
}
|
||||
global.DB.Create(ut)
|
||||
global.DB.Create(llog)
|
||||
if llog.Uuid != "" {
|
||||
AllService.PeerService.UuidBindUserId(llog.Uuid, u.Id)
|
||||
}
|
||||
return ut
|
||||
}
|
||||
|
||||
|
||||