From c4f3235fcf2cdeb2bfe2480c96de92ad488123e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 15:53:48 +0800 Subject: [PATCH 01/21] feat: add CI/CD auto deploy workflow --- .gitea/workflows/deploy.yml | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .gitea/workflows/deploy.yml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..66ee141 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,42 @@ +name: Auto Deploy + +on: + push: + branches: + - wuxichen # 当前分支 + - main + - master + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install dependencies + run: pnpm install + + - name: Build project + run: pnpm build + + - name: Deploy to server + uses: appleboy/scp-action@master + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + source: "dist/*" + target: ${{ secrets.DEPLOY_PATH }} + strip_components: 1 From 5c8cb3bc8863325a2e42b7646b18ea77b9c41b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 16:08:31 +0800 Subject: [PATCH 02/21] feat: update workflow for self-hosted runner --- .gitea/workflows/deploy.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 66ee141..f0c1ffb 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -32,11 +32,6 @@ jobs: run: pnpm build - name: Deploy to server - uses: appleboy/scp-action@master - with: - host: ${{ secrets.SSH_HOST }} - username: ${{ secrets.SSH_USER }} - key: ${{ secrets.SSH_PRIVATE_KEY }} - source: "dist/*" - target: ${{ secrets.DEPLOY_PATH }} - strip_components: 1 + run: | + rsync -av --delete dist/ /home/1panel/www/sites/admin.petshy.tashowz.com/index/ + echo "Deployed successfully!" From aa2f07de41dcf30950a785484559f9d3d83f5ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 16:23:28 +0800 Subject: [PATCH 03/21] test: add test file for CI/CD verification --- public/test.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 public/test.txt diff --git a/public/test.txt b/public/test.txt new file mode 100644 index 0000000..496d6e2 --- /dev/null +++ b/public/test.txt @@ -0,0 +1,2 @@ +CI/CD Test - Deployed at 2026-03-02 16:23 +This file is used to verify automatic deployment is working. From 929cb1966b295484aa3c0b8929d6d9274c67dbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 16:39:21 +0800 Subject: [PATCH 04/21] fix: use self-hosted runner for CI/CD --- .gitea/workflows/deploy.yml | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index f0c1ffb..ea12108 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -9,29 +9,17 @@ on: jobs: build-and-deploy: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '20' - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 8 - - - name: Install dependencies - run: pnpm install - - - name: Build project - run: pnpm build - - - name: Deploy to server + - name: Build and Deploy run: | + cd /tmp + rm -rf tashow-build + git clone -b ${{ github.ref_name }} http://gitea.tashowz.com/tashow/tashow-manager.git tashow-build + cd tashow-build + pnpm install + pnpm build rsync -av --delete dist/ /home/1panel/www/sites/admin.petshy.tashowz.com/index/ + rm -rf /tmp/tashow-build echo "Deployed successfully!" From 4facb0277749f75ee15a7e1dec85177eb9bb2eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 16:47:33 +0800 Subject: [PATCH 05/21] test: trigger CI/CD with self-hosted runner From 448531f9d34d3ac20c5598704c8642fb81def5cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 16:55:07 +0800 Subject: [PATCH 06/21] test: trigger CI/CD after installing Node.js and pnpm From ecbd4eefd72526cc1f2e023e942eb7d6172abbac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:08:43 +0800 Subject: [PATCH 07/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index ae2927e..98bc120 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式 + 其他登录方式1111 From 742674623978139eafc0a2119ec19d9647b40d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:12:56 +0800 Subject: [PATCH 08/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index 98bc120..ae2927e 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式1111 + 其他登录方式 From 47623d6b1e91765176e13d2c1829176016fcb2b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:21:08 +0800 Subject: [PATCH 09/21] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20CI/CD=20?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=EF=BC=8C=E4=BD=BF=E7=94=A8=E6=8C=81=E4=B9=85?= =?UTF-8?q?=E5=8C=96=E7=9B=AE=E5=BD=95=E5=92=8C=E7=BC=93=E5=AD=98=E5=8A=A0?= =?UTF-8?q?=E9=80=9F=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/deploy.yml | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index ea12108..d5182a2 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -14,12 +14,33 @@ jobs: steps: - name: Build and Deploy run: | - cd /tmp - rm -rf tashow-build - git clone -b ${{ github.ref_name }} http://gitea.tashowz.com/tashow/tashow-manager.git tashow-build - cd tashow-build - pnpm install + # 使用持久化工作目录,避免每次重新克隆 + WORK_DIR="/root/tashow-deploy" + + # 首次运行时克隆代码 + if [ ! -d "$WORK_DIR" ]; then + echo "首次部署,克隆代码..." + git clone http://gitea.tashowz.com/tashow/tashow-manager.git $WORK_DIR + fi + + cd $WORK_DIR + + # 更新代码到最新版本 + echo "更新代码..." + git fetch origin + git checkout ${{ github.ref_name }} + git reset --hard origin/${{ github.ref_name }} + + # 安装依赖(pnpm 会自动利用缓存) + echo "安装依赖..." + pnpm install --frozen-lockfile + + # 构建项目 + echo "构建项目..." pnpm build + + # 部署到服务器 + echo "部署到服务器..." rsync -av --delete dist/ /home/1panel/www/sites/admin.petshy.tashowz.com/index/ - rm -rf /tmp/tashow-build - echo "Deployed successfully!" + + echo "部署成功!" From f27fc56fd45a3c11630b34783871fc0e4e950efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:22:51 +0800 Subject: [PATCH 10/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index ae2927e..837fd53 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式 + 其他登录方式111 From b4017597f9f5f048b5b80f379215c34ac7732f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:27:36 +0800 Subject: [PATCH 11/21] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=20frozen-lockfi?= =?UTF-8?q?le=20=E6=A0=87=E5=BF=97=E4=BB=A5=E5=85=BC=E5=AE=B9=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index d5182a2..9207ccb 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -33,7 +33,7 @@ jobs: # 安装依赖(pnpm 会自动利用缓存) echo "安装依赖..." - pnpm install --frozen-lockfile + pnpm install # 构建项目 echo "构建项目..." From 066cee46b041d6b5745425cd0e8f921c2a7f7207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:27:58 +0800 Subject: [PATCH 12/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index 837fd53..b212880 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式111 + 其他登录方式111111 From 22ef893529befa5cce8cfd925b271c9240e24999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:28:50 +0800 Subject: [PATCH 13/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index b212880..6e28e41 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式111111 + 其他登录方式333333333333333 From 16bb5afaa7bfe00f410820f791008280ff8fe707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:32:10 +0800 Subject: [PATCH 14/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index 6e28e41..ae2927e 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式333333333333333 + 其他登录方式 From ba1a7f392bddf037772507fa68f8ca5ee6baad04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:33:26 +0800 Subject: [PATCH 15/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index ae2927e..98bc120 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式 + 其他登录方式1111 From c9709319548788270a73f7b5744193565eb117ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:35:31 +0800 Subject: [PATCH 16/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式1111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index 98bc120..ae2927e 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式1111 + 其他登录方式 From 44426d881229b222fd163f127e3eb3efccea5556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:40:20 +0800 Subject: [PATCH 17/21] =?UTF-8?q?chore(ci):=20=E6=9B=B4=E6=96=B0=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E5=B7=A5=E4=BD=9C=E6=B5=81=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 pnpm 缓存相关注释内容 --- .gitea/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 9207ccb..3ae4cb6 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -31,7 +31,7 @@ jobs: git checkout ${{ github.ref_name }} git reset --hard origin/${{ github.ref_name }} - # 安装依赖(pnpm 会自动利用缓存) + # 安装依赖 echo "安装依赖..." pnpm install From 4ad3706dfad309a0d4ff9887cddd7645e70555c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:44:23 +0800 Subject: [PATCH 18/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式111111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index ae2927e..b212880 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式 + 其他登录方式111111 From 6a3aa3bf5d45ff897756f833c641b43fbcc1dcb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Mon, 2 Mar 2026 17:52:06 +0800 Subject: [PATCH 19/21] =?UTF-8?q?chore(login):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=85=B6=E4=BB=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=96=B9=E5=BC=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将"其他登录方式"修改为"其他登录方式111111" --- src/pages/user/login/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index b212880..ae2927e 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式111111 + 其他登录方式 From d5a795de7776337b62e8e2623033018b241680cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Tue, 3 Mar 2026 09:25:22 +0800 Subject: [PATCH 20/21] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=92=8C=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 CLAUDE.md 项目文档 - 添加自动部署脚本 - 修改登录页面"其他登录方式"文本 Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 201 +++++++++++++++++++++++++++++++++ auto-deploy.ps1 | 30 +++++ src/pages/user/login/index.tsx | 2 +- 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 CLAUDE.md create mode 100644 auto-deploy.ps1 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..514f5a6 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,201 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a multi-tenant service management platform ("百业到家") built with Ant Design Pro, React 19, TypeScript, and UmiJS Max framework. The application uses dynamic routing loaded from a backend API and implements a comprehensive permission system. + +## Development Commands + +```bash +# Start development server (with mocks) +pnpm dev +# or +pnpm start + +# Start development server (without mocks, connects to backend) +pnpm start:dev + +# Build for production +pnpm build + +# Lint (Biome + TypeScript check) +pnpm lint + +# Run tests +pnpm test + +# Run tests with coverage +pnpm test:coverage + +# Type check only +pnpm tsc +``` + +**Important**: This project uses **pnpm** as the package manager, not npm or yarn. + +## Architecture + +### Dynamic Routing System + +Routes are **not** statically defined in `config/routes.ts` (most routes are commented out). Instead, routes are dynamically loaded from the backend API: + +1. On app initialization, `getInfo()` fetches user permissions and menu structure +2. `patchClientRoutes()` in `src/app.tsx` transforms backend menu data into UmiJS routes +3. `loopMenuItem()` in `src/utils/menuUtils.tsx` recursively converts menu items to route objects +4. Routes are lazy-loaded using `React.lazy(() => import('@/pages/${component}'))` + +**When adding new pages**: Create the page component in `src/pages/`, then configure the route in the backend system (not in code). + +### Multi-Tenant Architecture + +Every API request includes a `tenant-id` header. Tenant information is: +- Stored in web-storage-cache with key `CACHE_KEY.TenantId` +- Set during login via `setTenantId()` +- Automatically added to all requests by the request interceptor in `src/app.tsx` + +### Authentication Flow + +1. User logs in with tenant name, username, and password (password is RSA encrypted via JSEncrypt) +2. Backend returns `accessToken` and `refreshToken` +3. Tokens stored in web-storage-cache (see `src/utils/auth.ts`) +4. All requests include `Authorization: Bearer ${accessToken}` header +5. On 401 response, automatically attempts token refresh using `refreshToken` +6. If refresh fails, redirects to login page + +**Token refresh logic** is in `src/requestErrorConfig.ts` with request queuing to prevent duplicate refresh attempts. + +### Request Interceptors + +All API requests are automatically modified (see `src/app.tsx`): +- **API prefix**: `/admin-api` is prepended to all URLs (unless already present) +- **Headers**: `Authorization`, `tenant-id`, and `Accept` headers are added +- **Parameter serialization**: Arrays are serialized specially: + - `createTime` arrays become `createTime[0]` and `createTime[1]` + - Other arrays become `key[]` format + +### Caching Strategy + +Uses `web-storage-cache` library (see `src/hooks/web/useCache.ts`): +- `CACHE_KEY.USER`: Current user info +- `CACHE_KEY.ROLE_ROUTERS`: Dynamic menu/route data +- `CACHE_KEY.ACCESS_TOKEN` / `CACHE_KEY.REFRESH_TOKEN`: Auth tokens +- `CACHE_KEY.DICT_CACHE`: Dictionary/enum data loaded on app init +- `CACHE_KEY.LoginForm`: Remember me functionality (password encrypted) + +### State Management + +- **UmiJS Model Plugin**: For global state (see `src/app.tsx` - `initialState`) +- **Custom Hooks**: In `src/hooks/stores/` (e.g., `useDictStore` for dictionary management) +- **Web Storage Cache**: For persistent data across sessions + +## Project Structure + +``` +src/ +├── pages/ # Feature pages organized by domain +│ ├── ai/ # AI model and sample management +│ ├── prod/ # Product and category management +│ ├── system/ # System admin (users, roles, menus, tenants, logs, messages) +│ ├── trade/ # Order and sales management +│ └── user/ # Login page +├── services/ # API service layer (mirrors page structure) +├── components/ # Reusable components +│ ├── Draggable/ # Drag-and-drop components using @dnd-kit +│ ├── Upload/ # File/image/video upload components +│ ├── GroupTag/ # Tag management components +│ └── Tinymce/ # Rich text editor wrapper +├── hooks/ # Custom React hooks +│ ├── antd/ # Ant Design related hooks +│ ├── stores/ # State management hooks +│ └── web/ # Web utilities (cache, etc.) +├── utils/ # Utility functions +│ ├── auth.ts # Token and tenant management +│ ├── menuUtils.tsx # Dynamic route conversion +│ ├── dict.ts # Dictionary/enum utilities +│ └── tree.ts # Tree data structure helpers +├── constants/ # Shared constants and enums +├── locales/ # i18n translations (zh-CN default) +└── app.tsx # App initialization and runtime config +``` + +## Environment Configuration + +Multiple environment files: +- `.env.local` - Local overrides (gitignored) +- `.env.dev` - Development environment +- `.env.prod` - Production environment + +**Proxy configuration** in `config/proxy.ts`: +- `dev`: Points to local backend (currently `http://192.168.1.89:48080`) +- `test`: Points to test environment +- `pre`: Points to pre-production environment + +Switch environments using `UMI_ENV`: +```bash +cross-env UMI_ENV=dev pnpm start # Development +cross-env UMI_ENV=test pnpm start # Test +cross-env UMI_ENV=pre pnpm start # Pre-production +``` + +## Code Conventions + +### Linting +- Uses **Biome** (not ESLint) for linting and formatting +- Configured in `biome.json` +- Pre-commit hook runs Biome via lint-staged + +### Commit Messages +- Uses commitlint with conventional commits +- Enforced via Husky pre-commit hook +- Format: `type(scope): subject` (e.g., `feat: add user management`) + +### Component Patterns +- **ProTable**: Use `EnhancedProTable` wrapper for common table functionality +- **Forms**: Use `DrawerForm` or `ModalForm` from `@ant-design/pro-components` +- **File Uploads**: Use custom `UploadImages` or `UploadVideo` components in `src/components/Upload/` +- **Rich Text**: Use `Tinymce` component wrapper (TinyMCE is in `public/tinymce/`) + +### Service Layer +- All API calls go through `src/services/` +- Use UmiJS `request` from `@umijs/max` (configured in `src/app.tsx`) +- Response format: `{ code: number, data: any, msg: string }` +- Success when `code === 0` + +## Common Patterns + +### Adding a New Page + +1. Create page component in `src/pages/{domain}/{feature}/index.tsx` +2. Create corresponding service in `src/services/{domain}/{feature}/index.ts` +3. Configure the menu/route in the backend system (not in code) +4. The route will automatically appear after backend configuration + +### Working with Dictionaries/Enums + +Dictionaries are loaded on app init and cached: +```typescript +import { useDictStore } from '@/hooks/stores/dict'; + +const dictStore = useDictStore(); +const dictData = dictStore.getDictByType('dict_type_key'); +``` + +### File Uploads + +Media files are uploaded via `src/services/infra/file/index.ts` or `src/services/infra/media/index.ts`. Use the Upload components which handle the API integration. + +## Testing + +- Jest configured with `jest.config.ts` +- Test files should be colocated with components or in `__tests__` directories +- Run single test: `pnpm test -- path/to/test.spec.ts` + +## Important Notes + +- **Node version**: Requires Node.js >= 20.0.0 (see `package.json` engines) +- **React 19**: Uses React 19 with `@ant-design/v5-patch-for-react-19` compatibility patch +- **Mako bundler**: Uses UmiJS Mako for faster builds (configured in `config/config.ts`) +- **Mock data**: Located in `mock/` directory, enabled by default in dev mode +- **TinyMCE**: Static files in `public/tinymce/`, Chinese language pack included diff --git a/auto-deploy.ps1 b/auto-deploy.ps1 new file mode 100644 index 0000000..f0879d1 --- /dev/null +++ b/auto-deploy.ps1 @@ -0,0 +1,30 @@ +# Auto Deploy Script for PowerShell +$SERVER = "43.139.42.137" +$USER = "root" +$REMOTE_PATH = "/home/1panel/www/sites/admin.petshy.tashowz.com/index" + +Write-Host "=== Auto Deploy ===" -ForegroundColor Cyan +Write-Host "" + +# 1. Build project +Write-Host "Building project..." -ForegroundColor Yellow +pnpm build +if ($LASTEXITCODE -ne 0) { + Write-Host "Build failed" -ForegroundColor Red + exit 1 +} +Write-Host "Build complete" -ForegroundColor Green +Write-Host "" + +# 2. Upload files +Write-Host "Uploading files to server..." -ForegroundColor Yellow +scp -r dist/* ${USER}@${SERVER}:${REMOTE_PATH}/ + +if ($LASTEXITCODE -eq 0) { + Write-Host "" + Write-Host "Deploy complete!" -ForegroundColor Green + Write-Host "Visit: http://admin.petshy.tashowz.com" -ForegroundColor Cyan +} else { + Write-Host "Upload failed" -ForegroundColor Red + exit 1 +} diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index ae2927e..837fd53 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式 + 其他登录方式111 From cb7b22bca3a2e3bdaa6bab2f763e4e489fbd4fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E5=B1=B1?= <17738440858@163.com> Date: Wed, 4 Mar 2026 09:57:06 +0800 Subject: [PATCH 21/21] =?UTF-8?q?chore(docs):=20=E5=88=A0=E9=99=A4=20CLAUD?= =?UTF-8?q?E.md=20=E6=96=87=E4=BB=B6=E5=B9=B6=E6=B8=85=E7=90=86=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=A1=B5=E9=9D=A2=E4=B8=B4=E6=97=B6=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除整个 CLAUDE.md 项目指导文件 - 清理登录页面中的临时调试文本 "111" --- CLAUDE.md | 201 --------------------------------- auto-deploy.ps1 | 30 ----- src/pages/user/login/index.tsx | 2 +- 3 files changed, 1 insertion(+), 232 deletions(-) delete mode 100644 CLAUDE.md delete mode 100644 auto-deploy.ps1 diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 514f5a6..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,201 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -This is a multi-tenant service management platform ("百业到家") built with Ant Design Pro, React 19, TypeScript, and UmiJS Max framework. The application uses dynamic routing loaded from a backend API and implements a comprehensive permission system. - -## Development Commands - -```bash -# Start development server (with mocks) -pnpm dev -# or -pnpm start - -# Start development server (without mocks, connects to backend) -pnpm start:dev - -# Build for production -pnpm build - -# Lint (Biome + TypeScript check) -pnpm lint - -# Run tests -pnpm test - -# Run tests with coverage -pnpm test:coverage - -# Type check only -pnpm tsc -``` - -**Important**: This project uses **pnpm** as the package manager, not npm or yarn. - -## Architecture - -### Dynamic Routing System - -Routes are **not** statically defined in `config/routes.ts` (most routes are commented out). Instead, routes are dynamically loaded from the backend API: - -1. On app initialization, `getInfo()` fetches user permissions and menu structure -2. `patchClientRoutes()` in `src/app.tsx` transforms backend menu data into UmiJS routes -3. `loopMenuItem()` in `src/utils/menuUtils.tsx` recursively converts menu items to route objects -4. Routes are lazy-loaded using `React.lazy(() => import('@/pages/${component}'))` - -**When adding new pages**: Create the page component in `src/pages/`, then configure the route in the backend system (not in code). - -### Multi-Tenant Architecture - -Every API request includes a `tenant-id` header. Tenant information is: -- Stored in web-storage-cache with key `CACHE_KEY.TenantId` -- Set during login via `setTenantId()` -- Automatically added to all requests by the request interceptor in `src/app.tsx` - -### Authentication Flow - -1. User logs in with tenant name, username, and password (password is RSA encrypted via JSEncrypt) -2. Backend returns `accessToken` and `refreshToken` -3. Tokens stored in web-storage-cache (see `src/utils/auth.ts`) -4. All requests include `Authorization: Bearer ${accessToken}` header -5. On 401 response, automatically attempts token refresh using `refreshToken` -6. If refresh fails, redirects to login page - -**Token refresh logic** is in `src/requestErrorConfig.ts` with request queuing to prevent duplicate refresh attempts. - -### Request Interceptors - -All API requests are automatically modified (see `src/app.tsx`): -- **API prefix**: `/admin-api` is prepended to all URLs (unless already present) -- **Headers**: `Authorization`, `tenant-id`, and `Accept` headers are added -- **Parameter serialization**: Arrays are serialized specially: - - `createTime` arrays become `createTime[0]` and `createTime[1]` - - Other arrays become `key[]` format - -### Caching Strategy - -Uses `web-storage-cache` library (see `src/hooks/web/useCache.ts`): -- `CACHE_KEY.USER`: Current user info -- `CACHE_KEY.ROLE_ROUTERS`: Dynamic menu/route data -- `CACHE_KEY.ACCESS_TOKEN` / `CACHE_KEY.REFRESH_TOKEN`: Auth tokens -- `CACHE_KEY.DICT_CACHE`: Dictionary/enum data loaded on app init -- `CACHE_KEY.LoginForm`: Remember me functionality (password encrypted) - -### State Management - -- **UmiJS Model Plugin**: For global state (see `src/app.tsx` - `initialState`) -- **Custom Hooks**: In `src/hooks/stores/` (e.g., `useDictStore` for dictionary management) -- **Web Storage Cache**: For persistent data across sessions - -## Project Structure - -``` -src/ -├── pages/ # Feature pages organized by domain -│ ├── ai/ # AI model and sample management -│ ├── prod/ # Product and category management -│ ├── system/ # System admin (users, roles, menus, tenants, logs, messages) -│ ├── trade/ # Order and sales management -│ └── user/ # Login page -├── services/ # API service layer (mirrors page structure) -├── components/ # Reusable components -│ ├── Draggable/ # Drag-and-drop components using @dnd-kit -│ ├── Upload/ # File/image/video upload components -│ ├── GroupTag/ # Tag management components -│ └── Tinymce/ # Rich text editor wrapper -├── hooks/ # Custom React hooks -│ ├── antd/ # Ant Design related hooks -│ ├── stores/ # State management hooks -│ └── web/ # Web utilities (cache, etc.) -├── utils/ # Utility functions -│ ├── auth.ts # Token and tenant management -│ ├── menuUtils.tsx # Dynamic route conversion -│ ├── dict.ts # Dictionary/enum utilities -│ └── tree.ts # Tree data structure helpers -├── constants/ # Shared constants and enums -├── locales/ # i18n translations (zh-CN default) -└── app.tsx # App initialization and runtime config -``` - -## Environment Configuration - -Multiple environment files: -- `.env.local` - Local overrides (gitignored) -- `.env.dev` - Development environment -- `.env.prod` - Production environment - -**Proxy configuration** in `config/proxy.ts`: -- `dev`: Points to local backend (currently `http://192.168.1.89:48080`) -- `test`: Points to test environment -- `pre`: Points to pre-production environment - -Switch environments using `UMI_ENV`: -```bash -cross-env UMI_ENV=dev pnpm start # Development -cross-env UMI_ENV=test pnpm start # Test -cross-env UMI_ENV=pre pnpm start # Pre-production -``` - -## Code Conventions - -### Linting -- Uses **Biome** (not ESLint) for linting and formatting -- Configured in `biome.json` -- Pre-commit hook runs Biome via lint-staged - -### Commit Messages -- Uses commitlint with conventional commits -- Enforced via Husky pre-commit hook -- Format: `type(scope): subject` (e.g., `feat: add user management`) - -### Component Patterns -- **ProTable**: Use `EnhancedProTable` wrapper for common table functionality -- **Forms**: Use `DrawerForm` or `ModalForm` from `@ant-design/pro-components` -- **File Uploads**: Use custom `UploadImages` or `UploadVideo` components in `src/components/Upload/` -- **Rich Text**: Use `Tinymce` component wrapper (TinyMCE is in `public/tinymce/`) - -### Service Layer -- All API calls go through `src/services/` -- Use UmiJS `request` from `@umijs/max` (configured in `src/app.tsx`) -- Response format: `{ code: number, data: any, msg: string }` -- Success when `code === 0` - -## Common Patterns - -### Adding a New Page - -1. Create page component in `src/pages/{domain}/{feature}/index.tsx` -2. Create corresponding service in `src/services/{domain}/{feature}/index.ts` -3. Configure the menu/route in the backend system (not in code) -4. The route will automatically appear after backend configuration - -### Working with Dictionaries/Enums - -Dictionaries are loaded on app init and cached: -```typescript -import { useDictStore } from '@/hooks/stores/dict'; - -const dictStore = useDictStore(); -const dictData = dictStore.getDictByType('dict_type_key'); -``` - -### File Uploads - -Media files are uploaded via `src/services/infra/file/index.ts` or `src/services/infra/media/index.ts`. Use the Upload components which handle the API integration. - -## Testing - -- Jest configured with `jest.config.ts` -- Test files should be colocated with components or in `__tests__` directories -- Run single test: `pnpm test -- path/to/test.spec.ts` - -## Important Notes - -- **Node version**: Requires Node.js >= 20.0.0 (see `package.json` engines) -- **React 19**: Uses React 19 with `@ant-design/v5-patch-for-react-19` compatibility patch -- **Mako bundler**: Uses UmiJS Mako for faster builds (configured in `config/config.ts`) -- **Mock data**: Located in `mock/` directory, enabled by default in dev mode -- **TinyMCE**: Static files in `public/tinymce/`, Chinese language pack included diff --git a/auto-deploy.ps1 b/auto-deploy.ps1 deleted file mode 100644 index f0879d1..0000000 --- a/auto-deploy.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -# Auto Deploy Script for PowerShell -$SERVER = "43.139.42.137" -$USER = "root" -$REMOTE_PATH = "/home/1panel/www/sites/admin.petshy.tashowz.com/index" - -Write-Host "=== Auto Deploy ===" -ForegroundColor Cyan -Write-Host "" - -# 1. Build project -Write-Host "Building project..." -ForegroundColor Yellow -pnpm build -if ($LASTEXITCODE -ne 0) { - Write-Host "Build failed" -ForegroundColor Red - exit 1 -} -Write-Host "Build complete" -ForegroundColor Green -Write-Host "" - -# 2. Upload files -Write-Host "Uploading files to server..." -ForegroundColor Yellow -scp -r dist/* ${USER}@${SERVER}:${REMOTE_PATH}/ - -if ($LASTEXITCODE -eq 0) { - Write-Host "" - Write-Host "Deploy complete!" -ForegroundColor Green - Write-Host "Visit: http://admin.petshy.tashowz.com" -ForegroundColor Cyan -} else { - Write-Host "Upload failed" -ForegroundColor Red - exit 1 -} diff --git a/src/pages/user/login/index.tsx b/src/pages/user/login/index.tsx index 837fd53..ae2927e 100644 --- a/src/pages/user/login/index.tsx +++ b/src/pages/user/login/index.tsx @@ -143,7 +143,7 @@ const Page = () => { fontSize: 14, }} > - 其他登录方式111 + 其他登录方式