Compare commits
No commits in common. "dev" and "main" have entirely different histories.
231
.gitea/workflows/docker.yml
Normal file
231
.gitea/workflows/docker.yml
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
name: Build docker and publish
|
||||||
|
run-name: 简化的Docker构建和部署流程
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- dev
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- dev
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Docker镜像仓库
|
||||||
|
REPO: ${{ vars.REPO || 'registry.kxsw.us/ario-server' }}
|
||||||
|
# SSH连接信息
|
||||||
|
SSH_HOST: ${{ vars.SSH_HOST }}
|
||||||
|
SSH_PORT: ${{ vars.SSH_PORT }}
|
||||||
|
SSH_USER: ${{ vars.SSH_USER }}
|
||||||
|
SSH_PASSWORD: ${{ vars.SSH_PASSWORD }}
|
||||||
|
# TG通知
|
||||||
|
TG_BOT_TOKEN: 8114337882:AAHkEx03HSu7RxN4IHBJJEnsK9aPPzNLIk0
|
||||||
|
TG_CHAT_ID: "-4940243803"
|
||||||
|
# Go构建变量
|
||||||
|
SERVICE: ario
|
||||||
|
SERVICE_STYLE: ario
|
||||||
|
VERSION: ${{ github.sha }}
|
||||||
|
BUILDTIME: ${{ github.event.head_commit.timestamp }}
|
||||||
|
GOARCH: amd64
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ario-server
|
||||||
|
container:
|
||||||
|
image: node:20
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
# 只有node支持版本号别名
|
||||||
|
node: ['20.15.1']
|
||||||
|
steps:
|
||||||
|
# 步骤1: 下载代码
|
||||||
|
- name: 📥 下载代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# 步骤2: 设置动态环境变量
|
||||||
|
- name: ⚙️ 设置动态环境变量
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.ref_name }}" = "main" ]; then
|
||||||
|
echo "DOCKER_TAG_SUFFIX=latest" >> $GITHUB_ENV
|
||||||
|
echo "CONTAINER_NAME=ppanel-server" >> $GITHUB_ENV
|
||||||
|
echo "DEPLOY_PATH=/root/vpn_server" >> $GITHUB_ENV
|
||||||
|
echo "为 main 分支设置生产环境变量"
|
||||||
|
elif [ "${{ github.ref_name }}" = "dev" ]; then
|
||||||
|
echo "DOCKER_TAG_SUFFIX=dev" >> $GITHUB_ENV
|
||||||
|
echo "CONTAINER_NAME=ppanel-server-dev" >> $GITHUB_ENV
|
||||||
|
echo "DEPLOY_PATH=/root/vpn_server_dev" >> $GITHUB_ENV
|
||||||
|
echo "为 dev 分支设置开发环境变量"
|
||||||
|
else
|
||||||
|
echo "DOCKER_TAG_SUFFIX=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||||
|
echo "CONTAINER_NAME=ppanel-server-${{ github.ref_name }}" >> $GITHUB_ENV
|
||||||
|
echo "DEPLOY_PATH=/root/vpn_server_other" >> $GITHUB_ENV
|
||||||
|
echo "为其他分支 (${{ github.ref_name }}) 设置环境变量"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 步骤3: 安装系统工具 (Docker, curl, jq)
|
||||||
|
- name: 🔧 安装系统工具 (Docker, curl, jq)
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
echo "等待 apt/dpkg 锁释放 (unattended-upgrades)..."
|
||||||
|
# 等待最多 300 秒让 unattended-upgrades/apt/dpkg 锁释放
|
||||||
|
end=$((SECONDS+300))
|
||||||
|
while true; do
|
||||||
|
LOCKS_BUSY=0
|
||||||
|
# 如果 unattended-upgrades 正在运行,标记为忙碌
|
||||||
|
if pgrep -x unattended-upgrades >/dev/null 2>&1; then LOCKS_BUSY=1; fi
|
||||||
|
# 如果 fuser 存在,检查常见的锁文件
|
||||||
|
if command -v fuser >/dev/null 2>&1; then
|
||||||
|
if fuser /var/lib/dpkg/lock >/dev/null 2>&1 \
|
||||||
|
|| fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1 \
|
||||||
|
|| fuser /var/lib/apt/lists/lock >/dev/null 2>&1; then
|
||||||
|
LOCKS_BUSY=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# 如果不忙碌则跳出循环
|
||||||
|
if [ "$LOCKS_BUSY" -eq 0 ]; then break; fi
|
||||||
|
# 超时后约 5 分钟
|
||||||
|
if [ $SECONDS -ge $end ]; then
|
||||||
|
echo "等待 apt/dpkg 锁超时,使用 Dpkg::Lock::Timeout 继续..."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo "仍在等待锁释放..."; sleep 5
|
||||||
|
done
|
||||||
|
apt-get update -y -o Dpkg::Lock::Timeout=600
|
||||||
|
apt-get install -y -o Dpkg::Lock::Timeout=600 jq curl ca-certificates docker.io
|
||||||
|
docker --version
|
||||||
|
jq --version
|
||||||
|
curl --version
|
||||||
|
|
||||||
|
# 步骤4: 构建并发布到镜像仓库
|
||||||
|
- name: 📤 构建并发布到镜像仓库
|
||||||
|
run: |
|
||||||
|
echo "开始构建并推送镜像..."
|
||||||
|
echo "仓库: ${{ env.REPO }}"
|
||||||
|
echo "版本标签: ${{ env.VERSION }}"
|
||||||
|
echo "分支标签: ${{ env.DOCKER_TAG_SUFFIX }}"
|
||||||
|
|
||||||
|
# 构建镜像,同时打上版本和分支两个标签
|
||||||
|
docker build -f Dockerfile \
|
||||||
|
--platform linux/amd64 \
|
||||||
|
--build-arg TARGETARCH=amd64 \
|
||||||
|
--build-arg VERSION=${{ env.VERSION }} \
|
||||||
|
--build-arg BUILDTIME=${{ env.BUILDTIME }} \
|
||||||
|
-t ${{ env.REPO }}:${{ env.VERSION }} \
|
||||||
|
-t ${{ env.REPO }}:${{ env.DOCKER_TAG_SUFFIX }} \
|
||||||
|
.
|
||||||
|
|
||||||
|
echo "推送版本标签镜像: ${{ env.REPO }}:${{ env.VERSION }}"
|
||||||
|
docker push ${{ env.REPO }}:${{ env.VERSION }}
|
||||||
|
|
||||||
|
echo "推送分支标签镜像: ${{ env.REPO }}:${{ env.DOCKER_TAG_SUFFIX }}"
|
||||||
|
docker push ${{ env.REPO }}:${{ env.DOCKER_TAG_SUFFIX }}
|
||||||
|
|
||||||
|
echo "镜像推送完成"
|
||||||
|
|
||||||
|
# 步骤5: 连接服务器拉镜像启动
|
||||||
|
- name: 🚀 连接服务器拉镜像启动
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ env.SSH_HOST }}
|
||||||
|
username: ${{ env.SSH_USER }}
|
||||||
|
password: ${{ env.SSH_PASSWORD }}
|
||||||
|
port: ${{ env.SSH_PORT }}
|
||||||
|
timeout: 300s
|
||||||
|
command_timeout: 600s
|
||||||
|
script: |
|
||||||
|
echo "连接服务器成功,开始部署..."
|
||||||
|
echo "部署容器名: ${{ env.CONTAINER_NAME }}"
|
||||||
|
echo "部署路径: ${{ env.DEPLOY_PATH }}"
|
||||||
|
echo "部署镜像: ${{ env.REPO }}:${{ env.DOCKER_TAG_SUFFIX }}"
|
||||||
|
|
||||||
|
# 确保部署目录存在
|
||||||
|
mkdir -p ${{ env.DEPLOY_PATH }}/config
|
||||||
|
mkdir -p ${{ env.DEPLOY_PATH }}/logs
|
||||||
|
|
||||||
|
# 停止并删除旧容器(忽略所有错误)
|
||||||
|
if docker ps -a | grep -q ${{ env.CONTAINER_NAME }} 2>/dev/null; then
|
||||||
|
echo "停止旧容器..."
|
||||||
|
docker stop ${{ env.CONTAINER_NAME }} >/dev/null 2>&1 || true
|
||||||
|
echo "等待容器完全停止..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "删除旧容器..."
|
||||||
|
# 静默删除,完全忽略错误输出
|
||||||
|
docker rm ${{ env.CONTAINER_NAME }} >/dev/null 2>&1 || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# 如果仍然存在,尝试强制删除(静默)
|
||||||
|
if docker ps -a | grep -q ${{ env.CONTAINER_NAME }} 2>/dev/null; then
|
||||||
|
echo "尝试强制删除..."
|
||||||
|
docker rm -f ${{ env.CONTAINER_NAME }} >/dev/null 2>&1 || true
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "容器清理完成,继续部署..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 拉取最新分支镜像
|
||||||
|
echo "拉取镜像: ${{ env.REPO }}:${{ env.DOCKER_TAG_SUFFIX }}..."
|
||||||
|
docker pull ${{ env.REPO }}:${{ env.DOCKER_TAG_SUFFIX }}
|
||||||
|
|
||||||
|
# 启动新容器
|
||||||
|
echo "启动新容器..."
|
||||||
|
cd ${{ env.DEPLOY_PATH }}
|
||||||
|
docker run -d \
|
||||||
|
--name ${{ env.CONTAINER_NAME }} \
|
||||||
|
--restart unless-stopped \
|
||||||
|
--network host \
|
||||||
|
-v ./config/ppanel.yaml:/app/etc/ppanel.yaml \
|
||||||
|
-v ./logs:/app/logs \
|
||||||
|
${{ env.REPO }}:${{ env.DOCKER_TAG_SUFFIX }}
|
||||||
|
|
||||||
|
# 检查容器状态
|
||||||
|
sleep 5
|
||||||
|
if docker ps | grep -q ${{ env.CONTAINER_NAME }}; then
|
||||||
|
echo "✅ 容器启动成功"
|
||||||
|
else
|
||||||
|
echo "❌ 容器启动失败"
|
||||||
|
docker logs ${{ env.CONTAINER_NAME }}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 步骤6: TG通知 (成功)
|
||||||
|
- name: 📱 发送成功通知到Telegram
|
||||||
|
if: success()
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
token: ${{ env.TG_BOT_TOKEN }}
|
||||||
|
to: ${{ env.TG_CHAT_ID }}
|
||||||
|
message: |
|
||||||
|
✅ 部署成功!
|
||||||
|
|
||||||
|
📦 项目: ${{ github.repository }}
|
||||||
|
🌿 分支: ${{ github.ref_name }}
|
||||||
|
📝 提交: ${{ github.sha }}
|
||||||
|
👤 提交者: ${{ github.actor }}
|
||||||
|
🕐 时间: ${{ github.event.head_commit.timestamp }}
|
||||||
|
|
||||||
|
🚀 服务已成功部署到生产环境
|
||||||
|
parse_mode: Markdown
|
||||||
|
|
||||||
|
# 步骤5: TG通知 (失败)
|
||||||
|
- name: 📱 发送失败通知到Telegram
|
||||||
|
if: failure()
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
token: ${{ env.TG_BOT_TOKEN }}
|
||||||
|
to: ${{ env.TG_CHAT_ID }}
|
||||||
|
message: |
|
||||||
|
❌ 部署失败!
|
||||||
|
|
||||||
|
📦 项目: ${{ github.repository }}
|
||||||
|
🌿 分支: ${{ github.ref_name }}
|
||||||
|
📝 提交: ${{ github.sha }}
|
||||||
|
👤 提交者: ${{ github.actor }}
|
||||||
|
🕐 时间: ${{ github.event.head_commit.timestamp }}
|
||||||
|
|
||||||
|
⚠️ 请检查构建日志获取详细信息
|
||||||
|
parse_mode: Markdown
|
||||||
|
|
||||||
51
.github/workflows/develop.yaml
vendored
51
.github/workflows/develop.yaml
vendored
@ -1,51 +0,0 @@
|
|||||||
name: Deploy
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: ["develop"]
|
|
||||||
pull_request:
|
|
||||||
branches: ["develop"]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-and-deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Log in to Docker Hub
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Get short Git commit ID
|
|
||||||
id: vars
|
|
||||||
run: echo "COMMIT_ID=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
|
|
||||||
- name: Build Docker image
|
|
||||||
run: docker build --build-arg VERSION=${{ env.COMMIT_ID }} -t ${{ secrets.DOCKER_USERNAME }}/ppanel-server-dev:${{ env.COMMIT_ID }} .
|
|
||||||
|
|
||||||
- name: Push Docker image
|
|
||||||
run: docker push ${{ secrets.DOCKER_USERNAME }}/ppanel-server-dev:${{ env.COMMIT_ID }}
|
|
||||||
|
|
||||||
# - name: Deploy to server
|
|
||||||
# uses: appleboy/ssh-action@v0.1.6
|
|
||||||
# with:
|
|
||||||
# host: ${{ secrets.SSH_HOST }}
|
|
||||||
# username: ${{ secrets.SSH_USER }}
|
|
||||||
# key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
||||||
# script: |
|
|
||||||
# if [ $(docker ps -a -q -f name=ppanel-server-dev) ]; then
|
|
||||||
# echo "Stopping and removing existing ppanel-server container..."
|
|
||||||
# docker stop ppanel-server-dev
|
|
||||||
# docker rm ppanel-server-dev
|
|
||||||
# else
|
|
||||||
# echo "No existing ppanel-server-dev container running."
|
|
||||||
# fi
|
|
||||||
#
|
|
||||||
# docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
# docker run -d --restart=always --log-driver=journald --name ppanel-server-dev -p 8080:8080 -v /www/wwwroot/api/etc:/app/etc -v /www/wwwroot/api/logs:/app/logs --restart=always -d ${{ secrets.DOCKER_USERNAME }}/ppanel-server-dev:${{ env.COMMIT_ID }}
|
|
||||||
#
|
|
||||||
131
.github/workflows/release.yml
vendored
131
.github/workflows/release.yml
vendored
@ -1,131 +0,0 @@
|
|||||||
name: Release
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-docker:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
IMAGE_NAME: ppanel-server
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v3
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Log in to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Extract version from git tag
|
|
||||||
id: version
|
|
||||||
run: echo "VERSION=$(git describe --tags --abbrev=0 | sed 's/^v//')" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Get short SHA
|
|
||||||
id: sha
|
|
||||||
run: echo "GIT_SHA=${GITHUB_SHA::8}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set BUILD_TIME env
|
|
||||||
run: echo BUILD_TIME=$(date --iso-8601=seconds) >> ${GITHUB_ENV}
|
|
||||||
|
|
||||||
|
|
||||||
- name: Build and push Docker image for main release
|
|
||||||
if: "!contains(github.ref_name, 'beta')"
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: Dockerfile
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
build-args: |
|
|
||||||
VERSION=${{ env.VERSION }}
|
|
||||||
tags: |
|
|
||||||
${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
|
||||||
${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }}-${{ env.GIT_SHA }}
|
|
||||||
|
|
||||||
- name: Build and push Docker image for beta release
|
|
||||||
if: contains(github.ref_name, 'beta')
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: Dockerfile
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
build-args: |
|
|
||||||
VERSION=${{ env.VERSION }}
|
|
||||||
tags: |
|
|
||||||
${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:beta
|
|
||||||
${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }}-${{ env.GIT_SHA }}
|
|
||||||
|
|
||||||
release-notes:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: build-docker
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.21'
|
|
||||||
|
|
||||||
- name: Install GoReleaser
|
|
||||||
run: |
|
|
||||||
go install github.com/goreleaser/goreleaser/v2@latest
|
|
||||||
|
|
||||||
- name: Run GoReleaser
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
run: |
|
|
||||||
goreleaser check
|
|
||||||
goreleaser release --clean
|
|
||||||
|
|
||||||
releases-matrix:
|
|
||||||
name: Release ppanel-server binary
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: release-notes # wait for release-notes job to finish
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
# build and publish in parallel: linux/386, linux/amd64, linux/arm64,
|
|
||||||
# windows/386, windows/amd64, windows/arm64, darwin/amd64, darwin/arm64
|
|
||||||
goos: [ linux, windows, darwin ]
|
|
||||||
goarch: [ '386', amd64, arm64 ]
|
|
||||||
exclude:
|
|
||||||
- goarch: '386'
|
|
||||||
goos: darwin
|
|
||||||
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Extract version from git tag
|
|
||||||
id: version
|
|
||||||
run: echo "VERSION=$(git describe --tags --abbrev=0 | sed 's/^v//')" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set BUILD_TIME env
|
|
||||||
run: echo BUILD_TIME=$(date --iso-8601=seconds) >> ${GITHUB_ENV}
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: wangyoucao577/go-release-action@v1
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
goos: ${{ matrix.goos }}
|
|
||||||
goarch: ${{ matrix.goarch }}
|
|
||||||
asset_name: "ppanel-server-${{ matrix.goos }}-${{ matrix.goarch }}"
|
|
||||||
goversion: "https://dl.google.com/go/go1.23.3.linux-amd64.tar.gz"
|
|
||||||
project_path: "."
|
|
||||||
binary_name: "ppanel-server"
|
|
||||||
extra_files: LICENSE etc
|
|
||||||
ldflags: -X "github.com/perfect-panel/server/pkg/constant.Version=${{env.VERSION}}" -X "github.com/perfect-panel/server/pkg/constant.BuildTime=${{env.BUILD_TIME}}"
|
|
||||||
81
.github/workflows/swagger.yaml
vendored
81
.github/workflows/swagger.yaml
vendored
@ -1,81 +0,0 @@
|
|||||||
name: Go CI/CD with goctl and Swagger
|
|
||||||
|
|
||||||
on:
|
|
||||||
# release:
|
|
||||||
# types: [published]
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install goctl
|
|
||||||
run: |
|
|
||||||
curl -L https://github.com/zeromicro/go-zero/releases/download/tools%2Fgoctl%2Fv1.7.2/goctl-v1.7.2-linux-amd64.tar.gz -o goctl-v1.7.2-linux-amd64.tar.gz
|
|
||||||
tar -xvzf goctl-v1.7.2-linux-amd64.tar.gz
|
|
||||||
chmod +x goctl
|
|
||||||
sudo mv goctl /usr/local/bin/goctl
|
|
||||||
goctl --version
|
|
||||||
|
|
||||||
- name: Install goctl-swagger
|
|
||||||
run: |
|
|
||||||
curl -L https://github.com/tensionc/goctl-swagger/releases/download/v1.0.1/goctl-swagger-v1.0.1-linux-amd64.tar.gz -o goctl-swagger.tar.gz
|
|
||||||
tar -xvzf goctl-swagger.tar.gz
|
|
||||||
chmod +x goctl-swagger
|
|
||||||
sudo mv goctl-swagger /usr/local/bin/
|
|
||||||
|
|
||||||
- name: Generate Swagger file
|
|
||||||
run: |
|
|
||||||
mkdir -p swagger
|
|
||||||
goctl api plugin -plugin goctl-swagger='swagger -filename common.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_common.api -dir ./swagger
|
|
||||||
goctl api plugin -plugin goctl-swagger='swagger -filename user.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_user.api -dir ./swagger
|
|
||||||
goctl api plugin -plugin goctl-swagger='swagger -filename admin.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_admin.api -dir ./swagger
|
|
||||||
goctl api plugin -plugin goctl-swagger='swagger -filename ppanel.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ppanel.api -dir ./swagger
|
|
||||||
goctl api plugin -plugin goctl-swagger='swagger -filename node.json -pack Response -response "[{\"name\":\"code\",\"type\":\"integer\",\"description\":\"状态码\"},{\"name\":\"msg\",\"type\":\"string\",\"description\":\"消息\"},{\"name\":\"data\",\"type\":\"object\",\"description\":\"数据\",\"is_data\":true}]";' -api ./apis/swagger_node.api -dir ./swagger
|
|
||||||
|
|
||||||
|
|
||||||
- name: Verify Swagger file
|
|
||||||
run: |
|
|
||||||
test -f ./swagger/common.json
|
|
||||||
test -f ./swagger/user.json
|
|
||||||
test -f ./swagger/admin.json
|
|
||||||
|
|
||||||
- name: Checkout target repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: perfect-panel/ppanel-docs
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
path: ppanel-docs
|
|
||||||
persist-credentials: true
|
|
||||||
|
|
||||||
- name: Verify or create public/swagger directory
|
|
||||||
run: |
|
|
||||||
mkdir -p ./ppanel-docs/public/swagger
|
|
||||||
|
|
||||||
- name: Copy Swagger files
|
|
||||||
run: |
|
|
||||||
cp -rf swagger/* ppanel-docs/public/swagger
|
|
||||||
cd ppanel-docs
|
|
||||||
|
|
||||||
- name: Check for file changes
|
|
||||||
run: |
|
|
||||||
cd ppanel-docs
|
|
||||||
git add .
|
|
||||||
git status
|
|
||||||
if [ "$(git status --porcelain)" ]; then
|
|
||||||
echo "Changes detected in the doc repository."
|
|
||||||
git config user.name "GitHub Actions"
|
|
||||||
git config user.email "actions@ppanel.dev"
|
|
||||||
git commit -m "Update Swagger files"
|
|
||||||
git push
|
|
||||||
else
|
|
||||||
echo "No changes detected."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -6,12 +6,11 @@
|
|||||||
*.log
|
*.log
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*_test_config.go
|
*_test_config.go
|
||||||
*.log*
|
|
||||||
/build/
|
/build/
|
||||||
|
etc/ppanel.yaml
|
||||||
*.p8
|
*.p8
|
||||||
*.crt
|
*.crt
|
||||||
*.key
|
*.key
|
||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
package.json
|
package.json
|
||||||
/bin
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="go build github.com/perfect-panel/server" type="GoApplicationRunConfiguration" factoryName="Go Application" nameIsGenerated="true">
|
|
||||||
<module name="server" />
|
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
|
||||||
<parameters value="run --config etc/ppanel-dev.yaml" />
|
|
||||||
<kind value="PACKAGE" />
|
|
||||||
<package value="github.com/perfect-panel/server" />
|
|
||||||
<directory value="$PROJECT_DIR$" />
|
|
||||||
<filePath value="$PROJECT_DIR$/ppanel.go" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
128
DESIGN_SILENT_LOGIN.md
Normal file
128
DESIGN_SILENT_LOGIN.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# 设备静默登录机制设计方案
|
||||||
|
|
||||||
|
## 需求分析
|
||||||
|
1. 用户进来之后就是静默登录(设备登录)
|
||||||
|
2. 用户可以主动关联邮箱;也可以不关联邮箱
|
||||||
|
3. 用户换手机后在别的地方用邮箱登录会绑定另外一部手机的设备号
|
||||||
|
4. 没有游客概念,快捷登录进来的用户就是正式用户
|
||||||
|
|
||||||
|
## 当前系统分析
|
||||||
|
|
||||||
|
### 现有认证流程
|
||||||
|
- **设备登录**:已存在 `deviceLoginLogic.go`,通过设备标识符自动登录
|
||||||
|
- **邮箱登录**:已存在 `userLoginLogic.go`,需要邮箱+密码
|
||||||
|
- **游客模式**:通过 `Order.UserId = 0` 标识游客订单
|
||||||
|
|
||||||
|
### 现有设备管理
|
||||||
|
- **设备绑定**:`bindDeviceLogic.go` 处理设备与用户绑定
|
||||||
|
- **设备解绑**:`unbindDeviceLogic.go` 处理设备解绑
|
||||||
|
- **设备迁移**:支持设备在用户间转移
|
||||||
|
|
||||||
|
## 设计方案
|
||||||
|
|
||||||
|
### 1. 核心改动策略
|
||||||
|
- **保留现有设备登录机制**,作为默认登录方式
|
||||||
|
- **移除游客概念**,所有设备登录用户都是正式用户
|
||||||
|
- **增强邮箱绑定功能**,支持跨设备登录
|
||||||
|
- **优化设备迁移逻辑**,支持邮箱登录后绑定新设备
|
||||||
|
|
||||||
|
### 2. 具体实现方案
|
||||||
|
|
||||||
|
#### 2.1 修改设备登录逻辑
|
||||||
|
**文件**: `internal/logic/auth/deviceLoginLogic.go`
|
||||||
|
|
||||||
|
**改动点**:
|
||||||
|
- 移除 `registerUserAndDevice` 中的试用激活逻辑
|
||||||
|
- 确保所有通过设备登录创建的用户都是正式用户
|
||||||
|
- 保持现有的设备绑定机制
|
||||||
|
|
||||||
|
#### 2.2 修改订单处理逻辑
|
||||||
|
**文件**: `queue/logic/order/activateOrderLogic.go`
|
||||||
|
|
||||||
|
**改动点**:
|
||||||
|
- 移除 `getUserOrCreate` 中的游客判断逻辑 (`orderInfo.UserId == 0`)
|
||||||
|
- 移除 `createGuestUser` 函数
|
||||||
|
- 修改为:如果订单没有关联用户,通过设备标识符创建或获取用户
|
||||||
|
|
||||||
|
#### 2.3 修改订单关闭逻辑
|
||||||
|
**文件**: `internal/logic/public/order/closeOrderLogic.go`
|
||||||
|
|
||||||
|
**改动点**:
|
||||||
|
- 移除对 `UserId == 0` 的特殊处理
|
||||||
|
- 统一处理所有订单的关闭逻辑
|
||||||
|
|
||||||
|
#### 2.4 增强邮箱登录逻辑
|
||||||
|
**文件**: `internal/logic/auth/userLoginLogic.go`
|
||||||
|
|
||||||
|
**改动点**:
|
||||||
|
- 在邮箱登录成功后,如果提供了设备标识符,自动绑定设备
|
||||||
|
- 支持邮箱登录后在新设备上的自动绑定
|
||||||
|
|
||||||
|
#### 2.5 优化设备绑定逻辑
|
||||||
|
**文件**: `internal/logic/auth/bindDeviceLogic.go`
|
||||||
|
|
||||||
|
**改动点**:
|
||||||
|
- 增强设备迁移逻辑,支持邮箱用户登录新设备时的自动绑定
|
||||||
|
- 保持现有的设备冲突处理机制
|
||||||
|
|
||||||
|
### 3. 数据库变更
|
||||||
|
**无需修改数据库结构**,现有的用户和设备表结构已经支持新的需求。
|
||||||
|
|
||||||
|
### 4. API 变更
|
||||||
|
**无需修改 API 接口**,现有的设备登录和邮箱登录接口已经满足需求。
|
||||||
|
|
||||||
|
### 5. 前端适配
|
||||||
|
**前端需要调整**:
|
||||||
|
- 默认使用设备登录作为主要登录方式
|
||||||
|
- 提供邮箱绑定入口
|
||||||
|
- 在新设备上提供邮箱登录选项
|
||||||
|
|
||||||
|
## 实施步骤
|
||||||
|
|
||||||
|
### 第一步:修改订单逻辑
|
||||||
|
1. 修改 `activateOrderLogic.go`,移除游客概念
|
||||||
|
2. 修改 `closeOrderLogic.go`,统一订单处理逻辑
|
||||||
|
|
||||||
|
### 第二步:增强设备登录
|
||||||
|
1. 确保设备登录创建的都是正式用户
|
||||||
|
2. 优化设备绑定逻辑
|
||||||
|
|
||||||
|
### 第三步:增强邮箱登录
|
||||||
|
1. 在邮箱登录后支持设备绑定
|
||||||
|
2. 优化跨设备登录体验
|
||||||
|
|
||||||
|
### 第四步:测试验证
|
||||||
|
1. 测试设备静默登录
|
||||||
|
2. 测试邮箱绑定功能
|
||||||
|
3. 测试跨设备登录
|
||||||
|
|
||||||
|
## 优势分析
|
||||||
|
|
||||||
|
### 1. 最小化改动
|
||||||
|
- 复用现有的设备登录机制
|
||||||
|
- 保持现有的数据库结构
|
||||||
|
- 保持现有的 API 接口
|
||||||
|
|
||||||
|
### 2. 用户体验提升
|
||||||
|
- 用户进入即可使用,无需注册
|
||||||
|
- 支持邮箱绑定,便于跨设备使用
|
||||||
|
- 保持数据连续性
|
||||||
|
|
||||||
|
### 3. 系统稳定性
|
||||||
|
- 基于现有成熟机制
|
||||||
|
- 减少新增代码量
|
||||||
|
- 降低引入 bug 的风险
|
||||||
|
|
||||||
|
## 风险评估
|
||||||
|
|
||||||
|
### 1. 数据迁移
|
||||||
|
- **风险**: 现有游客数据需要处理
|
||||||
|
- **方案**: 可以保持现有游客数据不变,新用户使用新机制
|
||||||
|
|
||||||
|
### 2. 兼容性
|
||||||
|
- **风险**: 现有客户端可能需要适配
|
||||||
|
- **方案**: 保持 API 兼容,逐步引导用户使用新机制
|
||||||
|
|
||||||
|
### 3. 性能影响
|
||||||
|
- **风险**: 设备登录可能增加数据库压力
|
||||||
|
- **方案**: 现有机制已经过验证,影响可控
|
||||||
@ -24,11 +24,11 @@ RUN BUILD_TIME=$(date -u +"%Y-%m-%d %H:%M:%S") && \
|
|||||||
go build -ldflags="-s -w -X 'github.com/perfect-panel/server/pkg/constant.Version=${VERSION}' -X 'github.com/perfect-panel/server/pkg/constant.BuildTime=${BUILD_TIME}'" -o /app/ppanel ppanel.go
|
go build -ldflags="-s -w -X 'github.com/perfect-panel/server/pkg/constant.Version=${VERSION}' -X 'github.com/perfect-panel/server/pkg/constant.BuildTime=${BUILD_TIME}'" -o /app/ppanel ppanel.go
|
||||||
|
|
||||||
# Final minimal image
|
# Final minimal image
|
||||||
FROM scratch
|
FROM alpine:latest
|
||||||
|
|
||||||
# Copy CA certificates and timezone data
|
# Copy CA certificates and timezone data
|
||||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||||
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
|
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
|
||||||
|
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
@ -36,7 +36,6 @@ ENV TZ=Asia/Shanghai
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=builder /app/ppanel /app/ppanel
|
COPY --from=builder /app/ppanel /app/ppanel
|
||||||
COPY --from=builder /build/etc /app/etc
|
|
||||||
|
|
||||||
# Expose the port (optional)
|
# Expose the port (optional)
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|||||||
@ -11,11 +11,13 @@ info (
|
|||||||
type (
|
type (
|
||||||
// User login request
|
// User login request
|
||||||
UserLoginRequest {
|
UserLoginRequest {
|
||||||
Email string `json:"email" validate:"required"`
|
Identifier string `json:"identifier"`
|
||||||
Password string `json:"password" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
Password string `json:"password" validate:"required"`
|
||||||
UserAgent string `header:"User-Agent"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
// Check user is exist request
|
// Check user is exist request
|
||||||
CheckUserRequest {
|
CheckUserRequest {
|
||||||
@ -27,21 +29,25 @@ type (
|
|||||||
}
|
}
|
||||||
// User login response
|
// User login response
|
||||||
UserRegisterRequest {
|
UserRegisterRequest {
|
||||||
Email string `json:"email" validate:"required"`
|
Identifier string `json:"identifier"`
|
||||||
Password string `json:"password" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Invite string `json:"invite,optional"`
|
Password string `json:"password" validate:"required"`
|
||||||
Code string `json:"code,optional"`
|
Invite string `json:"invite,optional"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
Code string `json:"code,optional"`
|
||||||
UserAgent string `header:"User-Agent"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
// User login response
|
// User login response
|
||||||
ResetPasswordRequest {
|
ResetPasswordRequest {
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Email string `json:"email" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
Code string `json:"code,optional"`
|
Code string `json:"code,optional"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
UserAgent string `header:"User-Agent"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
LoginResponse {
|
LoginResponse {
|
||||||
@ -60,12 +66,14 @@ type (
|
|||||||
}
|
}
|
||||||
// login request
|
// login request
|
||||||
TelephoneLoginRequest {
|
TelephoneLoginRequest {
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Telephone string `json:"telephone" validate:"required"`
|
Telephone string `json:"telephone" validate:"required"`
|
||||||
TelephoneCode string `json:"telephone_code"`
|
TelephoneCode string `json:"telephone_code"`
|
||||||
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
UserAgent string `header:"User-Agent"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
// Check user is exist request
|
// Check user is exist request
|
||||||
@ -79,6 +87,7 @@ type (
|
|||||||
}
|
}
|
||||||
// User login response
|
// User login response
|
||||||
TelephoneRegisterRequest {
|
TelephoneRegisterRequest {
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Telephone string `json:"telephone" validate:"required"`
|
Telephone string `json:"telephone" validate:"required"`
|
||||||
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
@ -86,16 +95,19 @@ type (
|
|||||||
Code string `json:"code,optional"`
|
Code string `json:"code,optional"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
UserAgent string `header:"User-Agent"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type,optional"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
// User login response
|
// User login response
|
||||||
TelephoneResetPasswordRequest {
|
TelephoneResetPasswordRequest {
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Telephone string `json:"telephone" validate:"required"`
|
Telephone string `json:"telephone" validate:"required"`
|
||||||
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
Code string `json:"code,optional"`
|
Code string `json:"code,optional"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
UserAgent string `header:"User-Agent"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type,optional"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
AppleLoginCallbackRequest {
|
AppleLoginCallbackRequest {
|
||||||
@ -107,11 +119,18 @@ type (
|
|||||||
Code string `form:"code"`
|
Code string `form:"code"`
|
||||||
State string `form:"state"`
|
State string `form:"state"`
|
||||||
}
|
}
|
||||||
|
DeviceLoginRequest {
|
||||||
|
Identifier string `json:"identifier" validate:"required"`
|
||||||
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
|
UserAgent string `json:"user_agent" validate:"required"`
|
||||||
|
CfToken string `json:"cf_token,optional"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@server (
|
@server (
|
||||||
prefix: v1/auth
|
prefix: v1/auth
|
||||||
group: auth
|
group: auth
|
||||||
|
middleware: DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "User login"
|
@doc "User login"
|
||||||
@ -145,6 +164,10 @@ service ppanel {
|
|||||||
@doc "Reset password"
|
@doc "Reset password"
|
||||||
@handler TelephoneResetPassword
|
@handler TelephoneResetPassword
|
||||||
post /reset/telephone (TelephoneResetPasswordRequest) returns (LoginResponse)
|
post /reset/telephone (TelephoneResetPasswordRequest) returns (LoginResponse)
|
||||||
|
|
||||||
|
@doc "Device Login"
|
||||||
|
@handler DeviceLogin
|
||||||
|
post /login/device (DeviceLoginRequest) returns (LoginResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
@server (
|
@server (
|
||||||
|
|||||||
@ -92,6 +92,7 @@ type (
|
|||||||
@server (
|
@server (
|
||||||
prefix: v1/common
|
prefix: v1/common
|
||||||
group: common
|
group: common
|
||||||
|
middleware: DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Get global config"
|
@doc "Get global config"
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import "../types.api"
|
|||||||
@server (
|
@server (
|
||||||
prefix: v1/public/announcement
|
prefix: v1/public/announcement
|
||||||
group: public/announcement
|
group: public/announcement
|
||||||
middleware: AuthMiddleware
|
middleware: AuthMiddleware,DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Query announcement"
|
@doc "Query announcement"
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import "../types.api"
|
|||||||
@server (
|
@server (
|
||||||
prefix: v1/public/document
|
prefix: v1/public/document
|
||||||
group: public/document
|
group: public/document
|
||||||
middleware: AuthMiddleware
|
middleware: AuthMiddleware,DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Get document list"
|
@doc "Get document list"
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import "../types.api"
|
|||||||
@server (
|
@server (
|
||||||
prefix: v1/public/order
|
prefix: v1/public/order
|
||||||
group: public/order
|
group: public/order
|
||||||
middleware: AuthMiddleware
|
middleware: AuthMiddleware,DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Pre create order"
|
@doc "Pre create order"
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import "../types.api"
|
|||||||
@server (
|
@server (
|
||||||
prefix: v1/public/payment
|
prefix: v1/public/payment
|
||||||
group: public/payment
|
group: public/payment
|
||||||
middleware: AuthMiddleware
|
middleware: AuthMiddleware,DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Get available payment methods"
|
@doc "Get available payment methods"
|
||||||
|
|||||||
@ -70,6 +70,7 @@ type (
|
|||||||
@server (
|
@server (
|
||||||
prefix: v1/public/portal
|
prefix: v1/public/portal
|
||||||
group: public/portal
|
group: public/portal
|
||||||
|
middleware: DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Get available payment methods"
|
@doc "Get available payment methods"
|
||||||
|
|||||||
@ -14,16 +14,57 @@ type (
|
|||||||
QuerySubscribeListRequest {
|
QuerySubscribeListRequest {
|
||||||
Language string `form:"language"`
|
Language string `form:"language"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryUserSubscribeNodeListResponse {
|
||||||
|
List []UserSubscribeInfo `json:"list"`
|
||||||
|
}
|
||||||
|
|
||||||
|
UserSubscribeInfo {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
UserId int64 `json:"user_id"`
|
||||||
|
OrderId int64 `json:"order_id"`
|
||||||
|
SubscribeId int64 `json:"subscribe_id"`
|
||||||
|
StartTime int64 `json:"start_time"`
|
||||||
|
ExpireTime int64 `json:"expire_time"`
|
||||||
|
FinishedAt int64 `json:"finished_at"`
|
||||||
|
ResetTime int64 `json:"reset_time"`
|
||||||
|
Traffic int64 `json:"traffic"`
|
||||||
|
Download int64 `json:"download"`
|
||||||
|
Upload int64 `json:"upload"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
Status uint8 `json:"status"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
|
IsTryOut bool `json:"is_try_out"`
|
||||||
|
Nodes []*UserSubscribeNodeInfo `json:"nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
UserSubscribeNodeInfo{
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Uuid string `json:"uuid"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
Port uint16 `json:"port"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
City string `json:"city"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@server (
|
@server (
|
||||||
prefix: v1/public/subscribe
|
prefix: v1/public/subscribe
|
||||||
group: public/subscribe
|
group: public/subscribe
|
||||||
middleware: AuthMiddleware
|
middleware: AuthMiddleware,DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Get subscribe list"
|
@doc "Get subscribe list"
|
||||||
@handler QuerySubscribeList
|
@handler QuerySubscribeList
|
||||||
get /list (QuerySubscribeListRequest) returns (QuerySubscribeListResponse)
|
get /list (QuerySubscribeListRequest) returns (QuerySubscribeListResponse)
|
||||||
|
|
||||||
|
@doc "Get user subscribe node info"
|
||||||
|
@handler QueryUserSubscribeNodeList
|
||||||
|
get /node/list returns (QueryUserSubscribeNodeListResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ type (
|
|||||||
@server (
|
@server (
|
||||||
prefix: v1/public/ticket
|
prefix: v1/public/ticket
|
||||||
group: public/ticket
|
group: public/ticket
|
||||||
middleware: AuthMiddleware
|
middleware: AuthMiddleware,DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Get ticket list"
|
@doc "Get ticket list"
|
||||||
|
|||||||
@ -97,12 +97,21 @@ type (
|
|||||||
Email string `json:"email" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Code string `json:"code" validate:"required"`
|
Code string `json:"code" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetDeviceListResponse {
|
||||||
|
List []UserDevice `json:"list"`
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
|
UnbindDeviceRequest {
|
||||||
|
Id int64 `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@server (
|
@server (
|
||||||
prefix: v1/public/user
|
prefix: v1/public/user
|
||||||
group: public/user
|
group: public/user
|
||||||
middleware: AuthMiddleware
|
middleware: AuthMiddleware,DeviceMiddleware
|
||||||
)
|
)
|
||||||
service ppanel {
|
service ppanel {
|
||||||
@doc "Query User Info"
|
@doc "Query User Info"
|
||||||
@ -192,5 +201,13 @@ service ppanel {
|
|||||||
@doc "Update Bind Email"
|
@doc "Update Bind Email"
|
||||||
@handler UpdateBindEmail
|
@handler UpdateBindEmail
|
||||||
put /bind_email (UpdateBindEmailRequest)
|
put /bind_email (UpdateBindEmailRequest)
|
||||||
|
|
||||||
|
@doc "Get Device List"
|
||||||
|
@handler GetDeviceList
|
||||||
|
get /devices returns (GetDeviceListResponse)
|
||||||
|
|
||||||
|
@doc "Unbind Device"
|
||||||
|
@handler UnbindDevice
|
||||||
|
put /unbind_device (UnbindDeviceRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -115,6 +115,7 @@ type (
|
|||||||
AuthConfig {
|
AuthConfig {
|
||||||
Mobile MobileAuthenticateConfig `json:"mobile"`
|
Mobile MobileAuthenticateConfig `json:"mobile"`
|
||||||
Email EmailAuthticateConfig `json:"email"`
|
Email EmailAuthticateConfig `json:"email"`
|
||||||
|
Device DeviceAuthticateConfig `json:"device"`
|
||||||
Register PubilcRegisterConfig `json:"register"`
|
Register PubilcRegisterConfig `json:"register"`
|
||||||
}
|
}
|
||||||
PubilcRegisterConfig {
|
PubilcRegisterConfig {
|
||||||
@ -134,6 +135,14 @@ type (
|
|||||||
EnableDomainSuffix bool `json:"enable_domain_suffix"`
|
EnableDomainSuffix bool `json:"enable_domain_suffix"`
|
||||||
DomainSuffixList string `json:"domain_suffix_list"`
|
DomainSuffixList string `json:"domain_suffix_list"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceAuthticateConfig {
|
||||||
|
Enable bool `json:"enable"`
|
||||||
|
ShowAds bool `json:"show_ads"`
|
||||||
|
EnableSecurity bool `json:"enable_security"`
|
||||||
|
OnlyRealDevice bool `json:"only_real_device"`
|
||||||
|
}
|
||||||
|
|
||||||
RegisterConfig {
|
RegisterConfig {
|
||||||
StopRegister bool `json:"stop_register"`
|
StopRegister bool `json:"stop_register"`
|
||||||
EnableTrial bool `json:"enable_trial"`
|
EnableTrial bool `json:"enable_trial"`
|
||||||
@ -178,6 +187,7 @@ type (
|
|||||||
ForcedInvite bool `json:"forced_invite"`
|
ForcedInvite bool `json:"forced_invite"`
|
||||||
ReferralPercentage int64 `json:"referral_percentage"`
|
ReferralPercentage int64 `json:"referral_percentage"`
|
||||||
OnlyFirstPurchase bool `json:"only_first_purchase"`
|
OnlyFirstPurchase bool `json:"only_first_purchase"`
|
||||||
|
GiftDays int64 `json:"gift_days"`
|
||||||
}
|
}
|
||||||
TelegramConfig {
|
TelegramConfig {
|
||||||
TelegramBotToken string `json:"telegram_bot_token"`
|
TelegramBotToken string `json:"telegram_bot_token"`
|
||||||
@ -197,8 +207,8 @@ type (
|
|||||||
CurrencySymbol string `json:"currency_symbol"`
|
CurrencySymbol string `json:"currency_symbol"`
|
||||||
}
|
}
|
||||||
SubscribeDiscount {
|
SubscribeDiscount {
|
||||||
Quantity int64 `json:"quantity"`
|
Quantity int64 `json:"quantity"`
|
||||||
Discount int64 `json:"discount"`
|
Discount float64 `json:"discount"`
|
||||||
}
|
}
|
||||||
Subscribe {
|
Subscribe {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
@ -647,7 +657,7 @@ type (
|
|||||||
// public announcement
|
// public announcement
|
||||||
QueryAnnouncementRequest {
|
QueryAnnouncementRequest {
|
||||||
Page int `form:"page"`
|
Page int `form:"page"`
|
||||||
Size int `form:"size"`
|
Size int `form:"size,default=15"`
|
||||||
Pinned *bool `form:"pinned"`
|
Pinned *bool `form:"pinned"`
|
||||||
Popup *bool `form:"popup"`
|
Popup *bool `form:"popup"`
|
||||||
}
|
}
|
||||||
@ -664,6 +674,7 @@ type (
|
|||||||
List []SubscribeGroup `json:"list"`
|
List []SubscribeGroup `json:"list"`
|
||||||
Total int64 `json:"total"`
|
Total int64 `json:"total"`
|
||||||
}
|
}
|
||||||
|
|
||||||
GetUserSubscribeTrafficLogsRequest {
|
GetUserSubscribeTrafficLogsRequest {
|
||||||
Page int `form:"page"`
|
Page int `form:"page"`
|
||||||
Size int `form:"size"`
|
Size int `form:"size"`
|
||||||
|
|||||||
4
build.bat
Normal file
4
build.bat
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
SET CGO_ENABLED=0
|
||||||
|
SET GOOS=linux
|
||||||
|
SET GOARCH=amd64
|
||||||
|
go build -o ppanel .\ppanel.go
|
||||||
26
initialize/device.go
Normal file
26
initialize/device.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/config"
|
||||||
|
"github.com/perfect-panel/server/internal/model/auth"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/pkg/tool"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Device(ctx *svc.ServiceContext) {
|
||||||
|
logger.Debug("device config initialization")
|
||||||
|
method, err := ctx.AuthModel.FindOneByMethod(context.Background(), "device")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var cfg config.DeviceConfig
|
||||||
|
var deviceConfig auth.DeviceConfig
|
||||||
|
deviceConfig.Unmarshal(method.Config)
|
||||||
|
tool.DeepCopy(&cfg, deviceConfig)
|
||||||
|
cfg.Enable = *method.Enabled
|
||||||
|
ctx.Config.Device = cfg
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ func StartInitSystemConfig(svc *svc.ServiceContext) {
|
|||||||
Site(svc)
|
Site(svc)
|
||||||
Node(svc)
|
Node(svc)
|
||||||
Email(svc)
|
Email(svc)
|
||||||
|
Device(svc)
|
||||||
Invite(svc)
|
Invite(svc)
|
||||||
Verify(svc)
|
Verify(svc)
|
||||||
Subscribe(svc)
|
Subscribe(svc)
|
||||||
|
|||||||
2
initialize/migrate/database/02115_ads.up.sql
Normal file
2
initialize/migrate/database/02115_ads.up.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `ads`
|
||||||
|
ADD COLUMN `description` VARCHAR(255) DEFAULT '' COMMENT 'Description';
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
INSERT INTO `ppanel`.`system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
|
||||||
|
SELECT 'site', 'CustomData', '{
|
||||||
|
"kr_website_id": ""
|
||||||
|
}', 'string', 'Custom Data', '2025-04-22 14:25:16.637', '2025-10-14 15:47:19.187'
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM `ppanel`.`system` WHERE `category` = 'site' AND `key` = 'CustomData'
|
||||||
|
);
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
INSERT INTO `ppanel`.`system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`)
|
||||||
|
SELECT 'site', 'CustomData', '{
|
||||||
|
"kr_website_id": ""
|
||||||
|
}', 'string', 'Custom Data', '2025-04-22 14:25:16.637', '2025-10-14 15:47:19.187'
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM `ppanel`.`system` WHERE `category` = 'site' AND `key` = 'CustomData'
|
||||||
|
);
|
||||||
@ -2,6 +2,7 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
"github.com/perfect-panel/server/pkg/orm"
|
"github.com/perfect-panel/server/pkg/orm"
|
||||||
)
|
)
|
||||||
@ -20,6 +21,7 @@ type Config struct {
|
|||||||
Node NodeConfig `yaml:"Node"`
|
Node NodeConfig `yaml:"Node"`
|
||||||
Mobile MobileConfig `yaml:"Mobile"`
|
Mobile MobileConfig `yaml:"Mobile"`
|
||||||
Email EmailConfig `yaml:"Email"`
|
Email EmailConfig `yaml:"Email"`
|
||||||
|
Device DeviceConfig `yaml:"device"`
|
||||||
Verify Verify `yaml:"Verify"`
|
Verify Verify `yaml:"Verify"`
|
||||||
VerifyCode VerifyCode `yaml:"VerifyCode"`
|
VerifyCode VerifyCode `yaml:"VerifyCode"`
|
||||||
Register RegisterConfig `yaml:"Register"`
|
Register RegisterConfig `yaml:"Register"`
|
||||||
@ -95,6 +97,14 @@ type MobileConfig struct {
|
|||||||
Whitelist []string `yaml:"whitelist"`
|
Whitelist []string `yaml:"whitelist"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeviceConfig struct {
|
||||||
|
Enable bool `yaml:"enable" default:"true"`
|
||||||
|
ShowAds bool `yaml:"show_ads"`
|
||||||
|
EnableSecurity bool `yaml:"enable_security"`
|
||||||
|
OnlyRealDevice bool `yaml:"only_real_device"`
|
||||||
|
SecuritySecret string `yaml:"security_secret"`
|
||||||
|
}
|
||||||
|
|
||||||
type SiteConfig struct {
|
type SiteConfig struct {
|
||||||
Host string `yaml:"Host" default:""`
|
Host string `yaml:"Host" default:""`
|
||||||
SiteName string `yaml:"SiteName" default:""`
|
SiteName string `yaml:"SiteName" default:""`
|
||||||
@ -193,6 +203,7 @@ type InviteConfig struct {
|
|||||||
ForcedInvite bool `yaml:"ForcedInvite" default:"false"`
|
ForcedInvite bool `yaml:"ForcedInvite" default:"false"`
|
||||||
ReferralPercentage int64 `yaml:"ReferralPercentage" default:"0"`
|
ReferralPercentage int64 `yaml:"ReferralPercentage" default:"0"`
|
||||||
OnlyFirstPurchase bool `yaml:"OnlyFirstPurchase" default:"false"`
|
OnlyFirstPurchase bool `yaml:"OnlyFirstPurchase" default:"false"`
|
||||||
|
GiftDays int64 `yaml:"GiftDays" default:"3"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Telegram struct {
|
type Telegram struct {
|
||||||
|
|||||||
26
internal/handler/auth/deviceLoginHandler.go
Normal file
26
internal/handler/auth/deviceLoginHandler.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/perfect-panel/server/internal/logic/auth"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/internal/types"
|
||||||
|
"github.com/perfect-panel/server/pkg/result"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device Login
|
||||||
|
func DeviceLoginHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
var req types.DeviceLoginRequest
|
||||||
|
_ = c.ShouldBind(&req)
|
||||||
|
validateErr := svcCtx.Validate(&req)
|
||||||
|
if validateErr != nil {
|
||||||
|
result.ParamErrorResult(c, validateErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := auth.NewDeviceLoginLogic(c.Request.Context(), svcCtx)
|
||||||
|
resp, err := l.DeviceLogin(&req)
|
||||||
|
result.HttpResult(c, resp, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package subscribe
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/perfect-panel/server/internal/logic/public/subscribe"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/pkg/result"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get user subscribe node info
|
||||||
|
func QueryUserSubscribeNodeListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
|
||||||
|
l := subscribe.NewQueryUserSubscribeNodeListLogic(c.Request.Context(), svcCtx)
|
||||||
|
resp, err := l.QueryUserSubscribeNodeList()
|
||||||
|
result.HttpResult(c, resp, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
18
internal/handler/public/user/getDeviceListHandler.go
Normal file
18
internal/handler/public/user/getDeviceListHandler.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/perfect-panel/server/internal/logic/public/user"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/pkg/result"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get Device List
|
||||||
|
func GetDeviceListHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
|
||||||
|
l := user.NewGetDeviceListLogic(c.Request.Context(), svcCtx)
|
||||||
|
resp, err := l.GetDeviceList()
|
||||||
|
result.HttpResult(c, resp, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
internal/handler/public/user/unbindDeviceHandler.go
Normal file
26
internal/handler/public/user/unbindDeviceHandler.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/perfect-panel/server/internal/logic/public/user"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/internal/types"
|
||||||
|
"github.com/perfect-panel/server/pkg/result"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unbind Device
|
||||||
|
func UnbindDeviceHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
var req types.UnbindDeviceRequest
|
||||||
|
_ = c.ShouldBind(&req)
|
||||||
|
validateErr := svcCtx.Validate(&req)
|
||||||
|
if validateErr != nil {
|
||||||
|
result.ParamErrorResult(c, validateErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := user.NewUnbindDeviceLogic(c.Request.Context(), svcCtx)
|
||||||
|
err := l.UnbindDevice(&req)
|
||||||
|
result.HttpResult(c, nil, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -578,6 +578,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
authGroupRouter := router.Group("/v1/auth")
|
authGroupRouter := router.Group("/v1/auth")
|
||||||
|
authGroupRouter.Use(middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Check user is exist
|
// Check user is exist
|
||||||
@ -589,6 +590,9 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
// User login
|
// User login
|
||||||
authGroupRouter.POST("/login", auth.UserLoginHandler(serverCtx))
|
authGroupRouter.POST("/login", auth.UserLoginHandler(serverCtx))
|
||||||
|
|
||||||
|
// Device Login
|
||||||
|
authGroupRouter.POST("/login/device", auth.DeviceLoginHandler(serverCtx))
|
||||||
|
|
||||||
// User Telephone login
|
// User Telephone login
|
||||||
authGroupRouter.POST("/login/telephone", auth.TelephoneLoginHandler(serverCtx))
|
authGroupRouter.POST("/login/telephone", auth.TelephoneLoginHandler(serverCtx))
|
||||||
|
|
||||||
@ -619,6 +623,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
commonGroupRouter := router.Group("/v1/common")
|
commonGroupRouter := router.Group("/v1/common")
|
||||||
|
commonGroupRouter.Use(middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get Ads
|
// Get Ads
|
||||||
@ -650,7 +655,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publicAnnouncementGroupRouter := router.Group("/v1/public/announcement")
|
publicAnnouncementGroupRouter := router.Group("/v1/public/announcement")
|
||||||
publicAnnouncementGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicAnnouncementGroupRouter.Use(middleware.AuthMiddleware(serverCtx), middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Query announcement
|
// Query announcement
|
||||||
@ -658,7 +663,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publicDocumentGroupRouter := router.Group("/v1/public/document")
|
publicDocumentGroupRouter := router.Group("/v1/public/document")
|
||||||
publicDocumentGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicDocumentGroupRouter.Use(middleware.AuthMiddleware(serverCtx), middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get document detail
|
// Get document detail
|
||||||
@ -669,7 +674,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publicOrderGroupRouter := router.Group("/v1/public/order")
|
publicOrderGroupRouter := router.Group("/v1/public/order")
|
||||||
publicOrderGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicOrderGroupRouter.Use(middleware.AuthMiddleware(serverCtx), middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Close order
|
// Close order
|
||||||
@ -698,7 +703,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publicPaymentGroupRouter := router.Group("/v1/public/payment")
|
publicPaymentGroupRouter := router.Group("/v1/public/payment")
|
||||||
publicPaymentGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicPaymentGroupRouter.Use(middleware.AuthMiddleware(serverCtx), middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get available payment methods
|
// Get available payment methods
|
||||||
@ -706,6 +711,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publicPortalGroupRouter := router.Group("/v1/public/portal")
|
publicPortalGroupRouter := router.Group("/v1/public/portal")
|
||||||
|
publicPortalGroupRouter.Use(middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Purchase Checkout
|
// Purchase Checkout
|
||||||
@ -728,15 +734,18 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publicSubscribeGroupRouter := router.Group("/v1/public/subscribe")
|
publicSubscribeGroupRouter := router.Group("/v1/public/subscribe")
|
||||||
publicSubscribeGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicSubscribeGroupRouter.Use(middleware.AuthMiddleware(serverCtx), middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get subscribe list
|
// Get subscribe list
|
||||||
publicSubscribeGroupRouter.GET("/list", publicSubscribe.QuerySubscribeListHandler(serverCtx))
|
publicSubscribeGroupRouter.GET("/list", publicSubscribe.QuerySubscribeListHandler(serverCtx))
|
||||||
|
|
||||||
|
// Get user subscribe node info
|
||||||
|
publicSubscribeGroupRouter.GET("/node/list", publicSubscribe.QueryUserSubscribeNodeListHandler(serverCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
publicTicketGroupRouter := router.Group("/v1/public/ticket")
|
publicTicketGroupRouter := router.Group("/v1/public/ticket")
|
||||||
publicTicketGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicTicketGroupRouter.Use(middleware.AuthMiddleware(serverCtx), middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Update ticket status
|
// Update ticket status
|
||||||
@ -756,7 +765,7 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publicUserGroupRouter := router.Group("/v1/public/user")
|
publicUserGroupRouter := router.Group("/v1/public/user")
|
||||||
publicUserGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
|
publicUserGroupRouter.Use(middleware.AuthMiddleware(serverCtx), middleware.DeviceMiddleware(serverCtx))
|
||||||
|
|
||||||
{
|
{
|
||||||
// Query User Affiliate Count
|
// Query User Affiliate Count
|
||||||
@ -786,6 +795,9 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
// Query User Commission Log
|
// Query User Commission Log
|
||||||
publicUserGroupRouter.GET("/commission_log", publicUser.QueryUserCommissionLogHandler(serverCtx))
|
publicUserGroupRouter.GET("/commission_log", publicUser.QueryUserCommissionLogHandler(serverCtx))
|
||||||
|
|
||||||
|
// Get Device List
|
||||||
|
publicUserGroupRouter.GET("/devices", publicUser.GetDeviceListHandler(serverCtx))
|
||||||
|
|
||||||
// Query User Info
|
// Query User Info
|
||||||
publicUserGroupRouter.GET("/info", publicUser.QueryUserInfoHandler(serverCtx))
|
publicUserGroupRouter.GET("/info", publicUser.QueryUserInfoHandler(serverCtx))
|
||||||
|
|
||||||
@ -810,6 +822,9 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
// Reset User Subscribe Token
|
// Reset User Subscribe Token
|
||||||
publicUserGroupRouter.PUT("/subscribe_token", publicUser.ResetUserSubscribeTokenHandler(serverCtx))
|
publicUserGroupRouter.PUT("/subscribe_token", publicUser.ResetUserSubscribeTokenHandler(serverCtx))
|
||||||
|
|
||||||
|
// Unbind Device
|
||||||
|
publicUserGroupRouter.PUT("/unbind_device", publicUser.UnbindDeviceHandler(serverCtx))
|
||||||
|
|
||||||
// Unbind OAuth
|
// Unbind OAuth
|
||||||
publicUserGroupRouter.POST("/unbind_oauth", publicUser.UnbindOAuthHandler(serverCtx))
|
publicUserGroupRouter.POST("/unbind_oauth", publicUser.UnbindOAuthHandler(serverCtx))
|
||||||
|
|
||||||
@ -846,10 +861,10 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
|
|||||||
serverGroupRouter.GET("/user", server.GetServerUserListHandler(serverCtx))
|
serverGroupRouter.GET("/user", server.GetServerUserListHandler(serverCtx))
|
||||||
}
|
}
|
||||||
|
|
||||||
serverV2GroupRouter := router.Group("/v2/server")
|
serverGroupRouterV2 := router.Group("/v2/server")
|
||||||
|
|
||||||
{
|
{
|
||||||
// Get Server Protocol Config
|
// Get Server Protocol Config
|
||||||
serverV2GroupRouter.GET("/:server_id", server.QueryServerProtocolConfigHandler(serverCtx))
|
serverGroupRouterV2.GET("/:server_id", server.QueryServerProtocolConfigHandler(serverCtx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,6 +92,9 @@ func (l *UpdateAuthMethodConfigLogic) UpdateGlobal(method string) {
|
|||||||
if method == "mobile" {
|
if method == "mobile" {
|
||||||
initialize.Mobile(l.svcCtx)
|
initialize.Mobile(l.svcCtx)
|
||||||
}
|
}
|
||||||
|
if method == "device" {
|
||||||
|
initialize.Device(l.svcCtx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func validatePlatformConfig(platform string, cfg map[string]interface{}) (interface{}, error) {
|
func validatePlatformConfig(platform string, cfg map[string]interface{}) (interface{}, error) {
|
||||||
|
|||||||
314
internal/logic/auth/bindDeviceLogic.go
Normal file
314
internal/logic/auth/bindDeviceLogic.go
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/model/user"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BindDeviceLogic struct {
|
||||||
|
logger.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBindDeviceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BindDeviceLogic {
|
||||||
|
return &BindDeviceLogic{
|
||||||
|
Logger: logger.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindDeviceToUser binds a device to a user
|
||||||
|
// If the device is already bound to another user, it will disable that user and bind the device to the current user
|
||||||
|
func (l *BindDeviceLogic) BindDeviceToUser(identifier, ip, userAgent string, currentUserId int64) error {
|
||||||
|
if identifier == "" {
|
||||||
|
// No device identifier provided, skip binding
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Infow("binding device to user",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("user_id", currentUserId),
|
||||||
|
logger.Field("ip", ip),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Check if device exists
|
||||||
|
deviceInfo, err := l.svcCtx.UserModel.FindOneDeviceByIdentifier(l.ctx, identifier)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
// Device not found, create new device record
|
||||||
|
return l.createDeviceForUser(identifier, ip, userAgent, currentUserId)
|
||||||
|
}
|
||||||
|
l.Errorw("failed to query device",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query device failed: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device exists, check if it's bound to current user
|
||||||
|
if deviceInfo.UserId == currentUserId {
|
||||||
|
// Already bound to current user, just update IP and UserAgent
|
||||||
|
l.Infow("device already bound to current user, updating info",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("user_id", currentUserId),
|
||||||
|
)
|
||||||
|
deviceInfo.Ip = ip
|
||||||
|
deviceInfo.UserAgent = userAgent
|
||||||
|
if err := l.svcCtx.UserModel.UpdateDevice(l.ctx, deviceInfo); err != nil {
|
||||||
|
l.Errorw("failed to update device",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update device failed: %v", err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device is bound to another user, need to disable old user and rebind
|
||||||
|
l.Infow("device bound to another user, rebinding",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("old_user_id", deviceInfo.UserId),
|
||||||
|
logger.Field("new_user_id", currentUserId),
|
||||||
|
)
|
||||||
|
|
||||||
|
return l.rebindDeviceToNewUser(deviceInfo, ip, userAgent, currentUserId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *BindDeviceLogic) createDeviceForUser(identifier, ip, userAgent string, userId int64) error {
|
||||||
|
l.Infow("creating new device for user",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
)
|
||||||
|
|
||||||
|
err := l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
||||||
|
// Create device auth method
|
||||||
|
authMethod := &user.AuthMethods{
|
||||||
|
UserId: userId,
|
||||||
|
AuthType: "device",
|
||||||
|
AuthIdentifier: identifier,
|
||||||
|
Verified: true,
|
||||||
|
}
|
||||||
|
if err := db.Create(authMethod).Error; err != nil {
|
||||||
|
l.Errorw("failed to create device auth method",
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create device auth method failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create device record
|
||||||
|
deviceInfo := &user.Device{
|
||||||
|
Ip: ip,
|
||||||
|
UserId: userId,
|
||||||
|
UserAgent: userAgent,
|
||||||
|
Identifier: identifier,
|
||||||
|
Enabled: true,
|
||||||
|
Online: false,
|
||||||
|
}
|
||||||
|
if err := db.Create(deviceInfo).Error; err != nil {
|
||||||
|
l.Errorw("failed to create device",
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create device failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("device creation failed",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Infow("device created successfully",
|
||||||
|
logger.Field("identifier", identifier),
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *BindDeviceLogic) rebindDeviceToNewUser(deviceInfo *user.Device, ip, userAgent string, newUserId int64) error {
|
||||||
|
oldUserId := deviceInfo.UserId
|
||||||
|
|
||||||
|
err := l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
||||||
|
// Check if old user has other auth methods besides device
|
||||||
|
var authMethods []user.AuthMethods
|
||||||
|
if err := db.Where("user_id = ?", oldUserId).Find(&authMethods).Error; err != nil {
|
||||||
|
l.Errorw("failed to query auth methods for old user",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query auth methods failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count non-device auth methods
|
||||||
|
nonDeviceAuthCount := 0
|
||||||
|
for _, auth := range authMethods {
|
||||||
|
if auth.AuthType != "device" {
|
||||||
|
nonDeviceAuthCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only disable old user if they have no other auth methods
|
||||||
|
if nonDeviceAuthCount == 0 {
|
||||||
|
// Migrate user data from old user to new user before disabling
|
||||||
|
if err := l.migrateUserData(db, oldUserId, newUserId); err != nil {
|
||||||
|
l.Errorw("failed to migrate user data",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "migrate user data failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
falseVal := false
|
||||||
|
if err := db.Model(&user.User{}).Where("id = ?", oldUserId).Update("enable", &falseVal).Error; err != nil {
|
||||||
|
l.Errorw("failed to disable old user",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "disable old user failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Infow("disabled old user after data migration (no other auth methods)",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
l.Infow("old user has other auth methods, not disabling",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("non_device_auth_count", nonDeviceAuthCount),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update device auth method to new user
|
||||||
|
if err := db.Model(&user.AuthMethods{}).
|
||||||
|
Where("auth_type = ? AND auth_identifier = ?", "device", deviceInfo.Identifier).
|
||||||
|
Update("user_id", newUserId).Error; err != nil {
|
||||||
|
l.Errorw("failed to update device auth method",
|
||||||
|
logger.Field("identifier", deviceInfo.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update device auth method failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update device record
|
||||||
|
deviceInfo.UserId = newUserId
|
||||||
|
deviceInfo.Ip = ip
|
||||||
|
deviceInfo.UserAgent = userAgent
|
||||||
|
deviceInfo.Enabled = true
|
||||||
|
|
||||||
|
if err := db.Save(deviceInfo).Error; err != nil {
|
||||||
|
l.Errorw("failed to update device",
|
||||||
|
logger.Field("identifier", deviceInfo.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update device failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("device rebinding failed",
|
||||||
|
logger.Field("identifier", deviceInfo.Identifier),
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Infow("device rebound successfully",
|
||||||
|
logger.Field("identifier", deviceInfo.Identifier),
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// migrateUserData migrates user data from old user to new user
|
||||||
|
// This includes orders, subscriptions, balance, and other user-related data
|
||||||
|
func (l *BindDeviceLogic) migrateUserData(db *gorm.DB, oldUserId, newUserId int64) error {
|
||||||
|
l.Infow("starting user data migration",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Migrate orders - using table name directly
|
||||||
|
if err := db.Table("order").Where("user_id = ?", oldUserId).Update("user_id", newUserId).Error; err != nil {
|
||||||
|
l.Errorw("failed to migrate orders",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate user subscriptions - using Subscribe model
|
||||||
|
if err := db.Model(&user.Subscribe{}).Where("user_id = ?", oldUserId).Update("user_id", newUserId).Error; err != nil {
|
||||||
|
l.Errorw("failed to migrate user subscriptions",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate user balance and gift amount
|
||||||
|
var oldUser user.User
|
||||||
|
if err := db.Where("id = ?", oldUserId).First(&oldUser).Error; err != nil {
|
||||||
|
l.Errorw("failed to get old user data",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add old user's balance and gift to new user
|
||||||
|
if oldUser.Balance > 0 || oldUser.GiftAmount > 0 {
|
||||||
|
if err := db.Model(&user.User{}).Where("id = ?", newUserId).Updates(map[string]interface{}{
|
||||||
|
"balance": gorm.Expr("balance + ?", oldUser.Balance),
|
||||||
|
"gift_amount": gorm.Expr("gift_amount + ?", oldUser.GiftAmount),
|
||||||
|
}).Error; err != nil {
|
||||||
|
l.Errorw("failed to migrate user balance and gift",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
logger.Field("old_balance", oldUser.Balance),
|
||||||
|
logger.Field("old_gift", oldUser.GiftAmount),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate other user-related tables if needed
|
||||||
|
// Note: We don't migrate auth methods as they are handled separately
|
||||||
|
// Note: Traffic usage (Upload/Download) is tracked at subscription level, not user level
|
||||||
|
|
||||||
|
l.Infow("user data migration completed",
|
||||||
|
logger.Field("old_user_id", oldUserId),
|
||||||
|
logger.Field("new_user_id", newUserId),
|
||||||
|
logger.Field("migrated_balance", oldUser.Balance),
|
||||||
|
logger.Field("migrated_gift", oldUser.GiftAmount),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
293
internal/logic/auth/deviceLoginLogic.go
Normal file
293
internal/logic/auth/deviceLoginLogic.go
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/config"
|
||||||
|
"github.com/perfect-panel/server/internal/model/log"
|
||||||
|
"github.com/perfect-panel/server/internal/model/user"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/internal/types"
|
||||||
|
"github.com/perfect-panel/server/pkg/jwt"
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
"github.com/perfect-panel/server/pkg/tool"
|
||||||
|
"github.com/perfect-panel/server/pkg/uuidx"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeviceLoginLogic struct {
|
||||||
|
logger.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device Login
|
||||||
|
func NewDeviceLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeviceLoginLogic {
|
||||||
|
return &DeviceLoginLogic{
|
||||||
|
Logger: logger.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DeviceLoginLogic) DeviceLogin(req *types.DeviceLoginRequest) (resp *types.LoginResponse, err error) {
|
||||||
|
if !l.svcCtx.Config.Device.Enable {
|
||||||
|
return nil, xerr.NewErrMsg("Device login is disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
loginStatus := false
|
||||||
|
var userInfo *user.User
|
||||||
|
// Record login status
|
||||||
|
defer func() {
|
||||||
|
if userInfo != nil && userInfo.Id != 0 {
|
||||||
|
loginLog := log.Login{
|
||||||
|
Method: "device",
|
||||||
|
LoginIP: req.IP,
|
||||||
|
UserAgent: req.UserAgent,
|
||||||
|
Success: loginStatus,
|
||||||
|
Timestamp: time.Now().UnixMilli(),
|
||||||
|
}
|
||||||
|
content, _ := loginLog.Marshal()
|
||||||
|
if err := l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||||
|
Type: log.TypeLogin.Uint8(),
|
||||||
|
Date: time.Now().Format("2006-01-02"),
|
||||||
|
ObjectID: userInfo.Id,
|
||||||
|
Content: string(content),
|
||||||
|
}); err != nil {
|
||||||
|
l.Errorw("failed to insert login log",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("ip", req.IP),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Check if device exists by identifier
|
||||||
|
deviceInfo, err := l.svcCtx.UserModel.FindOneDeviceByIdentifier(l.ctx, req.Identifier)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
// Device not found, create new user and device
|
||||||
|
userInfo, err = l.registerUserAndDevice(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
l.Errorw("query device failed",
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query device failed: %v", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Device found, get user info
|
||||||
|
userInfo, err = l.svcCtx.UserModel.FindOne(l.ctx, deviceInfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("query user failed",
|
||||||
|
logger.Field("user_id", deviceInfo.UserId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query user failed: %v", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate session id
|
||||||
|
sessionId := uuidx.NewUUID().String()
|
||||||
|
|
||||||
|
// Generate token
|
||||||
|
token, err := jwt.NewJwtToken(
|
||||||
|
l.svcCtx.Config.JwtAuth.AccessSecret,
|
||||||
|
time.Now().Unix(),
|
||||||
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
|
jwt.WithOption("UserId", userInfo.Id),
|
||||||
|
jwt.WithOption("SessionId", sessionId),
|
||||||
|
jwt.WithOption("LoginType", "device"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("token generate error",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "token generate error: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store session id in redis
|
||||||
|
sessionIdCacheKey := fmt.Sprintf("%v:%v", config.SessionIdKey, sessionId)
|
||||||
|
if err = l.svcCtx.Redis.Set(l.ctx, sessionIdCacheKey, userInfo.Id, time.Duration(l.svcCtx.Config.JwtAuth.AccessExpire)*time.Second).Err(); err != nil {
|
||||||
|
l.Errorw("set session id error",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "set session id error: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
loginStatus = true
|
||||||
|
return &types.LoginResponse{
|
||||||
|
Token: token,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DeviceLoginLogic) registerUserAndDevice(req *types.DeviceLoginRequest) (*user.User, error) {
|
||||||
|
l.Infow("device not found, creating new user and device",
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("ip", req.IP),
|
||||||
|
)
|
||||||
|
|
||||||
|
var userInfo *user.User
|
||||||
|
err := l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
||||||
|
// Create new user
|
||||||
|
userInfo = &user.User{
|
||||||
|
OnlyFirstPurchase: &l.svcCtx.Config.Invite.OnlyFirstPurchase,
|
||||||
|
}
|
||||||
|
if err := db.Create(userInfo).Error; err != nil {
|
||||||
|
l.Errorw("failed to create user",
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create user failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update refer code
|
||||||
|
userInfo.ReferCode = uuidx.UserInviteCode(userInfo.Id)
|
||||||
|
if err := db.Model(&user.User{}).Where("id = ?", userInfo.Id).Update("refer_code", userInfo.ReferCode).Error; err != nil {
|
||||||
|
l.Errorw("failed to update refer code",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update refer code failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create device auth method
|
||||||
|
authMethod := &user.AuthMethods{
|
||||||
|
UserId: userInfo.Id,
|
||||||
|
AuthType: "device",
|
||||||
|
AuthIdentifier: req.Identifier,
|
||||||
|
Verified: true,
|
||||||
|
}
|
||||||
|
if err := db.Create(authMethod).Error; err != nil {
|
||||||
|
l.Errorw("failed to create device auth method",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "create device auth method failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert device record
|
||||||
|
deviceInfo := &user.Device{
|
||||||
|
Ip: req.IP,
|
||||||
|
UserId: userInfo.Id,
|
||||||
|
UserAgent: req.UserAgent,
|
||||||
|
Identifier: req.Identifier,
|
||||||
|
Enabled: true,
|
||||||
|
Online: false,
|
||||||
|
}
|
||||||
|
if err := db.Create(deviceInfo).Error; err != nil {
|
||||||
|
l.Errorw("failed to insert device",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "insert device failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate trial if enabled
|
||||||
|
if l.svcCtx.Config.Register.EnableTrial {
|
||||||
|
if err := l.activeTrial(userInfo.Id, db); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("device registration failed",
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Infow("device registration completed successfully",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("refer_code", userInfo.ReferCode),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Register log
|
||||||
|
registerLog := log.Register{
|
||||||
|
AuthMethod: "device",
|
||||||
|
Identifier: req.Identifier,
|
||||||
|
RegisterIP: req.IP,
|
||||||
|
UserAgent: req.UserAgent,
|
||||||
|
Timestamp: time.Now().UnixMilli(),
|
||||||
|
}
|
||||||
|
content, _ := registerLog.Marshal()
|
||||||
|
|
||||||
|
if err := l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||||
|
Type: log.TypeRegister.Uint8(),
|
||||||
|
Date: time.Now().Format("2006-01-02"),
|
||||||
|
ObjectID: userInfo.Id,
|
||||||
|
Content: string(content),
|
||||||
|
}); err != nil {
|
||||||
|
l.Errorw("failed to insert register log",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("ip", req.IP),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return userInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DeviceLoginLogic) activeTrial(userId int64, db *gorm.DB) error {
|
||||||
|
sub, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, l.svcCtx.Config.Register.TrialSubscribe)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("failed to find trial subscription template",
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
logger.Field("trial_subscribe_id", l.svcCtx.Config.Register.TrialSubscribe),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime := time.Now()
|
||||||
|
expireTime := tool.AddTime(l.svcCtx.Config.Register.TrialTimeUnit, l.svcCtx.Config.Register.TrialTime, startTime)
|
||||||
|
subscribeToken := uuidx.SubscribeToken(fmt.Sprintf("Trial-%v", userId))
|
||||||
|
subscribeUUID := uuidx.NewUUID().String()
|
||||||
|
|
||||||
|
userSub := &user.Subscribe{
|
||||||
|
UserId: userId,
|
||||||
|
OrderId: 0,
|
||||||
|
SubscribeId: sub.Id,
|
||||||
|
StartTime: startTime,
|
||||||
|
ExpireTime: expireTime,
|
||||||
|
Traffic: sub.Traffic,
|
||||||
|
Download: 0,
|
||||||
|
Upload: 0,
|
||||||
|
Token: subscribeToken,
|
||||||
|
UUID: subscribeUUID,
|
||||||
|
Status: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Create(userSub).Error; err != nil {
|
||||||
|
l.Errorw("failed to insert trial subscription",
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Infow("trial subscription activated successfully",
|
||||||
|
logger.Field("user_id", userId),
|
||||||
|
logger.Field("subscribe_id", sub.Id),
|
||||||
|
logger.Field("expire_time", expireTime),
|
||||||
|
logger.Field("traffic", sub.Traffic),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -107,6 +107,22 @@ func (l *ResetPasswordLogic) ResetPassword(req *types.ResetPasswordRequest) (res
|
|||||||
if err := l.svcCtx.UserModel.Update(l.ctx, userInfo); err != nil {
|
if err := l.svcCtx.UserModel.Update(l.ctx, userInfo); err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update user info failed: %v", err.Error())
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update user info failed: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind device to user if identifier is provided
|
||||||
|
if req.Identifier != "" {
|
||||||
|
bindLogic := NewBindDeviceLogic(l.ctx, l.svcCtx)
|
||||||
|
if err := bindLogic.BindDeviceToUser(req.Identifier, req.IP, req.UserAgent, userInfo.Id); err != nil {
|
||||||
|
l.Errorw("failed to bind device to user",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
// Don't fail register if device binding fails, just log the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.ctx.Value(constant.LoginType) != nil {
|
||||||
|
req.LoginType = l.ctx.Value(constant.LoginType).(string)
|
||||||
|
}
|
||||||
// Generate session id
|
// Generate session id
|
||||||
sessionId := uuidx.NewUUID().String()
|
sessionId := uuidx.NewUUID().String()
|
||||||
// Generate token
|
// Generate token
|
||||||
@ -116,6 +132,7 @@ func (l *ResetPasswordLogic) ResetPassword(req *types.ResetPasswordRequest) (res
|
|||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
jwt.WithOption("UserId", userInfo.Id),
|
||||||
jwt.WithOption("SessionId", sessionId),
|
jwt.WithOption("SessionId", sessionId),
|
||||||
|
jwt.WithOption("LoginType", req.LoginType),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
||||||
|
|||||||
@ -124,6 +124,23 @@ func (l *TelephoneLoginLogic) TelephoneLogin(req *types.TelephoneLoginRequest, r
|
|||||||
l.svcCtx.Redis.Del(l.ctx, cacheKey)
|
l.svcCtx.Redis.Del(l.ctx, cacheKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind device to user if identifier is provided
|
||||||
|
if req.Identifier != "" {
|
||||||
|
bindLogic := NewBindDeviceLogic(l.ctx, l.svcCtx)
|
||||||
|
if err := bindLogic.BindDeviceToUser(req.Identifier, req.IP, req.UserAgent, userInfo.Id); err != nil {
|
||||||
|
l.Errorw("failed to bind device to user",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
// Don't fail login if device binding fails, just log the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.ctx.Value(constant.LoginType) != nil {
|
||||||
|
req.LoginType = l.ctx.Value(constant.LoginType).(string)
|
||||||
|
}
|
||||||
|
|
||||||
// Generate session id
|
// Generate session id
|
||||||
sessionId := uuidx.NewUUID().String()
|
sessionId := uuidx.NewUUID().String()
|
||||||
// Generate token
|
// Generate token
|
||||||
@ -133,6 +150,7 @@ func (l *TelephoneLoginLogic) TelephoneLogin(req *types.TelephoneLoginRequest, r
|
|||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
jwt.WithOption("UserId", userInfo.Id),
|
||||||
jwt.WithOption("SessionId", sessionId),
|
jwt.WithOption("SessionId", sessionId),
|
||||||
|
jwt.WithOption("LoginType", req.LoginType),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
||||||
|
|||||||
@ -83,6 +83,21 @@ func (l *TelephoneResetPasswordLogic) TelephoneResetPassword(req *types.Telephon
|
|||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "update user password failed: %v", err.Error())
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "update user password failed: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind device to user if identifier is provided
|
||||||
|
if req.Identifier != "" {
|
||||||
|
bindLogic := NewBindDeviceLogic(l.ctx, l.svcCtx)
|
||||||
|
if err := bindLogic.BindDeviceToUser(req.Identifier, req.IP, req.UserAgent, userInfo.Id); err != nil {
|
||||||
|
l.Errorw("failed to bind device to user",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
// Don't fail register if device binding fails, just log the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.ctx.Value(constant.LoginType) != nil {
|
||||||
|
req.LoginType = l.ctx.Value(constant.LoginType).(string)
|
||||||
|
}
|
||||||
// Generate session id
|
// Generate session id
|
||||||
sessionId := uuidx.NewUUID().String()
|
sessionId := uuidx.NewUUID().String()
|
||||||
// Generate token
|
// Generate token
|
||||||
@ -92,6 +107,7 @@ func (l *TelephoneResetPasswordLogic) TelephoneResetPassword(req *types.Telephon
|
|||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
jwt.WithOption("UserId", userInfo.Id),
|
||||||
jwt.WithOption("SessionId", sessionId),
|
jwt.WithOption("SessionId", sessionId),
|
||||||
|
jwt.WithOption("LoginType", req.LoginType),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Errorw("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
l.Errorw("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
||||||
|
|||||||
@ -138,6 +138,22 @@ func (l *TelephoneUserRegisterLogic) TelephoneUserRegister(req *types.TelephoneR
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Bind device to user if identifier is provided
|
||||||
|
if req.Identifier != "" {
|
||||||
|
bindLogic := NewBindDeviceLogic(l.ctx, l.svcCtx)
|
||||||
|
if err := bindLogic.BindDeviceToUser(req.Identifier, req.IP, req.UserAgent, userInfo.Id); err != nil {
|
||||||
|
l.Errorw("failed to bind device to user",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
// Don't fail register if device binding fails, just log the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.ctx.Value(constant.LoginType) != nil {
|
||||||
|
req.LoginType = l.ctx.Value(constant.LoginType).(string)
|
||||||
|
}
|
||||||
// Generate session id
|
// Generate session id
|
||||||
sessionId := uuidx.NewUUID().String()
|
sessionId := uuidx.NewUUID().String()
|
||||||
// Generate token
|
// Generate token
|
||||||
@ -147,6 +163,7 @@ func (l *TelephoneUserRegisterLogic) TelephoneUserRegister(req *types.TelephoneR
|
|||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
jwt.WithOption("UserId", userInfo.Id),
|
||||||
jwt.WithOption("SessionId", sessionId),
|
jwt.WithOption("SessionId", sessionId),
|
||||||
|
jwt.WithOption("LoginType", req.LoginType),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/model/log"
|
"github.com/perfect-panel/server/internal/model/log"
|
||||||
|
"github.com/perfect-panel/server/pkg/constant"
|
||||||
"github.com/perfect-panel/server/pkg/logger"
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/config"
|
"github.com/perfect-panel/server/internal/config"
|
||||||
@ -79,6 +80,22 @@ func (l *UserLoginLogic) UserLogin(req *types.UserLoginRequest) (resp *types.Log
|
|||||||
if !tool.VerifyPassWord(req.Password, userInfo.Password) {
|
if !tool.VerifyPassWord(req.Password, userInfo.Password) {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserPasswordError), "user password")
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserPasswordError), "user password")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind device to user if identifier is provided
|
||||||
|
if req.Identifier != "" {
|
||||||
|
bindLogic := NewBindDeviceLogic(l.ctx, l.svcCtx)
|
||||||
|
if err := bindLogic.BindDeviceToUser(req.Identifier, req.IP, req.UserAgent, userInfo.Id); err != nil {
|
||||||
|
l.Errorw("failed to bind device to user",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
// Don't fail login if device binding fails, just log the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.ctx.Value(constant.LoginType) != nil {
|
||||||
|
req.LoginType = l.ctx.Value(constant.LoginType).(string)
|
||||||
|
}
|
||||||
// Generate session id
|
// Generate session id
|
||||||
sessionId := uuidx.NewUUID().String()
|
sessionId := uuidx.NewUUID().String()
|
||||||
// Generate token
|
// Generate token
|
||||||
@ -88,6 +105,7 @@ func (l *UserLoginLogic) UserLogin(req *types.UserLoginRequest) (resp *types.Log
|
|||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
jwt.WithOption("UserId", userInfo.Id),
|
||||||
jwt.WithOption("SessionId", sessionId),
|
jwt.WithOption("SessionId", sessionId),
|
||||||
|
jwt.WithOption("LoginType", req.LoginType),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
||||||
|
|||||||
@ -125,6 +125,21 @@ func (l *UserRegisterLogic) UserRegister(req *types.UserRegisterRequest) (resp *
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
// Bind device to user if identifier is provided
|
||||||
|
if req.Identifier != "" {
|
||||||
|
bindLogic := NewBindDeviceLogic(l.ctx, l.svcCtx)
|
||||||
|
if err := bindLogic.BindDeviceToUser(req.Identifier, req.IP, req.UserAgent, userInfo.Id); err != nil {
|
||||||
|
l.Errorw("failed to bind device to user",
|
||||||
|
logger.Field("user_id", userInfo.Id),
|
||||||
|
logger.Field("identifier", req.Identifier),
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
)
|
||||||
|
// Don't fail register if device binding fails, just log the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.ctx.Value(constant.LoginType) != nil {
|
||||||
|
req.LoginType = l.ctx.Value(constant.LoginType).(string)
|
||||||
|
}
|
||||||
// Generate session id
|
// Generate session id
|
||||||
sessionId := uuidx.NewUUID().String()
|
sessionId := uuidx.NewUUID().String()
|
||||||
// Generate token
|
// Generate token
|
||||||
@ -134,6 +149,7 @@ func (l *UserRegisterLogic) UserRegister(req *types.UserRegisterRequest) (resp *
|
|||||||
l.svcCtx.Config.JwtAuth.AccessExpire,
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
jwt.WithOption("UserId", userInfo.Id),
|
jwt.WithOption("UserId", userInfo.Id),
|
||||||
jwt.WithOption("SessionId", sessionId),
|
jwt.WithOption("SessionId", sessionId),
|
||||||
|
jwt.WithOption("LoginType", req.LoginType),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
l.Logger.Error("[UserLogin] token generate error", logger.Field("error", err.Error()))
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/perfect-panel/server/internal/svc"
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
"github.com/perfect-panel/server/internal/types"
|
"github.com/perfect-panel/server/internal/types"
|
||||||
@ -67,6 +68,10 @@ func (l *GetGlobalConfigLogic) GetGlobalConfig() (resp *types.GetGlobalConfigRes
|
|||||||
for _, method := range authMethods {
|
for _, method := range authMethods {
|
||||||
if *method.Enabled {
|
if *method.Enabled {
|
||||||
methods = append(methods, method.Method)
|
methods = append(methods, method.Method)
|
||||||
|
if method.Method == "device" {
|
||||||
|
_ = json.Unmarshal([]byte(method.Config), &resp.Auth.Device)
|
||||||
|
resp.Auth.Device.Enable = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp.OAuthMethods = methods
|
resp.OAuthMethods = methods
|
||||||
|
|||||||
@ -61,18 +61,7 @@ func (l *CloseOrderLogic) CloseOrder(req *types.CloseOrderRequest) error {
|
|||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// If User ID is 0, it means that the order is a guest order and does not need to be refunded, the order can be deleted directly
|
// All orders now have associated users, no special handling needed for guest orders
|
||||||
if orderInfo.UserId == 0 {
|
|
||||||
err = tx.Model(&order.Order{}).Where("order_no = ?", req.OrderNo).Delete(&order.Order{}).Error
|
|
||||||
if err != nil {
|
|
||||||
l.Errorw("[CloseOrder] Delete order failed",
|
|
||||||
logger.Field("error", err.Error()),
|
|
||||||
logger.Field("orderNo", req.OrderNo),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// refund deduction amount to user deduction balance
|
// refund deduction amount to user deduction balance
|
||||||
if orderInfo.GiftAmount > 0 {
|
if orderInfo.GiftAmount > 0 {
|
||||||
userInfo, err := l.svcCtx.UserModel.FindOne(l.ctx, orderInfo.UserId)
|
userInfo, err := l.svcCtx.UserModel.FindOne(l.ctx, orderInfo.UserId)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package order
|
|||||||
import "github.com/perfect-panel/server/internal/types"
|
import "github.com/perfect-panel/server/internal/types"
|
||||||
|
|
||||||
func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64) float64 {
|
func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64) float64 {
|
||||||
var finalDiscount int64 = 100
|
var finalDiscount float64 = 1.0
|
||||||
|
|
||||||
for _, discount := range discounts {
|
for _, discount := range discounts {
|
||||||
if inputMonths >= discount.Quantity && discount.Discount < finalDiscount {
|
if inputMonths >= discount.Quantity && discount.Discount < finalDiscount {
|
||||||
@ -11,5 +11,5 @@ func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64) float64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return float64(finalDiscount) / float64(100)
|
return finalDiscount
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,14 +7,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64) float64 {
|
func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64) float64 {
|
||||||
var finalDiscount int64 = 100
|
var finalDiscount float64 = 1.0
|
||||||
|
|
||||||
for _, discount := range discounts {
|
for _, discount := range discounts {
|
||||||
if inputMonths >= discount.Quantity && discount.Discount < finalDiscount {
|
if inputMonths >= discount.Quantity && discount.Discount < finalDiscount {
|
||||||
finalDiscount = discount.Discount
|
finalDiscount = discount.Discount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return float64(finalDiscount) / float64(100)
|
return finalDiscount
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateCoupon(amount int64, couponInfo *coupon.Coupon) int64 {
|
func calculateCoupon(amount int64, couponInfo *coupon.Coupon) int64 {
|
||||||
|
|||||||
@ -0,0 +1,195 @@
|
|||||||
|
package subscribe
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/model/node"
|
||||||
|
"github.com/perfect-panel/server/internal/model/user"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/internal/types"
|
||||||
|
"github.com/perfect-panel/server/pkg/constant"
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
"github.com/perfect-panel/server/pkg/tool"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type QueryUserSubscribeNodeListLogic struct {
|
||||||
|
logger.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user subscribe node info
|
||||||
|
func NewQueryUserSubscribeNodeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryUserSubscribeNodeListLogic {
|
||||||
|
return &QueryUserSubscribeNodeListLogic{
|
||||||
|
Logger: logger.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *QueryUserSubscribeNodeListLogic) QueryUserSubscribeNodeList() (resp *types.QueryUserSubscribeNodeListResponse, err error) {
|
||||||
|
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
||||||
|
if !ok {
|
||||||
|
logger.Error("current user is not found in context")
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access")
|
||||||
|
}
|
||||||
|
|
||||||
|
userSubscribes, err := l.svcCtx.UserModel.QueryUserSubscribe(l.ctx, u.Id, 1, 2)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorw("failed to query user subscribe", logger.Field("error", err.Error()), logger.Field("user_id", u.Id))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "DB_ERROR")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = &types.QueryUserSubscribeNodeListResponse{}
|
||||||
|
for _, us := range userSubscribes {
|
||||||
|
userSubscribe, err := l.getUserSubscribe(us.Token)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[SubscribeLogic] Get user subscribe failed", logger.Field("error", err.Error()), logger.Field("token", userSubscribe.Token))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
nodes, err := l.getServers(userSubscribe)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
userSubscribeInfo := types.UserSubscribeInfo{
|
||||||
|
Id: userSubscribe.Id,
|
||||||
|
Nodes: nodes,
|
||||||
|
Traffic: userSubscribe.Traffic,
|
||||||
|
Upload: userSubscribe.Upload,
|
||||||
|
Download: userSubscribe.Download,
|
||||||
|
Token: userSubscribe.Token,
|
||||||
|
UserId: userSubscribe.UserId,
|
||||||
|
OrderId: userSubscribe.OrderId,
|
||||||
|
SubscribeId: userSubscribe.SubscribeId,
|
||||||
|
StartTime: userSubscribe.StartTime.Unix(),
|
||||||
|
ExpireTime: userSubscribe.ExpireTime.Unix(),
|
||||||
|
Status: userSubscribe.Status,
|
||||||
|
CreatedAt: userSubscribe.CreatedAt.Unix(),
|
||||||
|
UpdatedAt: userSubscribe.UpdatedAt.Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if userSubscribe.FinishedAt != nil {
|
||||||
|
userSubscribeInfo.FinishedAt = userSubscribe.FinishedAt.Unix()
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.svcCtx.Config.Register.EnableTrial && l.svcCtx.Config.Register.TrialSubscribe == userSubscribe.SubscribeId {
|
||||||
|
userSubscribeInfo.IsTryOut = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.List = append(resp.List, userSubscribeInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *QueryUserSubscribeNodeListLogic) getServers(userSub *user.Subscribe) (userSubscribeNodes []*types.UserSubscribeNodeInfo, err error) {
|
||||||
|
userSubscribeNodes = make([]*types.UserSubscribeNodeInfo, 0)
|
||||||
|
if l.isSubscriptionExpired(userSub) {
|
||||||
|
return l.createExpiredServers(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
subDetails, err := l.svcCtx.SubscribeModel.FindOne(l.ctx, userSub.SubscribeId)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[Generate Subscribe]find subscribe details error: %v", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find subscribe details error: %v", err.Error())
|
||||||
|
}
|
||||||
|
nodeIds := tool.StringToInt64Slice(subDetails.Nodes)
|
||||||
|
tags := strings.Split(subDetails.NodeTags, ",")
|
||||||
|
|
||||||
|
l.Debugf("[Generate Subscribe]nodes: %v, NodeTags: %v", nodeIds, tags)
|
||||||
|
|
||||||
|
enable := true
|
||||||
|
|
||||||
|
_, nodes, err := l.svcCtx.NodeModel.FilterNodeList(l.ctx, &node.FilterNodeParams{
|
||||||
|
Page: 0,
|
||||||
|
Size: 1000,
|
||||||
|
NodeId: nodeIds,
|
||||||
|
Enabled: &enable, // Only get enabled nodes
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(nodes) > 0 {
|
||||||
|
var serverMapIds = make(map[int64]*node.Server)
|
||||||
|
for _, n := range nodes {
|
||||||
|
serverMapIds[n.ServerId] = nil
|
||||||
|
}
|
||||||
|
var serverIds []int64
|
||||||
|
for k := range serverMapIds {
|
||||||
|
serverIds = append(serverIds, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
servers, err := l.svcCtx.NodeModel.QueryServerList(l.ctx, serverIds)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[Generate Subscribe]find server details error: %v", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find server details error: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range servers {
|
||||||
|
serverMapIds[s.Id] = s
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, n := range nodes {
|
||||||
|
server := serverMapIds[n.ServerId]
|
||||||
|
if server == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
userSubscribeNode := &types.UserSubscribeNodeInfo{
|
||||||
|
Id: n.Id,
|
||||||
|
Name: n.Name,
|
||||||
|
Uuid: userSub.UUID,
|
||||||
|
Protocol: n.Protocol,
|
||||||
|
Port: n.Port,
|
||||||
|
Address: n.Address,
|
||||||
|
Tags: strings.Split(n.Tags, ","),
|
||||||
|
Country: server.Country,
|
||||||
|
City: server.City,
|
||||||
|
CreatedAt: n.CreatedAt.Unix(),
|
||||||
|
}
|
||||||
|
userSubscribeNodes = append(userSubscribeNodes, userSubscribeNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Debugf("[Query Subscribe]found servers: %v", len(nodes))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("[Generate Subscribe]find server details error: %v", logger.Field("error", err.Error()))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find server details error: %v", err.Error())
|
||||||
|
}
|
||||||
|
logger.Debugf("[Generate Subscribe]found servers: %v", len(nodes))
|
||||||
|
return userSubscribeNodes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *QueryUserSubscribeNodeListLogic) isSubscriptionExpired(userSub *user.Subscribe) bool {
|
||||||
|
return userSub.ExpireTime.Unix() < time.Now().Unix() && userSub.ExpireTime.Unix() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *QueryUserSubscribeNodeListLogic) createExpiredServers() []*types.UserSubscribeNodeInfo {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *QueryUserSubscribeNodeListLogic) getFirstHostLine() string {
|
||||||
|
host := l.svcCtx.Config.Host
|
||||||
|
lines := strings.Split(host, "\n")
|
||||||
|
if len(lines) > 0 {
|
||||||
|
return lines[0]
|
||||||
|
}
|
||||||
|
return host
|
||||||
|
}
|
||||||
|
func (l *QueryUserSubscribeNodeListLogic) getUserSubscribe(token string) (*user.Subscribe, error) {
|
||||||
|
userSub, err := l.svcCtx.UserModel.FindOneSubscribeByToken(l.ctx, token)
|
||||||
|
if err != nil {
|
||||||
|
l.Infow("[Generate Subscribe]find subscribe error: %v", logger.Field("error", err.Error()), logger.Field("token", token))
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find subscribe error: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore expiration check
|
||||||
|
//if userSub.Status > 1 {
|
||||||
|
// l.Infow("[Generate Subscribe]subscribe is not available", logger.Field("status", int(userSub.Status)), logger.Field("token", token))
|
||||||
|
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SubscribeNotAvailable), "subscribe is not available")
|
||||||
|
//}
|
||||||
|
|
||||||
|
return userSub, nil
|
||||||
|
}
|
||||||
39
internal/logic/public/user/getDeviceListLogic.go
Normal file
39
internal/logic/public/user/getDeviceListLogic.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/model/user"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/internal/types"
|
||||||
|
"github.com/perfect-panel/server/pkg/constant"
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
"github.com/perfect-panel/server/pkg/tool"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetDeviceListLogic struct {
|
||||||
|
logger.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Device List
|
||||||
|
func NewGetDeviceListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetDeviceListLogic {
|
||||||
|
return &GetDeviceListLogic{
|
||||||
|
Logger: logger.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetDeviceListLogic) GetDeviceList() (resp *types.GetDeviceListResponse, err error) {
|
||||||
|
userInfo := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
||||||
|
list, count, err := l.svcCtx.UserModel.QueryDeviceList(l.ctx, userInfo.Id)
|
||||||
|
userRespList := make([]types.UserDevice, 0)
|
||||||
|
tool.DeepCopy(&userRespList, list)
|
||||||
|
resp = &types.GetDeviceListResponse{
|
||||||
|
Total: count,
|
||||||
|
List: userRespList,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
72
internal/logic/public/user/unbindDeviceLogic.go
Normal file
72
internal/logic/public/user/unbindDeviceLogic.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/config"
|
||||||
|
"github.com/perfect-panel/server/internal/model/user"
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
"github.com/perfect-panel/server/internal/types"
|
||||||
|
"github.com/perfect-panel/server/pkg/constant"
|
||||||
|
"github.com/perfect-panel/server/pkg/logger"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UnbindDeviceLogic struct {
|
||||||
|
logger.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind Device
|
||||||
|
func NewUnbindDeviceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UnbindDeviceLogic {
|
||||||
|
return &UnbindDeviceLogic{
|
||||||
|
Logger: logger.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *UnbindDeviceLogic) UnbindDevice(req *types.UnbindDeviceRequest) error {
|
||||||
|
userInfo := l.ctx.Value(constant.CtxKeyUser).(*user.User)
|
||||||
|
device, err := l.svcCtx.UserModel.FindOneDevice(l.ctx, req.Id)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DeviceNotExist), "find device")
|
||||||
|
}
|
||||||
|
|
||||||
|
if device.UserId != userInfo.Id {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), "device not belong to user")
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.svcCtx.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
var deleteDevice user.Device
|
||||||
|
err = tx.Model(&deleteDevice).Where("id = ?", req.Id).First(&deleteDevice).Error
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.QueueEnqueueError), "find device err: %v", err)
|
||||||
|
}
|
||||||
|
err = tx.Delete(deleteDevice).Error
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete device err: %v", err)
|
||||||
|
}
|
||||||
|
var userAuth user.AuthMethods
|
||||||
|
err = tx.Model(&userAuth).Where("auth_identifier = ? and auth_type = ?", deleteDevice.Identifier, "device").First(&userAuth).Error
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find device online record err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Delete(&userAuth).Error
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseDeletedError), "delete device online record err: %v", err)
|
||||||
|
}
|
||||||
|
sessionId := l.ctx.Value(constant.CtxKeySessionID)
|
||||||
|
sessionIdCacheKey := fmt.Sprintf("%v:%v", config.SessionIdKey, sessionId)
|
||||||
|
l.svcCtx.Redis.Del(l.ctx, sessionIdCacheKey)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -48,22 +48,47 @@ func (l *UpdateBindEmailLogic) UpdateBindEmail(req *types.UpdateBindEmailRequest
|
|||||||
if m.Id > 0 {
|
if m.Id > 0 {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.UserExist), "email already bind")
|
return errors.Wrapf(xerr.NewErrCode(xerr.UserExist), "email already bind")
|
||||||
}
|
}
|
||||||
if method.Id == 0 {
|
// Use transaction to safely handle insert or update
|
||||||
method = &user.AuthMethods{
|
err = l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
|
||||||
UserId: u.Id,
|
if method.Id == 0 {
|
||||||
AuthType: "email",
|
// Check if record exists in current transaction
|
||||||
AuthIdentifier: req.Email,
|
var existingMethod user.AuthMethods
|
||||||
Verified: false,
|
err := db.Model(&user.AuthMethods{}).Where("user_id = ? AND auth_type = ?", u.Id, "email").First(&existingMethod).Error
|
||||||
}
|
if err != nil {
|
||||||
if err := l.svcCtx.UserModel.InsertUserAuthMethods(l.ctx, method); err != nil {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "InsertUserAuthMethods error")
|
// Create new record
|
||||||
}
|
method = &user.AuthMethods{
|
||||||
} else {
|
UserId: u.Id,
|
||||||
method.Verified = false
|
AuthType: "email",
|
||||||
method.AuthIdentifier = req.Email
|
AuthIdentifier: req.Email,
|
||||||
if err := l.svcCtx.UserModel.UpdateUserAuthMethods(l.ctx, method); err != nil {
|
Verified: false,
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "UpdateUserAuthMethods error")
|
}
|
||||||
|
if err := db.Create(method).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Record exists, update it
|
||||||
|
existingMethod.AuthIdentifier = req.Email
|
||||||
|
existingMethod.Verified = false
|
||||||
|
if err := db.Save(&existingMethod).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Update existing record
|
||||||
|
method.Verified = false
|
||||||
|
method.AuthIdentifier = req.Email
|
||||||
|
if err := db.Save(method).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "UpdateBindEmail transaction error")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,8 +58,9 @@ func (l *GetServerConfigLogic) GetServerConfig(req *types.GetServerConfigRequest
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compatible hysteria2, remove in future versions
|
// compatible hysteria2, remove in future versions
|
||||||
if req.Protocol == Hysteria2 {
|
protocolRequest := req.Protocol
|
||||||
req.Protocol = Hysteria
|
if protocolRequest == Hysteria2 {
|
||||||
|
protocolRequest = Hysteria
|
||||||
}
|
}
|
||||||
|
|
||||||
protocols, err := data.UnmarshalProtocols()
|
protocols, err := data.UnmarshalProtocols()
|
||||||
@ -68,7 +69,7 @@ func (l *GetServerConfigLogic) GetServerConfig(req *types.GetServerConfigRequest
|
|||||||
}
|
}
|
||||||
var cfg map[string]interface{}
|
var cfg map[string]interface{}
|
||||||
for _, protocol := range protocols {
|
for _, protocol := range protocols {
|
||||||
if protocol.Type == req.Protocol {
|
if protocol.Type == protocolRequest {
|
||||||
cfg = l.compatible(protocol)
|
cfg = l.compatible(protocol)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,11 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
|
|||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loginType := ""
|
||||||
|
if claims["LoginType"] != nil {
|
||||||
|
loginType = claims["LoginType"].(string)
|
||||||
|
}
|
||||||
// get user id from token
|
// get user id from token
|
||||||
userId := int64(claims["UserId"].(float64))
|
userId := int64(claims["UserId"].(float64))
|
||||||
// get session id from token
|
// get session id from token
|
||||||
@ -77,6 +82,7 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
|
|||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
ctx = context.WithValue(ctx, constant.LoginType, loginType)
|
||||||
ctx = context.WithValue(ctx, constant.CtxKeyUser, userInfo)
|
ctx = context.WithValue(ctx, constant.CtxKeyUser, userInfo)
|
||||||
ctx = context.WithValue(ctx, constant.CtxKeySessionID, sessionId)
|
ctx = context.WithValue(ctx, constant.CtxKeySessionID, sessionId)
|
||||||
c.Request = c.Request.WithContext(ctx)
|
c.Request = c.Request.WithContext(ctx)
|
||||||
|
|||||||
295
internal/middleware/deviceMiddleware.go
Normal file
295
internal/middleware/deviceMiddleware.go
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/perfect-panel/server/internal/svc"
|
||||||
|
pkgaes "github.com/perfect-panel/server/pkg/aes"
|
||||||
|
"github.com/perfect-panel/server/pkg/constant"
|
||||||
|
"github.com/perfect-panel/server/pkg/result"
|
||||||
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
noWritten = -1
|
||||||
|
defaultStatus = http.StatusOK
|
||||||
|
)
|
||||||
|
|
||||||
|
func DeviceMiddleware(srvCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
|
||||||
|
if !srvCtx.Config.Device.Enable {
|
||||||
|
c.Next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if srvCtx.Config.Device.SecuritySecret == "" {
|
||||||
|
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.SecretIsEmpty), "Secret is empty"))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := c.Request.Context()
|
||||||
|
if ctx.Value(constant.CtxKeyUser) == nil && c.GetHeader("Login-Type") != "" {
|
||||||
|
ctx = context.WithValue(ctx, constant.LoginType, c.GetHeader("Login-Type"))
|
||||||
|
c.Request = c.Request.WithContext(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
loginType, ok := ctx.Value(constant.LoginType).(string)
|
||||||
|
if !ok || loginType != "device" {
|
||||||
|
c.Next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rw := NewResponseWriter(c, srvCtx)
|
||||||
|
if !rw.Decrypt() {
|
||||||
|
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidCiphertext), "Invalid ciphertext"))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Writer = rw
|
||||||
|
c.Next()
|
||||||
|
rw.FlushAbort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResponseWriter(c *gin.Context, srvCtx *svc.ServiceContext) (rw *ResponseWriter) {
|
||||||
|
rw = &ResponseWriter{
|
||||||
|
c: c,
|
||||||
|
body: new(bytes.Buffer),
|
||||||
|
ResponseWriter: c.Writer,
|
||||||
|
}
|
||||||
|
rw.encryptionKey = srvCtx.Config.Device.SecuritySecret
|
||||||
|
rw.encryptionMethod = "AES"
|
||||||
|
rw.encryption = true
|
||||||
|
return rw
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Encrypt() {
|
||||||
|
if !rw.encryption {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buf := rw.body.Bytes()
|
||||||
|
params := map[string]interface{}{}
|
||||||
|
err := json.Unmarshal(buf, ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data := params["data"]
|
||||||
|
if data != nil {
|
||||||
|
var jsonData []byte
|
||||||
|
str, ok := data.(string)
|
||||||
|
if ok {
|
||||||
|
jsonData = []byte(str)
|
||||||
|
} else {
|
||||||
|
jsonData, _ = json.Marshal(data)
|
||||||
|
}
|
||||||
|
encrypt, iv, err := pkgaes.Encrypt(jsonData, rw.encryptionKey)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params["data"] = map[string]interface{}{
|
||||||
|
"data": encrypt,
|
||||||
|
"time": iv,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
marshal, _ := json.Marshal(params)
|
||||||
|
rw.body.Reset()
|
||||||
|
rw.body.Write(marshal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Decrypt() bool {
|
||||||
|
if !rw.encryption {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断url链接中是否存在data和iv数据,存在就进行解密并设置回去
|
||||||
|
query := rw.c.Request.URL.Query()
|
||||||
|
dataStr := query.Get("data")
|
||||||
|
timeStr := query.Get("time")
|
||||||
|
if dataStr != "" && timeStr != "" {
|
||||||
|
decrypt, err := pkgaes.Decrypt(dataStr, rw.encryptionKey, timeStr)
|
||||||
|
if err == nil {
|
||||||
|
params := map[string]interface{}{}
|
||||||
|
err = json.Unmarshal([]byte(decrypt), ¶ms)
|
||||||
|
if err == nil {
|
||||||
|
for k, v := range params {
|
||||||
|
query.Set(k, fmt.Sprintf("%v", v))
|
||||||
|
}
|
||||||
|
query.Del("data")
|
||||||
|
query.Del("time")
|
||||||
|
rw.c.Request.RequestURI = fmt.Sprintf("%s?%s", rw.c.Request.RequestURI[:strings.Index(rw.c.Request.RequestURI, "?")], query.Encode())
|
||||||
|
rw.c.Request.URL.RawQuery = query.Encode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断body是否存在数据,存在就尝试解密,并设置回去
|
||||||
|
body, err := io.ReadAll(rw.c.Request.Body)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(body) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
params := map[string]interface{}{}
|
||||||
|
err = json.Unmarshal(body, ¶ms)
|
||||||
|
data := params["data"]
|
||||||
|
nonce := params["time"]
|
||||||
|
if err != nil || data == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
str, ok := data.(string)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
iv, ok := nonce.(string)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypt, err := pkgaes.Decrypt(str, rw.encryptionKey, iv)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
rw.c.Request.Body = io.NopCloser(bytes.NewBuffer([]byte(decrypt)))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) FlushAbort() {
|
||||||
|
defer rw.c.Abort()
|
||||||
|
responseBody := rw.body.String()
|
||||||
|
fmt.Println("Original Response Body:", responseBody)
|
||||||
|
rw.flush = true
|
||||||
|
if rw.encryption {
|
||||||
|
rw.Encrypt()
|
||||||
|
}
|
||||||
|
_, err := rw.Write(rw.body.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseWriter struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
size int
|
||||||
|
status int
|
||||||
|
flush bool
|
||||||
|
body *bytes.Buffer
|
||||||
|
c *gin.Context
|
||||||
|
encryption bool
|
||||||
|
encryptionKey string
|
||||||
|
encryptionMethod string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Unwrap() http.ResponseWriter {
|
||||||
|
return rw.ResponseWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:unused
|
||||||
|
func (rw *ResponseWriter) reset(writer http.ResponseWriter) {
|
||||||
|
rw.ResponseWriter = writer
|
||||||
|
rw.size = noWritten
|
||||||
|
rw.status = defaultStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) WriteHeader(code int) {
|
||||||
|
if code > 0 && rw.status != code {
|
||||||
|
if rw.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rw.status = code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) WriteHeaderNow() {
|
||||||
|
if !rw.Written() {
|
||||||
|
rw.size = 0
|
||||||
|
rw.ResponseWriter.WriteHeader(rw.status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Write(data []byte) (n int, err error) {
|
||||||
|
if rw.flush {
|
||||||
|
rw.WriteHeaderNow()
|
||||||
|
n, err = rw.ResponseWriter.Write(data)
|
||||||
|
rw.size += n
|
||||||
|
} else {
|
||||||
|
rw.body.Write(data)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) WriteString(s string) (n int, err error) {
|
||||||
|
if rw.flush {
|
||||||
|
rw.WriteHeaderNow()
|
||||||
|
n, err = rw.ResponseWriter.Write([]byte(s))
|
||||||
|
rw.size += n
|
||||||
|
} else {
|
||||||
|
rw.body.Write([]byte(s))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Status() int {
|
||||||
|
return rw.status
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Size() int {
|
||||||
|
return rw.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Written() bool {
|
||||||
|
return rw.size != noWritten
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hijack implements the http.Hijacker interface.
|
||||||
|
func (rw *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
|
if rw.size < 0 {
|
||||||
|
rw.size = 0
|
||||||
|
}
|
||||||
|
return rw.ResponseWriter.(http.Hijacker).Hijack()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseNotify implements the http.CloseNotifier interface.
|
||||||
|
func (rw *ResponseWriter) CloseNotify() <-chan bool {
|
||||||
|
// 通过 r.Context().Done() 来监听请求的取消
|
||||||
|
done := rw.c.Request.Context().Done()
|
||||||
|
closed := make(chan bool)
|
||||||
|
|
||||||
|
// 当上下文被取消时,通过 closed channel 发送通知
|
||||||
|
go func() {
|
||||||
|
<-done
|
||||||
|
closed <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
return closed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush implements the http.Flusher interface.
|
||||||
|
func (rw *ResponseWriter) Flush() {
|
||||||
|
rw.WriteHeaderNow()
|
||||||
|
rw.ResponseWriter.(http.Flusher).Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rw *ResponseWriter) Pusher() (pusher http.Pusher) {
|
||||||
|
if pusher, ok := rw.ResponseWriter.(http.Pusher); ok {
|
||||||
|
return pusher
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -43,7 +43,7 @@ func (m *customAnnouncementModel) GetAnnouncementListByPage(ctx context.Context,
|
|||||||
if filter.Search != "" {
|
if filter.Search != "" {
|
||||||
conn = conn.Where("`title` LIKE ? OR `content` LIKE ?", "%"+filter.Search+"%", "%"+filter.Search+"%")
|
conn = conn.Where("`title` LIKE ? OR `content` LIKE ?", "%"+filter.Search+"%", "%"+filter.Search+"%")
|
||||||
}
|
}
|
||||||
return conn.Count(&total).Offset((page - 1) * size).Limit(size).Find(v).Error
|
return conn.Count(&total).Offset((page - 1) * size).Limit(size).Find(&list).Error
|
||||||
})
|
})
|
||||||
return total, list, err
|
return total, list, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ type (
|
|||||||
UpdateServer(ctx context.Context, data *Server, tx ...*gorm.DB) error
|
UpdateServer(ctx context.Context, data *Server, tx ...*gorm.DB) error
|
||||||
DeleteServer(ctx context.Context, id int64, tx ...*gorm.DB) error
|
DeleteServer(ctx context.Context, id int64, tx ...*gorm.DB) error
|
||||||
Transaction(ctx context.Context, fn func(db *gorm.DB) error) error
|
Transaction(ctx context.Context, fn func(db *gorm.DB) error) error
|
||||||
|
QueryServerList(ctx context.Context, ids []int64) (servers []*Server, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeModel interface {
|
NodeModel interface {
|
||||||
|
|||||||
@ -65,6 +65,12 @@ func (m *customServerModel) FilterServerList(ctx context.Context, params *Filter
|
|||||||
return total, servers, err
|
return total, servers, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *customServerModel) QueryServerList(ctx context.Context, ids []int64) (servers []*Server, err error) {
|
||||||
|
query := m.WithContext(ctx).Model(&Server{})
|
||||||
|
err = query.Where("id IN (?)", ids).Find(&servers).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// FilterNodeList Filter Node List
|
// FilterNodeList Filter Node List
|
||||||
func (m *customServerModel) FilterNodeList(ctx context.Context, params *FilterNodeParams) (int64, []*Node, error) {
|
func (m *customServerModel) FilterNodeList(ctx context.Context, params *FilterNodeParams) (int64, []*Node, error) {
|
||||||
var nodes []*Node
|
var nodes []*Node
|
||||||
|
|||||||
@ -71,8 +71,8 @@ func (s *Subscribe) BeforeUpdate(tx *gorm.DB) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Discount struct {
|
type Discount struct {
|
||||||
Months int64 `json:"months"`
|
Months int64 `json:"months"`
|
||||||
Discount int64 `json:"discount"`
|
Discount float64 `json:"discount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Group struct {
|
type Group struct {
|
||||||
|
|||||||
@ -46,6 +46,16 @@ func (m *customUserModel) QueryDevicePageList(ctx context.Context, userId, subsc
|
|||||||
return list, total, err
|
return list, total, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryDeviceList returns a list of records that meet the conditions.
|
||||||
|
func (m *customUserModel) QueryDeviceList(ctx context.Context, userId int64) ([]*Device, int64, error) {
|
||||||
|
var list []*Device
|
||||||
|
var total int64
|
||||||
|
err := m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
|
||||||
|
return conn.Model(&Device{}).Where("`user_id` = ?", userId).Count(&total).Find(&list).Error
|
||||||
|
})
|
||||||
|
return list, total, err
|
||||||
|
}
|
||||||
|
|
||||||
func (m *customUserModel) UpdateDevice(ctx context.Context, data *Device, tx ...*gorm.DB) error {
|
func (m *customUserModel) UpdateDevice(ctx context.Context, data *Device, tx ...*gorm.DB) error {
|
||||||
old, err := m.FindOneDevice(ctx, data.Id)
|
old, err := m.FindOneDevice(ctx, data.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -76,3 +86,18 @@ func (m *customUserModel) DeleteDevice(ctx context.Context, id int64, tx ...*gor
|
|||||||
}, data.GetCacheKeys()...)
|
}, data.GetCacheKeys()...)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *customUserModel) InsertDevice(ctx context.Context, data *Device, tx ...*gorm.DB) error {
|
||||||
|
defer func() {
|
||||||
|
if clearErr := m.ClearDeviceCache(ctx, data); clearErr != nil {
|
||||||
|
// log cache clear error
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return m.ExecNoCacheCtx(ctx, func(conn *gorm.DB) error {
|
||||||
|
if len(tx) > 0 {
|
||||||
|
conn = tx[0]
|
||||||
|
}
|
||||||
|
return conn.Create(data).Error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -77,6 +77,7 @@ type customUserLogicModel interface {
|
|||||||
QueryUserSubscribe(ctx context.Context, userId int64, status ...int64) ([]*SubscribeDetails, error)
|
QueryUserSubscribe(ctx context.Context, userId int64, status ...int64) ([]*SubscribeDetails, error)
|
||||||
FindOneSubscribeDetailsById(ctx context.Context, id int64) (*SubscribeDetails, error)
|
FindOneSubscribeDetailsById(ctx context.Context, id int64) (*SubscribeDetails, error)
|
||||||
FindOneUserSubscribe(ctx context.Context, id int64) (*SubscribeDetails, error)
|
FindOneUserSubscribe(ctx context.Context, id int64) (*SubscribeDetails, error)
|
||||||
|
FindActiveSubscribe(ctx context.Context, userId int64) (*Subscribe, error)
|
||||||
FindUsersSubscribeBySubscribeId(ctx context.Context, subscribeId int64) ([]*Subscribe, error)
|
FindUsersSubscribeBySubscribeId(ctx context.Context, subscribeId int64) ([]*Subscribe, error)
|
||||||
UpdateUserSubscribeWithTraffic(ctx context.Context, id, download, upload int64, tx ...*gorm.DB) error
|
UpdateUserSubscribeWithTraffic(ctx context.Context, id, download, upload int64, tx ...*gorm.DB) error
|
||||||
QueryResisterUserTotalByDate(ctx context.Context, date time.Time) (int64, error)
|
QueryResisterUserTotalByDate(ctx context.Context, date time.Time) (int64, error)
|
||||||
@ -95,10 +96,12 @@ type customUserLogicModel interface {
|
|||||||
FindUserAuthMethodByPlatform(ctx context.Context, userId int64, platform string) (*AuthMethods, error)
|
FindUserAuthMethodByPlatform(ctx context.Context, userId int64, platform string) (*AuthMethods, error)
|
||||||
FindOneByEmail(ctx context.Context, email string) (*User, error)
|
FindOneByEmail(ctx context.Context, email string) (*User, error)
|
||||||
FindOneDevice(ctx context.Context, id int64) (*Device, error)
|
FindOneDevice(ctx context.Context, id int64) (*Device, error)
|
||||||
|
QueryDeviceList(ctx context.Context, userid int64) ([]*Device, int64, error)
|
||||||
QueryDevicePageList(ctx context.Context, userid, subscribeId int64, page, size int) ([]*Device, int64, error)
|
QueryDevicePageList(ctx context.Context, userid, subscribeId int64, page, size int) ([]*Device, int64, error)
|
||||||
UpdateDevice(ctx context.Context, data *Device, tx ...*gorm.DB) error
|
UpdateDevice(ctx context.Context, data *Device, tx ...*gorm.DB) error
|
||||||
FindOneDeviceByIdentifier(ctx context.Context, id string) (*Device, error)
|
FindOneDeviceByIdentifier(ctx context.Context, id string) (*Device, error)
|
||||||
DeleteDevice(ctx context.Context, id int64, tx ...*gorm.DB) error
|
DeleteDevice(ctx context.Context, id int64, tx ...*gorm.DB) error
|
||||||
|
InsertDevice(ctx context.Context, data *Device, tx ...*gorm.DB) error
|
||||||
|
|
||||||
ClearSubscribeCache(ctx context.Context, data ...*Subscribe) error
|
ClearSubscribeCache(ctx context.Context, data ...*Subscribe) error
|
||||||
ClearUserCache(ctx context.Context, data ...*User) error
|
ClearUserCache(ctx context.Context, data ...*User) error
|
||||||
|
|||||||
@ -198,3 +198,24 @@ func (m *defaultUserModel) DeleteSubscribeById(ctx context.Context, id int64, tx
|
|||||||
func (m *defaultUserModel) ClearSubscribeCache(ctx context.Context, data ...*Subscribe) error {
|
func (m *defaultUserModel) ClearSubscribeCache(ctx context.Context, data ...*Subscribe) error {
|
||||||
return m.ClearSubscribeCacheByModels(ctx, data...)
|
return m.ClearSubscribeCacheByModels(ctx, data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindActiveSubscribe finds the user's active subscription
|
||||||
|
func (m *defaultUserModel) FindActiveSubscribe(ctx context.Context, userId int64) (*Subscribe, error) {
|
||||||
|
var data Subscribe
|
||||||
|
err := m.QueryNoCacheCtx(ctx, &data, func(conn *gorm.DB, v interface{}) error {
|
||||||
|
now := time.Now()
|
||||||
|
return conn.Model(&Subscribe{}).
|
||||||
|
Where("user_id = ? AND status = ? AND expire_time > ?", userId, 1, now).
|
||||||
|
Order("expire_time DESC").
|
||||||
|
First(&data).Error
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -118,6 +118,7 @@ type ApplicationVersion struct {
|
|||||||
type AuthConfig struct {
|
type AuthConfig struct {
|
||||||
Mobile MobileAuthenticateConfig `json:"mobile"`
|
Mobile MobileAuthenticateConfig `json:"mobile"`
|
||||||
Email EmailAuthticateConfig `json:"email"`
|
Email EmailAuthticateConfig `json:"email"`
|
||||||
|
Device DeviceAuthticateConfig `json:"device"`
|
||||||
Register PubilcRegisterConfig `json:"register"`
|
Register PubilcRegisterConfig `json:"register"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,6 +518,20 @@ type DeleteUserSubscribeRequest struct {
|
|||||||
UserSubscribeId int64 `json:"user_subscribe_id"`
|
UserSubscribeId int64 `json:"user_subscribe_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeviceAuthticateConfig struct {
|
||||||
|
Enable bool `json:"enable"`
|
||||||
|
ShowAds bool `json:"show_ads"`
|
||||||
|
EnableSecurity bool `json:"enable_security"`
|
||||||
|
OnlyRealDevice bool `json:"only_real_device"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeviceLoginRequest struct {
|
||||||
|
Identifier string `json:"identifier" validate:"required"`
|
||||||
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
|
UserAgent string `json:"user_agent" validate:"required"`
|
||||||
|
CfToken string `json:"cf_token,optional"`
|
||||||
|
}
|
||||||
|
|
||||||
type Document struct {
|
type Document struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
@ -802,6 +817,11 @@ type GetDetailRequest struct {
|
|||||||
Id int64 `form:"id" validate:"required"`
|
Id int64 `form:"id" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetDeviceListResponse struct {
|
||||||
|
List []UserDevice `json:"list"`
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
type GetDocumentDetailRequest struct {
|
type GetDocumentDetailRequest struct {
|
||||||
Id int64 `json:"id" validate:"required"`
|
Id int64 `json:"id" validate:"required"`
|
||||||
}
|
}
|
||||||
@ -1150,6 +1170,7 @@ type InviteConfig struct {
|
|||||||
ForcedInvite bool `json:"forced_invite"`
|
ForcedInvite bool `json:"forced_invite"`
|
||||||
ReferralPercentage int64 `json:"referral_percentage"`
|
ReferralPercentage int64 `json:"referral_percentage"`
|
||||||
OnlyFirstPurchase bool `json:"only_first_purchase"`
|
OnlyFirstPurchase bool `json:"only_first_purchase"`
|
||||||
|
GiftDays int64 `json:"gift_days"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KickOfflineRequest struct {
|
type KickOfflineRequest struct {
|
||||||
@ -1520,7 +1541,7 @@ type PurchaseOrderResponse struct {
|
|||||||
|
|
||||||
type QueryAnnouncementRequest struct {
|
type QueryAnnouncementRequest struct {
|
||||||
Page int `form:"page"`
|
Page int `form:"page"`
|
||||||
Size int `form:"size"`
|
Size int `form:"size,default=15"`
|
||||||
Pinned *bool `form:"pinned"`
|
Pinned *bool `form:"pinned"`
|
||||||
Popup *bool `form:"popup"`
|
Popup *bool `form:"popup"`
|
||||||
}
|
}
|
||||||
@ -1677,6 +1698,10 @@ type QueryUserSubscribeListResponse struct {
|
|||||||
Total int64 `json:"total"`
|
Total int64 `json:"total"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type QueryUserSubscribeNodeListResponse struct {
|
||||||
|
List []UserSubscribeInfo `json:"list"`
|
||||||
|
}
|
||||||
|
|
||||||
type QuotaTask struct {
|
type QuotaTask struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
Subscribers []int64 `json:"subscribers"`
|
Subscribers []int64 `json:"subscribers"`
|
||||||
@ -1737,12 +1762,14 @@ type RenewalOrderResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ResetPasswordRequest struct {
|
type ResetPasswordRequest struct {
|
||||||
Email string `json:"email" validate:"required"`
|
Identifier string `json:"identifier"`
|
||||||
Password string `json:"password" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Code string `json:"code,optional"`
|
Password string `json:"password" validate:"required"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
Code string `json:"code,optional"`
|
||||||
UserAgent string `header:"User-Agent"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResetSortRequest struct {
|
type ResetSortRequest struct {
|
||||||
@ -2039,8 +2066,8 @@ type SubscribeConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SubscribeDiscount struct {
|
type SubscribeDiscount struct {
|
||||||
Quantity int64 `json:"quantity"`
|
Quantity int64 `json:"quantity"`
|
||||||
Discount int64 `json:"discount"`
|
Discount float64 `json:"discount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubscribeGroup struct {
|
type SubscribeGroup struct {
|
||||||
@ -2090,16 +2117,19 @@ type TelephoneCheckUserResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TelephoneLoginRequest struct {
|
type TelephoneLoginRequest struct {
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Telephone string `json:"telephone" validate:"required"`
|
Telephone string `json:"telephone" validate:"required"`
|
||||||
TelephoneCode string `json:"telephone_code"`
|
TelephoneCode string `json:"telephone_code"`
|
||||||
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
UserAgent string `header:"User-Agent"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TelephoneRegisterRequest struct {
|
type TelephoneRegisterRequest struct {
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Telephone string `json:"telephone" validate:"required"`
|
Telephone string `json:"telephone" validate:"required"`
|
||||||
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
@ -2107,16 +2137,19 @@ type TelephoneRegisterRequest struct {
|
|||||||
Code string `json:"code,optional"`
|
Code string `json:"code,optional"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
UserAgent string `header:"User-Agent"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type,optional"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TelephoneResetPasswordRequest struct {
|
type TelephoneResetPasswordRequest struct {
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Telephone string `json:"telephone" validate:"required"`
|
Telephone string `json:"telephone" validate:"required"`
|
||||||
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
Code string `json:"code,optional"`
|
Code string `json:"code,optional"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
UserAgent string `header:"User-Agent"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type,optional"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2211,6 +2244,10 @@ type Tuic struct {
|
|||||||
SecurityConfig SecurityConfig `json:"security_config"`
|
SecurityConfig SecurityConfig `json:"security_config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UnbindDeviceRequest struct {
|
||||||
|
Id int64 `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type UnbindOAuthRequest struct {
|
type UnbindOAuthRequest struct {
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
}
|
}
|
||||||
@ -2490,21 +2527,25 @@ type UserLoginLog struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserLoginRequest struct {
|
type UserLoginRequest struct {
|
||||||
Email string `json:"email" validate:"required"`
|
Identifier string `json:"identifier"`
|
||||||
Password string `json:"password" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
Password string `json:"password" validate:"required"`
|
||||||
UserAgent string `header:"User-Agent"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserRegisterRequest struct {
|
type UserRegisterRequest struct {
|
||||||
Email string `json:"email" validate:"required"`
|
Identifier string `json:"identifier"`
|
||||||
Password string `json:"password" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Invite string `json:"invite,optional"`
|
Password string `json:"password" validate:"required"`
|
||||||
Code string `json:"code,optional"`
|
Invite string `json:"invite,optional"`
|
||||||
IP string `header:"X-Original-Forwarded-For"`
|
Code string `json:"code,optional"`
|
||||||
UserAgent string `header:"User-Agent"`
|
IP string `header:"X-Original-Forwarded-For"`
|
||||||
CfToken string `json:"cf_token,optional"`
|
UserAgent string `header:"User-Agent"`
|
||||||
|
LoginType string `header:"Login-Type"`
|
||||||
|
CfToken string `json:"cf_token,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserStatistics struct {
|
type UserStatistics struct {
|
||||||
@ -2559,6 +2600,26 @@ type UserSubscribeDetail struct {
|
|||||||
UpdatedAt int64 `json:"updated_at"`
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserSubscribeInfo struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
UserId int64 `json:"user_id"`
|
||||||
|
OrderId int64 `json:"order_id"`
|
||||||
|
SubscribeId int64 `json:"subscribe_id"`
|
||||||
|
StartTime int64 `json:"start_time"`
|
||||||
|
ExpireTime int64 `json:"expire_time"`
|
||||||
|
FinishedAt int64 `json:"finished_at"`
|
||||||
|
ResetTime int64 `json:"reset_time"`
|
||||||
|
Traffic int64 `json:"traffic"`
|
||||||
|
Download int64 `json:"download"`
|
||||||
|
Upload int64 `json:"upload"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
Status uint8 `json:"status"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
|
IsTryOut bool `json:"is_try_out"`
|
||||||
|
Nodes []*UserSubscribeNodeInfo `json:"nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
type UserSubscribeLog struct {
|
type UserSubscribeLog struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
UserId int64 `json:"user_id"`
|
UserId int64 `json:"user_id"`
|
||||||
@ -2569,6 +2630,19 @@ type UserSubscribeLog struct {
|
|||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserSubscribeNodeInfo struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Uuid string `json:"uuid"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
Port uint16 `json:"port"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
City string `json:"city"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type UserSubscribeTrafficLog struct {
|
type UserSubscribeTrafficLog struct {
|
||||||
SubscribeId int64 `json:"subscribe_id"` // Subscribe ID
|
SubscribeId int64 `json:"subscribe_id"` // Subscribe ID
|
||||||
UserId int64 `json:"user_id"` // User ID
|
UserId int64 `json:"user_id"` // User ID
|
||||||
|
|||||||
648
logs/access.log-2025-10-17
Normal file
648
logs/access.log-2025-10-17
Normal file
@ -0,0 +1,648 @@
|
|||||||
|
{"caller":"queue/queue.go:23","content":"start consumer service","level":"info","timestamp":"2025-10-17 09:32:30.652"}
|
||||||
|
{"caller":"scheduler/scheduler.go:26","content":"start scheduler service","level":"info","timestamp":"2025-10-17 09:32:30.652"}
|
||||||
|
{"caller":"initialize/version.go:21","content":"[Migrate] database not change","level":"info","timestamp":"2025-10-17 09:32:30.656"}
|
||||||
|
{"caller":"initialize/site.go:15","content":"[GORM] SQL Executed","duration":"0.3ms","level":"info","rows":7,"sql":"SELECT * FROM `system` WHERE `category` = 'site'","timestamp":"2025-10-17 09:32:30.656"}
|
||||||
|
{"caller":"initialize/node.go:17","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":9,"sql":"SELECT * FROM `system` WHERE `category` = 'server'","timestamp":"2025-10-17 09:32:30.657"}
|
||||||
|
{"caller":"internal/server.go:69","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:32:30.657"}
|
||||||
|
{"caller":"initialize/node.go:70","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `category` = 'server' AND `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:32:30.657"}
|
||||||
|
{"caller":"initialize/email.go:18","content":"[GORM] SQL Executed","duration":"0.3ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'email' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:32:30.657"}
|
||||||
|
{"caller":"initialize/device.go:16","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'device' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:32:30.658"}
|
||||||
|
{"caller":"initialize/invite.go:15","content":"[GORM] SQL Executed","duration":"0.3ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'invite'","timestamp":"2025-10-17 09:32:30.659"}
|
||||||
|
{"caller":"initialize/verify.go:23","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":5,"sql":"SELECT * FROM `system` WHERE `category` = 'verify'","timestamp":"2025-10-17 09:32:30.659"}
|
||||||
|
{"caller":"initialize/verify.go:41","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'verify_code'","timestamp":"2025-10-17 09:32:30.660"}
|
||||||
|
{"caller":"initialize/subscribe.go:15","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":6,"sql":"SELECT * FROM `system` WHERE `category` = 'subscribe'","timestamp":"2025-10-17 09:32:30.660"}
|
||||||
|
{"caller":"initialize/register.go:15","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":8,"sql":"SELECT * FROM `system` WHERE `category` = 'register'","timestamp":"2025-10-17 09:32:30.660"}
|
||||||
|
{"caller":"initialize/mobile.go:17","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'mobile' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:32:30.661"}
|
||||||
|
{"caller":"initialize/telegram.go:19","content":"[GORM] SQL Executed","duration":"0.2ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'telegram' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:32:30.661"}
|
||||||
|
{"caller":"trace/agent.go:46","content":"Starting agent","level":"info","timestamp":"2025-10-17 09:32:30.661"}
|
||||||
|
{"caller":"internal/server.go:87","content":"server start at 0.0.0.0:8888","level":"info","timestamp":"2025-10-17 09:32:30.662"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:33:30","level":"info","timestamp":"2025-10-17 09:33:30.781"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:33:30.786"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:33:30.786"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:33:30.787' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:33:30.788"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:33:30.788"}
|
||||||
|
{"caller":"scheduler/scheduler.go:55","content":"stop scheduler service","level":"info","timestamp":"2025-10-17 09:34:09.417"}
|
||||||
|
{"caller":"queue/queue.go:36","content":"stop consumer service","level":"info","timestamp":"2025-10-17 09:34:09.417"}
|
||||||
|
{"caller":"internal/server.go:108","content":"server shutdown","level":"info","timestamp":"2025-10-17 09:34:09.417"}
|
||||||
|
{"caller":"queue/queue.go:23","content":"start consumer service","level":"info","timestamp":"2025-10-17 09:34:24.620"}
|
||||||
|
{"caller":"scheduler/scheduler.go:26","content":"start scheduler service","level":"info","timestamp":"2025-10-17 09:34:24.620"}
|
||||||
|
{"caller":"initialize/version.go:21","content":"[Migrate] database not change","level":"info","timestamp":"2025-10-17 09:34:24.632"}
|
||||||
|
{"caller":"initialize/site.go:15","content":"[GORM] SQL Executed","duration":"0.6ms","level":"info","rows":7,"sql":"SELECT * FROM `system` WHERE `category` = 'site'","timestamp":"2025-10-17 09:34:24.632"}
|
||||||
|
{"caller":"initialize/node.go:17","content":"[GORM] SQL Executed","duration":"0.4ms","level":"info","rows":9,"sql":"SELECT * FROM `system` WHERE `category` = 'server'","timestamp":"2025-10-17 09:34:24.633"}
|
||||||
|
{"caller":"internal/server.go:69","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:34:24.634"}
|
||||||
|
{"caller":"initialize/node.go:70","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `category` = 'server' AND `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:34:24.634"}
|
||||||
|
{"caller":"initialize/email.go:18","content":"[GORM] SQL Executed","duration":"0.9ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'email' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:34:24.635"}
|
||||||
|
{"caller":"initialize/device.go:16","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'device' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:34:24.637"}
|
||||||
|
{"caller":"initialize/invite.go:15","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'invite'","timestamp":"2025-10-17 09:34:24.638"}
|
||||||
|
{"caller":"initialize/verify.go:23","content":"[GORM] SQL Executed","duration":"0.4ms","level":"info","rows":5,"sql":"SELECT * FROM `system` WHERE `category` = 'verify'","timestamp":"2025-10-17 09:34:24.639"}
|
||||||
|
{"caller":"initialize/verify.go:41","content":"[GORM] SQL Executed","duration":"0.4ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'verify_code'","timestamp":"2025-10-17 09:34:24.640"}
|
||||||
|
{"caller":"initialize/subscribe.go:15","content":"[GORM] SQL Executed","duration":"0.4ms","level":"info","rows":6,"sql":"SELECT * FROM `system` WHERE `category` = 'subscribe'","timestamp":"2025-10-17 09:34:24.640"}
|
||||||
|
{"caller":"initialize/register.go:15","content":"[GORM] SQL Executed","duration":"0.4ms","level":"info","rows":8,"sql":"SELECT * FROM `system` WHERE `category` = 'register'","timestamp":"2025-10-17 09:34:24.641"}
|
||||||
|
{"caller":"initialize/mobile.go:17","content":"[GORM] SQL Executed","duration":"0.4ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'mobile' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:34:24.642"}
|
||||||
|
{"caller":"initialize/telegram.go:19","content":"[GORM] SQL Executed","duration":"0.3ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'telegram' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:34:24.642"}
|
||||||
|
{"caller":"trace/agent.go:46","content":"Starting agent","level":"info","timestamp":"2025-10-17 09:34:24.643"}
|
||||||
|
{"caller":"internal/server.go:87","content":"server start at 0.0.0.0:8888","level":"info","timestamp":"2025-10-17 09:34:24.643"}
|
||||||
|
{"caller":"scheduler/scheduler.go:55","content":"stop scheduler service","level":"info","timestamp":"2025-10-17 09:34:38.883"}
|
||||||
|
{"caller":"queue/queue.go:36","content":"stop consumer service","level":"info","timestamp":"2025-10-17 09:34:38.883"}
|
||||||
|
{"caller":"internal/server.go:108","content":"server shutdown","level":"info","timestamp":"2025-10-17 09:34:38.884"}
|
||||||
|
{"caller":"queue/queue.go:23","content":"start consumer service","level":"info","timestamp":"2025-10-17 09:35:25.934"}
|
||||||
|
{"caller":"scheduler/scheduler.go:26","content":"start scheduler service","level":"info","timestamp":"2025-10-17 09:35:25.934"}
|
||||||
|
{"caller":"initialize/version.go:21","content":"[Migrate] database not change","level":"info","timestamp":"2025-10-17 09:35:25.941"}
|
||||||
|
{"caller":"initialize/site.go:15","content":"[GORM] SQL Executed","duration":"0.9ms","level":"info","rows":7,"sql":"SELECT * FROM `system` WHERE `category` = 'site'","timestamp":"2025-10-17 09:35:25.942"}
|
||||||
|
{"caller":"initialize/node.go:17","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":9,"sql":"SELECT * FROM `system` WHERE `category` = 'server'","timestamp":"2025-10-17 09:35:25.943"}
|
||||||
|
{"caller":"internal/server.go:69","content":"[GORM] SQL Executed","duration":"0.6ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:35:25.944"}
|
||||||
|
{"caller":"initialize/node.go:70","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `category` = 'server' AND `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:35:25.944"}
|
||||||
|
{"caller":"initialize/email.go:18","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'email' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:35:25.945"}
|
||||||
|
{"caller":"initialize/device.go:16","content":"[GORM] SQL Executed","duration":"0.6ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'device' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:35:25.946"}
|
||||||
|
{"caller":"initialize/invite.go:15","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'invite'","timestamp":"2025-10-17 09:35:25.947"}
|
||||||
|
{"caller":"initialize/verify.go:23","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":5,"sql":"SELECT * FROM `system` WHERE `category` = 'verify'","timestamp":"2025-10-17 09:35:25.949"}
|
||||||
|
{"caller":"initialize/verify.go:41","content":"[GORM] SQL Executed","duration":"0.6ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'verify_code'","timestamp":"2025-10-17 09:35:25.950"}
|
||||||
|
{"caller":"initialize/subscribe.go:15","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":6,"sql":"SELECT * FROM `system` WHERE `category` = 'subscribe'","timestamp":"2025-10-17 09:35:25.951"}
|
||||||
|
{"caller":"initialize/register.go:15","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":8,"sql":"SELECT * FROM `system` WHERE `category` = 'register'","timestamp":"2025-10-17 09:35:25.952"}
|
||||||
|
{"caller":"initialize/mobile.go:17","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'mobile' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:35:25.953"}
|
||||||
|
{"caller":"initialize/telegram.go:19","content":"[GORM] SQL Executed","duration":"0.4ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'telegram' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:35:25.954"}
|
||||||
|
{"caller":"trace/agent.go:46","content":"Starting agent","level":"info","timestamp":"2025-10-17 09:35:25.954"}
|
||||||
|
{"caller":"internal/server.go:87","content":"server start at 0.0.0.0:8888","level":"info","timestamp":"2025-10-17 09:35:25.954"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:33","content":"[GORM] SQL Executed","duration":"3.5ms","level":"info","rows":4,"span":"23ea0d3dd45bef4b","sql":"SELECT * FROM `system` WHERE `category` = 'currency'","timestamp":"2025-10-17 09:35:51.484","trace":"f44ddbb808543a1db0e36ac991c5fbc6"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"0.9ms","level":"info","rows":8,"span":"23ea0d3dd45bef4b","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 09:35:51.485","trace":"f44ddbb808543a1db0e36ac991c5fbc6"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:79","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":1,"span":"23ea0d3dd45bef4b","sql":"SELECT * FROM `system` WHERE `key` = 'WebAD' ORDER BY `system`.`id` LIMIT 1","timestamp":"2025-10-17 09:35:51.487","trace":"f44ddbb808543a1db0e36ac991c5fbc6"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"8.180333ms","ip":"::1","level":"info","query":"","request":"GET localhost:8888/v1/common/site/config","span":"23ea0d3dd45bef4b","status":200,"timestamp":"2025-10-17 09:35:51.488","trace":"f44ddbb808543a1db0e36ac991c5fbc6","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"2.417µs","ip":"::1","level":"info","query":"","request":"GET localhost:8888/favicon.ico","span":"765789945009392c","status":404,"timestamp":"2025-10-17 09:35:51.505","trace":"83524d5ade65a4e5de8598c8629ed226","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"}
|
||||||
|
{"caller":"scheduler/scheduler.go:55","content":"stop scheduler service","level":"info","timestamp":"2025-10-17 09:36:17.890"}
|
||||||
|
{"caller":"queue/queue.go:36","content":"stop consumer service","level":"info","timestamp":"2025-10-17 09:36:17.892"}
|
||||||
|
{"caller":"queue/queue.go:23","content":"start consumer service","level":"info","timestamp":"2025-10-17 09:36:19.449"}
|
||||||
|
{"caller":"scheduler/scheduler.go:26","content":"start scheduler service","level":"info","timestamp":"2025-10-17 09:36:19.449"}
|
||||||
|
{"caller":"initialize/version.go:21","content":"[Migrate] database not change","level":"info","timestamp":"2025-10-17 09:36:19.457"}
|
||||||
|
{"caller":"initialize/site.go:15","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":7,"sql":"SELECT * FROM `system` WHERE `category` = 'site'","timestamp":"2025-10-17 09:36:19.458"}
|
||||||
|
{"caller":"initialize/node.go:17","content":"[GORM] SQL Executed","duration":"1.2ms","level":"info","rows":9,"sql":"SELECT * FROM `system` WHERE `category` = 'server'","timestamp":"2025-10-17 09:36:19.460"}
|
||||||
|
{"caller":"internal/server.go:69","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:36:19.461"}
|
||||||
|
{"caller":"initialize/node.go:70","content":"[GORM] SQL Executed","duration":"0.9ms","level":"info","rows":1,"sql":"SELECT * FROM `system` WHERE `category` = 'server' AND `key` = 'NodeMultiplierConfig'","timestamp":"2025-10-17 09:36:19.462"}
|
||||||
|
{"caller":"initialize/email.go:18","content":"[GORM] SQL Executed","duration":"0.6ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'email' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:36:19.463"}
|
||||||
|
{"caller":"initialize/device.go:16","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'device' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:36:19.463"}
|
||||||
|
{"caller":"initialize/invite.go:15","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'invite'","timestamp":"2025-10-17 09:36:19.464"}
|
||||||
|
{"caller":"initialize/verify.go:23","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":5,"sql":"SELECT * FROM `system` WHERE `category` = 'verify'","timestamp":"2025-10-17 09:36:19.465"}
|
||||||
|
{"caller":"initialize/verify.go:41","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":3,"sql":"SELECT * FROM `system` WHERE `category` = 'verify_code'","timestamp":"2025-10-17 09:36:19.466"}
|
||||||
|
{"caller":"initialize/subscribe.go:15","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":6,"sql":"SELECT * FROM `system` WHERE `category` = 'subscribe'","timestamp":"2025-10-17 09:36:19.466"}
|
||||||
|
{"caller":"initialize/register.go:15","content":"[GORM] SQL Executed","duration":"0.6ms","level":"info","rows":8,"sql":"SELECT * FROM `system` WHERE `category` = 'register'","timestamp":"2025-10-17 09:36:19.467"}
|
||||||
|
{"caller":"initialize/mobile.go:17","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'mobile' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:36:19.469"}
|
||||||
|
{"caller":"initialize/telegram.go:19","content":"[GORM] SQL Executed","duration":"0.5ms","level":"info","rows":1,"sql":"SELECT * FROM `auth_method` WHERE method = 'telegram' ORDER BY `auth_method`.`id` LIMIT 1","timestamp":"2025-10-17 09:36:19.469"}
|
||||||
|
{"caller":"trace/agent.go:46","content":"Starting agent","level":"info","timestamp":"2025-10-17 09:36:19.470"}
|
||||||
|
{"caller":"internal/server.go:87","content":"server start at 0.0.0.0:8080","level":"info","timestamp":"2025-10-17 09:36:19.470"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:33","content":"[GORM] SQL Executed","duration":"2.4ms","level":"info","rows":4,"span":"e3720526d2c6bebd","sql":"SELECT * FROM `system` WHERE `category` = 'currency'","timestamp":"2025-10-17 09:36:23.372","trace":"7a72be23eb1f252558c027732d1a15b1"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":8,"span":"e3720526d2c6bebd","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 09:36:23.374","trace":"7a72be23eb1f252558c027732d1a15b1"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:79","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":1,"span":"e3720526d2c6bebd","sql":"SELECT * FROM `system` WHERE `key` = 'WebAD' ORDER BY `system`.`id` LIMIT 1","timestamp":"2025-10-17 09:36:23.376","trace":"7a72be23eb1f252558c027732d1a15b1"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"8.298417ms","ip":"::1","level":"info","query":"","request":"GET localhost:8080/v1/common/site/config","span":"e3720526d2c6bebd","status":200,"timestamp":"2025-10-17 09:36:23.377","trace":"7a72be23eb1f252558c027732d1a15b1","user-agent":"Go-http-client/1.1"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"391.583µs","ip":"192.168.1.100","level":"info","query":"","request":"POST localhost:8080/v1/auth/login/device","request_body":"{\"identifier\":\"device-001\",\"user_agent\":\"TestAgent/1.0\"}","response_body":"{\"code\":500,\"msg\":\"Device login is disabled\"}","span":"4824a79c0640edee","status":200,"timestamp":"2025-10-17 09:36:23.379","trace":"a852e5e4ac87ab817310e695aade6c8a","user-agent":"Go-http-client/1.1"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":8,"span":"d06ea00d90ad1c47","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 09:36:29.384","trace":"73f36f8cadf14346785ce6b9f73711bd"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"1.671166ms","ip":"::1","level":"info","query":"","request":"GET localhost:8080/v1/common/site/config","span":"d06ea00d90ad1c47","status":200,"timestamp":"2025-10-17 09:36:29.384","trace":"73f36f8cadf14346785ce6b9f73711bd","user-agent":"curl/8.7.1"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"8.2ms","level":"info","rows":8,"span":"4986cbc59b822fc5","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 09:36:37.414","trace":"a2b8f7ee63d9e0d38b54d59a3d736071"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"9.138042ms","ip":"::1","level":"info","query":"","request":"GET localhost:8080/v1/common/site/config","span":"4986cbc59b822fc5","status":200,"timestamp":"2025-10-17 09:36:37.414","trace":"a2b8f7ee63d9e0d38b54d59a3d736071","user-agent":"curl/8.7.1"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":8,"span":"dd41f835e4cfedd6","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 09:36:41.131","trace":"f854a0e96eebb1c50b355c3224599d72"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"1.6465ms","ip":"::1","level":"info","query":"","request":"GET localhost:8080/v1/common/site/config","span":"dd41f835e4cfedd6","status":200,"timestamp":"2025-10-17 09:36:41.131","trace":"f854a0e96eebb1c50b355c3224599d72","user-agent":"Go-http-client/1.1"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"104.916µs","ip":"192.168.1.100","level":"info","query":"","request":"POST localhost:8080/v1/auth/login/device","request_body":"{\"identifier\":\"device-001\",\"user_agent\":\"TestAgent/1.0\"}","response_body":"{\"code\":500,\"msg\":\"Device login is disabled\"}","span":"83a85bacb229a286","status":200,"timestamp":"2025-10-17 09:36:41.132","trace":"ee8e5f35edf0f3a0534980f842feaae6","user-agent":"Go-http-client/1.1"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:37:19","level":"info","timestamp":"2025-10-17 09:37:19.595"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"10.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:37:19.612"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:37:19.612"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:37:19.613' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:37:19.617"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:37:19.617"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"847.75µs","error":"UserAgent is a required field","ip":"::1","level":"info","query":"","request":"POST localhost:8080/v1/auth/login/device","request_body":"{\"identifier\":\"device-001\"}","response_body":"{\"code\":400,\"msg\":\"UserAgent is a required field\"}","span":"806eee7134c85656","status":200,"timestamp":"2025-10-17 09:37:37.117","trace":"147a42ddb57fec3df54d2be5ce791020","user-agent":"TestAgent/1.0"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:38:19","level":"info","timestamp":"2025-10-17 09:38:19.733"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:38:19.745"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:38:19.745"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:38:19.747' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:38:19.749"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:38:19.749"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:39:19","level":"info","timestamp":"2025-10-17 09:39:19.879"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:39:19.887"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:39:19.888"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:39:19.889' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:39:19.890"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:39:19.890"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:40:19","level":"info","timestamp":"2025-10-17 09:40:19.022"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:40:19.042"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:40:19.042"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:40:19.044' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:40:19.046"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:40:19.046"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"4.6ms","level":"info","rows":8,"span":"23bd7b723e08cddd","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 09:41:16.399","trace":"a0d2b8d305804b3795020e8e52d693d8"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"6.011917ms","ip":"::1","level":"info","query":"","request":"GET localhost:8080/v1/common/site/config","span":"23bd7b723e08cddd","status":200,"timestamp":"2025-10-17 09:41:16.399","trace":"a0d2b8d305804b3795020e8e52d693d8","user-agent":"Go-http-client/1.1"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"1.458µs","ip":"::1","level":"info","query":"","request":"POST localhost:8080/v1/auth/v1/auth/login/device","request_body":"{\"identifier\":\"device-001\"}","response_body":"","span":"1c950034b1268b62","status":404,"timestamp":"2025-10-17 09:41:16.400","trace":"152890c268ed39bed7aa0341587345a5","user-agent":"TestAgent/1.0"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:41:19","level":"info","timestamp":"2025-10-17 09:41:19.167"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:41:19.171"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:41:19.171"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:41:19.173' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:41:19.175"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:41:19.175"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:42:19","level":"info","timestamp":"2025-10-17 09:42:19.320"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:42:19.328"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:42:19.328"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:42:19.331' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:42:19.334"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:42:19.334"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:43:19","level":"info","timestamp":"2025-10-17 09:43:19.473"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:43:19.486"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:43:19.486"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:43:19.488' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:43:19.490"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:43:19.490"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:44:19","level":"info","timestamp":"2025-10-17 09:44:19.625"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:44:19.631"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:44:19.631"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:44:19.637' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:44:19.641"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:44:19.642"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:45:19","level":"info","timestamp":"2025-10-17 09:45:19.774"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:45:19.780"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:45:19.780"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:45:19.78' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:45:19.782"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:45:19.782"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:46:19","level":"info","timestamp":"2025-10-17 09:46:19.921"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:46:19.936"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:46:19.936"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:46:19.937' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:46:19.938"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:46:19.938"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:47:19","level":"info","timestamp":"2025-10-17 09:47:19.081"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:47:19.083"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:47:19.083"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:47:19.084' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:47:19.085"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:47:19.085"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:48:19","level":"info","timestamp":"2025-10-17 09:48:19.266"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:48:19.275"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:48:19.275"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:48:19.277' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:48:19.279"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:48:19.279"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:49:19","level":"info","timestamp":"2025-10-17 09:49:19.467"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:49:19.482"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:49:19.482"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:49:19.484' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:49:19.486"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:49:19.486"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:50:19","level":"info","timestamp":"2025-10-17 09:50:19.667"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:50:19.670"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:50:19.670"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:50:19.672' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:50:19.674"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:50:19.674"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"105.25µs","error":"UserAgent is a required field","ip":"::1","level":"info","query":"","request":"POST localhost:8080/v1/auth/login/device","request_body":"{\"identifier\":\"device-001\"}","response_body":"{\"code\":400,\"msg\":\"UserAgent is a required field\"}","span":"5b74d72a7c93dec9","status":200,"timestamp":"2025-10-17 09:51:17.738","trace":"a07177cb7dbc846fe572075764154cef","user-agent":"TestAgent/1.0"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:51:19","level":"info","timestamp":"2025-10-17 09:51:19.857"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"8.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:51:19.867"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:51:19.867"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:51:19.869' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:51:19.872"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:51:19.872"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:52:20","level":"info","timestamp":"2025-10-17 09:52:20.005"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:52:20.022"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:52:20.022"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:52:20.024' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:52:20.027"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:52:20.027"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:53:19","level":"info","timestamp":"2025-10-17 09:53:19.151"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:53:19.155"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:53:19.155"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:53:19.157' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:53:19.159"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:53:19.159"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:54:19","level":"info","timestamp":"2025-10-17 09:54:19.296"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:54:19.306"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:54:19.306"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:54:19.308' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:54:19.311"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:54:19.311"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:55:19","level":"info","timestamp":"2025-10-17 09:55:19.434"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:55:19.449"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:55:19.449"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:55:19.451' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:55:19.453"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:55:19.453"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:56:19","level":"info","timestamp":"2025-10-17 09:56:19.581"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:56:19.585"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:56:19.585"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:56:19.588' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:56:19.590"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:56:19.590"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:57:19","level":"info","timestamp":"2025-10-17 09:57:19.780"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"10.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:57:19.792"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:57:19.793"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:57:19.794' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:57:19.798"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:57:19.798"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:58:19","level":"info","timestamp":"2025-10-17 09:58:19.983"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:58:19.998"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:58:19.999"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:58:20.001' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:58:20.003"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:58:20.003"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 09:59:19","level":"info","timestamp":"2025-10-17 09:59:19.167"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 09:59:19.171"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:59:19.171"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 00:59:19.173' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 09:59:19.176"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 09:59:19.176"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"26.3ms","level":"info","rows":8,"span":"f6ae781646a62766","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 09:59:55.005","trace":"d850ac206b9f71411ad2290fed1b909b"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"29.533458ms","ip":"::1","level":"info","query":"","request":"GET localhost:8080/v1/common/site/config","span":"f6ae781646a62766","status":200,"timestamp":"2025-10-17 09:59:55.006","trace":"d850ac206b9f71411ad2290fed1b909b","user-agent":"Go-http-client/1.1"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"1.833µs","ip":"::1","level":"info","query":"","request":"POST localhost:8080/v1/auth/v1/auth/login/device","request_body":"{\"identifier\":\"device-001\",\"user_agent\":\"TestAgent/1.0\"}","response_body":"","span":"440b193d1228926f","status":404,"timestamp":"2025-10-17 09:59:55.007","trace":"76718a7641d7c60bc470a2d545af0954","user-agent":"TestAgent/1.0"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"134.708µs","ip":"::1","level":"info","query":"","request":"POST localhost:8080/v1/auth/login/device","request_body":"{\"identifier\":\"device-001\",\"user_agent\":\"TestAgent/1.0\"}","response_body":"{\"code\":500,\"msg\":\"Device login is disabled\"}","span":"af587e583111e034","status":200,"timestamp":"2025-10-17 10:00:10.476","trace":"17202798a9b492c1305ffa9b20b98cf0","user-agent":"curl/8.7.1"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:00:19","level":"info","timestamp":"2025-10-17 10:00:19.327"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:00:19.330"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:00:19.330"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:00:19.331' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:00:19.332"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:00:19.332"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:01:19","level":"info","timestamp":"2025-10-17 10:01:19.466"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:01:19.478"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:01:19.478"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:01:19.479' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:01:19.480"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:01:19.480"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:02:19","level":"info","timestamp":"2025-10-17 10:02:19.612"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:02:19.615"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:02:19.616"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:02:19.617' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:02:19.619"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:02:19.619"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:03:19","level":"info","timestamp":"2025-10-17 10:03:19.763"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:03:19.766"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:03:19.766"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:03:19.767' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:03:19.770"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:03:19.770"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:04:19","level":"info","timestamp":"2025-10-17 10:04:19.901"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:04:19.911"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:04:19.911"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:04:19.912' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:04:19.913"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:04:19.913"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:05:19","level":"info","timestamp":"2025-10-17 10:05:19.034"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:05:19.038"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:05:19.038"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:05:19.04' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:05:19.044"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:05:19.044"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:06:19","level":"info","timestamp":"2025-10-17 10:06:19.187"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:06:19.193"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:06:19.194"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:06:19.195' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:06:19.198"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:06:19.198"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:07:19","level":"info","timestamp":"2025-10-17 10:07:19.329"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:07:19.339"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:07:19.340"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:07:19.341' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:07:19.342"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:07:19.342"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:08:19","level":"info","timestamp":"2025-10-17 10:08:19.474"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:08:19.478"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:08:19.479"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:08:19.481' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:08:19.483"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:08:19.483"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:09:19","level":"info","timestamp":"2025-10-17 10:09:19.632"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:09:19.638"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:09:19.638"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:09:19.639' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:09:19.641"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:09:19.641"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:10:19","level":"info","timestamp":"2025-10-17 10:10:19.788"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:10:19.792"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:10:19.792"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:10:19.793' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:10:19.795"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:10:19.795"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:11:19","level":"info","timestamp":"2025-10-17 10:11:19.930"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:11:19.934"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:11:19.934"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:11:19.936' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:11:19.939"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:11:19.939"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:12:19","level":"info","timestamp":"2025-10-17 10:12:19.066"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:12:19.075"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:12:19.075"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:12:19.077' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:12:19.080"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:12:19.080"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:13:19","level":"info","timestamp":"2025-10-17 10:13:19.233"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:13:19.242"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:13:19.242"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:13:19.243' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:13:19.246"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:13:19.246"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:14:19","level":"info","timestamp":"2025-10-17 10:14:19.405"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:14:19.409"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:14:19.409"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:14:19.411' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:14:19.414"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:14:19.414"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:15:19","level":"info","timestamp":"2025-10-17 10:15:19.573"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:15:19.579"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:15:19.579"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:15:19.581' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:15:19.582"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:15:19.583"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:16:19","level":"info","timestamp":"2025-10-17 10:16:19.745"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:16:19.752"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:16:19.752"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:16:19.755' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:16:19.758"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:16:19.759"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:17:19","level":"info","timestamp":"2025-10-17 10:17:19.918"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:17:19.919"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:17:19.919"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:17:19.919' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:17:19.920"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:17:19.920"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:18:19","level":"info","timestamp":"2025-10-17 10:18:19.056"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:18:19.060"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:18:19.060"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:18:19.061' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:18:19.062"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:18:19.062"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:19:19","level":"info","timestamp":"2025-10-17 10:19:19.202"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:19:19.215"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:19:19.216"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:19:19.218' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:19:19.223"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:19:19.223"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:20:19","level":"info","timestamp":"2025-10-17 10:20:19.349"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:20:19.353"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:20:19.353"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:20:19.355' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:20:19.358"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:20:19.358"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:21:19","level":"info","timestamp":"2025-10-17 10:21:19.489"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:21:19.495"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:21:19.495"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:21:19.496' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:21:19.497"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:21:19.498"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:22:19","level":"info","timestamp":"2025-10-17 10:22:19.633"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:22:19.637"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:22:19.637"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:22:19.638' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:22:19.639"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:22:19.639"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:23:19","level":"info","timestamp":"2025-10-17 10:23:19.797"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:23:19.801"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:23:19.801"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:23:19.804' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:23:19.806"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:23:19.806"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:24:19","level":"info","timestamp":"2025-10-17 10:24:19.972"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:24:19.979"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:24:19.979"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:24:19.981' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:24:19.983"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:24:19.983"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:25:19","level":"info","timestamp":"2025-10-17 10:25:19.165"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:25:19.179"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:25:19.179"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:25:19.181' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:25:19.184"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:25:19.184"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:26:19","level":"info","timestamp":"2025-10-17 10:26:19.352"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:26:19.356"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:26:19.356"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:26:19.358' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:26:19.360"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:26:19.360"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:27:19","level":"info","timestamp":"2025-10-17 10:27:19.528"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:27:19.538"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:27:19.538"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:27:19.54' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:27:19.543"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:27:19.543"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 10:44:27","level":"info","timestamp":"2025-10-17 10:44:27.766"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 10:44:27.771"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:44:27.771"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 01:44:27.772' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 10:44:27.773"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 10:44:27.773"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:01:10","level":"info","timestamp":"2025-10-17 19:01:10.775"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:01:10.783"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:01:10.783"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:01:10.786' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:01:10.789"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:01:10.789"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:02:10","level":"info","timestamp":"2025-10-17 19:02:10.910"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:02:10.917"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:02:10.917"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:02:10.919' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:02:10.921"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:02:10.922"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:03:10","level":"info","timestamp":"2025-10-17 19:03:10.041"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:03:10.047"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:03:10.047"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:03:10.048' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:03:10.050"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:03:10.050"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:04:10","level":"info","timestamp":"2025-10-17 19:04:10.185"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:04:10.190"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:04:10.190"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:04:10.191' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:04:10.192"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:04:10.192"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:05:10","level":"info","timestamp":"2025-10-17 19:05:10.305"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"10.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:05:10.321"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:05:10.321"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:05:10.323' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:05:10.326"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:05:10.326"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:06:10","level":"info","timestamp":"2025-10-17 19:06:10.454"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:06:10.461"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:06:10.461"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:06:10.463' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:06:10.465"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:06:10.466"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:07:10","level":"info","timestamp":"2025-10-17 19:07:10.604"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:07:10.619"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:07:10.619"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:07:10.621' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:07:10.624"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:07:10.624"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:08:10","level":"info","timestamp":"2025-10-17 19:08:10.750"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:08:10.755"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:08:10.755"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:08:10.758' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:08:10.762"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:08:10.762"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:09:10","level":"info","timestamp":"2025-10-17 19:09:10.903"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:09:10.907"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:09:10.907"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:09:10.91' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:09:10.913"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:09:10.913"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:10:10","level":"info","timestamp":"2025-10-17 19:10:10.056"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:10:10.075"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:10:10.075"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:10:10.082' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:10:10.083"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:10:10.083"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:11:10","level":"info","timestamp":"2025-10-17 19:11:10.255"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:11:10.260"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:11:10.260"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:11:10.262' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:11:10.265"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:11:10.265"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:12:10","level":"info","timestamp":"2025-10-17 19:12:10.438"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:12:10.446"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:12:10.446"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:12:10.448' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:12:10.450"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:12:10.450"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:13:10","level":"info","timestamp":"2025-10-17 19:13:10.633"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:13:10.648"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:13:10.648"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:13:10.649' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:13:10.651"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:13:10.652"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:14:10","level":"info","timestamp":"2025-10-17 19:14:10.831"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:14:10.835"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:14:10.835"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:14:10.838' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:14:10.841"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:14:10.841"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:15:10","level":"info","timestamp":"2025-10-17 19:15:10.996"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:15:11.005"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:15:11.005"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:15:11.007' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:15:11.010"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:15:11.010"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:16:10","level":"info","timestamp":"2025-10-17 19:16:10.137"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:16:10.154"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:16:10.154"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:16:10.156' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:16:10.159"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:16:10.159"}
|
||||||
|
{"caller":"common/getGlobalConfigLogic.go:63","content":"[GORM] SQL Executed","duration":"10.1ms","level":"info","rows":8,"span":"45d6f5732ebdebfb","sql":"SELECT * FROM `auth_method`","timestamp":"2025-10-17 19:16:18.696","trace":"5819489c3278b121ef85e2e69170978f"}
|
||||||
|
{"caller":"middleware/loggerMiddleware.go:92","content":"HTTP Request","duration":"13.2645ms","ip":"::1","level":"info","query":"","request":"GET localhost:8080/v1/common/site/config","span":"45d6f5732ebdebfb","status":200,"timestamp":"2025-10-17 19:16:18.696","trace":"5819489c3278b121ef85e2e69170978f","user-agent":"Go-http-client/1.1"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:17:10","level":"info","timestamp":"2025-10-17 19:17:10.280"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:17:10.288"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:17:10.288"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:17:10.296' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:17:10.298"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:17:10.298"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:18:10","level":"info","timestamp":"2025-10-17 19:18:10.409"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:18:10.416"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:18:10.416"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:18:10.418' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:18:10.420"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:18:10.420"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:19:10","level":"info","timestamp":"2025-10-17 19:19:10.467"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:19:10.482"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:19:10.482"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:19:10.483' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:19:10.485"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:19:10.485"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:20:10","level":"info","timestamp":"2025-10-17 19:20:10.627"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:20:10.628"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:20:10.628"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:20:10.629' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:20:10.630"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:20:10.630"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:21:10","level":"info","timestamp":"2025-10-17 19:21:10.773"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:21:10.781"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:21:10.781"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:21:10.782' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:21:10.784"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:21:10.784"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:22:10","level":"info","timestamp":"2025-10-17 19:22:10.919"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:22:10.924"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:22:10.924"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:22:10.925' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:22:10.926"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:22:10.926"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:23:10","level":"info","timestamp":"2025-10-17 19:23:10.042"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:23:10.044"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:23:10.044"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:23:10.046' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:23:10.047"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:23:10.047"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:24:10","level":"info","timestamp":"2025-10-17 19:24:10.191"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"9.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:24:10.202"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:24:10.202"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:24:10.203' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:24:10.204"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:24:10.205"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:25:10","level":"info","timestamp":"2025-10-17 19:25:10.318"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:25:10.325"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:25:10.325"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:25:10.327' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:25:10.329"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:25:10.329"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:26:10","level":"info","timestamp":"2025-10-17 19:26:10.457"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:26:10.459"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:26:10.459"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:26:10.461' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:26:10.462"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:26:10.462"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:27:10","level":"info","timestamp":"2025-10-17 19:27:10.570"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:27:10.575"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:27:10.575"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:27:10.577' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:27:10.579"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:27:10.579"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:28:10","level":"info","timestamp":"2025-10-17 19:28:10.713"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:28:10.719"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:28:10.719"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:28:10.72' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:28:10.721"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:28:10.721"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:29:10","level":"info","timestamp":"2025-10-17 19:29:10.854"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:29:10.857"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:29:10.857"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:29:10.858' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:29:10.860"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:29:10.860"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:30:10","level":"info","timestamp":"2025-10-17 19:30:10.995"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:30:11.000"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:30:11.000"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:30:11.002' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:30:11.005"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:30:11.005"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:31:10","level":"info","timestamp":"2025-10-17 19:31:10.141"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:31:10.144"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:31:10.144"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:31:10.145' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:31:10.147"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:31:10.147"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:32:10","level":"info","timestamp":"2025-10-17 19:32:10.259"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:32:10.265"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:32:10.265"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:32:10.267' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:32:10.270"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:32:10.270"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:33:10","level":"info","timestamp":"2025-10-17 19:33:10.409"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:33:10.417"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:33:10.417"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:33:10.421' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:33:10.424"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:33:10.424"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:34:10","level":"info","timestamp":"2025-10-17 19:34:10.648"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:34:10.653"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:34:10.653"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:34:10.654' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:34:10.655"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:34:10.655"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:35:10","level":"info","timestamp":"2025-10-17 19:35:10.787"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:35:10.789"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:35:10.789"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:35:10.79' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:35:10.791"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:35:10.791"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:36:10","level":"info","timestamp":"2025-10-17 19:36:10.952"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:36:10.957"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:36:10.957"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:36:10.958' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:36:10.959"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:36:10.959"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:37:10","level":"info","timestamp":"2025-10-17 19:37:10.113"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:37:10.123"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:37:10.124"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:37:10.126' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:37:10.130"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:37:10.130"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:38:10","level":"info","timestamp":"2025-10-17 19:38:10.281"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:38:10.286"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:38:10.286"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:38:10.288' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:38:10.291"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:38:10.291"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:39:10","level":"info","timestamp":"2025-10-17 19:39:10.444"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:39:10.449"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:39:10.449"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:39:10.45' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:39:10.451"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:39:10.451"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:40:10","level":"info","timestamp":"2025-10-17 19:40:10.624"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:40:10.635"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:40:10.635"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:40:10.638' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:40:10.640"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:40:10.640"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:41:10","level":"info","timestamp":"2025-10-17 19:41:10.833"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:41:10.839"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:41:10.839"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:41:10.841' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:41:10.846"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:41:10.846"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:42:10","level":"info","timestamp":"2025-10-17 19:42:10.050"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:42:10.057"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:42:10.057"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:42:10.06' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:42:10.063"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:42:10.063"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:43:10","level":"info","timestamp":"2025-10-17 19:43:10.271"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:43:10.281"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:43:10.281"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:43:10.283' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:43:10.286"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:43:10.286"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:44:10","level":"info","timestamp":"2025-10-17 19:44:10.479"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:44:10.483"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:44:10.483"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:44:10.486' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:44:10.488"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:44:10.488"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:45:10","level":"info","timestamp":"2025-10-17 19:45:10.695"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:45:10.705"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:45:10.705"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:45:10.707' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:45:10.711"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:45:10.711"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:46:10","level":"info","timestamp":"2025-10-17 19:46:10.906"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"8.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:46:10.916"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:46:10.916"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:46:10.919' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:46:10.921"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:46:10.921"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:47:10","level":"info","timestamp":"2025-10-17 19:47:10.128"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:47:10.132"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:47:10.132"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:47:10.135' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:47:10.138"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:47:10.138"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:48:10","level":"info","timestamp":"2025-10-17 19:48:10.340"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"9.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:48:10.352"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:48:10.352"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:48:10.355' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:48:10.358"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:48:10.358"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:49:10","level":"info","timestamp":"2025-10-17 19:49:10.547"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:49:10.553"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:49:10.553"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:49:10.554' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:49:10.555"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:49:10.555"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:50:10","level":"info","timestamp":"2025-10-17 19:50:10.726"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:50:10.731"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:50:10.731"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:50:10.733' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:50:10.737"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:50:10.737"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:51:10","level":"info","timestamp":"2025-10-17 19:51:10.918"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:51:10.926"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:51:10.926"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:51:10.929' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:51:10.932"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:51:10.932"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:52:10","level":"info","timestamp":"2025-10-17 19:52:10.118"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:52:10.132"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:52:10.132"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"9.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:52:10.134' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:52:10.143"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:52:10.143"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:53:10","level":"info","timestamp":"2025-10-17 19:53:10.333"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:53:10.338"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:53:10.338"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:53:10.341' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:53:10.345"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:53:10.345"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:54:10","level":"info","timestamp":"2025-10-17 19:54:10.526"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:54:10.536"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:54:10.537"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:54:10.539' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:54:10.542"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:54:10.542"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-17 19:59:38","level":"info","timestamp":"2025-10-17 19:59:38.965"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-17 19:59:38.981"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:59:38.981"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 10:59:38.983' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-17 19:59:38.989"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-17 19:59:38.989"}
|
||||||
235
logs/access.log-2025-10-18
Normal file
235
logs/access.log-2025-10-18
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:48:13","level":"info","timestamp":"2025-10-18 03:48:13.806"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:48:13.819"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:48:13.819"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:48:13.821' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:48:13.826"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:48:13.826"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:49:13","level":"info","timestamp":"2025-10-18 03:49:13.983"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:49:13.991"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:49:13.991"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:49:13.994' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:49:13.997"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:49:13.997"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:50:13","level":"info","timestamp":"2025-10-18 03:50:13.159"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:50:13.163"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:50:13.163"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:50:13.165' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:50:13.168"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:50:13.169"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:51:13","level":"info","timestamp":"2025-10-18 03:51:13.323"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:51:13.333"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:51:13.333"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:51:13.334' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:51:13.336"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:51:13.336"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:52:13","level":"info","timestamp":"2025-10-18 03:52:13.464"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:52:13.472"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:52:13.473"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:52:13.473' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:52:13.474"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:52:13.474"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:53:13","level":"info","timestamp":"2025-10-18 03:53:13.665"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:53:13.668"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:53:13.668"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:53:13.669' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:53:13.670"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:53:13.670"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:54:13","level":"info","timestamp":"2025-10-18 03:54:13.815"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:54:13.840"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:54:13.840"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"0.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:54:13.843' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:54:13.843"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:54:13.843"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:55:13","level":"info","timestamp":"2025-10-18 03:55:13.978"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:55:13.981"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:55:13.981"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:55:13.983' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:55:13.985"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:55:13.985"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:56:13","level":"info","timestamp":"2025-10-18 03:56:13.142"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:56:13.147"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:56:13.147"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:56:13.15' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:56:13.153"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:56:13.153"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:57:13","level":"info","timestamp":"2025-10-18 03:57:13.306"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"6.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:57:13.334"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:57:13.334"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:57:13.336' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:57:13.337"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:57:13.337"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:58:13","level":"info","timestamp":"2025-10-18 03:58:13.484"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:58:13.489"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:58:13.489"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:58:13.49' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:58:13.492"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:58:13.492"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 03:59:13","level":"info","timestamp":"2025-10-18 03:59:13.702"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 03:59:13.707"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:59:13.707"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 18:59:13.711' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 03:59:13.714"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 03:59:13.714"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:00:13","level":"info","timestamp":"2025-10-18 04:00:13.936"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:00:13.965"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:00:13.965"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:00:13.966' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:00:13.967"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:00:13.967"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:01:13","level":"info","timestamp":"2025-10-18 04:01:13.145"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:01:13.149"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:01:13.149"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:01:13.152' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:01:13.153"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:01:13.153"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:02:13","level":"info","timestamp":"2025-10-18 04:02:13.353"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:02:13.357"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:02:13.357"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:02:13.361' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:02:13.363"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:02:13.363"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:03:13","level":"info","timestamp":"2025-10-18 04:03:13.563"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:03:13.570"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:03:13.570"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:03:13.574' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:03:13.577"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:03:13.577"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:04:13","level":"info","timestamp":"2025-10-18 04:04:13.773"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:04:13.778"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:04:13.778"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:04:13.781' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:04:13.784"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:04:13.784"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:05:13","level":"info","timestamp":"2025-10-18 04:05:13.943"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:05:13.948"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:05:13.948"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:05:13.951' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:05:13.955"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:05:13.955"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:06:13","level":"info","timestamp":"2025-10-18 04:06:13.119"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:06:13.129"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:06:13.129"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:06:13.132' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:06:13.136"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:06:13.136"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:07:13","level":"info","timestamp":"2025-10-18 04:07:13.285"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:07:13.287"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:07:13.287"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:07:13.288' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:07:13.289"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:07:13.289"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:08:13","level":"info","timestamp":"2025-10-18 04:08:13.467"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:08:13.472"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:08:13.472"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:08:13.475' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:08:13.478"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:08:13.478"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:09:13","level":"info","timestamp":"2025-10-18 04:09:13.669"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:09:13.681"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:09:13.681"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:09:13.685' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:09:13.689"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:09:13.689"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:10:13","level":"info","timestamp":"2025-10-18 04:10:13.879"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:10:13.882"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:10:13.882"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:10:13.885' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:10:13.889"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:10:13.889"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:11:13","level":"info","timestamp":"2025-10-18 04:11:13.083"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:11:13.088"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:11:13.088"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:11:13.091' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:11:13.094"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:11:13.094"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:12:13","level":"info","timestamp":"2025-10-18 04:12:13.295"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"11.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:12:13.327"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:12:13.328"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:12:13.329' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:12:13.330"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:12:13.330"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:13:13","level":"info","timestamp":"2025-10-18 04:13:13.507"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:13:13.513"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:13:13.513"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:13:13.516' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:13:13.519"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:13:13.519"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:14:13","level":"info","timestamp":"2025-10-18 04:14:13.734"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:14:13.740"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:14:13.740"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:14:13.743' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:14:13.747"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:14:13.747"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:15:13","level":"info","timestamp":"2025-10-18 04:15:13.947"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:15:13.973"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:15:13.973"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:15:13.974' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:15:13.976"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:15:13.976"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:16:13","level":"info","timestamp":"2025-10-18 04:16:13.159"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:16:13.163"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:16:13.163"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:16:13.165' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:16:13.169"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:16:13.169"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:17:13","level":"info","timestamp":"2025-10-18 04:17:13.384"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:17:13.389"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:17:13.389"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:17:13.392' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:17:13.395"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:17:13.395"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:18:13","level":"info","timestamp":"2025-10-18 04:18:13.604"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:18:13.633"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:18:13.634"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:18:13.635' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:18:13.637"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:18:13.637"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:19:13","level":"info","timestamp":"2025-10-18 04:19:13.808"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:19:13.812"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:19:13.812"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:19:13.816' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:19:13.819"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:19:13.819"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:20:14","level":"info","timestamp":"2025-10-18 04:20:14.010"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:20:14.015"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:20:14.015"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:20:14.019' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:20:14.022"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:20:14.022"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:21:13","level":"info","timestamp":"2025-10-18 04:21:13.212"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"5.1ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:21:13.241"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:21:13.241"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:21:13.243' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:21:13.244"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:21:13.244"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:22:13","level":"info","timestamp":"2025-10-18 04:22:13.425"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:22:13.429"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:22:13.430"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.4ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:22:13.432' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:22:13.435"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:22:13.435"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:23:13","level":"info","timestamp":"2025-10-18 04:23:13.651"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:23:13.657"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:23:13.657"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:23:13.66' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:23:13.664"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:23:13.664"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 04:24:13","level":"info","timestamp":"2025-10-18 04:24:13.852"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"7.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 04:24:13.879"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:24:13.879"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 19:24:13.881' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 04:24:13.884"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 04:24:13.884"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 06:10:31","level":"info","timestamp":"2025-10-18 06:10:31.049"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 06:10:31.056"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 06:10:31.056"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 21:10:31.058' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 06:10:31.061"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 06:10:31.061"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 06:11:30","level":"info","timestamp":"2025-10-18 06:11:30.219"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 06:11:30.225"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 06:11:30.225"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 21:11:30.227' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 06:11:30.230"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 06:11:30.230"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 06:17:12","level":"info","timestamp":"2025-10-18 06:17:12.393"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 06:17:12.399"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 06:17:12.399"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-18 21:17:12.4' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 06:17:12.401"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 06:17:12.401"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 18:00:51","level":"info","timestamp":"2025-10-18 18:00:51.432"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 18:00:51.438"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 18:00:51.438"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-19 09:00:51.439' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 18:00:51.441"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 18:00:51.441"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 18:01:51","level":"info","timestamp":"2025-10-18 18:01:51.599"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 18:01:51.603"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 18:01:51.603"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.8ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-19 09:01:51.605' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 18:01:51.606"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 18:01:51.606"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 18:07:27","level":"info","timestamp":"2025-10-18 18:07:27.842"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 18:07:27.848"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 18:07:27.848"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.5ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-19 09:07:27.851' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 18:07:27.853"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 18:07:27.853"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 21:23:51","level":"info","timestamp":"2025-10-18 21:23:51.591"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 21:23:51.596"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 21:23:51.596"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.0ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-19 12:23:51.608' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 21:23:51.609"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 21:23:51.609"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 23:03:17","level":"info","timestamp":"2025-10-18 23:03:17.708"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"4.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 23:03:17.716"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 23:03:17.716"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.2ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-19 14:03:17.718' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 23:03:17.720"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 23:03:17.720"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 23:04:16","level":"info","timestamp":"2025-10-18 23:04:16.864"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"3.3ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 23:04:16.871"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 23:04:16.871"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"2.7ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-19 14:04:16.873' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 23:04:16.876"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 23:04:16.876"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:29","content":"[CheckSubscription] Start check subscription: 2025-10-18 23:20:22","level":"info","timestamp":"2025-10-18 23:20:22.736"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.6ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE upload + download >= traffic AND status IN (0, 1) AND traffic > 0 ","timestamp":"2025-10-18 23:20:22.738"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:67","content":"[Check Subscription Traffic] No subscribe need to update","level":"info","timestamp":"2025-10-18 23:20:22.738"}
|
||||||
|
{"caller":"user/default.go:156","content":"[GORM] SQL Executed","duration":"1.9ms","level":"info","rows":0,"sql":"SELECT * FROM `user_subscribe` WHERE `status` IN (0, 1) AND `expire_time` < '2025-10-19 14:20:22.74' AND `expire_time` != '1970-01-01 08:00:00' and `finished_at` IS NULL","timestamp":"2025-10-18 23:20:22.742"}
|
||||||
|
{"caller":"subscription/checkSubscriptionLogic.go:109","content":"[Check Subscription Expire] No subscribe need to update","level":"info","timestamp":"2025-10-18 23:20:22.742"}
|
||||||
@ -8,4 +8,5 @@ const (
|
|||||||
CtxKeyRequestHost CtxKey = "requestHost"
|
CtxKeyRequestHost CtxKey = "requestHost"
|
||||||
CtxKeyPlatform CtxKey = "platform"
|
CtxKeyPlatform CtxKey = "platform"
|
||||||
CtxKeyPayment CtxKey = "payment"
|
CtxKeyPayment CtxKey = "payment"
|
||||||
|
LoginType CtxKey = "loginType"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -3,5 +3,5 @@ package tool
|
|||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestEncodePassWord(t *testing.T) {
|
func TestEncodePassWord(t *testing.T) {
|
||||||
t.Logf("EncodePassWord: %v", EncodePassWord(""))
|
t.Logf("EncodePassWord: %v", EncodePassWord("password"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,7 @@ const (
|
|||||||
ErrorTokenExpire uint32 = 40004
|
ErrorTokenExpire uint32 = 40004
|
||||||
InvalidAccess uint32 = 40005
|
InvalidAccess uint32 = 40005
|
||||||
InvalidCiphertext uint32 = 40006
|
InvalidCiphertext uint32 = 40006
|
||||||
|
SecretIsEmpty uint32 = 40007
|
||||||
)
|
)
|
||||||
|
|
||||||
//coupon error
|
//coupon error
|
||||||
|
|||||||
@ -14,6 +14,7 @@ func init() {
|
|||||||
ErrorTokenEmpty: "User token is empty",
|
ErrorTokenEmpty: "User token is empty",
|
||||||
ErrorTokenInvalid: "User token is invalid",
|
ErrorTokenInvalid: "User token is invalid",
|
||||||
ErrorTokenExpire: "User token is expired",
|
ErrorTokenExpire: "User token is expired",
|
||||||
|
SecretIsEmpty: "Secret is empty",
|
||||||
InvalidAccess: "Invalid access",
|
InvalidAccess: "Invalid access",
|
||||||
InvalidCiphertext: "Invalid ciphertext",
|
InvalidCiphertext: "Invalid ciphertext",
|
||||||
// Database error
|
// Database error
|
||||||
|
|||||||
@ -179,8 +179,8 @@ func (l *ActivateOrderLogic) NewPurchase(ctx context.Context, orderInfo *order.O
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle commission in separate goroutine to avoid blocking
|
// Handle referral reward in separate goroutine to avoid blocking
|
||||||
go l.handleCommission(context.Background(), userInfo, orderInfo)
|
go l.handleReferralReward(context.Background(), userInfo, orderInfo)
|
||||||
|
|
||||||
// Clear cache
|
// Clear cache
|
||||||
l.clearServerCache(ctx, sub)
|
l.clearServerCache(ctx, sub)
|
||||||
@ -192,12 +192,12 @@ func (l *ActivateOrderLogic) NewPurchase(ctx context.Context, orderInfo *order.O
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getUserOrCreate retrieves an existing user or creates a new guest user based on order details
|
// getUserOrCreate retrieves an existing user or creates a new user based on order details
|
||||||
func (l *ActivateOrderLogic) getUserOrCreate(ctx context.Context, orderInfo *order.Order) (*user.User, error) {
|
func (l *ActivateOrderLogic) getUserOrCreate(ctx context.Context, orderInfo *order.Order) (*user.User, error) {
|
||||||
if orderInfo.UserId != 0 {
|
if orderInfo.UserId != 0 {
|
||||||
return l.getExistingUser(ctx, orderInfo.UserId)
|
return l.getExistingUser(ctx, orderInfo.UserId)
|
||||||
}
|
}
|
||||||
return l.createGuestUser(ctx, orderInfo)
|
return l.createUserFromTempOrder(ctx, orderInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getExistingUser retrieves user information by user ID
|
// getExistingUser retrieves user information by user ID
|
||||||
@ -213,9 +213,9 @@ func (l *ActivateOrderLogic) getExistingUser(ctx context.Context, userId int64)
|
|||||||
return userInfo, nil
|
return userInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createGuestUser creates a new user account for guest orders using temporary order information
|
// createUserFromTempOrder creates a new user account using temporary order information
|
||||||
// stored in Redis cache
|
// stored in Redis cache. All users created this way are formal users, not guests.
|
||||||
func (l *ActivateOrderLogic) createGuestUser(ctx context.Context, orderInfo *order.Order) (*user.User, error) {
|
func (l *ActivateOrderLogic) createUserFromTempOrder(ctx context.Context, orderInfo *order.Order) (*user.User, error) {
|
||||||
tempOrder, err := l.getTempOrderInfo(ctx, orderInfo.OrderNo)
|
tempOrder, err := l.getTempOrderInfo(ctx, orderInfo.OrderNo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -253,7 +253,7 @@ func (l *ActivateOrderLogic) createGuestUser(ctx context.Context, orderInfo *ord
|
|||||||
// Handle referrer relationship
|
// Handle referrer relationship
|
||||||
l.handleReferrer(ctx, userInfo, tempOrder.InviteCode)
|
l.handleReferrer(ctx, userInfo, tempOrder.InviteCode)
|
||||||
|
|
||||||
logger.WithContext(ctx).Info("Create guest user success",
|
logger.WithContext(ctx).Info("Create user success",
|
||||||
logger.Field("user_id", userInfo.Id),
|
logger.Field("user_id", userInfo.Id),
|
||||||
logger.Field("identifier", tempOrder.Identifier),
|
logger.Field("identifier", tempOrder.Identifier),
|
||||||
logger.Field("auth_type", tempOrder.AuthType),
|
logger.Field("auth_type", tempOrder.AuthType),
|
||||||
@ -349,10 +349,12 @@ func (l *ActivateOrderLogic) createUserSubscription(ctx context.Context, orderIn
|
|||||||
return userSub, nil
|
return userSub, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleCommission processes referral commission for the referrer if applicable.
|
// handleReferralReward processes referral rewards for the referrer if applicable.
|
||||||
// This runs asynchronously to avoid blocking the main order processing flow.
|
// This runs asynchronously to avoid blocking the main order processing flow.
|
||||||
func (l *ActivateOrderLogic) handleCommission(ctx context.Context, userInfo *user.User, orderInfo *order.Order) {
|
// If referral percentage > 0: commission reward
|
||||||
if !l.shouldProcessCommission(userInfo, orderInfo.IsNew) {
|
// If referral percentage = 0: gift days to both parties
|
||||||
|
func (l *ActivateOrderLogic) handleReferralReward(ctx context.Context, userInfo *user.User, orderInfo *order.Order) {
|
||||||
|
if !l.shouldProcessReferralReward(userInfo, orderInfo.IsNew) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,13 +374,25 @@ func (l *ActivateOrderLogic) handleCommission(ctx context.Context, userInfo *use
|
|||||||
referralPercentage = uint8(l.svc.Config.Invite.ReferralPercentage)
|
referralPercentage = uint8(l.svc.Config.Invite.ReferralPercentage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if this is commission reward or gift days reward
|
||||||
|
if referralPercentage > 0 {
|
||||||
|
// Commission reward mode
|
||||||
|
l.processCommissionReward(ctx, referer, orderInfo, referralPercentage)
|
||||||
|
} else {
|
||||||
|
// Gift days reward mode
|
||||||
|
l.processGiftDaysReward(ctx, referer, userInfo, orderInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// processCommissionReward handles commission-based rewards
|
||||||
|
func (l *ActivateOrderLogic) processCommissionReward(ctx context.Context, referer *user.User, orderInfo *order.Order, percentage uint8) {
|
||||||
// Order commission calculation: (Order Amount - Order Fee) * Referral Percentage
|
// Order commission calculation: (Order Amount - Order Fee) * Referral Percentage
|
||||||
amount := l.calculateCommission(orderInfo.Amount-orderInfo.FeeAmount, referralPercentage)
|
amount := l.calculateCommission(orderInfo.Amount-orderInfo.FeeAmount, percentage)
|
||||||
|
|
||||||
// Use transaction for commission updates
|
// Use transaction for commission updates
|
||||||
err = l.svc.DB.Transaction(func(tx *gorm.DB) error {
|
err := l.svc.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
referer.Commission += amount
|
referer.Commission += amount
|
||||||
if err = l.svc.UserModel.Update(ctx, referer, tx); err != nil {
|
if err := l.svc.UserModel.Update(ctx, referer, tx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,9 +434,73 @@ func (l *ActivateOrderLogic) handleCommission(ctx context.Context, userInfo *use
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldProcessCommission determines if commission should be processed based on
|
// processGiftDaysReward handles gift days rewards for both parties
|
||||||
|
func (l *ActivateOrderLogic) processGiftDaysReward(ctx context.Context, referer *user.User, referee *user.User, orderInfo *order.Order) {
|
||||||
|
giftDays := l.svc.Config.Invite.GiftDays
|
||||||
|
if giftDays <= 0 {
|
||||||
|
giftDays = 3 // Default to 3 days
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the subscription info to determine the unit time
|
||||||
|
sub, err := l.getSubscribeInfo(ctx, orderInfo.SubscribeId)
|
||||||
|
if err != nil {
|
||||||
|
logger.WithContext(ctx).Error("Get subscribe info failed for gift days",
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
logger.Field("subscribe_id", orderInfo.SubscribeId),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grant gift days to both referer and referee
|
||||||
|
l.grantGiftDays(ctx, referer, giftDays, sub.UnitTime, "referer")
|
||||||
|
l.grantGiftDays(ctx, referee, giftDays, sub.UnitTime, "referee")
|
||||||
|
}
|
||||||
|
|
||||||
|
// grantGiftDays grants gift days to a user by extending their subscription
|
||||||
|
func (l *ActivateOrderLogic) grantGiftDays(ctx context.Context, user *user.User, days int64, unitTime string, role string) {
|
||||||
|
// Find user's active subscription
|
||||||
|
userSub, err := l.svc.UserModel.FindActiveSubscribe(ctx, user.Id)
|
||||||
|
if err != nil {
|
||||||
|
logger.WithContext(ctx).Error("Find user active subscription failed for gift days",
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
logger.Field("user_id", user.Id),
|
||||||
|
logger.Field("role", role),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if userSub == nil {
|
||||||
|
logger.WithContext(ctx).Info("User has no active subscription for gift days",
|
||||||
|
logger.Field("user_id", user.Id),
|
||||||
|
logger.Field("role", role),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend subscription by gift days
|
||||||
|
userSub.ExpireTime = tool.AddTime("day", days, userSub.ExpireTime)
|
||||||
|
|
||||||
|
err = l.svc.UserModel.UpdateSubscribe(ctx, userSub)
|
||||||
|
if err != nil {
|
||||||
|
logger.WithContext(ctx).Error("Update user subscription for gift days failed",
|
||||||
|
logger.Field("error", err.Error()),
|
||||||
|
logger.Field("user_id", user.Id),
|
||||||
|
logger.Field("role", role),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.WithContext(ctx).Info("Gift days granted successfully",
|
||||||
|
logger.Field("user_id", user.Id),
|
||||||
|
logger.Field("role", role),
|
||||||
|
logger.Field("days", days),
|
||||||
|
logger.Field("new_expire_time", userSub.ExpireTime),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// shouldProcessReferralReward determines if referral reward should be processed based on
|
||||||
// referrer existence, commission settings, and order type
|
// referrer existence, commission settings, and order type
|
||||||
func (l *ActivateOrderLogic) shouldProcessCommission(userInfo *user.User, isFirstPurchase bool) bool {
|
func (l *ActivateOrderLogic) shouldProcessReferralReward(userInfo *user.User, isFirstPurchase bool) bool {
|
||||||
if userInfo == nil || userInfo.RefererId == 0 {
|
if userInfo == nil || userInfo.RefererId == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -504,8 +582,8 @@ func (l *ActivateOrderLogic) Renewal(ctx context.Context, orderInfo *order.Order
|
|||||||
// Clear cache
|
// Clear cache
|
||||||
l.clearServerCache(ctx, sub)
|
l.clearServerCache(ctx, sub)
|
||||||
|
|
||||||
// Handle commission
|
// Handle referral reward
|
||||||
go l.handleCommission(context.Background(), userInfo, orderInfo)
|
go l.handleReferralReward(context.Background(), userInfo, orderInfo)
|
||||||
|
|
||||||
// Send notifications
|
// Send notifications
|
||||||
l.sendNotifications(ctx, orderInfo, userInfo, sub, userSub, telegram.RenewalNotify)
|
l.sendNotifications(ctx, orderInfo, userInfo, sub, userSub, telegram.RenewalNotify)
|
||||||
|
|||||||
30
script/build_docker.sh
Executable file
30
script/build_docker.sh
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# build-and-push.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd /Users/Apple/vpn/ppanel-server
|
||||||
|
# 固定版本号为latest
|
||||||
|
VERSION=v1.0
|
||||||
|
|
||||||
|
# 构建镜像
|
||||||
|
echo "Building image with version: $VERSION"
|
||||||
|
docker build -f Dockerfile --platform linux/amd64 --build-arg TARGETARCH=amd64 -t registry.kxsw.us/ppanel/ario-server:$VERSION .
|
||||||
|
docker tag registry.kxsw.us/ppanel/ario-server:$VERSION registry.kxsw.us/ppanel/ario-server:$VERSION
|
||||||
|
|
||||||
|
# 推送镜像
|
||||||
|
echo "Pushing image to registry.kxsw.us"
|
||||||
|
docker push registry.kxsw.us/ppanel/ario-server:$VERSION
|
||||||
|
docker push registry.kxsw.us/ppanel/ario-server:$VERSION
|
||||||
|
|
||||||
|
echo "Build and push completed successfully!"
|
||||||
|
# docker-compose exec certbot certbot certonly --webroot --webroot-path=/etc/letsencrypt -d api-dev.kxsw.us
|
||||||
|
|
||||||
|
docker run -d -p 3001:3000 \
|
||||||
|
-e NEXT_PUBLIC_DEFAULT_LANGUAGE=en-US \
|
||||||
|
-e NEXT_PUBLIC_SITE_URL=https://4d3vsw8.88xgaen.hifast.biz \
|
||||||
|
-e NEXT_PUBLIC_API_URL=https://api.hifast.biz \
|
||||||
|
-e NEXT_PUBLIC_DEFAULT_USER_EMAIL=admin@ppanel.dev \
|
||||||
|
-e NEXT_PUBLIC_DEFAULT_USER_PASSWORD=password \
|
||||||
|
--name ppanel-admin-web \
|
||||||
|
ppanel/ppanel-admin-web:latest
|
||||||
Loading…
x
Reference in New Issue
Block a user