Merge branch 'dev' of github.com:engigu/baihu into dev
This commit is contained in:
@@ -6,7 +6,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- 'Dockerfile.base'
|
- 'docker/Dockerfile.base'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: ghcr.io
|
REGISTRY: ghcr.io
|
||||||
@@ -17,9 +17,39 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
base_type: [debian, alpine, debian13]
|
||||||
platform:
|
platform:
|
||||||
- linux/amd64
|
- linux/amd64
|
||||||
- linux/arm64
|
- linux/arm64
|
||||||
|
include:
|
||||||
|
- base_type: debian
|
||||||
|
platform: linux/arm/v7
|
||||||
|
dockerfile: docker/Dockerfile.base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: debian
|
||||||
|
platform: linux/amd64
|
||||||
|
dockerfile: docker/Dockerfile.base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: debian
|
||||||
|
platform: linux/arm64
|
||||||
|
dockerfile: docker/Dockerfile.base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: alpine
|
||||||
|
platform: linux/amd64
|
||||||
|
dockerfile: docker/Dockerfile.alpine.base
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: alpine
|
||||||
|
platform: linux/arm64
|
||||||
|
dockerfile: docker/Dockerfile.alpine.base
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: debian13
|
||||||
|
platform: linux/amd64
|
||||||
|
dockerfile: docker/Dockerfile.debian13.base
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
- base_type: debian13
|
||||||
|
platform: linux/arm64
|
||||||
|
dockerfile: docker/Dockerfile.debian13.base
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -33,7 +63,7 @@ jobs:
|
|||||||
id: platform
|
id: platform
|
||||||
run: |
|
run: |
|
||||||
platform=${{ matrix.platform }}
|
platform=${{ matrix.platform }}
|
||||||
echo "pair=${platform//\//-}" >> $GITHUB_OUTPUT
|
echo "pair=${platform//\//-}-${{ matrix.base_type }}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
@@ -55,14 +85,14 @@ jobs:
|
|||||||
images: |
|
images: |
|
||||||
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=base
|
type=raw,value=base${{ matrix.tag_suffix }}
|
||||||
|
|
||||||
- name: Build and push by digest
|
- name: Build and push by digest
|
||||||
id: build
|
id: build
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile.base
|
file: ${{ matrix.dockerfile }}
|
||||||
platforms: ${{ matrix.platform }}
|
platforms: ${{ matrix.platform }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
outputs: type=image,name=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
outputs: type=image,name=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
||||||
@@ -87,6 +117,16 @@ jobs:
|
|||||||
merge:
|
merge:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
base_type: [debian, alpine, debian13]
|
||||||
|
include:
|
||||||
|
- base_type: debian
|
||||||
|
tag: base
|
||||||
|
- base_type: alpine
|
||||||
|
tag: base-alpine
|
||||||
|
- base_type: debian13
|
||||||
|
tag: base-debian13
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -100,7 +140,7 @@ jobs:
|
|||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: /tmp/digests
|
path: /tmp/digests
|
||||||
pattern: digests-*
|
pattern: digests-*-${{ matrix.base_type }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
@@ -120,7 +160,7 @@ jobs:
|
|||||||
images: |
|
images: |
|
||||||
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=base
|
type=raw,value=${{ matrix.tag }}
|
||||||
|
|
||||||
- name: Create manifest list and push
|
- name: Create manifest list and push
|
||||||
working-directory: /tmp/digests
|
working-directory: /tmp/digests
|
||||||
@@ -130,4 +170,4 @@ jobs:
|
|||||||
|
|
||||||
- name: Inspect image
|
- name: Inspect image
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:base
|
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ matrix.tag }}
|
||||||
|
|||||||
@@ -12,6 +12,19 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
base_type: [debian, alpine, debian13]
|
||||||
|
include:
|
||||||
|
- base_type: debian
|
||||||
|
base_tag: base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: alpine
|
||||||
|
base_tag: base-alpine
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: debian13
|
||||||
|
base_tag: base-debian13
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -38,10 +51,9 @@ jobs:
|
|||||||
images: |
|
images: |
|
||||||
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
type=semver,pattern={{version}}-amd64
|
type=raw,value=latest-amd64${{ matrix.tag_suffix }},enable={{is_default_branch}}
|
||||||
type=raw,value=latest-amd64,enable={{is_default_branch}}
|
type=ref,event=branch,suffix=-amd64${{ matrix.tag_suffix }}
|
||||||
type=ref,event=branch,suffix=-amd64
|
type=sha,prefix={{branch}}-,suffix=-amd64${{ matrix.tag_suffix }}
|
||||||
type=sha,prefix={{branch}}-,suffix=-amd64
|
|
||||||
|
|
||||||
- name: Get build time
|
- name: Get build time
|
||||||
id: build_time
|
id: build_time
|
||||||
@@ -51,6 +63,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
file: ./docker/Dockerfile
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
@@ -58,11 +71,13 @@ jobs:
|
|||||||
build-args: |
|
build-args: |
|
||||||
VERSION=${{ github.ref_name }}
|
VERSION=${{ github.ref_name }}
|
||||||
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
||||||
cache-from: type=gha,scope=linux-amd64
|
BASE_TAG=${{ matrix.base_tag }}
|
||||||
cache-to: type=gha,scope=linux-amd64,mode=max
|
cache-from: type=gha,scope=linux-amd64-${{ matrix.base_type }}
|
||||||
|
cache-to: type=gha,scope=linux-amd64-${{ matrix.base_type }},mode=max
|
||||||
provenance: false
|
provenance: false
|
||||||
|
|
||||||
- name: Deploy to Demo server
|
- name: Deploy to Demo server
|
||||||
|
if: github.ref == 'refs/heads/main' && matrix.base_type == 'debian'
|
||||||
uses: appleboy/ssh-action@v1.2.0
|
uses: appleboy/ssh-action@v1.2.0
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.DEPLOY_HOST }}
|
host: ${{ secrets.DEPLOY_HOST }}
|
||||||
@@ -71,10 +86,11 @@ jobs:
|
|||||||
port: ${{ secrets.DEPLOY_PORT }}
|
port: ${{ secrets.DEPLOY_PORT }}
|
||||||
script: |
|
script: |
|
||||||
cd ${{ secrets.DEPLOY_PATH }}
|
cd ${{ secrets.DEPLOY_PATH }}
|
||||||
docker-compose pull
|
docker-compose -f docker/docker-compose.yml pull
|
||||||
docker-compose up -d
|
docker-compose -f docker/docker-compose.yml up -d
|
||||||
|
|
||||||
- name: Deploy to X server
|
- name: Deploy to X server
|
||||||
|
if: github.ref == 'refs/heads/main' && matrix.base_type == 'debian'
|
||||||
uses: appleboy/ssh-action@v1.2.0
|
uses: appleboy/ssh-action@v1.2.0
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.DEPLOY_HOST }}
|
host: ${{ secrets.DEPLOY_HOST }}
|
||||||
@@ -83,5 +99,5 @@ jobs:
|
|||||||
port: ${{ secrets.DEPLOY_PORT }}
|
port: ${{ secrets.DEPLOY_PORT }}
|
||||||
script: |
|
script: |
|
||||||
cd ${{ secrets.DEPLOY_X_PATH }}
|
cd ${{ secrets.DEPLOY_X_PATH }}
|
||||||
docker-compose pull
|
docker-compose -f docker/docker-compose.yml pull
|
||||||
docker-compose up -d
|
docker-compose -f docker/docker-compose.yml up -d
|
||||||
@@ -12,6 +12,19 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
base_type: [debian, alpine, debian13]
|
||||||
|
include:
|
||||||
|
- base_type: debian
|
||||||
|
base_tag: base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: alpine
|
||||||
|
base_tag: base-alpine
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: debian13
|
||||||
|
base_tag: base-debian13
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -38,8 +51,9 @@ jobs:
|
|||||||
images: |
|
images: |
|
||||||
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
type=semver,pattern={{version}}-amd64
|
type=semver,pattern={{version}}-amd64${{ matrix.tag_suffix }}
|
||||||
type=raw,value=latest-amd64,enable={{is_default_branch}}
|
type=raw,value=latest-amd64${{ matrix.tag_suffix }},enable={{is_default_branch}}
|
||||||
|
type=ref,event=branch,suffix=-amd64${{ matrix.tag_suffix }}
|
||||||
|
|
||||||
- name: Get build time
|
- name: Get build time
|
||||||
id: build_time
|
id: build_time
|
||||||
@@ -49,6 +63,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
file: ./docker/Dockerfile
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
@@ -56,6 +71,7 @@ jobs:
|
|||||||
build-args: |
|
build-args: |
|
||||||
VERSION=${{ github.ref_name }}
|
VERSION=${{ github.ref_name }}
|
||||||
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
||||||
cache-from: type=gha,scope=linux-amd64
|
BASE_TAG=${{ matrix.base_tag }}
|
||||||
cache-to: type=gha,scope=linux-amd64,mode=max
|
cache-from: type=gha,scope=linux-amd64-${{ matrix.base_type }}
|
||||||
|
cache-to: type=gha,scope=linux-amd64-${{ matrix.base_type }},mode=max
|
||||||
provenance: false
|
provenance: false
|
||||||
|
|||||||
@@ -12,6 +12,19 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
base_type: [debian, alpine, debian13]
|
||||||
|
include:
|
||||||
|
- base_type: debian
|
||||||
|
base_tag: base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: alpine
|
||||||
|
base_tag: base-alpine
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: debian13
|
||||||
|
base_tag: base-debian13
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -41,8 +54,9 @@ jobs:
|
|||||||
images: |
|
images: |
|
||||||
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
type=semver,pattern={{version}}-arm64
|
type=semver,pattern={{version}}-arm64${{ matrix.tag_suffix }}
|
||||||
type=raw,value=latest-arm64,enable={{is_default_branch}}
|
type=raw,value=latest-arm64${{ matrix.tag_suffix }},enable={{is_default_branch}}
|
||||||
|
type=ref,event=branch,suffix=-arm64${{ matrix.tag_suffix }}
|
||||||
|
|
||||||
- name: Get build time
|
- name: Get build time
|
||||||
id: build_time
|
id: build_time
|
||||||
@@ -52,6 +66,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
file: ./docker/Dockerfile
|
||||||
platforms: linux/arm64
|
platforms: linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
@@ -59,6 +74,7 @@ jobs:
|
|||||||
build-args: |
|
build-args: |
|
||||||
VERSION=${{ github.ref_name }}
|
VERSION=${{ github.ref_name }}
|
||||||
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
||||||
cache-from: type=gha,scope=linux-arm64
|
BASE_TAG=${{ matrix.base_tag }}
|
||||||
cache-to: type=gha,scope=linux-arm64,mode=max
|
cache-from: type=gha,scope=linux-arm64-${{ matrix.base_type }}
|
||||||
|
cache-to: type=gha,scope=linux-arm64-${{ matrix.base_type }},mode=max
|
||||||
provenance: false
|
provenance: false
|
||||||
|
|||||||
@@ -14,9 +14,39 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
base_type: [debian, alpine, debian13]
|
||||||
platform:
|
platform:
|
||||||
- linux/amd64
|
- linux/amd64
|
||||||
- linux/arm64
|
- linux/arm64
|
||||||
|
include:
|
||||||
|
- base_type: debian
|
||||||
|
platform: linux/arm/v7
|
||||||
|
base_tag: base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: debian
|
||||||
|
platform: linux/amd64
|
||||||
|
base_tag: base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: debian
|
||||||
|
platform: linux/arm64
|
||||||
|
base_tag: base
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: alpine
|
||||||
|
platform: linux/amd64
|
||||||
|
base_tag: base-alpine
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: alpine
|
||||||
|
platform: linux/arm64
|
||||||
|
base_tag: base-alpine
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: debian13
|
||||||
|
platform: linux/amd64
|
||||||
|
base_tag: base-debian13
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
- base_type: debian13
|
||||||
|
platform: linux/arm64
|
||||||
|
base_tag: base-debian13
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -30,7 +60,7 @@ jobs:
|
|||||||
id: platform
|
id: platform
|
||||||
run: |
|
run: |
|
||||||
platform=${{ matrix.platform }}
|
platform=${{ matrix.platform }}
|
||||||
echo "pair=${platform//\//-}" >> $GITHUB_OUTPUT
|
echo "pair=${platform//\//-}-${{ matrix.base_type }}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
@@ -61,10 +91,12 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
file: ./docker/Dockerfile
|
||||||
platforms: ${{ matrix.platform }}
|
platforms: ${{ matrix.platform }}
|
||||||
build-args: |
|
build-args: |
|
||||||
VERSION=${{ github.ref_name }}
|
VERSION=${{ github.ref_name }}
|
||||||
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
BUILD_TIME=${{ steps.build_time.outputs.time }}
|
||||||
|
BASE_TAG=${{ matrix.base_tag }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
outputs: type=image,name=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
outputs: type=image,name=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
||||||
cache-from: type=gha,scope=${{ steps.platform.outputs.pair }}
|
cache-from: type=gha,scope=${{ steps.platform.outputs.pair }}
|
||||||
@@ -88,6 +120,16 @@ jobs:
|
|||||||
merge:
|
merge:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
base_type: [debian, alpine, debian13]
|
||||||
|
include:
|
||||||
|
- base_type: debian
|
||||||
|
tag_suffix: ""
|
||||||
|
- base_type: alpine
|
||||||
|
tag_suffix: "-alpine"
|
||||||
|
- base_type: debian13
|
||||||
|
tag_suffix: "-debian13"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -101,7 +143,7 @@ jobs:
|
|||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: /tmp/digests
|
path: /tmp/digests
|
||||||
pattern: digests-*
|
pattern: digests-*-${{ matrix.base_type }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
@@ -121,8 +163,8 @@ jobs:
|
|||||||
images: |
|
images: |
|
||||||
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}${{ matrix.tag_suffix }}
|
||||||
type=raw,value=latest
|
type=raw,value=latest${{ matrix.tag_suffix }}
|
||||||
|
|
||||||
- name: Create manifest list and push
|
- name: Create manifest list and push
|
||||||
working-directory: /tmp/digests
|
working-directory: /tmp/digests
|
||||||
@@ -132,9 +174,10 @@ jobs:
|
|||||||
|
|
||||||
- name: Inspect image
|
- name: Inspect image
|
||||||
run: |
|
run: |
|
||||||
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
|
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}${{ matrix.tag_suffix }}
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
|
if: matrix.base_type == 'debian'
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ github.ref_name }}
|
tag_name: ${{ github.ref_name }}
|
||||||
|
|||||||
@@ -48,3 +48,4 @@ configs/config.local.json
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
|
.stfolder
|
||||||
@@ -6,7 +6,7 @@ GOGET=go get
|
|||||||
GOMOD=go mod
|
GOMOD=go mod
|
||||||
VERSION=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
VERSION=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
||||||
BUILD_TIME=$(shell date '+%Y/%m/%d %H:%M:%S')
|
BUILD_TIME=$(shell date '+%Y/%m/%d %H:%M:%S')
|
||||||
LDFLAGS=-ldflags="-s -w -X 'baihu/internal/constant.Version=$(VERSION)' -X 'baihu/internal/constant.BuildTime=$(BUILD_TIME)'"
|
LDFLAGS=-ldflags="-s -w -X 'github.com/engigu/baihu-panel/internal/constant.Version=$(VERSION)' -X 'github.com/engigu/baihu-panel/internal/constant.BuildTime=$(BUILD_TIME)'"
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
all: build
|
all: build
|
||||||
@@ -66,7 +66,7 @@ deps:
|
|||||||
|
|
||||||
# Docker build
|
# Docker build
|
||||||
docker-build:
|
docker-build:
|
||||||
docker build -t $(BINARY) .
|
docker build -t $(BINARY) -f docker/Dockerfile .
|
||||||
|
|
||||||
# Docker run
|
# Docker run
|
||||||
docker-run:
|
docker-run:
|
||||||
@@ -74,11 +74,11 @@ docker-run:
|
|||||||
|
|
||||||
# Docker compose up
|
# Docker compose up
|
||||||
docker-up:
|
docker-up:
|
||||||
docker-compose up -d
|
docker-compose -f docker/docker-compose.yml up -d
|
||||||
|
|
||||||
# Docker compose down
|
# Docker compose down
|
||||||
docker-down:
|
docker-down:
|
||||||
docker-compose down
|
docker-compose -f docker/docker-compose.yml down
|
||||||
|
|
||||||
# Help
|
# Help
|
||||||
help:
|
help:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# 白虎面板
|
# 白虎面板
|
||||||
|
|
||||||
[](https://hits.sh/github.com/engigu/baihu-panel/)
|
[](https://hits.sh/github.com/engigu/baihu-panel/)
|
||||||
[](https://ghcr-badge.egpl.dev/engigu/baihu/tags)
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
@@ -10,6 +9,14 @@
|
|||||||
|
|
||||||
演示站点(演示站点的服务器比较烂,见谅) [演示站点](https://baihu-demo-site.qwapi.eu.org/)
|
演示站点(演示站点的服务器比较烂,见谅) [演示站点](https://baihu-demo-site.qwapi.eu.org/)
|
||||||
|
|
||||||
|
## 更新日志 ☕
|
||||||
|
|
||||||
|
### 最近更新
|
||||||
|
|
||||||
|
**2026.02.06** - 整理 Docker 目录结构,增加 Alpine 及 Debian 13 (Trixie) 镜像支持
|
||||||
|
|
||||||
|
[查看完整更新日志](./CHANGELOG.md)
|
||||||
|
|
||||||
## 项目来由
|
## 项目来由
|
||||||
|
|
||||||
多少和青龙面板有点关系,我自己也是青龙面板的使用者,但是现在的青龙面板性能我觉得有点难以接受。以我自己的使用(`机器1C2G`)为例,一个`python`的`requests`脚本每隔`30s`执行一次,有时候cpu执行的时候能跳变到`50%`以上。可以看看下面gif图片(如果不动,点击图片查看)
|
多少和青龙面板有点关系,我自己也是青龙面板的使用者,但是现在的青龙面板性能我觉得有点难以接受。以我自己的使用(`机器1C2G`)为例,一个`python`的`requests`脚本每隔`30s`执行一次,有时候cpu执行的时候能跳变到`50%`以上。可以看看下面gif图片(如果不动,点击图片查看)
|
||||||
@@ -24,6 +31,8 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
如果项目有用,请帮忙点个star。
|
||||||
|
|
||||||
## 特色
|
## 特色
|
||||||
|
|
||||||
- **轻量级:** docker/compose部署,无需复杂配置,开箱即用
|
- **轻量级:** docker/compose部署,无需复杂配置,开箱即用
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
ARG BASE_TAG=base
|
||||||
# ================================
|
# ================================
|
||||||
# Stage 1: Build frontend
|
# Stage 1: Build frontend
|
||||||
# ================================
|
# ================================
|
||||||
FROM node:20-alpine AS frontend-builder
|
FROM --platform=$BUILDPLATFORM node:20-alpine AS frontend-builder
|
||||||
|
|
||||||
WORKDIR /app/web
|
WORKDIR /app/web
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ COPY --from=frontend-builder /app/web/dist ./internal/static/dist
|
|||||||
RUN VERSION_VAL=$(cat /build-info/version.txt) && \
|
RUN VERSION_VAL=$(cat /build-info/version.txt) && \
|
||||||
BUILD_TIME_VAL=$(cat /build-info/build_time.txt) && \
|
BUILD_TIME_VAL=$(cat /build-info/build_time.txt) && \
|
||||||
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
|
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
|
||||||
go build -ldflags="-s -w -X baihu/internal/constant.Version=${VERSION_VAL} -X 'baihu/internal/constant.BuildTime=${BUILD_TIME_VAL}'" \
|
go build -ldflags="-s -w -X github.com/engigu/baihu-panel/internal/constant.Version=${VERSION_VAL} -X 'github.com/engigu/baihu-panel/internal/constant.BuildTime=${BUILD_TIME_VAL}'" \
|
||||||
-o baihu .
|
-o baihu .
|
||||||
|
|
||||||
# ================================
|
# ================================
|
||||||
@@ -104,7 +105,8 @@ RUN VERSION_VAL=$(cat /build-info/version.txt) && \
|
|||||||
# ================================
|
# ================================
|
||||||
# Stage 4: Final image
|
# Stage 4: Final image
|
||||||
# ================================
|
# ================================
|
||||||
FROM ghcr.io/engigu/baihu:base
|
ARG BASE_TAG
|
||||||
|
FROM ghcr.io/engigu/baihu:${BASE_TAG}
|
||||||
|
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
ENV PATH="/app/envs/node/bin:/app/envs/python/bin:$PATH"
|
ENV PATH="/app/envs/node/bin:/app/envs/python/bin:$PATH"
|
||||||
@@ -130,7 +132,7 @@ COPY --from=frontend-builder /app/web/dist ./internal/static/dist
|
|||||||
|
|
||||||
# Copy configs and entrypoint
|
# Copy configs and entrypoint
|
||||||
COPY --from=backend-builder /app/configs ./configs
|
COPY --from=backend-builder /app/configs ./configs
|
||||||
COPY docker-entrypoint.sh .
|
COPY docker/docker-entrypoint.sh .
|
||||||
|
|
||||||
# Copy sync.py to /opt
|
# Copy sync.py to /opt
|
||||||
COPY custom/sync.py /opt/sync.py
|
COPY custom/sync.py /opt/sync.py
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
FROM alpine:3.19
|
||||||
|
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
ENV PATH="/app/envs/node/bin:/app/envs/python/bin:$PATH"
|
||||||
|
ENV NODE_PATH="/app/envs/node/lib/node_modules"
|
||||||
|
|
||||||
|
# 安装必要系统工具 + Node + Python
|
||||||
|
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \
|
||||||
|
&& apk add --no-cache \
|
||||||
|
tzdata \
|
||||||
|
git \
|
||||||
|
gcc \
|
||||||
|
musl-dev \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
vim \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
|
python3 \
|
||||||
|
py3-pip \
|
||||||
|
htop \
|
||||||
|
&& cp /usr/share/zoneinfo/${TZ} /etc/localtime \
|
||||||
|
&& echo "${TZ}" > /etc/timezone \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
ENV PATH="/app/envs/node/bin:/app/envs/python/bin:$PATH"
|
||||||
|
ENV NODE_PATH="/app/envs/node/lib/node_modules"
|
||||||
|
|
||||||
|
# 安装必要系统工具 + Node + Python
|
||||||
|
RUN sed -i 's@deb.debian.org@mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list.d/debian.sources \
|
||||||
|
&& sed -i 's@security.debian.org@mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list.d/debian.sources \
|
||||||
|
&& echo "${TZ}" > /etc/timezone \
|
||||||
|
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
tzdata git gcc curl wget vim nodejs htop npm python3 python3-venv python3-pip \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
module baihu
|
module github.com/engigu/baihu-panel
|
||||||
|
|
||||||
go 1.24.0
|
go 1.24.0
|
||||||
|
|
||||||
@@ -11,8 +11,10 @@ require (
|
|||||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
|
github.com/shirou/gopsutil/v3 v3.24.5
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
golang.org/x/text v0.32.0
|
golang.org/x/text v0.32.0
|
||||||
|
gopkg.in/ini.v1 v1.67.0
|
||||||
gorm.io/driver/mysql v1.6.0
|
gorm.io/driver/mysql v1.6.0
|
||||||
gorm.io/driver/postgres v1.6.0
|
gorm.io/driver/postgres v1.6.0
|
||||||
gorm.io/gorm v1.31.1
|
gorm.io/gorm v1.31.1
|
||||||
@@ -51,7 +53,6 @@ require (
|
|||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||||
github.com/shirou/gopsutil/v3 v3.24.5 // indirect
|
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
@@ -64,7 +65,6 @@ require (
|
|||||||
golang.org/x/sync v0.19.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.39.0 // indirect
|
golang.org/x/sys v0.39.0 // indirect
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
modernc.org/libc v1.22.5 // indirect
|
modernc.org/libc v1.22.5 // indirect
|
||||||
modernc.org/mathutil v1.5.0 // indirect
|
modernc.org/mathutil v1.5.0 // indirect
|
||||||
|
|||||||
@@ -41,9 +41,10 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
|
|||||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||||
@@ -100,6 +101,8 @@ github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/i
|
|||||||
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
|
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||||
|
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||||
|
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
@@ -111,8 +114,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
|
||||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||||
@@ -144,8 +148,6 @@ golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
|||||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/router"
|
"github.com/engigu/baihu-panel/internal/router"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
Vendored
+3
-3
@@ -3,9 +3,9 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// siteCache 站点设置内存缓存
|
// siteCache 站点设置内存缓存
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ type Sentence struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
lineCount int
|
lineCount int
|
||||||
lineOffsets []int64
|
lineOffsets []int64
|
||||||
sentenceOnce sync.Once
|
sentenceOnce sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
// initSentences 初始化:统计行数和记录每行偏移
|
// initSentences 初始化:统计行数和记录每行偏移
|
||||||
@@ -44,13 +44,16 @@ func GetRandomSentence() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
targetLine := rand.Intn(lineCount)
|
targetLine := rand.Intn(lineCount)
|
||||||
|
|
||||||
scanner := bufio.NewScanner(bytes.NewReader(sentenceData))
|
scanner := bufio.NewScanner(bytes.NewReader(sentenceData))
|
||||||
currentLine := 0
|
currentLine := 0
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
if currentLine == targetLine {
|
if currentLine == targetLine {
|
||||||
var s Sentence
|
var s Sentence
|
||||||
if err := json.Unmarshal(scanner.Bytes(), &s); err == nil && s.Name != "" {
|
if err := json.Unmarshal(scanner.Bytes(), &s); err == nil && s.Name != "" {
|
||||||
|
if s.From != "" {
|
||||||
|
return "\"" + s.Name + "\"—— " + s.From
|
||||||
|
}
|
||||||
return s.Name
|
return s.Name
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/middleware"
|
"github.com/engigu/baihu-panel/internal/middleware"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/services/tasks"
|
"github.com/engigu/baihu-panel/internal/services/tasks"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/services/tasks"
|
"github.com/engigu/baihu-panel/internal/services/tasks"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/services/tasks"
|
"github.com/engigu/baihu-panel/internal/services/tasks"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/services/tasks"
|
"github.com/engigu/baihu-panel/internal/services/tasks"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/creack/pty"
|
"github.com/creack/pty"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
|
|
||||||
"github.com/glebarez/sqlite"
|
"github.com/glebarez/sqlite"
|
||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Migrate() error {
|
func Migrate() error {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoginLog 登录日志
|
// LoginLog 登录日志
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SendStats 任务执行统计
|
// SendStats 任务执行统计
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setting 系统设置
|
// Setting 系统设置
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/controllers"
|
"github.com/engigu/baihu-panel/internal/controllers"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/services/tasks"
|
"github.com/engigu/baihu-panel/internal/services/tasks"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cronService *tasks.CronService
|
var cronService *tasks.CronService
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"baihu/internal/controllers"
|
"github.com/engigu/baihu-panel/internal/controllers"
|
||||||
"baihu/internal/middleware"
|
"github.com/engigu/baihu-panel/internal/middleware"
|
||||||
"baihu/internal/services"
|
"github.com/engigu/baihu-panel/internal/services"
|
||||||
"baihu/internal/static"
|
"github.com/engigu/baihu-panel/internal/static"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/services/tasks"
|
"github.com/engigu/baihu-panel/internal/services/tasks"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BackupService struct {
|
type BackupService struct {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ func LoadConfig(path string) (*AppConfig, error) {
|
|||||||
Port: 3306,
|
Port: 3306,
|
||||||
User: "root",
|
User: "root",
|
||||||
Password: "",
|
Password: "",
|
||||||
DBName: "baihu",
|
DBName: "github.com/engigu/baihu-panel",
|
||||||
Path: constant.DefaultDBPath,
|
Path: constant.DefaultDBPath,
|
||||||
TablePrefix: "baihu_",
|
TablePrefix: "baihu_",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DependencyService struct{}
|
type DependencyService struct{}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EnvService struct{}
|
type EnvService struct{}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InitService struct {
|
type InitService struct {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LoginLogService struct{}
|
type LoginLogService struct{}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScriptService struct{}
|
type ScriptService struct{}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package services
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SendStatsService struct{}
|
type SendStatsService struct{}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/cache"
|
"github.com/engigu/baihu-panel/internal/cache"
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsService struct{}
|
type SettingsService struct{}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
|
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package tasks
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package tasks
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package tasks
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/logger"
|
"github.com/engigu/baihu-panel/internal/logger"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
"baihu/internal/utils"
|
"github.com/engigu/baihu-panel/internal/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package tasks
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TaskService struct{}
|
type TaskService struct{}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
"baihu/internal/database"
|
"github.com/engigu/baihu-panel/internal/database"
|
||||||
"baihu/internal/models"
|
"github.com/engigu/baihu-panel/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserService struct{}
|
type UserService struct{}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"baihu/internal/cache"
|
"github.com/engigu/baihu-panel/internal/cache"
|
||||||
"baihu/internal/constant"
|
"github.com/engigu/baihu-panel/internal/constant"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "baihu/internal/bootstrap"
|
import "github.com/engigu/baihu-panel/internal/bootstrap"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
bootstrap.New().Run()
|
bootstrap.New().Run()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import { RouterLink, RouterView, useRoute } from 'vue-router'
|
import { RouterLink, RouterView, useRoute } from 'vue-router'
|
||||||
import { resetAuthCache } from '@/router'
|
import { resetAuthCache } from '@/router'
|
||||||
import { LayoutDashboard, ListTodo, FileCode, Settings, LogOut, ScrollText, Terminal, Variable, KeyRound, Package, Menu, X, Server } from 'lucide-vue-next'
|
import { LayoutDashboard, ListTodo, FileCode, Settings, LogOut, ScrollText, Terminal, Variable, KeyRound, Package, Menu, X, Server } from 'lucide-vue-next'
|
||||||
@@ -17,7 +17,7 @@ function loadSentenceFromCache(): string | null {
|
|||||||
try {
|
try {
|
||||||
const cached = localStorage.getItem(SENTENCE_CACHE_KEY)
|
const cached = localStorage.getItem(SENTENCE_CACHE_KEY)
|
||||||
const cacheTime = localStorage.getItem(SENTENCE_CACHE_TIME_KEY)
|
const cacheTime = localStorage.getItem(SENTENCE_CACHE_TIME_KEY)
|
||||||
|
|
||||||
if (cached && cacheTime) {
|
if (cached && cacheTime) {
|
||||||
const age = Date.now() - parseInt(cacheTime)
|
const age = Date.now() - parseInt(cacheTime)
|
||||||
// 如果缓存未过期,使用缓存
|
// 如果缓存未过期,使用缓存
|
||||||
@@ -46,6 +46,10 @@ const cachedSentence = loadSentenceFromCache()
|
|||||||
const sentence = ref(cachedSentence || '欢迎使用白虎面板')
|
const sentence = ref(cachedSentence || '欢迎使用白虎面板')
|
||||||
const { siteSettings, loadSettings } = useSiteSettings()
|
const { siteSettings, loadSettings } = useSiteSettings()
|
||||||
const mobileMenuOpen = ref(false)
|
const mobileMenuOpen = ref(false)
|
||||||
|
const sentenceContent = computed(() => {
|
||||||
|
const match = sentence.value.match(/^"(.+)"—— /)
|
||||||
|
return match ? match[1] : sentence.value
|
||||||
|
})
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{ to: '/', icon: LayoutDashboard, label: '数据仪表', exact: true },
|
{ to: '/', icon: LayoutDashboard, label: '数据仪表', exact: true },
|
||||||
@@ -101,19 +105,13 @@ onMounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex h-screen bg-muted/40">
|
<div class="flex h-screen bg-muted/40">
|
||||||
<!-- Mobile Menu Overlay -->
|
<!-- Mobile Menu Overlay -->
|
||||||
<div
|
<div v-if="mobileMenuOpen" class="fixed inset-0 bg-black/50 z-40 lg:hidden" @click="mobileMenuOpen = false" />
|
||||||
v-if="mobileMenuOpen"
|
|
||||||
class="fixed inset-0 bg-black/50 z-40 lg:hidden"
|
|
||||||
@click="mobileMenuOpen = false"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<aside
|
<aside :class="[
|
||||||
:class="[
|
'fixed lg:static inset-y-0 left-0 z-50 w-44 border-r bg-background flex flex-col transform transition-transform duration-200 ease-in-out lg:transform-none',
|
||||||
'fixed lg:static inset-y-0 left-0 z-50 w-44 border-r bg-background flex flex-col transform transition-transform duration-200 ease-in-out lg:transform-none',
|
mobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'
|
||||||
mobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'
|
]">
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div class="h-14 flex items-center justify-center px-4 font-semibold text-lg border-b relative">
|
<div class="h-14 flex items-center justify-center px-4 font-semibold text-lg border-b relative">
|
||||||
<span>{{ siteSettings.title }}</span>
|
<span>{{ siteSettings.title }}</span>
|
||||||
<Button variant="ghost" size="icon" class="h-8 w-8 lg:hidden absolute right-2" @click="mobileMenuOpen = false">
|
<Button variant="ghost" size="icon" class="h-8 w-8 lg:hidden absolute right-2" @click="mobileMenuOpen = false">
|
||||||
@@ -121,25 +119,18 @@ onMounted(() => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<nav class="flex-1 px-3 py-6 space-y-1 flex flex-col items-center">
|
<nav class="flex-1 px-3 py-6 space-y-1 flex flex-col items-center">
|
||||||
<RouterLink
|
<RouterLink v-for="item in navItems" :key="item.to" :to="item.to" custom v-slot="{ navigate }">
|
||||||
v-for="item in navItems"
|
<Button variant="ghost"
|
||||||
:key="item.to"
|
|
||||||
:to="item.to"
|
|
||||||
custom
|
|
||||||
v-slot="{ navigate }"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
:class="['justify-start gap-3 h-9 px-3', isItemActive(item) && 'bg-accent text-accent-foreground']"
|
:class="['justify-start gap-3 h-9 px-3', isItemActive(item) && 'bg-accent text-accent-foreground']"
|
||||||
@click="handleNavClick(navigate)"
|
@click="handleNavClick(navigate)">
|
||||||
>
|
|
||||||
<component :is="item.icon" class="h-4 w-4" />
|
<component :is="item.icon" class="h-4 w-4" />
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</Button>
|
</Button>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="px-3 py-4 border-t flex justify-center">
|
<div class="px-3 py-4 border-t flex justify-center">
|
||||||
<Button variant="ghost" class="justify-start gap-3 h-9 px-3 text-muted-foreground hover:text-foreground" @click="logout">
|
<Button variant="ghost" class="justify-start gap-3 h-9 px-3 text-muted-foreground hover:text-foreground"
|
||||||
|
@click="logout">
|
||||||
<LogOut class="h-4 w-4" />
|
<LogOut class="h-4 w-4" />
|
||||||
退出登录
|
退出登录
|
||||||
</Button>
|
</Button>
|
||||||
@@ -149,11 +140,14 @@ onMounted(() => {
|
|||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<main class="flex-1 overflow-auto w-full">
|
<main class="flex-1 overflow-auto w-full">
|
||||||
<div class="h-14 border-b bg-background flex items-center justify-between px-4 lg:px-6">
|
<div class="h-14 border-b bg-background flex items-center justify-between px-4 lg:px-6">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3 flex-1 min-w-0">
|
||||||
<Button variant="ghost" size="icon" class="h-8 w-8 lg:hidden" @click="mobileMenuOpen = true">
|
<Button variant="ghost" size="icon" class="h-8 w-8 lg:hidden shrink-0" @click="mobileMenuOpen = true">
|
||||||
<Menu class="h-5 w-5" />
|
<Menu class="h-5 w-5" />
|
||||||
</Button>
|
</Button>
|
||||||
<span class="text-sm text-muted-foreground truncate max-w-[200px] sm:max-w-none">{{ sentence }}</span>
|
<span class="text-sm text-muted-foreground truncate" :title="sentence">
|
||||||
|
<span class="hidden sm:inline">{{ sentence }}</span>
|
||||||
|
<span class="sm:hidden">{{ sentenceContent }}</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,23 +37,23 @@ function animateNumber(key: keyof Stats, target: number) {
|
|||||||
const start = displayStats.value[key]
|
const start = displayStats.value[key]
|
||||||
const duration = 800 // 动画持续时间
|
const duration = 800 // 动画持续时间
|
||||||
const startTime = performance.now()
|
const startTime = performance.now()
|
||||||
|
|
||||||
function update(currentTime: number) {
|
function update(currentTime: number) {
|
||||||
const elapsed = currentTime - startTime
|
const elapsed = currentTime - startTime
|
||||||
const progress = Math.min(elapsed / duration, 1)
|
const progress = Math.min(elapsed / duration, 1)
|
||||||
|
|
||||||
// 使用 easeOutCubic 缓动函数
|
// 使用 easeOutCubic 缓动函数
|
||||||
const easeProgress = 1 - Math.pow(1 - progress, 3)
|
const easeProgress = 1 - Math.pow(1 - progress, 3)
|
||||||
|
|
||||||
displayStats.value[key] = Math.round(start + (target - start) * easeProgress)
|
displayStats.value[key] = Math.round(start + (target - start) * easeProgress)
|
||||||
|
|
||||||
if (progress < 1) {
|
if (progress < 1) {
|
||||||
requestAnimationFrame(update)
|
requestAnimationFrame(update)
|
||||||
} else {
|
} else {
|
||||||
displayStats.value[key] = target
|
displayStats.value[key] = target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(update)
|
requestAnimationFrame(update)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ function getGridColor() {
|
|||||||
function handleThemeChange() {
|
function handleThemeChange() {
|
||||||
// 初始化期间忽略主题变化
|
// 初始化期间忽略主题变化
|
||||||
if (isInitializing) return
|
if (isInitializing) return
|
||||||
|
|
||||||
const newIsDark = document.documentElement.classList.contains('dark')
|
const newIsDark = document.documentElement.classList.contains('dark')
|
||||||
if (newIsDark !== isDark.value) {
|
if (newIsDark !== isDark.value) {
|
||||||
isDark.value = newIsDark
|
isDark.value = newIsDark
|
||||||
@@ -127,11 +127,11 @@ async function reloadCharts() {
|
|||||||
// 等待 Vue 更新 DOM
|
// 等待 Vue 更新 DOM
|
||||||
await nextTick()
|
await nextTick()
|
||||||
await new Promise(resolve => setTimeout(resolve, 100))
|
await new Promise(resolve => setTimeout(resolve, 100))
|
||||||
|
|
||||||
// 检查容器是否存在再渲染
|
// 检查容器是否存在再渲染
|
||||||
const statsChart = document.querySelector("#stats-chart")
|
const statsChart = document.querySelector("#stats-chart")
|
||||||
const pieChartEl = document.querySelector("#pie-chart")
|
const pieChartEl = document.querySelector("#pie-chart")
|
||||||
|
|
||||||
if (statsChart && pieChartEl && statsChart.parentElement && pieChartEl.parentElement) {
|
if (statsChart && pieChartEl && statsChart.parentElement && pieChartEl.parentElement) {
|
||||||
renderLineChart()
|
renderLineChart()
|
||||||
renderPieChart()
|
renderPieChart()
|
||||||
@@ -143,15 +143,15 @@ async function reloadCharts() {
|
|||||||
const renderLineChart = () => {
|
const renderLineChart = () => {
|
||||||
const container = document.querySelector("#stats-chart")
|
const container = document.querySelector("#stats-chart")
|
||||||
if (!container || !container.parentElement) return
|
if (!container || !container.parentElement) return
|
||||||
|
|
||||||
if (lineChart) {
|
if (lineChart) {
|
||||||
lineChart.destroy()
|
lineChart.destroy()
|
||||||
lineChart = null
|
lineChart = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空容器
|
// 清空容器
|
||||||
container.innerHTML = ''
|
container.innerHTML = ''
|
||||||
|
|
||||||
const textColor = getTextColor()
|
const textColor = getTextColor()
|
||||||
const gridColor = getGridColor()
|
const gridColor = getGridColor()
|
||||||
const options = {
|
const options = {
|
||||||
@@ -282,18 +282,18 @@ const renderLineChart = () => {
|
|||||||
|
|
||||||
const renderPieChart = () => {
|
const renderPieChart = () => {
|
||||||
if (taskStats.value.length === 0) return
|
if (taskStats.value.length === 0) return
|
||||||
|
|
||||||
const container = document.querySelector("#pie-chart")
|
const container = document.querySelector("#pie-chart")
|
||||||
if (!container || !container.parentElement) return
|
if (!container || !container.parentElement) return
|
||||||
|
|
||||||
if (pieChart) {
|
if (pieChart) {
|
||||||
pieChart.destroy()
|
pieChart.destroy()
|
||||||
pieChart = null
|
pieChart = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空容器
|
// 清空容器
|
||||||
container.innerHTML = ''
|
container.innerHTML = ''
|
||||||
|
|
||||||
const totalCount = taskStats.value.reduce((sum, item) => sum + item.count, 0)
|
const totalCount = taskStats.value.reduce((sum, item) => sum + item.count, 0)
|
||||||
const textColor = getTextColor()
|
const textColor = getTextColor()
|
||||||
const options = {
|
const options = {
|
||||||
@@ -366,13 +366,13 @@ const renderPieChart = () => {
|
|||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
formatter: (val: number) => val.toFixed(1) + '%',
|
formatter: (val: number) => val.toFixed(1) + '%',
|
||||||
style: {
|
style: {
|
||||||
fontSize: '11px',
|
fontSize: '11px',
|
||||||
fontFamily: 'Inter, sans-serif',
|
fontFamily: 'Inter, sans-serif',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
colors: ['#ffffff']
|
colors: ['#ffffff']
|
||||||
},
|
},
|
||||||
dropShadow: {
|
dropShadow: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
top: 1,
|
top: 1,
|
||||||
left: 1,
|
left: 1,
|
||||||
@@ -395,7 +395,7 @@ const renderPieChart = () => {
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
window.addEventListener('resize', handleResize)
|
window.addEventListener('resize', handleResize)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [statsData, sendStatsData, taskStatsData] = await Promise.all([
|
const [statsData, sendStatsData, taskStatsData] = await Promise.all([
|
||||||
api.dashboard.stats(),
|
api.dashboard.stats(),
|
||||||
@@ -405,13 +405,13 @@ onMounted(async () => {
|
|||||||
updateStats(statsData)
|
updateStats(statsData)
|
||||||
sendStats.value = sendStatsData
|
sendStats.value = sendStatsData
|
||||||
taskStats.value = taskStatsData
|
taskStats.value = taskStatsData
|
||||||
|
|
||||||
// 渲染图表
|
// 渲染图表
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
renderLineChart()
|
renderLineChart()
|
||||||
renderPieChart()
|
renderPieChart()
|
||||||
chartsLoaded.value = true
|
chartsLoaded.value = true
|
||||||
|
|
||||||
// 图表渲染完成后,延迟启动主题监听,避免初始化时的闪烁
|
// 图表渲染完成后,延迟启动主题监听,避免初始化时的闪烁
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
isInitializing = false
|
isInitializing = false
|
||||||
@@ -422,7 +422,7 @@ onMounted(async () => {
|
|||||||
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })
|
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })
|
||||||
}, 500)
|
}, 500)
|
||||||
}, 100)
|
}, 100)
|
||||||
} catch {}
|
} catch { }
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@@ -448,7 +448,8 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid gap-4 grid-cols-2 sm:grid-cols-3 lg:grid-cols-6">
|
<div class="grid gap-4 grid-cols-2 sm:grid-cols-3 lg:grid-cols-6">
|
||||||
<Card v-for="item in statItems" :key="item.key" class="cursor-pointer hover:bg-accent/50 transition-colors" @click="navigateTo(item.route)">
|
<Card v-for="item in statItems" :key="item.key" class="cursor-pointer hover:bg-accent/50 transition-colors"
|
||||||
|
@click="navigateTo(item.route)">
|
||||||
<CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
|
<CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||||
<CardTitle class="text-xs sm:text-sm font-medium">{{ item.label }}</CardTitle>
|
<CardTitle class="text-xs sm:text-sm font-medium">{{ item.label }}</CardTitle>
|
||||||
<component :is="item.icon" class="h-4 w-4 text-muted-foreground" />
|
<component :is="item.icon" class="h-4 w-4 text-muted-foreground" />
|
||||||
@@ -467,7 +468,8 @@ onUnmounted(() => {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="relative h-[300px]">
|
<CardContent class="relative h-[300px]">
|
||||||
<div id="stats-chart" class="w-full h-full"></div>
|
<div id="stats-chart" class="w-full h-full"></div>
|
||||||
<div v-if="!chartsLoaded" class="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm bg-card">
|
<div v-if="!chartsLoaded"
|
||||||
|
class="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm bg-card">
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@@ -480,10 +482,12 @@ onUnmounted(() => {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="relative h-[300px]">
|
<CardContent class="relative h-[300px]">
|
||||||
<div id="pie-chart" class="w-full h-full"></div>
|
<div id="pie-chart" class="w-full h-full"></div>
|
||||||
<div v-if="!chartsLoaded" class="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm bg-card">
|
<div v-if="!chartsLoaded"
|
||||||
|
class="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm bg-card">
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="taskStats.length === 0" class="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm bg-card">
|
<div v-else-if="taskStats.length === 0"
|
||||||
|
class="absolute inset-0 flex items-center justify-center text-muted-foreground text-sm bg-card">
|
||||||
暂无数据
|
暂无数据
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { Input } from '@/components/ui/input'
|
|||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||||
import { Badge } from '@/components/ui/badge'
|
|
||||||
import DirTreeSelect from '@/components/DirTreeSelect.vue'
|
import DirTreeSelect from '@/components/DirTreeSelect.vue'
|
||||||
import { Plus, ChevronDown, X } from 'lucide-vue-next'
|
import { Plus, ChevronDown, X } from 'lucide-vue-next'
|
||||||
import { api, type Task, type EnvVar, type Agent } from '@/api'
|
import { api, type Task, type EnvVar, type Agent } from '@/api'
|
||||||
@@ -132,8 +131,7 @@ function addEnv(id: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function removeEnv(id: number) {
|
function removeEnv(id: number) {
|
||||||
const idx = selectedEnvIds.value.indexOf(id)
|
selectedEnvIds.value = selectedEnvIds.value.filter(envId => envId !== id)
|
||||||
if (idx !== -1) selectedEnvIds.value.splice(idx, 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
@@ -266,10 +264,10 @@ async function save() {
|
|||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
<div v-if="selectedEnvs.length > 0" class="flex flex-wrap gap-1">
|
<div v-if="selectedEnvs.length > 0" class="flex flex-wrap gap-1">
|
||||||
<Badge v-for="env in selectedEnvs" :key="env.id" variant="secondary" class="gap-0.5 pr-0.5 text-xs h-5">
|
<div v-for="env in selectedEnvs" :key="env.id" class="inline-flex items-center gap-0.5 px-2 py-0.5 text-xs h-5 rounded-full bg-secondary text-secondary-foreground">
|
||||||
{{ env.name }}
|
<span>{{ env.name }}</span>
|
||||||
<X class="h-2.5 w-2.5 cursor-pointer hover:text-destructive" @click.stop="removeEnv(env.id)" />
|
<X class="h-2.5 w-2.5 cursor-pointer hover:text-destructive" @click="removeEnv(env.id)" />
|
||||||
</Badge>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user