From c84b5a0b35b50d78cda41266b4e9ba20b10f1a2c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 28 Dec 2025 04:49:51 +0000 Subject: [PATCH 01/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.2.4=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.2.4=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.2.4](https://github.com/perfect-panel/frontend/compare/v1.2.3...v1.2.4) (2025-12-28) ### 🐛 Bug Fixes / 问题修复 * Add onSuccess callback to Unsubscribe component and conditionally render Renewal component ([7b5367a](https://github.com/perfect-panel/frontend/commit/7b5367a9a99ac8ae608a765b79a66c1f7380dcd8)) * Remove the system log dialog component from the system version card ([71cb827](https://github.com/perfect-panel/frontend/commit/71cb827918ee3250f0c9d06d46d876ce6799b8ac)) * Update invite link format in auth forms and sidebar to include hash fragment for routing. ([7a8c010](https://github.com/perfect-panel/frontend/commit/7a8c0102958a859c9e7476810d5c9b822f882692)) ### 📚 Documentation / 文档更新 * Add one-click installation script for PPanel with Docker support ([912c5c4](https://github.com/perfect-panel/frontend/commit/912c5c4cb63eeb0ecbc33bef6b31bd50d83d6491)) ### 🔧 Chores / 其他变更 * **release:** Release 1.2.4-dev.1 / 发布版本 1.2.4-dev.1 [skip ci] ([62d45bb](https://github.com/perfect-panel/frontend/commit/62d45bbac17fab9656c1cce029a379ce8bb757d6)) --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 729c5c9..79534d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,22 @@ This document records all notable changes to ShadCN Admin. --- +## [1.2.4](https://github.com/perfect-panel/frontend/compare/v1.2.3...v1.2.4) (2025-12-28) + +### 🐛 Bug Fixes / 问题修复 + +* Add onSuccess callback to Unsubscribe component and conditionally render Renewal component ([7b5367a](https://github.com/perfect-panel/frontend/commit/7b5367a9a99ac8ae608a765b79a66c1f7380dcd8)) +* Remove the system log dialog component from the system version card ([71cb827](https://github.com/perfect-panel/frontend/commit/71cb827918ee3250f0c9d06d46d876ce6799b8ac)) +* Update invite link format in auth forms and sidebar to include hash fragment for routing. ([7a8c010](https://github.com/perfect-panel/frontend/commit/7a8c0102958a859c9e7476810d5c9b822f882692)) + +### 📚 Documentation / 文档更新 + +* Add one-click installation script for PPanel with Docker support ([912c5c4](https://github.com/perfect-panel/frontend/commit/912c5c4cb63eeb0ecbc33bef6b31bd50d83d6491)) + +### 🔧 Chores / 其他变更 + +* **release:** Release 1.2.4-dev.1 / 发布版本 1.2.4-dev.1 [skip ci] ([62d45bb](https://github.com/perfect-panel/frontend/commit/62d45bbac17fab9656c1cce029a379ce8bb757d6)) + ## [1.2.4-dev.1](https://github.com/perfect-panel/frontend/compare/v1.2.3...v1.2.4-dev.1) (2025-12-22) ### 🐛 Bug Fixes / 问题修复 diff --git a/package.json b/package.json index c051e63..024d21c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.2.4-dev.1", + "version": "1.2.4", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": { From 7279275532ad0b73994ffe5cf2e4c2f8dabc280b Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Sun, 28 Dec 2025 07:05:21 +0000 Subject: [PATCH 02/32] =?UTF-8?q?=F0=9F=93=9D=20docs:=20Update=20default?= =?UTF-8?q?=20administrator=20account=20information=20and=20security=20rec?= =?UTF-8?q?ommendations=20in=20installation=20guides?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/guide/installation.md | 15 +++++++++++++-- docs/guide/installation/binary.md | 8 ++++++++ docs/guide/installation/docker-compose.md | 6 +++++- docs/guide/installation/docker-run.md | 8 ++++++++ docs/public/scripts/en/install-ppanel.sh | 16 ++++++++++++++-- docs/public/scripts/zh/install-ppanel.sh | 14 ++++++++++++++ docs/zh/guide/installation.md | 15 +++++++++++++-- docs/zh/guide/installation/binary.md | 8 ++++++++ docs/zh/guide/installation/docker-compose.md | 6 +++++- docs/zh/guide/installation/docker-run.md | 8 ++++++++ 10 files changed, 96 insertions(+), 8 deletions(-) diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 735fea6..6292e42 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -211,8 +211,19 @@ After successful installation, you can access: - **User Panel**: `http://your-server-ip:8080` - **Admin Panel**: `http://your-server-ip:8080/admin/` -::: warning Default Credentials -Please change the default admin password immediately after first login for security. +::: warning Administrator Account +**Default Administrator Account** (if not configured in config file): +- **Email**: `admin@ppanel.dev` +- **Password**: `password` + +**One-Click Installation Script** will automatically generate random administrator credentials displayed at the end: +- **Email**: `admin-[8 random characters]@ppanel.dev` +- **Password**: `[Randomly generated 16-character password]` + +**Security Recommendations**: +- When using the one-click script, save the generated credentials securely +- Change your password immediately after first login +- If using default credentials, **must** change both email and password after first login ::: ### Configure Reverse Proxy (Optional) diff --git a/docs/guide/installation/binary.md b/docs/guide/installation/binary.md index f5ad4cb..64fb979 100644 --- a/docs/guide/installation/binary.md +++ b/docs/guide/installation/binary.md @@ -309,6 +309,14 @@ ps aux | grep ppanel - **User Panel**: `http://your-server-ip:8080` - **Admin Panel**: `http://your-server-ip:8080/admin/` +::: warning Default Credentials +**Default Administrator Account**: +- **Email**: `admin@ppanel.dev` +- **Password**: `password` + +**Security**: Change the default credentials immediately after first login. +::: + ### Configure Firewall ```bash diff --git a/docs/guide/installation/docker-compose.md b/docs/guide/installation/docker-compose.md index 9e69296..737f8a3 100644 --- a/docs/guide/installation/docker-compose.md +++ b/docs/guide/installation/docker-compose.md @@ -223,7 +223,11 @@ After successful installation, you can access: - **Admin Panel**: `http://your-server-ip:8080/admin/` ::: warning Default Credentials -Please change the default admin password immediately after first login for security. +**Default Administrator Account** (if not configured): +- **Email**: `admin@ppanel.dev` +- **Password**: `password` + +**Security**: Change the default credentials immediately after first login. ::: ### Configure Reverse Proxy (Recommended) diff --git a/docs/guide/installation/docker-run.md b/docs/guide/installation/docker-run.md index 1b75030..a201a38 100644 --- a/docs/guide/installation/docker-run.md +++ b/docs/guide/installation/docker-run.md @@ -232,6 +232,14 @@ docker volume rm ppanel-data ``` ::: +::: warning Default Credentials +**Default Administrator Account**: +- **Email**: `admin@ppanel.dev` +- **Password**: `password` + +**Security**: Change the default credentials immediately after first login. +::: + ## Upgrading Upgrade PPanel directly from the **Admin Dashboard**. On the dashboard homepage, you can check for new versions and upgrade with one click. diff --git a/docs/public/scripts/en/install-ppanel.sh b/docs/public/scripts/en/install-ppanel.sh index 713da45..bbbb58c 100755 --- a/docs/public/scripts/en/install-ppanel.sh +++ b/docs/public/scripts/en/install-ppanel.sh @@ -113,6 +113,12 @@ get_user_input() { log_info "✓ Redis password generated" + # Administrator configuration + ADMIN_EMAIL="admin-$(generate_secret | cut -c1-8)@ppanel.dev" + ADMIN_PASSWORD=$(generate_secret | cut -c1-16) + + log_info "✓ Administrator password generated" + # Generate JWT secret JWT_SECRET=$(generate_secret) log_info "✓ JWT secret generated" @@ -145,6 +151,10 @@ JwtAuth: AccessSecret: $JWT_SECRET AccessExpire: 604800 +Administrator: + Email: $ADMIN_EMAIL + Password: "$ADMIN_PASSWORD" + Logger: ServiceName: ApiService Mode: console @@ -343,8 +353,10 @@ show_access_info() { else log_warn "Unable to get public IP, please configure manually for public access" fi - echo "" - log_info "Database Information:" + echo "" log_info "Administrator Account:" + echo " Email: $ADMIN_EMAIL" + echo " Password: $ADMIN_PASSWORD" + echo "" log_info "Database Information:" echo " MySQL (Container Network):" echo " Address: mysql:3306" echo " User: $MYSQL_USER" diff --git a/docs/public/scripts/zh/install-ppanel.sh b/docs/public/scripts/zh/install-ppanel.sh index fec0313..8f6be90 100755 --- a/docs/public/scripts/zh/install-ppanel.sh +++ b/docs/public/scripts/zh/install-ppanel.sh @@ -113,6 +113,12 @@ get_user_input() { log_info "✓ 已生成 Redis 密码" + # 管理员配置 + ADMIN_EMAIL="admin-$(generate_secret | cut -c1-8)@ppanel.dev" + ADMIN_PASSWORD=$(generate_secret | cut -c1-16) + + log_info "✓ 已生成管理员密码" + # 生成 JWT 密钥 JWT_SECRET=$(generate_secret) log_info "✓ 已生成 JWT 密钥" @@ -145,6 +151,10 @@ JwtAuth: AccessSecret: $JWT_SECRET AccessExpire: 604800 +Administrator: + Email: $ADMIN_EMAIL + Password: "$ADMIN_PASSWORD" + Logger: ServiceName: ApiService Mode: console @@ -346,6 +356,10 @@ show_access_info() { log_warn "未能获取公网IP,如需外网访问请手动配置" fi echo "" + log_info "管理员账户:" + echo " 邮箱: $ADMIN_EMAIL" + echo " 密码: $ADMIN_PASSWORD" + echo "" log_info "数据库信息:" echo " MySQL (容器间通信):" echo " 地址: mysql:3306" diff --git a/docs/zh/guide/installation.md b/docs/zh/guide/installation.md index 9615dae..cfeb31f 100644 --- a/docs/zh/guide/installation.md +++ b/docs/zh/guide/installation.md @@ -211,8 +211,19 @@ docker compose ps - **用户面板**: `http://your-server-ip:8080` - **管理后台**: `http://your-server-ip:8080/admin` -::: warning 默认凭据 -为了安全起见,首次登录后请立即修改默认管理员密码。 +::: warning 管理员账户 +**默认管理员账户**(如果配置文件未设置): +- **邮箱**: `admin@ppanel.dev` +- **密码**: `password` + +**一键安装脚本**会自动生成随机的管理员账户并在安装结束时显示: +- **邮箱**: `admin-[8位随机字符]@ppanel.dev` +- **密码**: `[随机生成的16位密码]` + +**安全建议**: +- 使用一键安装脚本时,请妥善保管脚本生成的凭据 +- 首次登录后立即修改密码 +- 如果使用默认账户,**必须**在首次登录后修改邮箱和密码 ::: ### 配置反向代理(可选) diff --git a/docs/zh/guide/installation/binary.md b/docs/zh/guide/installation/binary.md index a7fc7dd..b523184 100644 --- a/docs/zh/guide/installation/binary.md +++ b/docs/zh/guide/installation/binary.md @@ -309,6 +309,14 @@ ps aux | grep ppanel - **用户面板**: `http://your-server-ip:8080` - **管理后台**: `http://your-server-ip:8080/admin/` +::: warning 默认凭据 +**默认管理员账号**: +- **邮箱**: `admin@ppanel.dev` +- **密码**: `password` + +**安全提醒**: 首次登录后请立即修改默认凭据。 +::: + ### 配置防火墙 ```bash diff --git a/docs/zh/guide/installation/docker-compose.md b/docs/zh/guide/installation/docker-compose.md index 9df8d42..3cb9722 100644 --- a/docs/zh/guide/installation/docker-compose.md +++ b/docs/zh/guide/installation/docker-compose.md @@ -219,7 +219,11 @@ docker compose logs -f ppanel - **管理后台**: `http://your-server-ip:8080/admin/` ::: warning 默认凭据 -为了安全起见,首次登录后请立即修改默认管理员密码。 +**默认管理员账号**(如果未配置时): +- **邮箱**: `admin@ppanel.dev` +- **密码**: `password` + +**安全提醒**: 首次登录后请立即修改默认凭据。 ::: ### 配置反向代理(推荐) diff --git a/docs/zh/guide/installation/docker-run.md b/docs/zh/guide/installation/docker-run.md index b7eeca1..045a83d 100644 --- a/docs/zh/guide/installation/docker-run.md +++ b/docs/zh/guide/installation/docker-run.md @@ -232,6 +232,14 @@ docker volume rm ppanel-data ``` ::: +::: warning 默认凭据 +**默认管理员账号**: +- **邮箱**: `admin@ppanel.dev` +- **密码**: `password` + +**安全提醒**: 首次登录后请立即修改默认凭据。 +::: + ## 升级 直接从**管理后台**主页升级 PPanel。在仪表盘主页可以检查新版本并一键升级。 From 543a7b9eb9b2cd278a70f668b0a0e0e9e261fe57 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 05:34:01 +0000 Subject: [PATCH 03/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Add=20original=20pric?= =?UTF-8?q?e=20display=20option=20and=20enhance=20inventory=20messages=20i?= =?UTF-8?q?n=20subscription=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/locales/en-US/components.json | 2 + .../public/assets/locales/en-US/product.json | 4 ++ .../assets/locales/zh-CN/components.json | 2 + .../public/assets/locales/zh-CN/product.json | 4 ++ .../components/system-version-card.tsx | 6 +- .../src/sections/product/subscribe-form.tsx | 34 ++++++++++- .../src/sections/product/subscribe-table.tsx | 17 +++--- .../assets/locales/en-US/components.json | 2 + .../assets/locales/en-US/subscribe.json | 1 + .../assets/locales/zh-CN/components.json | 2 + .../assets/locales/zh-CN/subscribe.json | 1 + .../main/product-showcase/content.tsx | 51 +++++++++++----- apps/user/src/sections/purchasing/content.tsx | 1 + apps/user/src/sections/purchasing/order.tsx | 1 + apps/user/src/sections/subscribe/billing.tsx | 15 ++++- apps/user/src/sections/subscribe/index.tsx | 41 ++++++++++--- apps/user/src/sections/subscribe/purchase.tsx | 1 + apps/user/src/sections/subscribe/renewal.tsx | 1 + apps/user/src/sections/user/payment/index.tsx | 1 + packages/ui/src/lib/request.ts | 8 +++ packages/ui/src/services/admin/server.ts | 22 ------- packages/ui/src/services/admin/typings.d.ts | 19 +++++- packages/ui/src/services/admin/user.ts | 58 +++++++++++++++++++ packages/ui/src/services/common/typings.d.ts | 6 +- packages/ui/src/services/user/typings.d.ts | 2 +- 25 files changed, 241 insertions(+), 61 deletions(-) diff --git a/apps/admin/public/assets/locales/en-US/components.json b/apps/admin/public/assets/locales/en-US/components.json index dd65d5a..a55a707 100644 --- a/apps/admin/public/assets/locales/en-US/components.json +++ b/apps/admin/public/assets/locales/en-US/components.json @@ -44,6 +44,8 @@ "60003": "An existing subscription is detected. Please cancel it before proceeding.", "60004": "Unable to delete at the moment as the subscription has active users.", "60005": "Single subscription mode has exceeded user limit", + "60006": "User quota limit has been reached, unable to continue.", + "60007": "Insufficient inventory, please try again later or contact the administrator.", "70001": "Incorrect verification code, please re-enter.", "80001": "Task was not successfully queued, please try again later.", "90001": "Please disable DEBUG mode and try again.", diff --git a/apps/admin/public/assets/locales/en-US/product.json b/apps/admin/public/assets/locales/en-US/product.json index a06e7ca..4f1f0ff 100644 --- a/apps/admin/public/assets/locales/en-US/product.json +++ b/apps/admin/public/assets/locales/en-US/product.json @@ -30,6 +30,8 @@ "discountPercent": "Discount Percentage", "Hour": "Hour", "inventory": "Subscription Limit", + "inventoryDescription": "Set to -1 for unlimited inventory", + "unlimitedInventory": "Unlimited (enter -1)", "language": "Language", "languageDescription": "Leave empty for default without language restriction", "languagePlaceholder": "Language identifier for the subscription, e.g., en-US, zh-CN", @@ -54,6 +56,8 @@ "resetOn1st": "Reset on the 1st", "selectResetCycle": "Please select a reset cycle", "selectUnitTime": "Please select a unit of time", + "showOriginalPrice": "Show Original Price", + "showOriginalPriceDescription": "When enabled, the subscription card will display both the original price and the discounted price to help users understand the discount amount", "speedLimit": "Speed Limit ", "traffic": "Traffic", "unitPrice": "Unit Price", diff --git a/apps/admin/public/assets/locales/zh-CN/components.json b/apps/admin/public/assets/locales/zh-CN/components.json index 60fb6ff..b56ad5a 100644 --- a/apps/admin/public/assets/locales/zh-CN/components.json +++ b/apps/admin/public/assets/locales/zh-CN/components.json @@ -44,6 +44,8 @@ "60003": "检测到现有订阅,请先取消后再继续。", "60004": "由于订阅有活跃用户,暂时无法删除。", "60005": "单一订阅模式已超过用户限制", + "60006": "用户配额已达到限制,无法继续操作。", + "60007": "库存不足,请稍后再试或联系管理员。", "70001": "验证码不正确,请重新输入。", "80001": "任务未成功加入队列,请稍后再试。", "90001": "请禁用 DEBUG 模式后再试。", diff --git a/apps/admin/public/assets/locales/zh-CN/product.json b/apps/admin/public/assets/locales/zh-CN/product.json index b1dd2c3..4bf0a04 100644 --- a/apps/admin/public/assets/locales/zh-CN/product.json +++ b/apps/admin/public/assets/locales/zh-CN/product.json @@ -30,6 +30,8 @@ "discountPercent": "折扣百分比", "Hour": "小时", "inventory": "订阅库存", + "inventoryDescription": "设置为 -1 表示不限制库存", + "unlimitedInventory": "无限制(输入 -1)", "language": "语言", "languageDescription": "留空为默认无语言限制", "languagePlaceholder": "订阅的语言标识符,例如 en-US、zh-CN", @@ -54,6 +56,8 @@ "resetOn1st": "每月1日重置", "selectResetCycle": "请选择重置周期", "selectUnitTime": "请选择时间单位", + "showOriginalPrice": "显示原价", + "showOriginalPriceDescription": "开启后,在订阅卡片上将会显示原价和折后价,帮助用户了解优惠幅度", "speedLimit": "速度限制", "traffic": "流量", "unitPrice": "单价", diff --git a/apps/admin/src/sections/dashboard/components/system-version-card.tsx b/apps/admin/src/sections/dashboard/components/system-version-card.tsx index 2fde9fa..4a8cfe2 100644 --- a/apps/admin/src/sections/dashboard/components/system-version-card.tsx +++ b/apps/admin/src/sections/dashboard/components/system-version-card.tsx @@ -69,7 +69,7 @@ export default function SystemVersionCard() { queryFn: async () => { const { data } = await basicCheckServiceVersion( { - service_name: "admin", + service_name: "admin-web-with-api", secret: moduleConfig!.secret, }, { skipErrorHandler: true } @@ -105,13 +105,13 @@ export default function SystemVersionCard() { setIsUpdatingWeb(true); try { await basicUpdateService({ - service_name: "admin", + service_name: "admin-web-with-api", secret: moduleConfig.secret, }); toast.success(t("adminUpdateSuccess", "Admin updated successfully")); await basicUpdateService({ - service_name: "user", + service_name: "user-web-with-api", secret: moduleConfig.secret, }); toast.success(t("userUpdateSuccess", "User updated successfully")); diff --git a/apps/admin/src/sections/product/subscribe-form.tsx b/apps/admin/src/sections/product/subscribe-form.tsx index a6532d4..198d124 100644 --- a/apps/admin/src/sections/product/subscribe-form.tsx +++ b/apps/admin/src/sections/product/subscribe-form.tsx @@ -120,6 +120,7 @@ export default function SubscribeForm>({ allow_deduction: z.boolean().optional(), reset_cycle: z.number().optional(), renewal_reset: z.boolean().optional(), + show_original_price: z.boolean().optional(), }); const form = useForm>({ @@ -444,16 +445,18 @@ export default function SubscribeForm>({ {t("form.inventory")} { form.setValue(field.name, value); }} - placeholder={t("form.noLimit")} + placeholder={t("form.unlimitedInventory")} step={1} type="number" value={field.value} /> + + {t("form.inventoryDescription")} + )} @@ -864,6 +867,33 @@ export default function SubscribeForm>({ )} /> + ( + +
+
+ + {t("form.showOriginalPrice")} + + + {t("form.showOriginalPriceDescription")} + +
+ + { + form.setValue(field.name, value); + }} + /> + +
+ +
+ )} + /> diff --git a/apps/admin/src/sections/product/subscribe-table.tsx b/apps/admin/src/sections/product/subscribe-table.tsx index e9942ee..8287987 100644 --- a/apps/admin/src/sections/product/subscribe-table.tsx +++ b/apps/admin/src/sections/product/subscribe-table.tsx @@ -208,15 +208,14 @@ export default function SubscribeTable() { { accessorKey: "inventory", header: t("inventory"), - cell: ({ row }) => ( - - ), + cell: ({ row }) => { + const inventory = row.getValue("inventory") as number; + return inventory === -1 ? ( + t("unlimited") + ) : ( + + ); + }, }, { accessorKey: "quota", diff --git a/apps/user/public/assets/locales/en-US/components.json b/apps/user/public/assets/locales/en-US/components.json index 19d26b4..71cb528 100644 --- a/apps/user/public/assets/locales/en-US/components.json +++ b/apps/user/public/assets/locales/en-US/components.json @@ -44,6 +44,8 @@ "60003": "An existing subscription is detected. Please cancel it before proceeding.", "60004": "Unable to delete at the moment as the subscription has active users.", "60005": "Single subscription mode has exceeded user limit", + "60006": "User quota limit has been reached, unable to continue.", + "60007": "Insufficient inventory, please try again later or contact the administrator.", "70001": "Incorrect verification code, please re-enter.", "80001": "Task was not successfully queued, please try again later.", "90001": "Please disable DEBUG mode and try again.", diff --git a/apps/user/public/assets/locales/en-US/subscribe.json b/apps/user/public/assets/locales/en-US/subscribe.json index 3860388..bee2b6d 100644 --- a/apps/user/public/assets/locales/en-US/subscribe.json +++ b/apps/user/public/assets/locales/en-US/subscribe.json @@ -6,6 +6,7 @@ "duration": "Duration", "fee": "Fee", "gift": "gift Deduction", + "originalPrice": "Original Price (Monthly)", "price": "Price", "productDiscount": "Product Discount", "total": "Total" diff --git a/apps/user/public/assets/locales/zh-CN/components.json b/apps/user/public/assets/locales/zh-CN/components.json index 95c9d21..390f131 100644 --- a/apps/user/public/assets/locales/zh-CN/components.json +++ b/apps/user/public/assets/locales/zh-CN/components.json @@ -44,6 +44,8 @@ "60003": "检测到现有订阅,请先取消后再继续。", "60004": "由于订阅有活跃用户,暂时无法删除。", "60005": "单一订阅模式已超过用户限制", + "60006": "用户配额已达到限制,无法继续操作。", + "60007": "库存不足,请稍后再试或联系管理员。", "70001": "验证码不正确,请重新输入。", "80001": "任务未成功加入队列,请稍后再试。", "90001": "请禁用 DEBUG 模式后再试。", diff --git a/apps/user/public/assets/locales/zh-CN/subscribe.json b/apps/user/public/assets/locales/zh-CN/subscribe.json index 59efb44..0c94342 100644 --- a/apps/user/public/assets/locales/zh-CN/subscribe.json +++ b/apps/user/public/assets/locales/zh-CN/subscribe.json @@ -6,6 +6,7 @@ "duration": "套餐时长", "fee": "手续费", "gift": "赠金抵扣", + "originalPrice": "原价(按月)", "price": "价格", "productDiscount": "商品折扣", "total": "总价" diff --git a/apps/user/src/sections/main/product-showcase/content.tsx b/apps/user/src/sections/main/product-showcase/content.tsx index aecbd26..01079d8 100644 --- a/apps/user/src/sections/main/product-showcase/content.tsx +++ b/apps/user/src/sections/main/product-showcase/content.tsx @@ -142,19 +142,44 @@ export function Content({ subscriptionData }: ProductShowcaseProps) { - - - - / - {unitTimeMap[item.unit_time!] || - t(item.unit_time || "Month", item.unit_time || "Month")} - - + {(() => { + const hasDiscount = item.discount && item.discount.length > 0; + const shouldShowOriginal = item.show_original_price !== false; + + const displayPrice = + shouldShowOriginal || !hasDiscount + ? item.unit_price + : Math.round( + item.unit_price * + (item.discount?.[0]?.quantity ?? 1) * + ((item.discount?.[0]?.discount ?? 100) / 100) + ); + + const displayQuantity = + shouldShowOriginal || !hasDiscount + ? 1 + : (item.discount?.[0]?.quantity ?? 1); + + const unitTime = + unitTimeMap[item.unit_time!] || + t(item.unit_time || "Month", item.unit_time || "Month"); + + return ( + + + + {displayQuantity === 1 + ? `/${unitTime}` + : `/${displayQuantity} ${unitTime}`} + + + ); + })()} From bc451eea16b51f1ab81b6cacf65201886866e1cc Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 05:51:24 +0000 Subject: [PATCH 05/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Added=20reset=20and?= =?UTF-8?q?=20pause=20subscription=20functionality,=20and=20updated=20the?= =?UTF-8?q?=20status=20display.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/assets/locales/en-US/user.json | 15 ++++ .../public/assets/locales/zh-CN/user.json | 15 ++++ .../sections/user/user-subscription/index.tsx | 90 +++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/apps/admin/public/assets/locales/en-US/user.json b/apps/admin/public/assets/locales/en-US/user.json index f5a55e7..0127346 100644 --- a/apps/admin/public/assets/locales/en-US/user.json +++ b/apps/admin/public/assets/locales/en-US/user.json @@ -71,6 +71,21 @@ "remove": "Remove", "resetLogs": "Reset Logs", "resetTime": "Reset Time", + "resetToken": "Reset Subscription Address", + "resetTokenDescription": "This will reset the subscription address and regenerate a new token.", + "resetTokenSuccess": "Subscription address reset successfully", + "confirmResetToken": "Confirm Reset Subscription Address", + "stopSubscribe": "Stop Subscription", + "stopSubscribeDescription": "This will stop the subscription temporarily. User will not be able to use it.", + "stopSubscribeSuccess": "Subscription stopped successfully", + "confirmStopSubscribe": "Confirm Stop Subscription", + "status": "Status", + "statusPending": "Pending", + "statusActive": "Active", + "statusFinished": "Finished", + "statusExpired": "Expired", + "statusDeducted": "Deducted", + "statusStopped": "Stopped", "save": "Save", "speedLimit": "Speed Limit", "startTime": "startTime", diff --git a/apps/admin/public/assets/locales/zh-CN/user.json b/apps/admin/public/assets/locales/zh-CN/user.json index 57b7bc8..e4dc3d2 100644 --- a/apps/admin/public/assets/locales/zh-CN/user.json +++ b/apps/admin/public/assets/locales/zh-CN/user.json @@ -71,6 +71,21 @@ "remove": "移除", "resetLogs": "重置日志", "resetTime": "重置时间", + "resetToken": "重置订阅地址", + "resetTokenDescription": "这将重置订阅地址并重新生成新的令牌。", + "resetTokenSuccess": "订阅地址重置成功", + "confirmResetToken": "确认重置订阅地址", + "stopSubscribe": "暂停订阅", + "stopSubscribeDescription": "这将暂时停止订阅。用户将无法使用。", + "stopSubscribeSuccess": "订阅已暂停", + "confirmStopSubscribe": "确认暂停订阅", + "status": "状态", + "statusPending": "待处理", + "statusActive": "活跃", + "statusFinished": "已完成", + "statusExpired": "已过期", + "statusDeducted": "已扣除", + "statusStopped": "已停止", "save": "保存", "speedLimit": "速度限制", "startTime": "开始时间", diff --git a/apps/admin/src/sections/user/user-subscription/index.tsx b/apps/admin/src/sections/user/user-subscription/index.tsx index a279d18..fd90618 100644 --- a/apps/admin/src/sections/user/user-subscription/index.tsx +++ b/apps/admin/src/sections/user/user-subscription/index.tsx @@ -1,4 +1,5 @@ import { Link } from "@tanstack/react-router"; +import { Badge } from "@workspace/ui/components/badge"; import { Button } from "@workspace/ui/components/button"; import { DropdownMenu, @@ -15,6 +16,8 @@ import { createUserSubscribe, deleteUserSubscribe, getUserSubscribe, + resetUserSubscribeToken, + stopUserSubscribe, updateUserSubscribe, } from "@workspace/ui/services/admin/user"; import { useRef, useState } from "react"; @@ -68,6 +71,53 @@ export default function UserSubscription({ userId }: { userId: number }) { > {t("copySubscription", "Copy Subscription")} , + { + await resetUserSubscribeToken({ user_subscribe_id: row.id }); + toast.success( + t( + "resetTokenSuccess", + "Subscription address reset successfully" + ) + ); + ref.current?.refresh(); + }} + title={t("confirmResetToken", "Confirm Reset Subscription Address")} + trigger={ + + } + />, + { + await stopUserSubscribe({ user_subscribe_id: row.id }); + toast.success( + t("stopSubscribeSuccess", "Subscription stopped successfully") + ); + ref.current?.refresh(); + }} + title={t("confirmStopSubscribe", "Confirm Stop Subscription")} + trigger={ + + } + />, row.original.subscribe.name, }, + { + accessorKey: "status", + header: t("status", "Status"), + cell: ({ row }) => { + const status = row.getValue("status") as number; + const statusMap: Record< + number, + { + label: string; + variant: "default" | "secondary" | "destructive" | "outline"; + } + > = { + 0: { label: t("statusPending", "Pending"), variant: "outline" }, + 1: { label: t("statusActive", "Active"), variant: "default" }, + 2: { + label: t("statusFinished", "Finished"), + variant: "secondary", + }, + 3: { + label: t("statusExpired", "Expired"), + variant: "destructive", + }, + 4: { + label: t("statusDeducted", "Deducted"), + variant: "secondary", + }, + 5: { + label: t("statusStopped", "Stopped"), + variant: "destructive", + }, + }; + const statusInfo = statusMap[status] || { + label: "Unknown", + variant: "outline", + }; + return ( + {statusInfo.label} + ); + }, + }, { accessorKey: "upload", header: t("upload", "Upload"), From 5f5c33987e54533c5348223b3cebe31aef91aa25 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 05:59:30 +0000 Subject: [PATCH 06/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Added=20the=20option?= =?UTF-8?q?=20to=20restore=20subscription,=20and=20updated=20the=20relevan?= =?UTF-8?q?t=20description=20and=20confirmation=20information.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/assets/locales/en-US/user.json | 4 ++ .../public/assets/locales/zh-CN/user.json | 4 ++ .../sections/user/user-subscription/index.tsx | 41 ++++++++++++++----- packages/ui/src/services/admin/typings.d.ts | 8 ++-- packages/ui/src/services/admin/user.ts | 8 ++-- 5 files changed, 47 insertions(+), 18 deletions(-) diff --git a/apps/admin/public/assets/locales/en-US/user.json b/apps/admin/public/assets/locales/en-US/user.json index 0127346..d03c4e2 100644 --- a/apps/admin/public/assets/locales/en-US/user.json +++ b/apps/admin/public/assets/locales/en-US/user.json @@ -79,6 +79,10 @@ "stopSubscribeDescription": "This will stop the subscription temporarily. User will not be able to use it.", "stopSubscribeSuccess": "Subscription stopped successfully", "confirmStopSubscribe": "Confirm Stop Subscription", + "resumeSubscribe": "Resume Subscription", + "resumeSubscribeDescription": "This will resume the subscription and allow the user to use it.", + "resumeSubscribeSuccess": "Subscription resumed successfully", + "confirmResumeSubscribe": "Confirm Resume Subscription", "status": "Status", "statusPending": "Pending", "statusActive": "Active", diff --git a/apps/admin/public/assets/locales/zh-CN/user.json b/apps/admin/public/assets/locales/zh-CN/user.json index e4dc3d2..5be625c 100644 --- a/apps/admin/public/assets/locales/zh-CN/user.json +++ b/apps/admin/public/assets/locales/zh-CN/user.json @@ -79,6 +79,10 @@ "stopSubscribeDescription": "这将暂时停止订阅。用户将无法使用。", "stopSubscribeSuccess": "订阅已暂停", "confirmStopSubscribe": "确认暂停订阅", + "resumeSubscribe": "恢复订阅", + "resumeSubscribeDescription": "这将恢复订阅,允许用户继续使用。", + "resumeSubscribeSuccess": "订阅已恢复", + "confirmResumeSubscribe": "确认恢复订阅", "status": "状态", "statusPending": "待处理", "statusActive": "活跃", diff --git a/apps/admin/src/sections/user/user-subscription/index.tsx b/apps/admin/src/sections/user/user-subscription/index.tsx index fd90618..7ad9554 100644 --- a/apps/admin/src/sections/user/user-subscription/index.tsx +++ b/apps/admin/src/sections/user/user-subscription/index.tsx @@ -17,7 +17,7 @@ import { deleteUserSubscribe, getUserSubscribe, resetUserSubscribeToken, - stopUserSubscribe, + toggleUserSubscribeStatus, updateUserSubscribe, } from "@workspace/ui/services/admin/user"; import { useRef, useState } from "react"; @@ -99,22 +99,43 @@ export default function UserSubscription({ userId }: { userId: number }) { { - await stopUserSubscribe({ user_subscribe_id: row.id }); + await toggleUserSubscribeStatus({ user_subscribe_id: row.id }); toast.success( - t("stopSubscribeSuccess", "Subscription stopped successfully") + row.status === 5 + ? t( + "resumeSubscribeSuccess", + "Subscription resumed successfully" + ) + : t( + "stopSubscribeSuccess", + "Subscription stopped successfully" + ) ); ref.current?.refresh(); }} - title={t("confirmStopSubscribe", "Confirm Stop Subscription")} + title={ + row.status === 5 + ? t("confirmResumeSubscribe", "Confirm Resume Subscription") + : t("confirmStopSubscribe", "Confirm Stop Subscription") + } trigger={ } />, diff --git a/packages/ui/src/services/admin/typings.d.ts b/packages/ui/src/services/admin/typings.d.ts index 87b3689..4457357 100644 --- a/packages/ui/src/services/admin/typings.d.ts +++ b/packages/ui/src/services/admin/typings.d.ts @@ -2004,10 +2004,6 @@ declare namespace API { id: number; }; - type StopUserSubscribeRequest = { - user_subscribe_id: number; - }; - type StripePayment = { method: string; client_secret: string; @@ -2167,6 +2163,10 @@ declare namespace API { enable: boolean; }; + type ToggleUserSubscribeStatusRequest = { + user_subscribe_id: number; + }; + type TosConfig = { tos_content: string; }; diff --git a/packages/ui/src/services/admin/user.ts b/packages/ui/src/services/admin/user.ts index 641b96e..39c6429 100644 --- a/packages/ui/src/services/admin/user.ts +++ b/packages/ui/src/services/admin/user.ts @@ -465,13 +465,13 @@ export async function resetUserSubscribeTraffic( ); } -/** Stop user subscribe POST /v1/admin/user/subscribe/stop */ -export async function stopUserSubscribe( - body: API.StopUserSubscribeRequest, +/** Stop user subscribe POST /v1/admin/user/subscribe/toggle */ +export async function toggleUserSubscribeStatus( + body: API.ToggleUserSubscribeStatusRequest, options?: { [key: string]: any } ) { return request( - `${import.meta.env.VITE_API_PREFIX || ""}/v1/admin/user/subscribe/stop`, + `${import.meta.env.VITE_API_PREFIX || ""}/v1/admin/user/subscribe/toggle`, { method: "POST", headers: { From 9559e003b7821303f7d0ac7f4da5fae4bf1ccad4 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 06:07:19 +0000 Subject: [PATCH 07/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Update=20queryKey=20s?= =?UTF-8?q?tructure=20in=20Purchase=20and=20Renewal=20components=20for=20i?= =?UTF-8?q?mproved=20order=20creation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/user/src/sections/subscribe/purchase.tsx | 8 +++++++- apps/user/src/sections/subscribe/renewal.tsx | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/user/src/sections/subscribe/purchase.tsx b/apps/user/src/sections/subscribe/purchase.tsx index 9526ac5..f629c98 100644 --- a/apps/user/src/sections/subscribe/purchase.tsx +++ b/apps/user/src/sections/subscribe/purchase.tsx @@ -45,7 +45,13 @@ export default function Purchase({ const { data: order } = useQuery({ enabled: !!subscribe?.id, - queryKey: ["preCreateOrder", params], + queryKey: [ + "preCreateOrder", + subscribe?.id, + params.quantity, + params.payment, + params.coupon, + ], queryFn: async () => { try { const { data } = await preCreateOrder({ diff --git a/apps/user/src/sections/subscribe/renewal.tsx b/apps/user/src/sections/subscribe/renewal.tsx index d52bda1..f4610f2 100644 --- a/apps/user/src/sections/subscribe/renewal.tsx +++ b/apps/user/src/sections/subscribe/renewal.tsx @@ -44,7 +44,13 @@ export default function Renewal({ id, subscribe }: Readonly) { const { data: order } = useQuery({ enabled: !!subscribe.id && open, - queryKey: ["preCreateOrder", params], + queryKey: [ + "preCreateOrder", + subscribe.id, + params.quantity, + params.payment, + params.coupon, + ], queryFn: async () => { try { const { data } = await preCreateOrder({ From f432ba06f9d3a86ec00bfd316d1c020ddf779de6 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 06:12:10 +0000 Subject: [PATCH 08/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Refactor=20Subscripti?= =?UTF-8?q?onForm=20layout=20for=20improved=20readability=20and=20maintain?= =?UTF-8?q?ability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user-subscription/subscription-form.tsx | 280 +++++++++--------- 1 file changed, 142 insertions(+), 138 deletions(-) diff --git a/apps/admin/src/sections/user/user-subscription/subscription-form.tsx b/apps/admin/src/sections/user/user-subscription/subscription-form.tsx index 3001fea..9eb1051 100644 --- a/apps/admin/src/sections/user/user-subscription/subscription-form.tsx +++ b/apps/admin/src/sections/user/user-subscription/subscription-form.tsx @@ -96,144 +96,148 @@ export function SubscriptionForm({ {title} -
- - ( - - {t("subscription", "Subscription")} - - - onChange={(value) => { - form.setValue(field.name, value); - }} - options={subscribes?.map((item) => ({ - value: item.id!, - label: item.name!, - }))} - placeholder="Select Subscription" - value={field.value} - /> - - - - )} - /> - ( - - {t("trafficLimit", "Traffic Limit")} - - - unitConversion("bytesToGb", value) - } - formatOutput={(value) => - unitConversion("gbToBytes", value) - } - onValueChange={(value) => { - form.setValue(field.name, value as number); - }} - suffix="GB" - /> - - - - )} - /> - ( - - - {t("uploadTraffic", "Upload Traffic")} - - - - unitConversion("bytesToGb", value) - } - formatOutput={(value) => - unitConversion("gbToBytes", value) - } - onValueChange={(value) => { - form.setValue(field.name, value as number); - }} - suffix="GB" - /> - - - - )} - /> - ( - - - {t("downloadTraffic", "Download Traffic")} - - - - unitConversion("bytesToGb", value) - } - formatOutput={(value) => - unitConversion("gbToBytes", value) - } - onValueChange={(value) => { - form.setValue(field.name, value as number); - }} - suffix="GB" - /> - - - - )} - /> - ( - - {t("expiredAt", "Expired At")} - - { - form.setValue(field.name, value || 0); - }} - placeholder={t("permanent", "Permanent")} - value={ - field.value && field.value > 0 - ? field.value - : undefined - } - /> - - - - )} - /> - - +
+
+ + ( + + {t("subscription", "Subscription")} + + + onChange={(value) => { + form.setValue(field.name, value); + }} + options={subscribes?.map((item) => ({ + value: item.id!, + label: item.name!, + }))} + placeholder="Select Subscription" + value={field.value} + /> + + + + )} + /> + ( + + + {t("trafficLimit", "Traffic Limit")} + + + + unitConversion("bytesToGb", value) + } + formatOutput={(value) => + unitConversion("gbToBytes", value) + } + onValueChange={(value) => { + form.setValue(field.name, value as number); + }} + suffix="GB" + /> + + + + )} + /> + ( + + + {t("uploadTraffic", "Upload Traffic")} + + + + unitConversion("bytesToGb", value) + } + formatOutput={(value) => + unitConversion("gbToBytes", value) + } + onValueChange={(value) => { + form.setValue(field.name, value as number); + }} + suffix="GB" + /> + + + + )} + /> + ( + + + {t("downloadTraffic", "Download Traffic")} + + + + unitConversion("bytesToGb", value) + } + formatOutput={(value) => + unitConversion("gbToBytes", value) + } + onValueChange={(value) => { + form.setValue(field.name, value as number); + }} + suffix="GB" + /> + + + + )} + /> + ( + + {t("expiredAt", "Expired At")} + + { + form.setValue(field.name, value || 0); + }} + placeholder={t("permanent", "Permanent")} + value={ + field.value && field.value > 0 + ? field.value + : undefined + } + /> + + + + )} + /> + + +
))}
From 9f95cec876c9ac8bf00a6ca12a5c40243c7171af Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 07:02:31 +0000 Subject: [PATCH 11/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Added=20localized=20s?= =?UTF-8?q?upport=20for=20user=20subscription=20and=20deletion=20status,?= =?UTF-8?q?=20and=20optimized=20the=20subscription=20form=20and=20user=20i?= =?UTF-8?q?nterface.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/assets/locales/en-US/user.json | 3 + .../public/assets/locales/zh-CN/user.json | 3 + .../src/sections/product/subscribe-form.tsx | 2 +- apps/admin/src/sections/user/index.tsx | 19 +- .../sections/user/user-subscription/index.tsx | 257 ++++--- .../user-subscription/subscription-form.tsx | 2 +- .../src/sections/user/dashboard/content.tsx | 651 +++++++++--------- packages/ui/src/composed/date-picker.tsx | 27 +- 8 files changed, 520 insertions(+), 444 deletions(-) diff --git a/apps/admin/public/assets/locales/en-US/user.json b/apps/admin/public/assets/locales/en-US/user.json index d03c4e2..028fe70 100644 --- a/apps/admin/public/assets/locales/en-US/user.json +++ b/apps/admin/public/assets/locales/en-US/user.json @@ -25,9 +25,11 @@ "createSuccess": "Created successfully", "createUser": "Create User", "delete": "Delete", + "deleted": "Deleted", "deleteDescription": "This action cannot be undone.", "deleteSubscriptionDescription": "This action cannot be undone.", "deleteSuccess": "Deleted successfully", + "isDeleted": "Status", "deviceLimit": "Device Limit", "download": "Download", "downloadTraffic": "Download Traffic", @@ -51,6 +53,7 @@ "loginStatus": "Login Status", "manager": "Administrator", "more": "More", + "normal": "Normal", "notifySettingsTitle": "Notify Settings", "offline": "Offline", "online": "Online", diff --git a/apps/admin/public/assets/locales/zh-CN/user.json b/apps/admin/public/assets/locales/zh-CN/user.json index 5be625c..0de2b9c 100644 --- a/apps/admin/public/assets/locales/zh-CN/user.json +++ b/apps/admin/public/assets/locales/zh-CN/user.json @@ -25,9 +25,11 @@ "createSuccess": "创建成功", "createUser": "创建用户", "delete": "删除", + "deleted": "已删除", "deleteDescription": "此操作无法撤销。", "deleteSubscriptionDescription": "此操作无法撤销。", "deleteSuccess": "删除成功", + "isDeleted": "状态", "deviceLimit": "IP限制", "download": "下载", "downloadTraffic": "下载流量", @@ -51,6 +53,7 @@ "loginStatus": "登录状态", "manager": "管理员", "more": "更多", + "normal": "正常", "notifySettingsTitle": "通知设置", "offline": "离线", "online": "在线", diff --git a/apps/admin/src/sections/product/subscribe-form.tsx b/apps/admin/src/sections/product/subscribe-form.tsx index 198d124..495171b 100644 --- a/apps/admin/src/sections/product/subscribe-form.tsx +++ b/apps/admin/src/sections/product/subscribe-form.tsx @@ -277,7 +277,7 @@ export default function SubscribeForm>({ {trigger} - + {title} diff --git a/apps/admin/src/sections/user/index.tsx b/apps/admin/src/sections/user/index.tsx index b550f2f..a027b0b 100644 --- a/apps/admin/src/sections/user/index.tsx +++ b/apps/admin/src/sections/user/index.tsx @@ -172,6 +172,18 @@ export default function User() { accessorKey: "id", header: "ID", }, + { + accessorKey: "deleted_at", + header: t("isDeleted", "Deleted"), + cell: ({ row }) => { + const deletedAt = row.getValue("deleted_at") as number | undefined; + return deletedAt ? ( + {t("deleted", "Deleted")} + ) : ( + {t("normal", "Normal")} + ); + }, + }, { accessorKey: "auth_methods", header: t("userName", "Username"), @@ -355,16 +367,13 @@ function SubscriptionSheet({ userId }: { userId: number }) { - + {t("subscriptionList", "Subscription List")} · ID: {userId} -
+
diff --git a/apps/admin/src/sections/user/user-subscription/index.tsx b/apps/admin/src/sections/user/user-subscription/index.tsx index 7ad9554..5a2c755 100644 --- a/apps/admin/src/sections/user/user-subscription/index.tsx +++ b/apps/admin/src/sections/user/user-subscription/index.tsx @@ -33,7 +33,6 @@ export default function UserSubscription({ userId }: { userId: number }) { const { t } = useTranslation("user"); const [loading, setLoading] = useState(false); const ref = useRef(null); - const { getUserSubscribe: getUserSubscribeUrls } = useGlobalStore(); return ( > @@ -59,105 +58,13 @@ export default function UserSubscription({ userId }: { userId: number }) { title={t("editSubscription", "Edit Subscription")} trigger={t("edit", "Edit")} />, - , - { - await resetUserSubscribeToken({ user_subscribe_id: row.id }); - toast.success( - t( - "resetTokenSuccess", - "Subscription address reset successfully" - ) - ); - ref.current?.refresh(); - }} - title={t("confirmResetToken", "Confirm Reset Subscription Address")} - trigger={ - - } + ref.current?.refresh()} + row={row} + token={row.token} + userId={userId} />, - { - await toggleUserSubscribeStatus({ user_subscribe_id: row.id }); - toast.success( - row.status === 5 - ? t( - "resumeSubscribeSuccess", - "Subscription resumed successfully" - ) - : t( - "stopSubscribeSuccess", - "Subscription stopped successfully" - ) - ); - ref.current?.refresh(); - }} - title={ - row.status === 5 - ? t("confirmResumeSubscribe", "Confirm Resume Subscription") - : t("confirmStopSubscribe", "Confirm Stop Subscription") - } - trigger={ - - } - />, - { - await deleteUserSubscribe({ user_subscribe_id: row.id }); - toast.success(t("deleteSuccess", "Deleted successfully")); - ref.current?.refresh(); - }} - title={t("confirmDelete", "Confirm Delete")} - trigger={ - - } - />, - , ], }} columns={[ @@ -175,6 +82,11 @@ export default function UserSubscription({ userId }: { userId: number }) { header: t("status", "Status"), cell: ({ row }) => { const status = row.getValue("status") as number; + const expireTime = row.original.expire_time; + + // 如果过期时间为0,说明是永久订阅,应该显示为激活状态 + const displayStatus = status === 3 && expireTime === 0 ? 1 : status; + const statusMap: Record< number, { @@ -201,7 +113,7 @@ export default function UserSubscription({ userId }: { userId: number }) { variant: "destructive", }, }; - const statusInfo = statusMap[status] || { + const statusInfo = statusMap[displayStatus] || { label: "Unknown", variant: "outline", }; @@ -261,10 +173,12 @@ export default function UserSubscription({ userId }: { userId: number }) { { accessorKey: "expire_time", header: t("expireTime", "Expire Time"), - cell: ({ row }) => - row.getValue("expire_time") - ? formatDate(row.getValue("expire_time")) - : t("permanent", "Permanent"), + cell: ({ row }) => { + const expireTime = row.getValue("expire_time") as number; + return expireTime && expireTime !== 0 + ? formatDate(expireTime) + : t("permanent", "Permanent"); + }, }, { accessorKey: "created_at", @@ -308,9 +222,24 @@ export default function UserSubscription({ userId }: { userId: number }) { ); } -function RowMoreActions({ userId, subId }: { userId: number; subId: number }) { +function RowMoreActions({ + userId, + row, + token, + refresh, +}: { + userId: number; + row: API.UserSubscribe; + token: string; + refresh: () => void; +}) { const triggerRef = useRef(null); + const resetTokenRef = useRef(null); + const toggleStatusRef = useRef(null); + const deleteRef = useRef(null); const { t } = useTranslation("user"); + const { getUserSubscribe: getUserSubscribeUrls } = useGlobalStore(); + return (
@@ -318,9 +247,47 @@ function RowMoreActions({ userId, subId }: { userId: number; subId: number }) { + { + e.preventDefault(); + await navigator.clipboard.writeText( + getUserSubscribeUrls(token)[0] || "" + ); + toast.success(t("copySuccess", "Copied successfully")); + }} + > + {t("copySubscription", "Copy Subscription")} + + { + e.preventDefault(); + resetTokenRef.current?.click(); + }} + > + {t("resetToken", "Reset Subscription Address")} + + { + e.preventDefault(); + toggleStatusRef.current?.click(); + }} + > + {row.status === 5 + ? t("resumeSubscribe", "Resume Subscription") + : t("stopSubscribe", "Stop Subscription")} + + { + e.preventDefault(); + deleteRef.current?.click(); + }} + > + {t("delete", "Delete")} + {t("subscriptionLogs", "Subscription Logs")} @@ -328,7 +295,7 @@ function RowMoreActions({ userId, subId }: { userId: number; subId: number }) { {t("resetLogs", "Reset Logs")} @@ -336,7 +303,7 @@ function RowMoreActions({ userId, subId }: { userId: number; subId: number }) { {t("trafficStats", "Traffic Stats")} @@ -344,7 +311,7 @@ function RowMoreActions({ userId, subId }: { userId: number; subId: number }) { {t("trafficDetails", "Traffic Details")} @@ -361,8 +328,78 @@ function RowMoreActions({ userId, subId }: { userId: number; subId: number }) { + {/* Hidden triggers for confirm dialogs */} + { + await resetUserSubscribeToken({ + user_subscribe_id: row.subscribe_id, + }); + toast.success( + t("resetTokenSuccess", "Subscription address reset successfully") + ); + refresh(); + }} + title={t("confirmResetToken", "Confirm Reset Subscription Address")} + trigger={ - - - - - {t("prompt", "Prompt")} - - - {t( - "confirmResetSubscription", - "Are you sure you want to reset your subscription?" - )} - - - - - {t("cancel", "Cancel")} - - { - await resetUserSubscribeToken({ - user_subscribe_id: item.id, - }); - await refetch(); - toast.success(t("resetSuccess", "Reset Success")); + return ( + + ); + })} ) : ( <> diff --git a/packages/ui/src/composed/date-picker.tsx b/packages/ui/src/composed/date-picker.tsx index acbbfe6..690e8e7 100644 --- a/packages/ui/src/composed/date-picker.tsx +++ b/packages/ui/src/composed/date-picker.tsx @@ -34,6 +34,15 @@ export function DatePicker({ } }; + const handleClear = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + setDate(undefined); + if (onChange) { + onChange(0); + } + }; + return ( @@ -47,16 +56,14 @@ export function DatePicker({ {value ? intlFormat(value) : {placeholder}}
{value && ( - { - e.stopPropagation(); - setDate(undefined); - if (onChange) { - onChange(0); - } - }} - /> + )}
From 8d514dfd8f0a8fb9acc97a288addd1b1cbc882b8 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 07:04:49 +0000 Subject: [PATCH 12/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Update=20API=20proxy?= =?UTF-8?q?=20target=20to=20use=20environment=20variable=20for=20improved?= =?UTF-8?q?=20configurability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/vite.config.ts | 3 +-- apps/user/vite.config.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/admin/vite.config.ts b/apps/admin/vite.config.ts index b1a59cd..97a1593 100644 --- a/apps/admin/vite.config.ts +++ b/apps/admin/vite.config.ts @@ -44,10 +44,9 @@ export default defineConfig({ server: { proxy: { "/api": { - target: "https://api.ppanel.dev", + target: import.meta.env.VITE_API_BASE_URL || "https://api.ppanel.dev", changeOrigin: true, secure: false, - rewrite: (path) => path.replace(/^\/api/, ""), }, }, }, diff --git a/apps/user/vite.config.ts b/apps/user/vite.config.ts index a1f8f95..9d0c236 100644 --- a/apps/user/vite.config.ts +++ b/apps/user/vite.config.ts @@ -44,7 +44,7 @@ export default defineConfig({ server: { proxy: { "/api": { - target: "https://api.ppanel.dev", + target: import.meta.env.VITE_API_BASE_URL || "https://api.ppanel.dev", changeOrigin: true, secure: false, }, From d36a2c902b7943441282278009c5e5210d30c746 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 07:16:13 +0000 Subject: [PATCH 13/32] =?UTF-8?q?=E2=9C=A8=20feat:=20Update=20Vite=20confi?= =?UTF-8?q?guration=20to=20load=20environment=20variables=20for=20improved?= =?UTF-8?q?=20API=20proxy=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/vite.config.ts | 60 +++++++++++++++++++++------------------ apps/user/vite.config.ts | 60 +++++++++++++++++++++------------------ 2 files changed, 64 insertions(+), 56 deletions(-) diff --git a/apps/admin/vite.config.ts b/apps/admin/vite.config.ts index 97a1593..a03c3f5 100644 --- a/apps/admin/vite.config.ts +++ b/apps/admin/vite.config.ts @@ -4,7 +4,7 @@ import tailwindcss from "@tailwindcss/vite"; import { devtools } from "@tanstack/devtools-vite"; import { tanstackRouter } from "@tanstack/router-plugin/vite"; import viteReact from "@vitejs/plugin-react"; -import { defineConfig, type Plugin } from "vite"; +import { defineConfig, loadEnv, type Plugin } from "vite"; // Plugin to generate version.lock file after build function versionLockPlugin(): Plugin { @@ -24,33 +24,37 @@ function versionLockPlugin(): Plugin { } // https://vitejs.dev/config/ -export default defineConfig({ - base: "./", - plugins: [ - devtools({ eventBusConfig: { port: 42_070 } }), - tanstackRouter({ - target: "react", - autoCodeSplitting: true, - }), - viteReact(), - tailwindcss(), - versionLockPlugin(), - ], - resolve: { - alias: { - "@": fileURLToPath(new URL("./src", import.meta.url)), - }, - }, - server: { - proxy: { - "/api": { - target: import.meta.env.VITE_API_BASE_URL || "https://api.ppanel.dev", - changeOrigin: true, - secure: false, +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), ""); + + return { + base: "./", + plugins: [ + devtools({ eventBusConfig: { port: 42_070 } }), + tanstackRouter({ + target: "react", + autoCodeSplitting: true, + }), + viteReact(), + tailwindcss(), + versionLockPlugin(), + ], + resolve: { + alias: { + "@": fileURLToPath(new URL("./src", import.meta.url)), }, }, - }, - build: { - assetsDir: "static", - }, + server: { + proxy: { + "/api": { + target: env.VITE_API_BASE_URL || "https://api.ppanel.dev", + changeOrigin: true, + secure: false, + }, + }, + }, + build: { + assetsDir: "static", + }, + }; }); diff --git a/apps/user/vite.config.ts b/apps/user/vite.config.ts index 9d0c236..43771e8 100644 --- a/apps/user/vite.config.ts +++ b/apps/user/vite.config.ts @@ -4,7 +4,7 @@ import tailwindcss from "@tailwindcss/vite"; import { devtools } from "@tanstack/devtools-vite"; import { tanstackRouter } from "@tanstack/router-plugin/vite"; import viteReact from "@vitejs/plugin-react"; -import { defineConfig, type Plugin } from "vite"; +import { defineConfig, loadEnv, type Plugin } from "vite"; // Plugin to generate version.lock file after build function versionLockPlugin(): Plugin { @@ -24,33 +24,37 @@ function versionLockPlugin(): Plugin { } // https://vitejs.dev/config/ -export default defineConfig({ - base: "./", - plugins: [ - devtools({ eventBusConfig: { port: 42_069 } }), - tanstackRouter({ - target: "react", - autoCodeSplitting: true, - }), - viteReact(), - tailwindcss(), - versionLockPlugin(), - ], - resolve: { - alias: { - "@": fileURLToPath(new URL("./src", import.meta.url)), - }, - }, - server: { - proxy: { - "/api": { - target: import.meta.env.VITE_API_BASE_URL || "https://api.ppanel.dev", - changeOrigin: true, - secure: false, +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), ""); + + return { + base: "./", + plugins: [ + devtools({ eventBusConfig: { port: 42_069 } }), + tanstackRouter({ + target: "react", + autoCodeSplitting: true, + }), + viteReact(), + tailwindcss(), + versionLockPlugin(), + ], + resolve: { + alias: { + "@": fileURLToPath(new URL("./src", import.meta.url)), }, }, - }, - build: { - assetsDir: "static", - }, + server: { + proxy: { + "/api": { + target: env.VITE_API_BASE_URL || "https://api.ppanel.dev", + changeOrigin: true, + secure: false, + }, + }, + }, + build: { + assetsDir: "static", + }, + }; }); From 2316609c82d563b380ee05aa781958ccb6ec43bd Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 29 Dec 2025 07:20:09 +0000 Subject: [PATCH 14/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.3.0=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.3.0=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.3.0](https://github.com/perfect-panel/frontend/compare/v1.2.4...v1.3.0) (2025-12-29) ### ✨ Features / 新功能 * Add original price display option and enhance inventory messages in subscription components ([543a7b9](https://github.com/perfect-panel/frontend/commit/543a7b9eb9b2cd278a70f668b0a0e0e9e261fe57)) * Added localized support for user subscription and deletion status, and optimized the subscription form and user interface. ([9f95cec](https://github.com/perfect-panel/frontend/commit/9f95cec876c9ac8bf00a6ca12a5c40243c7171af)) * Added reset and pause subscription functionality, and updated the status display. ([bc451ee](https://github.com/perfect-panel/frontend/commit/bc451eea16b51f1ab81b6cacf65201886866e1cc)) * Added the option to restore subscription, and updated the relevant description and confirmation information. ([5f5c339](https://github.com/perfect-panel/frontend/commit/5f5c33987e54533c5348223b3cebe31aef91aa25)) * Enhance DatePicker component with clear button and improved value handling ([b27b928](https://github.com/perfect-panel/frontend/commit/b27b9287be0eb26fe5d5189b618a32db340c506c)) * Refactor SubscriptionForm layout for improved readability and maintainability ([f432ba0](https://github.com/perfect-panel/frontend/commit/f432ba06f9d3a86ec00bfd316d1c020ddf779de6)) * Update API proxy target to use environment variable for improved configurability ([8d514df](https://github.com/perfect-panel/frontend/commit/8d514dfd8f0a8fb9acc97a288addd1b1cbc882b8)) * Update queryKey structure in Purchase and Renewal components for improved order creation ([9559e00](https://github.com/perfect-panel/frontend/commit/9559e003b7821303f7d0ac7f4da5fae4bf1ccad4)) * Update Vite configuration to load environment variables for improved API proxy setup ([d36a2c9](https://github.com/perfect-panel/frontend/commit/d36a2c902b7943441282278009c5e5210d30c746)) ### 🐛 Bug Fixes / 问题修复 * Replace tag removal icon with a button for better accessibility and event handling ([3751f64](https://github.com/perfect-panel/frontend/commit/3751f64f73cd70eaddd44cb650dd38949f0ca069)) * Uncomment navigation to dashboard for authenticated users ([4d15b2b](https://github.com/perfect-panel/frontend/commit/4d15b2b6fc8f0d178c7c749aa9e1d9826bb706f8)) ### 📚 Documentation / 文档更新 * Update default administrator account information and security recommendations in installation guides ([7279275](https://github.com/perfect-panel/frontend/commit/7279275532ad0b73994ffe5cf2e4c2f8dabc280b)) --- CHANGELOG.md | 23 +++++++++++++++++++++++ package.json | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79534d8..850881e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,29 @@ This document records all notable changes to ShadCN Admin. --- +## [1.3.0](https://github.com/perfect-panel/frontend/compare/v1.2.4...v1.3.0) (2025-12-29) + +### ✨ Features / 新功能 + +* Add original price display option and enhance inventory messages in subscription components ([543a7b9](https://github.com/perfect-panel/frontend/commit/543a7b9eb9b2cd278a70f668b0a0e0e9e261fe57)) +* Added localized support for user subscription and deletion status, and optimized the subscription form and user interface. ([9f95cec](https://github.com/perfect-panel/frontend/commit/9f95cec876c9ac8bf00a6ca12a5c40243c7171af)) +* Added reset and pause subscription functionality, and updated the status display. ([bc451ee](https://github.com/perfect-panel/frontend/commit/bc451eea16b51f1ab81b6cacf65201886866e1cc)) +* Added the option to restore subscription, and updated the relevant description and confirmation information. ([5f5c339](https://github.com/perfect-panel/frontend/commit/5f5c33987e54533c5348223b3cebe31aef91aa25)) +* Enhance DatePicker component with clear button and improved value handling ([b27b928](https://github.com/perfect-panel/frontend/commit/b27b9287be0eb26fe5d5189b618a32db340c506c)) +* Refactor SubscriptionForm layout for improved readability and maintainability ([f432ba0](https://github.com/perfect-panel/frontend/commit/f432ba06f9d3a86ec00bfd316d1c020ddf779de6)) +* Update API proxy target to use environment variable for improved configurability ([8d514df](https://github.com/perfect-panel/frontend/commit/8d514dfd8f0a8fb9acc97a288addd1b1cbc882b8)) +* Update queryKey structure in Purchase and Renewal components for improved order creation ([9559e00](https://github.com/perfect-panel/frontend/commit/9559e003b7821303f7d0ac7f4da5fae4bf1ccad4)) +* Update Vite configuration to load environment variables for improved API proxy setup ([d36a2c9](https://github.com/perfect-panel/frontend/commit/d36a2c902b7943441282278009c5e5210d30c746)) + +### 🐛 Bug Fixes / 问题修复 + +* Replace tag removal icon with a button for better accessibility and event handling ([3751f64](https://github.com/perfect-panel/frontend/commit/3751f64f73cd70eaddd44cb650dd38949f0ca069)) +* Uncomment navigation to dashboard for authenticated users ([4d15b2b](https://github.com/perfect-panel/frontend/commit/4d15b2b6fc8f0d178c7c749aa9e1d9826bb706f8)) + +### 📚 Documentation / 文档更新 + +* Update default administrator account information and security recommendations in installation guides ([7279275](https://github.com/perfect-panel/frontend/commit/7279275532ad0b73994ffe5cf2e4c2f8dabc280b)) + ## [1.2.4](https://github.com/perfect-panel/frontend/compare/v1.2.3...v1.2.4) (2025-12-28) ### 🐛 Bug Fixes / 问题修复 diff --git a/package.json b/package.json index 024d21c..9b8ccc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.2.4", + "version": "1.3.0", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": { From 83d821a2dc24d97838af43ab610b65ff0d0d0d15 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 08:08:31 +0000 Subject: [PATCH 15/32] =?UTF-8?q?=F0=9F=90=9B=20fix::=20Update=20localizat?= =?UTF-8?q?ion=20files=20and=20improve=20display=20logic=20for=20inventory?= =?UTF-8?q?=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/public/assets/locales/en-US/components.json | 2 +- apps/admin/public/assets/locales/en-US/product.json | 1 - apps/admin/public/assets/locales/zh-CN/product.json | 1 - apps/admin/src/components/display.tsx | 4 ++-- apps/admin/src/sections/product/subscribe-form.tsx | 3 --- apps/user/src/sections/subscribe/duration-selector.tsx | 2 +- 6 files changed, 4 insertions(+), 9 deletions(-) diff --git a/apps/admin/public/assets/locales/en-US/components.json b/apps/admin/public/assets/locales/en-US/components.json index a55a707..6c26754 100644 --- a/apps/admin/public/assets/locales/en-US/components.json +++ b/apps/admin/public/assets/locales/en-US/components.json @@ -63,5 +63,5 @@ "system": "System", "toggle": "Toggle theme" }, - "unlimited": "unlimited" + "unlimited": "Unlimited" } diff --git a/apps/admin/public/assets/locales/en-US/product.json b/apps/admin/public/assets/locales/en-US/product.json index 4f1f0ff..f590049 100644 --- a/apps/admin/public/assets/locales/en-US/product.json +++ b/apps/admin/public/assets/locales/en-US/product.json @@ -30,7 +30,6 @@ "discountPercent": "Discount Percentage", "Hour": "Hour", "inventory": "Subscription Limit", - "inventoryDescription": "Set to -1 for unlimited inventory", "unlimitedInventory": "Unlimited (enter -1)", "language": "Language", "languageDescription": "Leave empty for default without language restriction", diff --git a/apps/admin/public/assets/locales/zh-CN/product.json b/apps/admin/public/assets/locales/zh-CN/product.json index 4bf0a04..d8a6e28 100644 --- a/apps/admin/public/assets/locales/zh-CN/product.json +++ b/apps/admin/public/assets/locales/zh-CN/product.json @@ -30,7 +30,6 @@ "discountPercent": "折扣百分比", "Hour": "小时", "inventory": "订阅库存", - "inventoryDescription": "设置为 -1 表示不限制库存", "unlimitedInventory": "无限制(输入 -1)", "language": "语言", "languageDescription": "留空为默认无语言限制", diff --git a/apps/admin/src/components/display.tsx b/apps/admin/src/components/display.tsx index d7ec6bf..28181c9 100644 --- a/apps/admin/src/components/display.tsx +++ b/apps/admin/src/components/display.tsx @@ -28,7 +28,7 @@ export function Display({ if ( ["traffic", "trafficSpeed", "number"].includes(type) && unlimited && - !value + (value === 0 || value === null || value === undefined) ) { return t("unlimited"); } @@ -42,7 +42,7 @@ export function Display({ } if (type === "number") { - return value ? value.toString() : "0"; + return value !== null && value !== undefined ? value.toString() : "0"; } return "0"; diff --git a/apps/admin/src/sections/product/subscribe-form.tsx b/apps/admin/src/sections/product/subscribe-form.tsx index 495171b..884d45c 100644 --- a/apps/admin/src/sections/product/subscribe-form.tsx +++ b/apps/admin/src/sections/product/subscribe-form.tsx @@ -454,9 +454,6 @@ export default function SubscribeForm>({ value={field.value} /> - - {t("form.inventoryDescription")} - )} diff --git a/apps/user/src/sections/subscribe/duration-selector.tsx b/apps/user/src/sections/subscribe/duration-selector.tsx index a90ba58..6ecdb39 100644 --- a/apps/user/src/sections/subscribe/duration-selector.tsx +++ b/apps/user/src/sections/subscribe/duration-selector.tsx @@ -78,7 +78,7 @@ const DurationSelector: React.FC = ({ {discountPercentage > 0 ? ( - -{discountPercentage}% {t("discount", "Discount")} + -{discountPercentage.toFixed(2)}% {t("discount", "Discount")} ) : ( -- From cc52e3614d9b6723f4ce8ab6385d626f0fcc54d7 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 08:17:45 +0000 Subject: [PATCH 16/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20SubscribeT?= =?UTF-8?q?able=20to=20display=20inventory=20using=20Display=20component?= =?UTF-8?q?=20for=20better=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/src/sections/product/subscribe-table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/admin/src/sections/product/subscribe-table.tsx b/apps/admin/src/sections/product/subscribe-table.tsx index 8287987..de846e8 100644 --- a/apps/admin/src/sections/product/subscribe-table.tsx +++ b/apps/admin/src/sections/product/subscribe-table.tsx @@ -211,7 +211,7 @@ export default function SubscribeTable() { cell: ({ row }) => { const inventory = row.getValue("inventory") as number; return inventory === -1 ? ( - t("unlimited") + ) : ( ); From a2746073a636706b0e214eca84055735417680f3 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 08:34:15 +0000 Subject: [PATCH 17/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20quantity?= =?UTF-8?q?=20handling=20in=20Purchase=20and=20Renewal=20components=20base?= =?UTF-8?q?d=20on=20showOriginalPrice=20prop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/user/src/sections/subscribe/duration-selector.tsx | 4 +++- apps/user/src/sections/subscribe/purchase.tsx | 7 ++++++- apps/user/src/sections/subscribe/renewal.tsx | 7 ++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/user/src/sections/subscribe/duration-selector.tsx b/apps/user/src/sections/subscribe/duration-selector.tsx index 6ecdb39..17da97a 100644 --- a/apps/user/src/sections/subscribe/duration-selector.tsx +++ b/apps/user/src/sections/subscribe/duration-selector.tsx @@ -15,6 +15,7 @@ interface DurationSelectorProps { unitTime?: string; discounts?: Array<{ quantity: number; discount: number }>; onChange: (value: number) => void; + showOriginalPrice?: boolean; } const DurationSelector: React.FC = ({ @@ -22,6 +23,7 @@ const DurationSelector: React.FC = ({ unitTime = "Month", discounts = [], onChange, + showOriginalPrice = true, }) => { const { t } = useTranslation("subscribe"); const handleChange = useCallback( @@ -61,7 +63,7 @@ const DurationSelector: React.FC = ({ onValueChange={handleChange} value={String(quantity)} > - {unitTime !== "Minute" && ( + {showOriginalPrice && unitTime !== "Minute" && ( )} {discounts?.map((item) => ( diff --git a/apps/user/src/sections/subscribe/purchase.tsx b/apps/user/src/sections/subscribe/purchase.tsx index f629c98..af89b68 100644 --- a/apps/user/src/sections/subscribe/purchase.tsx +++ b/apps/user/src/sections/subscribe/purchase.tsx @@ -74,9 +74,13 @@ export default function Purchase({ useEffect(() => { if (subscribe) { + const defaultQuantity = + subscribe.show_original_price === false && subscribe.discount?.[0] + ? subscribe.discount[0].quantity + : 1; setParams((prev) => ({ ...prev, - quantity: 1, + quantity: defaultQuantity, subscribe_id: subscribe?.id, })); } @@ -146,6 +150,7 @@ export default function Purchase({ handleChange("quantity", value); }} quantity={params.quantity as number} + showOriginalPrice={subscribe?.show_original_price} unitTime={subscribe?.unit_time} /> ) { useEffect(() => { if (subscribe.id && id) { + const defaultQuantity = + subscribe.show_original_price === false && subscribe.discount?.[0] + ? subscribe.discount[0].quantity + : 1; setParams((prev) => ({ ...prev, - quantity: 1, + quantity: defaultQuantity, subscribe_id: subscribe.id, user_subscribe_id: id, })); @@ -145,6 +149,7 @@ export default function Renewal({ id, subscribe }: Readonly) { handleChange("quantity", value); }} quantity={params.quantity!} + showOriginalPrice={subscribe?.show_original_price} unitTime={subscribe?.unit_time} /> Date: Mon, 29 Dec 2025 08:35:40 +0000 Subject: [PATCH 18/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.3.1=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.3.1=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.3.1](https://github.com/perfect-panel/frontend/compare/v1.3.0...v1.3.1) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 * : Update localization files and improve display logic for inventory handling ([83d821a](https://github.com/perfect-panel/frontend/commit/83d821a2dc24d97838af43ab610b65ff0d0d0d15)) * Update quantity handling in Purchase and Renewal components based on showOriginalPrice prop ([a274607](https://github.com/perfect-panel/frontend/commit/a2746073a636706b0e214eca84055735417680f3)) * Update SubscribeTable to display inventory using Display component for better clarity ([cc52e36](https://github.com/perfect-panel/frontend/commit/cc52e3614d9b6723f4ce8ab6385d626f0fcc54d7)) --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 850881e..2b231cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,14 @@ This document records all notable changes to ShadCN Admin. --- +## [1.3.1](https://github.com/perfect-panel/frontend/compare/v1.3.0...v1.3.1) (2025-12-29) + +### 🐛 Bug Fixes / 问题修复 + +* : Update localization files and improve display logic for inventory handling ([83d821a](https://github.com/perfect-panel/frontend/commit/83d821a2dc24d97838af43ab610b65ff0d0d0d15)) +* Update quantity handling in Purchase and Renewal components based on showOriginalPrice prop ([a274607](https://github.com/perfect-panel/frontend/commit/a2746073a636706b0e214eca84055735417680f3)) +* Update SubscribeTable to display inventory using Display component for better clarity ([cc52e36](https://github.com/perfect-panel/frontend/commit/cc52e3614d9b6723f4ce8ab6385d626f0fcc54d7)) + ## [1.3.0](https://github.com/perfect-panel/frontend/compare/v1.2.4...v1.3.0) (2025-12-29) ### ✨ Features / 新功能 diff --git a/package.json b/package.json index 9b8ccc4..986c7b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.3.0", + "version": "1.3.1", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": { From 0690debf6c1bab7472468c742f9b15639f904c20 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 09:02:02 +0000 Subject: [PATCH 19/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Refactor=20update?= =?UTF-8?q?=20dialog=20logic=20in=20SystemVersionCard=20for=20better=20cla?= =?UTF-8?q?rity=20and=20handling=20of=20update=20states?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/system-version-card.tsx | 198 +++++++++--------- 1 file changed, 100 insertions(+), 98 deletions(-) diff --git a/apps/admin/src/sections/dashboard/components/system-version-card.tsx b/apps/admin/src/sections/dashboard/components/system-version-card.tsx index 4a8cfe2..0b1e527 100644 --- a/apps/admin/src/sections/dashboard/components/system-version-card.tsx +++ b/apps/admin/src/sections/dashboard/components/system-version-card.tsx @@ -80,6 +80,7 @@ export default function SystemVersionCard() { staleTime: 0, retry: 1, }); + console.log(webVersionInfo); const updateServerMutation = useMutation({ mutationFn: async (serviceName: string) => { @@ -188,52 +189,52 @@ export default function SystemVersionCard() {
V{packageJson.version} - {hasWebNewVersion && webVersionInfo && ( - - - + + + + + {t("confirmUpdate", "Confirm Update")} + + + {webVersionInfo + ? t( + "updateWebDescription", + "Are you sure you want to update the web version from V{{current}} to V{{latest}}?", + { + current: packageJson.version, + latest: webVersionInfo.latest_version, + } + ) + : t( + "updateDescription", + "Are you sure you want to update?" + )} + + + + {t("cancel", "Cancel")} + - - - - - {t("confirmUpdate", "Confirm Update")} - - - {t( - "updateWebDescription", - "Are you sure you want to update the web version from V{{current}} to V{{latest}}?", - { - current: packageJson.version, - latest: webVersionInfo.latest_version, - } - )} - - - - - {t("cancel", "Cancel")} - - - - - - )} + + +
@@ -251,62 +252,63 @@ export default function SystemVersionCard() { serverVersionInfo?.current_version || "1.0.0"} - {hasServerNewVersion && serverVersionInfo && moduleConfig && ( - - + + + + + + + + {t("confirmUpdate", "Confirm Update")} + + + {serverVersionInfo && moduleConfig + ? t( + "updateServerDescription", + "Are you sure you want to update the server version from V{{current}} to V{{latest}}?", + { + current: + moduleConfig.service_version || + serverVersionInfo.current_version, + latest: serverVersionInfo.latest_version, + } + ) + : t( + "updateDescription", + "Are you sure you want to update?" + )} + + + + {t("cancel", "Cancel")} - - - - - {t("confirmUpdate", "Confirm Update")} - - - {t( - "updateServerDescription", - "Are you sure you want to update the server version from V{{current}} to V{{latest}}?", - { - current: - moduleConfig.service_version || - serverVersionInfo.current_version, - latest: serverVersionInfo.latest_version, - } - )} - - - - - {t("cancel", "Cancel")} - - - - - - )} + + +
From 2f50c6df3345e26bc92f5730bc8b891d0515a367 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 09:03:09 +0000 Subject: [PATCH 20/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20default=20?= =?UTF-8?q?inventory=20value=20in=20SubscribeForm=20to=20-1=20for=20better?= =?UTF-8?q?=20handling=20of=20inventory=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/src/sections/product/subscribe-form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/admin/src/sections/product/subscribe-form.tsx b/apps/admin/src/sections/product/subscribe-form.tsx index 884d45c..4c06eb4 100644 --- a/apps/admin/src/sections/product/subscribe-form.tsx +++ b/apps/admin/src/sections/product/subscribe-form.tsx @@ -63,7 +63,7 @@ interface SubscribeFormProps { } const defaultValues = { - inventory: 0, + inventory: -1, speed_limit: 0, device_limit: 0, traffic: 0, From 2c14f69cef38ef0a412ac15834effe45764dbae3 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 29 Dec 2025 09:05:18 +0000 Subject: [PATCH 21/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.3.2=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.3.2=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.3.2](https://github.com/perfect-panel/frontend/compare/v1.3.1...v1.3.2) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 * Refactor update dialog logic in SystemVersionCard for better clarity and handling of update states ([0690deb](https://github.com/perfect-panel/frontend/commit/0690debf6c1bab7472468c742f9b15639f904c20)) * Update default inventory value in SubscribeForm to -1 for better handling of inventory state ([2f50c6d](https://github.com/perfect-panel/frontend/commit/2f50c6df3345e26bc92f5730bc8b891d0515a367)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b231cc..54ce96d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,13 @@ This document records all notable changes to ShadCN Admin. --- +## [1.3.2](https://github.com/perfect-panel/frontend/compare/v1.3.1...v1.3.2) (2025-12-29) + +### 🐛 Bug Fixes / 问题修复 + +* Refactor update dialog logic in SystemVersionCard for better clarity and handling of update states ([0690deb](https://github.com/perfect-panel/frontend/commit/0690debf6c1bab7472468c742f9b15639f904c20)) +* Update default inventory value in SubscribeForm to -1 for better handling of inventory state ([2f50c6d](https://github.com/perfect-panel/frontend/commit/2f50c6df3345e26bc92f5730bc8b891d0515a367)) + ## [1.3.1](https://github.com/perfect-panel/frontend/compare/v1.3.0...v1.3.1) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 diff --git a/package.json b/package.json index 986c7b5..9ea3381 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.3.1", + "version": "1.3.2", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": { From 2156a7f1df52970b5ab0816dd1da5dc7cefc1dae Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 09:08:44 +0000 Subject: [PATCH 22/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20user=5Fsub?= =?UTF-8?q?scribe=5Fid=20reference=20in=20RowMoreActions=20to=20use=20row.?= =?UTF-8?q?id=20for=20correct=20token=20reset=20and=20status=20toggle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/src/sections/user/user-subscription/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/admin/src/sections/user/user-subscription/index.tsx b/apps/admin/src/sections/user/user-subscription/index.tsx index 5a2c755..a8caf1f 100644 --- a/apps/admin/src/sections/user/user-subscription/index.tsx +++ b/apps/admin/src/sections/user/user-subscription/index.tsx @@ -338,7 +338,7 @@ function RowMoreActions({ )} onConfirm={async () => { await resetUserSubscribeToken({ - user_subscribe_id: row.subscribe_id, + user_subscribe_id: row.id, }); toast.success( t("resetTokenSuccess", "Subscription address reset successfully") @@ -365,7 +365,7 @@ function RowMoreActions({ } onConfirm={async () => { await toggleUserSubscribeStatus({ - user_subscribe_id: row.subscribe_id, + user_subscribe_id: row.id, }); toast.success( row.status === 5 From 6f3c70863f87c1a52fa1b9607fd5eeebe4a52446 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 29 Dec 2025 09:10:25 +0000 Subject: [PATCH 23/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.3.3=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.3.3=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.3.3](https://github.com/perfect-panel/frontend/compare/v1.3.2...v1.3.3) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 * Update user_subscribe_id reference in RowMoreActions to use row.id for correct token reset and status toggle ([2156a7f](https://github.com/perfect-panel/frontend/commit/2156a7f1df52970b5ab0816dd1da5dc7cefc1dae)) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54ce96d..dd3e1bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,12 @@ This document records all notable changes to ShadCN Admin. --- +## [1.3.3](https://github.com/perfect-panel/frontend/compare/v1.3.2...v1.3.3) (2025-12-29) + +### 🐛 Bug Fixes / 问题修复 + +* Update user_subscribe_id reference in RowMoreActions to use row.id for correct token reset and status toggle ([2156a7f](https://github.com/perfect-panel/frontend/commit/2156a7f1df52970b5ab0816dd1da5dc7cefc1dae)) + ## [1.3.2](https://github.com/perfect-panel/frontend/compare/v1.3.1...v1.3.2) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 diff --git a/package.json b/package.json index 9ea3381..75f6751 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.3.2", + "version": "1.3.3", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": { From 51a98afcae2c8b83c7176898ad8ac2c8b11ad3d9 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 09:44:18 +0000 Subject: [PATCH 24/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20SendCode?= =?UTF-8?q?=20parameters=20to=20use=20form.watch=20for=20email=20and=20tel?= =?UTF-8?q?ephone=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/src/sections/auth/email/register-form.tsx | 2 +- apps/admin/src/sections/auth/email/reset-form.tsx | 2 +- apps/user/src/sections/auth/email/register-form.tsx | 2 +- apps/user/src/sections/auth/email/reset-form.tsx | 2 +- apps/user/src/sections/auth/phone/login-form.tsx | 5 ++++- apps/user/src/sections/auth/phone/register-form.tsx | 5 ++++- apps/user/src/sections/auth/phone/reset-form.tsx | 3 ++- apps/user/src/sections/user/profile/third-party-accounts.tsx | 4 ++-- 8 files changed, 16 insertions(+), 9 deletions(-) diff --git a/apps/admin/src/sections/auth/email/register-form.tsx b/apps/admin/src/sections/auth/email/register-form.tsx index 522bf58..7e15174 100644 --- a/apps/admin/src/sections/auth/email/register-form.tsx +++ b/apps/admin/src/sections/auth/email/register-form.tsx @@ -179,7 +179,7 @@ export default function RegisterForm({ /> Date: Mon, 29 Dec 2025 09:47:09 +0000 Subject: [PATCH 25/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20HTMLEditor?= =?UTF-8?q?=20onChange=20event=20and=20set=20DropdownMenu=20modal=20to=20f?= =?UTF-8?q?alse=20for=20better=20user=20experience?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/auth-control/forms/email-settings-form.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/admin/src/sections/auth-control/forms/email-settings-form.tsx b/apps/admin/src/sections/auth-control/forms/email-settings-form.tsx index 060dda4..09a6cce 100644 --- a/apps/admin/src/sections/auth-control/forms/email-settings-form.tsx +++ b/apps/admin/src/sections/auth-control/forms/email-settings-form.tsx @@ -538,7 +538,7 @@ export default function EmailSettingsForm() { Date: Mon, 29 Dec 2025 09:49:48 +0000 Subject: [PATCH 26/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Only=20update=20int?= =?UTF-8?q?ernalValue=20in=20MonacoEditor=20if=20propValue=20has=20changed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui/src/composed/editor/monaco-editor.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/composed/editor/monaco-editor.tsx b/packages/ui/src/composed/editor/monaco-editor.tsx index 9949cf2..b6ad761 100644 --- a/packages/ui/src/composed/editor/monaco-editor.tsx +++ b/packages/ui/src/composed/editor/monaco-editor.tsx @@ -60,7 +60,10 @@ export function MonacoEditor({ const size = useSize(ref); useEffect(() => { - setInternalValue(propValue); + // Only update internalValue if propValue has actually changed and is different from current value + if (propValue !== internalValue) { + setInternalValue(propValue); + } }, [propValue]); const debouncedOnChange = useRef( From 0253b62b6365476591121b6f18dcb3f3261cb4ff Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Mon, 29 Dec 2025 09:54:34 +0000 Subject: [PATCH 27/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Set=20modal=20prop?= =?UTF-8?q?=20to=20false=20for=20DropdownMenu=20in=20multiple=20components?= =?UTF-8?q?=20for=20improved=20user=20experience?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/src/sections/servers/server-form.tsx | 2 +- apps/admin/src/sections/user/index.tsx | 2 +- apps/admin/src/sections/user/user-subscription/index.tsx | 2 +- apps/user/src/layout/user-nav.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/admin/src/sections/servers/server-form.tsx b/apps/admin/src/sections/servers/server-form.tsx index 26f5678..46f11f5 100644 --- a/apps/admin/src/sections/servers/server-form.tsx +++ b/apps/admin/src/sections/servers/server-form.tsx @@ -98,7 +98,7 @@ function DynamicField({ field.generate ? ( field.generate.functions && field.generate.functions.length > 0 ? ( - + } />, - + diff --git a/apps/admin/src/sections/user/user-subscription/index.tsx b/apps/admin/src/sections/user/user-subscription/index.tsx index a8caf1f..309c97d 100644 --- a/apps/admin/src/sections/user/user-subscription/index.tsx +++ b/apps/admin/src/sections/user/user-subscription/index.tsx @@ -242,7 +242,7 @@ function RowMoreActions({ return (
- + diff --git a/apps/user/src/layout/user-nav.tsx b/apps/user/src/layout/user-nav.tsx index 8f29812..ea6c6cf 100644 --- a/apps/user/src/layout/user-nav.tsx +++ b/apps/user/src/layout/user-nav.tsx @@ -33,7 +33,7 @@ export function UserNav() { if (user) { return ( - +
From 1c93df8172dc9d95f7a315ca8b090da77163875e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 29 Dec 2025 09:56:03 +0000 Subject: [PATCH 28/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.3.4=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.3.4=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.3.4](https://github.com/perfect-panel/frontend/compare/v1.3.3...v1.3.4) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 * Only update internalValue in MonacoEditor if propValue has changed ([fe14002](https://github.com/perfect-panel/frontend/commit/fe1400235967f2ad0c1ffbc05d9e15bab370c664)) * Set modal prop to false for DropdownMenu in multiple components for improved user experience ([0253b62](https://github.com/perfect-panel/frontend/commit/0253b62b6365476591121b6f18dcb3f3261cb4ff)) * Update HTMLEditor onChange event and set DropdownMenu modal to false for better user experience ([ba65588](https://github.com/perfect-panel/frontend/commit/ba65588fdfcfba146cd76bfe7d14e053291f5926)) * Update SendCode parameters to use form.watch for email and telephone fields ([51a98af](https://github.com/perfect-panel/frontend/commit/51a98afcae2c8b83c7176898ad8ac2c8b11ad3d9)) --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3e1bf..682c1d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,15 @@ This document records all notable changes to ShadCN Admin. --- +## [1.3.4](https://github.com/perfect-panel/frontend/compare/v1.3.3...v1.3.4) (2025-12-29) + +### 🐛 Bug Fixes / 问题修复 + +* Only update internalValue in MonacoEditor if propValue has changed ([fe14002](https://github.com/perfect-panel/frontend/commit/fe1400235967f2ad0c1ffbc05d9e15bab370c664)) +* Set modal prop to false for DropdownMenu in multiple components for improved user experience ([0253b62](https://github.com/perfect-panel/frontend/commit/0253b62b6365476591121b6f18dcb3f3261cb4ff)) +* Update HTMLEditor onChange event and set DropdownMenu modal to false for better user experience ([ba65588](https://github.com/perfect-panel/frontend/commit/ba65588fdfcfba146cd76bfe7d14e053291f5926)) +* Update SendCode parameters to use form.watch for email and telephone fields ([51a98af](https://github.com/perfect-panel/frontend/commit/51a98afcae2c8b83c7176898ad8ac2c8b11ad3d9)) + ## [1.3.3](https://github.com/perfect-panel/frontend/compare/v1.3.2...v1.3.3) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 diff --git a/package.json b/package.json index 75f6751..1405e50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.3.3", + "version": "1.3.4", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": { From 39ebd09f0989b37308c1c803d8e380f967ab0db5 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Tue, 30 Dec 2025 06:10:44 +0000 Subject: [PATCH 29/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20getUserSub?= =?UTF-8?q?scribe=20function=20to=20accept=20short=20and=20token=20paramet?= =?UTF-8?q?ers=20for=20improved=20URL=20generation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/sections/user/user-subscription/index.tsx | 2 +- apps/admin/src/stores/global.tsx | 13 +++++++------ apps/user/src/sections/user/dashboard/content.tsx | 2 +- apps/user/src/stores/global.tsx | 13 +++++++------ 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/apps/admin/src/sections/user/user-subscription/index.tsx b/apps/admin/src/sections/user/user-subscription/index.tsx index 309c97d..a132924 100644 --- a/apps/admin/src/sections/user/user-subscription/index.tsx +++ b/apps/admin/src/sections/user/user-subscription/index.tsx @@ -251,7 +251,7 @@ function RowMoreActions({ onSelect={async (e) => { e.preventDefault(); await navigator.clipboard.writeText( - getUserSubscribeUrls(token)[0] || "" + getUserSubscribeUrls(row.short, token)[0] || "" ); toast.success(t("copySuccess", "Copied successfully")); }} diff --git a/apps/admin/src/stores/global.tsx b/apps/admin/src/stores/global.tsx index b3133fa..9660293 100644 --- a/apps/admin/src/stores/global.tsx +++ b/apps/admin/src/stores/global.tsx @@ -8,7 +8,7 @@ export interface GlobalStore { setCommon: (common: Partial) => void; setUser: (user?: API.User) => void; getUserInfo: () => Promise; - getUserSubscribe: (uuid: string, type?: string) => string[]; + getUserSubscribe: (short: string, token: string, type?: string) => string[]; getAppSubLink: (url: string, schema?: string) => string; } @@ -120,7 +120,7 @@ export const useGlobalStore = create((set, get) => ({ console.error("Failed to refresh user:", error); } }, - getUserSubscribe: (uuid: string, type?: string) => { + getUserSubscribe: (short: string, token: string, type?: string) => { const { pan_domain, subscribe_domain, subscribe_path } = get().common.subscribe || {}; const domains = subscribe_domain @@ -129,12 +129,13 @@ export const useGlobalStore = create((set, get) => ({ return domains.map((domain) => { if (pan_domain) { - if (type) return `https://${uuid}.${type}.${domain}`; - return `https://${uuid}.${domain}`; + if (type) + return `https://${short}.${type}.${domain}${subscribe_path}?token=${token}&type=${type}`; + return `https://${short}.${domain}${subscribe_path}?token=${token}`; } if (type) - return `https://${domain}${subscribe_path}?token=${uuid}&type=${type}`; - return `https://${domain}${subscribe_path}?token=${uuid}`; + return `https://${domain}${subscribe_path}?token=${token}&type=${type}`; + return `https://${domain}${subscribe_path}?token=${token}`; }); }, getAppSubLink: (url: string, schema?: string) => { diff --git a/apps/user/src/sections/user/dashboard/content.tsx b/apps/user/src/sections/user/dashboard/content.tsx index 6a297d5..ff9fa30 100644 --- a/apps/user/src/sections/user/dashboard/content.tsx +++ b/apps/user/src/sections/user/dashboard/content.tsx @@ -394,7 +394,7 @@ export default function Content() { defaultValue="0" type="single" > - {getUserSubscribe(item.token, protocol)?.map( + {getUserSubscribe(item.short, item.token, protocol)?.map( (url, index) => ( diff --git a/apps/user/src/stores/global.tsx b/apps/user/src/stores/global.tsx index 3e7eb52..07ce695 100644 --- a/apps/user/src/stores/global.tsx +++ b/apps/user/src/stores/global.tsx @@ -8,7 +8,7 @@ export interface GlobalStore { setCommon: (common: Partial) => void; setUser: (user?: API.User) => void; getUserInfo: () => Promise; - getUserSubscribe: (uuid: string, type?: string) => string[]; + getUserSubscribe: (short: string, token: string, type?: string) => string[]; getAppSubLink: (url: string, schema?: string) => string; } @@ -120,7 +120,7 @@ export const useGlobalStore = create((set, get) => ({ console.error("Failed to refresh user:", error); } }, - getUserSubscribe: (uuid: string, type?: string) => { + getUserSubscribe: (short: string, token: string, type?: string) => { const { pan_domain, subscribe_domain, subscribe_path } = get().common.subscribe || {}; const domains = subscribe_domain @@ -129,12 +129,13 @@ export const useGlobalStore = create((set, get) => ({ return domains.map((domain) => { if (pan_domain) { - if (type) return `https://${uuid}.${type}.${domain}`; - return `https://${uuid}.${domain}`; + if (type) + return `https://${short}.${type}.${domain}${subscribe_path}?token=${token}&type=${type}`; + return `https://${short}.${domain}${subscribe_path}?token=${token}`; } if (type) - return `https://${domain}${subscribe_path}?token=${uuid}&type=${type}`; - return `https://${domain}${subscribe_path}?token=${uuid}`; + return `https://${domain}${subscribe_path}?token=${token}&type=${type}`; + return `https://${domain}${subscribe_path}?token=${token}`; }); }, getAppSubLink: (url: string, schema?: string) => { From c5dbd97e19bef368a4e336ca966164b8a911b03d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 30 Dec 2025 06:14:30 +0000 Subject: [PATCH 30/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.3.5=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.3.5=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.3.5](https://github.com/perfect-panel/frontend/compare/v1.3.4...v1.3.5) (2025-12-30) ### 🐛 Bug Fixes / 问题修复 * Update getUserSubscribe function to accept short and token parameters for improved URL generation ([39ebd09](https://github.com/perfect-panel/frontend/commit/39ebd09f0989b37308c1c803d8e380f967ab0db5)) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 682c1d9..245352a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,12 @@ This document records all notable changes to ShadCN Admin. --- +## [1.3.5](https://github.com/perfect-panel/frontend/compare/v1.3.4...v1.3.5) (2025-12-30) + +### 🐛 Bug Fixes / 问题修复 + +* Update getUserSubscribe function to accept short and token parameters for improved URL generation ([39ebd09](https://github.com/perfect-panel/frontend/commit/39ebd09f0989b37308c1c803d8e380f967ab0db5)) + ## [1.3.4](https://github.com/perfect-panel/frontend/compare/v1.3.3...v1.3.4) (2025-12-29) ### 🐛 Bug Fixes / 问题修复 diff --git a/package.json b/package.json index 1405e50..c3caacf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.3.4", + "version": "1.3.5", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": { From cbd6e29deda1c7a913fae4edb169e0a0a43a3dd9 Mon Sep 17 00:00:00 2001 From: "web@ppanel" Date: Tue, 30 Dec 2025 08:08:48 +0000 Subject: [PATCH 31/32] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Update=20server=20a?= =?UTF-8?q?nd=20web=20version=20update=20descriptions=20to=20remove=20vers?= =?UTF-8?q?ion=20prefix=20for=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/public/assets/locales/en-US/tool.json | 4 ++-- apps/admin/public/assets/locales/zh-CN/tool.json | 4 ++-- .../dashboard/components/system-version-card.tsx | 9 ++++----- packages/ui/src/lib/request.ts | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/apps/admin/public/assets/locales/en-US/tool.json b/apps/admin/public/assets/locales/en-US/tool.json index 1503c5c..0bf5b5d 100644 --- a/apps/admin/public/assets/locales/en-US/tool.json +++ b/apps/admin/public/assets/locales/en-US/tool.json @@ -13,9 +13,9 @@ "systemServices": "System Services", "update": "Update", "updateFailed": "Update failed", - "updateServerDescription": "Are you sure you want to update the server version from V{{current}} to V{{latest}}?", + "updateServerDescription": "Are you sure you want to update the server version from {{current}} to {{latest}}?", "updateSuccess": "Update completed successfully", - "updateWebDescription": "Are you sure you want to update the web version from V{{current}} to V{{latest}}?", + "updateWebDescription": "Are you sure you want to update the web version from {{current}} to {{latest}}?", "userUpdateSuccess": "User updated successfully", "webVersion": "Web Version" } diff --git a/apps/admin/public/assets/locales/zh-CN/tool.json b/apps/admin/public/assets/locales/zh-CN/tool.json index 478dbbc..32a6b2a 100644 --- a/apps/admin/public/assets/locales/zh-CN/tool.json +++ b/apps/admin/public/assets/locales/zh-CN/tool.json @@ -13,9 +13,9 @@ "systemServices": "系统服务", "update": "更新", "updateFailed": "更新失败", - "updateServerDescription": "确定要将服务器版本从 V{{current}} 更新到 V{{latest}} 吗?", + "updateServerDescription": "确定要将服务器版本从 {{current}} 更新到 {{latest}} 吗?", "updateSuccess": "更新成功", - "updateWebDescription": "确定要将前端版本从 V{{current}} 更新到 V{{latest}} 吗?", + "updateWebDescription": "确定要将前端版本从 {{current}} 更新到 {{latest}} 吗?", "userUpdateSuccess": "用户端更新成功", "webVersion": "前端版本" } diff --git a/apps/admin/src/sections/dashboard/components/system-version-card.tsx b/apps/admin/src/sections/dashboard/components/system-version-card.tsx index 0b1e527..daeda25 100644 --- a/apps/admin/src/sections/dashboard/components/system-version-card.tsx +++ b/apps/admin/src/sections/dashboard/components/system-version-card.tsx @@ -80,7 +80,6 @@ export default function SystemVersionCard() { staleTime: 0, retry: 1, }); - console.log(webVersionInfo); const updateServerMutation = useMutation({ mutationFn: async (serviceName: string) => { @@ -199,7 +198,7 @@ export default function SystemVersionCard() { > {hasWebNewVersion && webVersionInfo - ? `${t("update", "Update")} V${webVersionInfo.latest_version}` + ? `${t("update", "Update")} ${webVersionInfo.latest_version}` : t("update", "Update")} @@ -212,9 +211,9 @@ export default function SystemVersionCard() { {webVersionInfo ? t( "updateWebDescription", - "Are you sure you want to update the web version from V{{current}} to V{{latest}}?", + "Are you sure you want to update the web version from {{current}} to {{latest}}?", { - current: packageJson.version, + current: webVersionInfo.current_version, latest: webVersionInfo.latest_version, } ) @@ -278,7 +277,7 @@ export default function SystemVersionCard() { {serverVersionInfo && moduleConfig ? t( "updateServerDescription", - "Are you sure you want to update the server version from V{{current}} to V{{latest}}?", + "Are you sure you want to update the server version from {{current}} to {{latest}}?", { current: moduleConfig.service_version || diff --git a/packages/ui/src/lib/request.ts b/packages/ui/src/lib/request.ts index da6d08c..dcd4422 100644 --- a/packages/ui/src/lib/request.ts +++ b/packages/ui/src/lib/request.ts @@ -193,7 +193,7 @@ request.interceptors.request.use( request.interceptors.response.use( (response) => { const { code } = response.data; - if (code !== 200) { + if (code !== 200 && code !== 0) { handleError({ data: response.data, config: { From ed5c56fb2a4a7d85f3d230e4bec24f0c4a68f26a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 30 Dec 2025 08:11:29 +0000 Subject: [PATCH 32/32] =?UTF-8?q?=F0=9F=9A=80=20chore(release):=20Release?= =?UTF-8?q?=201.3.6=20/=20=E5=8F=91=E5=B8=83=E7=89=88=E6=9C=AC=201.3.6=20[?= =?UTF-8?q?skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.3.6](https://github.com/perfect-panel/frontend/compare/v1.3.5...v1.3.6) (2025-12-30) ### 🐛 Bug Fixes / 问题修复 * Update server and web version update descriptions to remove version prefix for clarity ([cbd6e29](https://github.com/perfect-panel/frontend/commit/cbd6e29deda1c7a913fae4edb169e0a0a43a3dd9)) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 245352a..abebf31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,12 @@ This document records all notable changes to ShadCN Admin. --- +## [1.3.6](https://github.com/perfect-panel/frontend/compare/v1.3.5...v1.3.6) (2025-12-30) + +### 🐛 Bug Fixes / 问题修复 + +* Update server and web version update descriptions to remove version prefix for clarity ([cbd6e29](https://github.com/perfect-panel/frontend/commit/cbd6e29deda1c7a913fae4edb169e0a0a43a3dd9)) + ## [1.3.5](https://github.com/perfect-panel/frontend/compare/v1.3.4...v1.3.5) (2025-12-30) ### 🐛 Bug Fixes / 问题修复 diff --git a/package.json b/package.json index c3caacf..88a99c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "1.3.5", + "version": "1.3.6", "private": true, "homepage": "https://github.com/perfect-panel/frontend", "bugs": {