fix(pricing): 手动调价支持负数降价对冲

之前手动调价只允许非负整数,无法用负数对冲降价。

前端 (admin-web settings/page.tsx):
- 移除 input min="0" 限制,允许输入负数
- 验证改为:只校验 isNaN 和总价不低于 0(15831 + amount >= 0)
- 文案:"加价金额" → "调价金额",placeholder 改为"正数涨价,负数降价"
- 实时预览条件从 amount >= 0 改为总价 >= 0
- 提示文案更新为"正数涨价,负数降价对冲"

后端 (admin-service tree-pricing.service.ts):
- 移除 newSupplement < 0 的硬性拒绝
- 改为校验 BASE_PRICE(15831) + newSupplement >= 0,防止总价为负

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-26 11:58:11 -08:00
parent 12004d1c2e
commit cfc03fe523
2 changed files with 18 additions and 12 deletions

View File

@ -79,8 +79,10 @@ export class TreePricingService {
reason: string, reason: string,
operatorId: string, operatorId: string,
): Promise<TreePricingConfigResponse> { ): Promise<TreePricingConfigResponse> {
if (newSupplement < 0) { // 允许负数(降价对冲),但总价不能低于 0
throw new Error('加价金额不能为负数'); const BASE_PRICE = 15831;
if (BASE_PRICE + newSupplement < 0) {
throw new Error(`调价金额不能低于 -${BASE_PRICE},否则总价为负`);
} }
const config = await this.getOrCreateConfig(); const config = await this.getOrCreateConfig();

View File

@ -321,21 +321,26 @@ export default function SettingsPage() {
// 手动修改加价金额 // 手动修改加价金额
const handleSupplementUpdate = useCallback(async () => { const handleSupplementUpdate = useCallback(async () => {
const amount = parseInt(newSupplement, 10); const amount = parseInt(newSupplement, 10);
if (isNaN(amount) || amount < 0) { if (isNaN(amount)) {
alert('请输入有效的加价金额(非负整数)'); alert('请输入有效的调价金额(整数)');
return;
}
if (15831 + amount < 0) {
alert(`调价金额不能低于 -15831否则总价为负`);
return; return;
} }
if (!supplementReason.trim()) { if (!supplementReason.trim()) {
alert('请填写变更原因'); alert('请填写变更原因');
return; return;
} }
if (!confirm(`确认将加价金额修改为 ${amount} USDT\n正式认种总价将变为 ${15831 + amount} USDT/棵\n预种总价将变为 ${Math.floor((15831 + amount) / 5)} USDT/份`)) return; const totalPrice = 15831 + amount;
if (!confirm(`确认将调价金额修改为 ${amount} USDT\n正式认种总价将变为 ${totalPrice.toLocaleString()} USDT/棵\n预种总价将变为 ${Math.floor(totalPrice / 5).toLocaleString()} USDT/份`)) return;
setPricingSaving(true); setPricingSaving(true);
try { try {
await treePricingService.updateSupplement(amount, supplementReason.trim()); await treePricingService.updateSupplement(amount, supplementReason.trim());
setSupplementReason(''); setSupplementReason('');
await loadPricingConfig(); await loadPricingConfig();
alert('价金额修改成功'); alert('价金额修改成功');
} catch (error) { } catch (error) {
console.error('Failed to update supplement:', error); console.error('Failed to update supplement:', error);
alert('修改失败,请重试'); alert('修改失败,请重试');
@ -1180,15 +1185,14 @@ export default function SettingsPage() {
{/* 手动调价 */} {/* 手动调价 */}
<div className={styles.settings__quotaCard}> <div className={styles.settings__quotaCard}>
<div className={styles.settings__quotaHeader}> <div className={styles.settings__quotaHeader}>
<span className={styles.settings__quotaTitle}></span> <span className={styles.settings__quotaTitle}></span>
</div> </div>
<div className={styles.settings__quotaInputRow}> <div className={styles.settings__quotaInputRow}>
<span className={styles.settings__quotaText}></span> <span className={styles.settings__quotaText}></span>
<input <input
type="number" type="number"
min="0"
className={cn(styles.settings__input, styles['settings__input--medium'])} className={cn(styles.settings__input, styles['settings__input--medium'])}
placeholder="加价金额" placeholder="正数涨价,负数降价"
value={newSupplement} value={newSupplement}
onChange={(e) => setNewSupplement(e.target.value)} onChange={(e) => setNewSupplement(e.target.value)}
/> />
@ -1214,8 +1218,8 @@ export default function SettingsPage() {
</button> </button>
</div> </div>
<span className={styles.settings__hint}> <span className={styles.settings__hint}>
(S0000000001) 10 (S0000000001) 10
{newSupplement && !isNaN(parseInt(newSupplement, 10)) && parseInt(newSupplement, 10) >= 0 && ( {newSupplement && !isNaN(parseInt(newSupplement, 10)) && (15831 + parseInt(newSupplement, 10)) >= 0 && (
<> 修改后: 正式认种 {(15831 + parseInt(newSupplement, 10)).toLocaleString()} USDT/ {Math.floor((15831 + parseInt(newSupplement, 10)) / 5).toLocaleString()} USDT/</> <> 修改后: 正式认种 {(15831 + parseInt(newSupplement, 10)).toLocaleString()} USDT/ {Math.floor((15831 + parseInt(newSupplement, 10)) / 5).toLocaleString()} USDT/</>
)} )}
</span> </span>