feat(admin): streamline subscription plan benefits editor with bulk actions

Restore the avatar/icon header for the “Model Benefits” section
Replace scattered controls with a compact toolbar-style workflow
Support multi-select add with a default quota for new items
Add row selection with bulk apply-to-selected / apply-to-all quota updates
Enable delete-selected to manage benefits faster and reduce mistakes
This commit is contained in:
t0ng7u
2026-01-30 16:24:51 +08:00
parent 348ae6df73
commit a60783e99f
3 changed files with 220 additions and 22 deletions

View File

@@ -27,10 +27,14 @@ export const useSubscriptionsData = () => {
const [compactMode, setCompactMode] = useTableCompactMode('subscriptions');
// State management
const [plans, setPlans] = useState([]);
const [allPlans, setAllPlans] = useState([]);
const [loading, setLoading] = useState(true);
const [pricingModels, setPricingModels] = useState([]);
// Pagination (client-side for now)
const [activePage, setActivePage] = useState(1);
const [pageSize, setPageSize] = useState(10);
// Drawer states
const [showEdit, setShowEdit] = useState(false);
const [editingPlan, setEditingPlan] = useState(null);
@@ -54,7 +58,12 @@ export const useSubscriptionsData = () => {
try {
const res = await API.get('/api/subscription/admin/plans');
if (res.data?.success) {
setPlans(res.data.data || []);
const next = res.data.data || [];
setAllPlans(next);
// Keep page in range after data changes
const totalPages = Math.max(1, Math.ceil(next.length / pageSize));
setActivePage((p) => Math.min(p || 1, totalPages));
} else {
showError(res.data?.message || t('加载失败'));
}
@@ -70,6 +79,15 @@ export const useSubscriptionsData = () => {
await loadPlans();
};
const handlePageChange = (page) => {
setActivePage(page);
};
const handlePageSizeChange = (size) => {
setPageSize(size);
setActivePage(1);
};
// Disable plan
const disablePlan = async (planId) => {
if (!planId) return;
@@ -113,9 +131,16 @@ export const useSubscriptionsData = () => {
loadPlans();
}, []);
const planCount = allPlans.length;
const plans = allPlans.slice(
Math.max(0, (activePage - 1) * pageSize),
Math.max(0, (activePage - 1) * pageSize) + pageSize,
);
return {
// Data state
plans,
planCount,
loading,
pricingModels,
@@ -130,6 +155,12 @@ export const useSubscriptionsData = () => {
compactMode,
setCompactMode,
// Pagination
activePage,
pageSize,
handlePageChange,
handlePageSizeChange,
// Actions
loadPlans,
disablePlan,