mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-04-20 05:18:38 +00:00
feat: add billing display mode selection and update pricing rendering
Introduce a billing display mode feature allowing users to toggle between price and ratio views. Update relevant components and hooks to support this new functionality, ensuring consistent pricing information is displayed across the application.
This commit is contained in:
110
web/src/hooks/usage-logs/useUsageLogsData.jsx
vendored
110
web/src/hooks/usage-logs/useUsageLogsData.jsx
vendored
@@ -78,6 +78,9 @@ export const useLogsData = () => {
|
||||
const STORAGE_KEY = isAdminUser
|
||||
? 'logs-table-columns-admin'
|
||||
: 'logs-table-columns-user';
|
||||
const BILLING_DISPLAY_MODE_STORAGE_KEY = isAdminUser
|
||||
? 'logs-billing-display-mode-admin'
|
||||
: 'logs-billing-display-mode-user';
|
||||
|
||||
// Statistics state
|
||||
const [stat, setStat] = useState({
|
||||
@@ -102,50 +105,6 @@ export const useLogsData = () => {
|
||||
logType: '0',
|
||||
};
|
||||
|
||||
// Column visibility state
|
||||
const [visibleColumns, setVisibleColumns] = useState({});
|
||||
const [showColumnSelector, setShowColumnSelector] = useState(false);
|
||||
|
||||
// Compact mode
|
||||
const [compactMode, setCompactMode] = useTableCompactMode('logs');
|
||||
|
||||
// User info modal state
|
||||
const [showUserInfo, setShowUserInfoModal] = useState(false);
|
||||
const [userInfoData, setUserInfoData] = useState(null);
|
||||
|
||||
// Channel affinity usage cache stats modal state (admin only)
|
||||
const [
|
||||
showChannelAffinityUsageCacheModal,
|
||||
setShowChannelAffinityUsageCacheModal,
|
||||
] = useState(false);
|
||||
const [channelAffinityUsageCacheTarget, setChannelAffinityUsageCacheTarget] =
|
||||
useState(null);
|
||||
|
||||
// Load saved column preferences from localStorage
|
||||
useEffect(() => {
|
||||
const savedColumns = localStorage.getItem(STORAGE_KEY);
|
||||
if (savedColumns) {
|
||||
try {
|
||||
const parsed = JSON.parse(savedColumns);
|
||||
const defaults = getDefaultColumnVisibility();
|
||||
const merged = { ...defaults, ...parsed };
|
||||
|
||||
// For non-admin users, force-hide admin-only columns (does not touch admin settings)
|
||||
if (!isAdminUser) {
|
||||
merged[COLUMN_KEYS.CHANNEL] = false;
|
||||
merged[COLUMN_KEYS.USERNAME] = false;
|
||||
merged[COLUMN_KEYS.RETRY] = false;
|
||||
}
|
||||
setVisibleColumns(merged);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse saved column preferences', e);
|
||||
initDefaultColumns();
|
||||
}
|
||||
} else {
|
||||
initDefaultColumns();
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Get default column visibility based on user role
|
||||
const getDefaultColumnVisibility = () => {
|
||||
return {
|
||||
@@ -166,6 +125,58 @@ export const useLogsData = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const getInitialVisibleColumns = () => {
|
||||
const defaults = getDefaultColumnVisibility();
|
||||
const savedColumns = localStorage.getItem(STORAGE_KEY);
|
||||
|
||||
if (!savedColumns) {
|
||||
return defaults;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(savedColumns);
|
||||
const merged = { ...defaults, ...parsed };
|
||||
|
||||
if (!isAdminUser) {
|
||||
merged[COLUMN_KEYS.CHANNEL] = false;
|
||||
merged[COLUMN_KEYS.USERNAME] = false;
|
||||
merged[COLUMN_KEYS.RETRY] = false;
|
||||
}
|
||||
|
||||
return merged;
|
||||
} catch (e) {
|
||||
console.error('Failed to parse saved column preferences', e);
|
||||
return defaults;
|
||||
}
|
||||
};
|
||||
|
||||
const getInitialBillingDisplayMode = () => {
|
||||
const savedMode = localStorage.getItem(BILLING_DISPLAY_MODE_STORAGE_KEY);
|
||||
return savedMode === 'price' || savedMode === 'ratio' ? savedMode : 'price';
|
||||
};
|
||||
|
||||
// Column visibility state
|
||||
const [visibleColumns, setVisibleColumns] = useState(getInitialVisibleColumns);
|
||||
const [showColumnSelector, setShowColumnSelector] = useState(false);
|
||||
const [billingDisplayMode, setBillingDisplayMode] = useState(
|
||||
getInitialBillingDisplayMode,
|
||||
);
|
||||
|
||||
// Compact mode
|
||||
const [compactMode, setCompactMode] = useTableCompactMode('logs');
|
||||
|
||||
// User info modal state
|
||||
const [showUserInfo, setShowUserInfoModal] = useState(false);
|
||||
const [userInfoData, setUserInfoData] = useState(null);
|
||||
|
||||
// Channel affinity usage cache stats modal state (admin only)
|
||||
const [
|
||||
showChannelAffinityUsageCacheModal,
|
||||
setShowChannelAffinityUsageCacheModal,
|
||||
] = useState(false);
|
||||
const [channelAffinityUsageCacheTarget, setChannelAffinityUsageCacheTarget] =
|
||||
useState(null);
|
||||
|
||||
// Initialize default column visibility
|
||||
const initDefaultColumns = () => {
|
||||
const defaults = getDefaultColumnVisibility();
|
||||
@@ -207,6 +218,10 @@ export const useLogsData = () => {
|
||||
}
|
||||
}, [visibleColumns]);
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem(BILLING_DISPLAY_MODE_STORAGE_KEY, billingDisplayMode);
|
||||
}, [BILLING_DISPLAY_MODE_STORAGE_KEY, billingDisplayMode]);
|
||||
|
||||
// 获取表单值的辅助函数,确保所有值都是字符串
|
||||
const getFormValues = () => {
|
||||
const formValues = formApi ? formApi.getValues() : {};
|
||||
@@ -406,6 +421,7 @@ export const useLogsData = () => {
|
||||
other.cache_creation_ratio_1h ||
|
||||
other.cache_creation_ratio ||
|
||||
1.0,
|
||||
billingDisplayMode,
|
||||
)
|
||||
: renderLogContent(
|
||||
other?.model_ratio,
|
||||
@@ -420,6 +436,7 @@ export const useLogsData = () => {
|
||||
other.web_search_call_count || 0,
|
||||
other.file_search || false,
|
||||
other.file_search_call_count || 0,
|
||||
billingDisplayMode,
|
||||
),
|
||||
});
|
||||
if (logs[i]?.content) {
|
||||
@@ -473,6 +490,7 @@ export const useLogsData = () => {
|
||||
other?.user_group_ratio,
|
||||
other?.cache_tokens || 0,
|
||||
other?.cache_ratio || 1.0,
|
||||
billingDisplayMode,
|
||||
);
|
||||
} else if (other?.claude) {
|
||||
content = renderClaudeModelPrice(
|
||||
@@ -495,6 +513,7 @@ export const useLogsData = () => {
|
||||
other.cache_creation_ratio_1h ||
|
||||
other.cache_creation_ratio ||
|
||||
1.0,
|
||||
billingDisplayMode,
|
||||
);
|
||||
} else {
|
||||
content = renderModelPrice(
|
||||
@@ -521,6 +540,7 @@ export const useLogsData = () => {
|
||||
other?.audio_input_price || 0,
|
||||
other?.image_generation_call || false,
|
||||
other?.image_generation_call_price || 0,
|
||||
billingDisplayMode,
|
||||
);
|
||||
}
|
||||
expandDataLocal.push({
|
||||
@@ -764,6 +784,8 @@ export const useLogsData = () => {
|
||||
visibleColumns,
|
||||
showColumnSelector,
|
||||
setShowColumnSelector,
|
||||
billingDisplayMode,
|
||||
setBillingDisplayMode,
|
||||
handleColumnVisibilityChange,
|
||||
handleSelectAll,
|
||||
initDefaultColumns,
|
||||
|
||||
Reference in New Issue
Block a user