mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-03-30 11:13:40 +00:00
Summary • Backend – Moved duplicate-name validation and total vendor-count aggregation from controllers (`controller/model_meta.go`, `controller/vendor_meta.go`, `controller/prefill_group.go`) to model layer (`model/model_meta.go`, `model/vendor_meta.go`, `model/prefill_group.go`). – Added `GetVendorModelCounts()` and `Is*NameDuplicated()` helpers; controllers now call these instead of duplicating queries. – API response for `/api/models` now returns `vendor_counts` with per-vendor totals across all pages, plus `all` summary. – Removed redundant checks and unused imports, eliminating `go vet` warnings. • Frontend – `useModelsData.js` updated to consume backend-supplied `vendor_counts`, calculate the `all` total once, and drop legacy client-side counting logic. – Simplified initial data flow: first render now triggers only one models request. – Deleted obsolete `updateVendorCounts` helper and related comments. – Ensured search flow also sets `vendorCounts`, keeping tab badges accurate. Why This refactor enforces single-responsibility (aggregation in model layer), delivers consistent totals irrespective of pagination, and removes redundant client queries, leading to cleaner code and better performance.
137 lines
3.8 KiB
JavaScript
137 lines
3.8 KiB
JavaScript
/*
|
|
Copyright (C) 2025 QuantumNous
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
For commercial licensing, please contact support@quantumnous.com
|
|
*/
|
|
|
|
import React, { useState } from 'react';
|
|
import MissingModelsModal from './modals/MissingModelsModal.jsx';
|
|
import PrefillGroupManagement from './modals/PrefillGroupManagement.jsx';
|
|
import { Button, Space, Modal } from '@douyinfe/semi-ui';
|
|
import CompactModeToggle from '../../common/ui/CompactModeToggle';
|
|
import { showError } from '../../../helpers';
|
|
import SelectionNotification from './components/SelectionNotification.jsx';
|
|
|
|
const ModelsActions = ({
|
|
selectedKeys,
|
|
setEditingModel,
|
|
setShowEdit,
|
|
batchDeleteModels,
|
|
compactMode,
|
|
setCompactMode,
|
|
t,
|
|
}) => {
|
|
// Modal states
|
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
|
const [showMissingModal, setShowMissingModal] = useState(false);
|
|
const [showGroupManagement, setShowGroupManagement] = useState(false);
|
|
|
|
// Handle delete selected models with confirmation
|
|
const handleDeleteSelectedModels = () => {
|
|
if (selectedKeys.length === 0) {
|
|
showError(t('请至少选择一个模型!'));
|
|
return;
|
|
}
|
|
setShowDeleteModal(true);
|
|
};
|
|
|
|
// Handle delete confirmation
|
|
const handleConfirmDelete = () => {
|
|
batchDeleteModels();
|
|
setShowDeleteModal(false);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="flex flex-wrap gap-2 w-full md:w-auto order-2 md:order-1">
|
|
<Button
|
|
type="primary"
|
|
className="flex-1 md:flex-initial"
|
|
onClick={() => {
|
|
setEditingModel({
|
|
id: undefined,
|
|
});
|
|
setShowEdit(true);
|
|
}}
|
|
size="small"
|
|
>
|
|
{t('添加模型')}
|
|
</Button>
|
|
|
|
|
|
<Button
|
|
type="secondary"
|
|
className="flex-1 md:flex-initial"
|
|
size="small"
|
|
onClick={() => setShowMissingModal(true)}
|
|
>
|
|
{t('未配置模型')}
|
|
</Button>
|
|
|
|
<Button
|
|
type="secondary"
|
|
className="flex-1 md:flex-initial"
|
|
size="small"
|
|
onClick={() => setShowGroupManagement(true)}
|
|
>
|
|
{t('预填组管理')}
|
|
</Button>
|
|
|
|
<CompactModeToggle
|
|
compactMode={compactMode}
|
|
setCompactMode={setCompactMode}
|
|
t={t}
|
|
/>
|
|
</div>
|
|
|
|
<SelectionNotification
|
|
selectedKeys={selectedKeys}
|
|
t={t}
|
|
onDelete={handleDeleteSelectedModels}
|
|
/>
|
|
|
|
<Modal
|
|
title={t('批量删除模型')}
|
|
visible={showDeleteModal}
|
|
onCancel={() => setShowDeleteModal(false)}
|
|
onOk={handleConfirmDelete}
|
|
type="warning"
|
|
>
|
|
<div>
|
|
{t('确定要删除所选的 {{count}} 个模型吗?', { count: selectedKeys.length })}
|
|
</div>
|
|
</Modal>
|
|
|
|
<MissingModelsModal
|
|
visible={showMissingModal}
|
|
onClose={() => setShowMissingModal(false)}
|
|
onConfigureModel={(name) => {
|
|
setEditingModel({ id: undefined, model_name: name });
|
|
setShowEdit(true);
|
|
setShowMissingModal(false);
|
|
}}
|
|
t={t}
|
|
/>
|
|
|
|
<PrefillGroupManagement
|
|
visible={showGroupManagement}
|
|
onClose={() => setShowGroupManagement(false)}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default ModelsActions; |