| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import { useEffect, useState } from 'react';
- import { useNavigate } from 'react-router-dom';
- import { deleteDiscount, fetchDiscounts, upsertDiscount } from '../api';
- import type { Discount } from '../types';
- import './Discounts.css';
- export function Discounts() {
- const [list, setList] = useState<Discount[]>([]);
- const [domain, setDomain] = useState('');
- const [discount, setDiscount] = useState('');
- const [note, setNote] = useState('');
- const [editing, setEditing] = useState<Discount | null>(null);
- const [error, setError] = useState('');
- const navigate = useNavigate();
- const load = () => fetchDiscounts().then(setList).catch(() => {});
- useEffect(() => { load(); }, []);
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- setError('');
- const d = parseFloat(discount);
- if (isNaN(d) || d <= 0 || d > 1) {
- setError('折扣系数需在 0~1 之间,如 0.8 表示八折');
- return;
- }
- try {
- await upsertDiscount(domain.trim(), d, note.trim() || undefined);
- setDomain(''); setDiscount(''); setNote(''); setEditing(null);
- load();
- } catch (err: any) {
- setError(err.message);
- }
- };
- const startEdit = (item: Discount) => {
- setEditing(item);
- setDomain(item.domain);
- setDiscount(String(item.discount));
- setNote(item.note ?? '');
- };
- const handleDelete = async (id: number) => {
- await deleteDiscount(id);
- load();
- };
- return (
- <div className="discounts-page">
- <header className="discounts-header">
- <span className="discounts-title">折扣管理</span>
- </header>
- <form className="discount-form" onSubmit={handleSubmit}>
- <input
- className="discount-input"
- placeholder="域名,如 aigc.wangxunai.com"
- value={domain}
- onChange={e => setDomain(e.target.value)}
- required
- />
- <input
- className="discount-input discount-input--short"
- placeholder="折扣系数,如 0.8"
- value={discount}
- onChange={e => setDiscount(e.target.value)}
- required
- />
- <input
- className="discount-input"
- placeholder="备注(可选)"
- value={note}
- onChange={e => setNote(e.target.value)}
- />
- <button className="discount-btn discount-btn--primary" type="submit">
- {editing ? '保存' : '添加'}
- </button>
- {editing && (
- <button className="discount-btn" type="button" onClick={() => {
- setEditing(null); setDomain(''); setDiscount(''); setNote('');
- }}>取消</button>
- )}
- </form>
- {error && <div className="discount-error">{error}</div>}
- <div className="discount-table-wrap">
- <table className="discount-table">
- <thead>
- <tr>
- <th>域名</th>
- <th>折扣系数</th>
- <th>折扣</th>
- <th>备注</th>
- <th>更新时间</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- {list.map(item => (
- <tr key={item.id}>
- <td className="td-domain">
- <button
- className="td-domain-link"
- onClick={() => navigate(`/discounts/${encodeURIComponent(item.domain)}/model-prices`)}
- >
- {item.domain}
- </button>
- </td>
- <td className="td-discount">{item.discount}</td>
- <td className="td-discount">{Math.round(item.discount * 10)}折</td>
- <td className="td-note">{item.note ?? '—'}</td>
- <td className="td-time">{new Date(item.updated_at).toLocaleString()}</td>
- <td className="td-actions">
- <button className="discount-btn discount-btn--sm discount-btn--config" onClick={() => navigate(`/discounts/${encodeURIComponent(item.domain)}/model-prices`)}>模型价格</button>
- <button className="discount-btn discount-btn--sm" onClick={() => startEdit(item)}>编辑</button>
- <button className="discount-btn discount-btn--sm discount-btn--danger" onClick={() => handleDelete(item.id)}>删除</button>
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- {list.length === 0 && <div className="empty-msg">暂无折扣配置,所有域名按原价返回</div>}
- </div>
- </div>
- );
- }
|