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}`} + + + ); + })()}