修复(#122): 合并促销价档位提交到测试环境
PR Check / Lint, Check, Test and Build (push) Has been cancelled

This commit is contained in:
2026-05-29 04:15:40 -07:00
parent c46944aae1
commit 23f51a1ef4
14 changed files with 369 additions and 34 deletions
+86 -14
View File
@@ -23,11 +23,16 @@ import { useState } from "react";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { z } from "zod";
import { getSubscribeUnitPrice } from "./utils";
import {
formatCurrency,
getSubscribeDiscounts,
getSubscribeUnitPrice,
} from "./utils";
const priceSchema = z.object({
rule_id: z.number().min(1),
promo_rule_id: z.number().min(1),
subscribe_id: z.number().min(1),
quantity: z.number().min(1),
promo_price: z.number().min(1),
});
@@ -51,26 +56,42 @@ export default function PriceForm({
const form = useForm<PriceFormValues>({
resolver: zodResolver(priceSchema),
defaultValues: {
rule_id: 0,
promo_rule_id: 0,
subscribe_id: 0,
quantity: 0,
promo_price: 0,
},
});
const subscribeId = form.watch("subscribe_id");
const quantity = form.watch("quantity");
const subscribe = subscribes.find((item) => item.id === subscribeId);
const discounts = getSubscribeDiscounts(subscribe);
const unitPrice = getSubscribeUnitPrice(subscribe);
const originalPrice = unitPrice * quantity;
const hasSelectedSubscribe = subscribeId > 0;
const hasDiscounts = discounts.length > 0;
async function handleSubmit(values: PriceFormValues) {
if (unitPrice > 0 && values.promo_price >= unitPrice) {
const maxPrice = unitPrice * values.quantity;
if (maxPrice > 0 && values.promo_price >= maxPrice) {
form.setError("promo_price", {
message: t(
"form.promoPriceLessThanUnitPrice",
"Promo price must be lower than unit price"
"form.promoPriceLessThanOriginalPrice",
"Promo price must be lower than original price"
),
});
return;
}
const success = await onSubmit(values);
const success = await onSubmit({
promo_rule_id: values.promo_rule_id,
items: [
{
subscribe_id: values.subscribe_id,
quantity: values.quantity,
promo_price: values.promo_price,
},
],
});
if (success) setOpen(false);
}
@@ -79,7 +100,12 @@ export default function PriceForm({
<SheetTrigger asChild>
<Button
onClick={() => {
form.reset({ rule_id: 0, subscribe_id: 0, promo_price: 0 });
form.reset({
promo_rule_id: 0,
subscribe_id: 0,
quantity: 0,
promo_price: 0,
});
setOpen(true);
}}
size="sm"
@@ -99,7 +125,7 @@ export default function PriceForm({
>
<FormField
control={form.control}
name="rule_id"
name="promo_rule_id"
render={({ field }) => (
<FormItem>
<FormLabel>{t("rule", "Rule")}</FormLabel>
@@ -126,7 +152,14 @@ export default function PriceForm({
<FormLabel>{t("subscribe", "Subscribe")}</FormLabel>
<FormControl>
<Combobox<number>
onChange={field.onChange}
onChange={(value) => {
field.onChange(value);
form.setValue("quantity", 0, {
shouldDirty: true,
shouldValidate: true,
});
form.clearErrors(["quantity", "promo_price"]);
}}
options={subscribes
.filter((item) => typeof item.id === "number")
.map((item) => ({
@@ -144,6 +177,41 @@ export default function PriceForm({
</FormItem>
)}
/>
<FormField
control={form.control}
name="quantity"
render={({ field }) => (
<FormItem>
<FormLabel>{t("quantity", "Quantity")}</FormLabel>
<FormControl>
<Combobox<number>
onChange={field.onChange}
options={discounts.map((item) => ({
label: `${item.quantity} x ${t(
subscribe?.unit_time || "Month",
subscribe?.unit_time || "Month"
)}`,
value: item.quantity,
}))}
placeholder={t(
"form.selectQuantity",
"Select discount quantity"
)}
value={field.value}
/>
</FormControl>
{hasSelectedSubscribe && !hasDiscounts && (
<p className="text-destructive text-xs">
{t(
"form.noDiscounts",
"This subscribe has no discount quantities and cannot be configured."
)}
</p>
)}
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="promo_price"
@@ -165,10 +233,10 @@ export default function PriceForm({
value={field.value}
/>
</FormControl>
{unitPrice > 0 && (
{originalPrice > 0 && (
<p className="text-muted-foreground text-xs">
{t("unitPriceHint", "Unit price")}:{" "}
{unitConversion("centsToDollars", unitPrice)}
{t("originalPriceHint", "Original price")}:{" "}
{formatCurrency(originalPrice)}
</p>
)}
<FormMessage />
@@ -178,7 +246,11 @@ export default function PriceForm({
</form>
</Form>
<SheetFooter>
<Button disabled={loading} form="promo-price-form" type="submit">
<Button
disabled={loading || (hasSelectedSubscribe && !hasDiscounts)}
form="promo-price-form"
type="submit"
>
{t("confirm", "Confirm")}
</Button>
</SheetFooter>