fix: 样本管理

This commit is contained in:
2026-02-27 10:34:49 +08:00
parent a5d3342d93
commit 912ab4c321
10 changed files with 47 additions and 57 deletions

View File

@@ -19,8 +19,7 @@ const Settings: ProLayoutProps & {
pwa: true, pwa: true,
logo: '/logo.svg', logo: '/logo.svg',
iconfontUrl: '', iconfontUrl: '',
splitMenus: true, // splitMenus: true,
token: { token: {
// 参见ts声明demo 见文档通过token 修改样式 // 参见ts声明demo 见文档通过token 修改样式
// 设置内容区域的边距 // 设置内容区域的边距

View File

@@ -45,6 +45,7 @@ export async function getInitialState(): Promise<{
throw new Error('No token found'); throw new Error('No token found');
} }
const data = await getInfo(); const data = await getInfo();
console.log(data, 'data');
wsCache.set(CACHE_KEY.USER, data); wsCache.set(CACHE_KEY.USER, data);
wsCache.set(CACHE_KEY.ROLE_ROUTERS, data.menus); wsCache.set(CACHE_KEY.ROLE_ROUTERS, data.menus);
@@ -73,7 +74,6 @@ export async function getInitialState(): Promise<{
await fetchUserInfo(); await fetchUserInfo();
} }
const menus = wsCache.get(CACHE_KEY.ROLE_ROUTERS); const menus = wsCache.get(CACHE_KEY.ROLE_ROUTERS);
console.log(111);
return { return {
fetchUserInfo, fetchUserInfo,
currentUser, currentUser,
@@ -93,27 +93,14 @@ export const layout: RunTimeLayoutConfig = ({
initialState, initialState,
setInitialState, setInitialState,
}) => { }) => {
const { wsCache } = useCache();
return { return {
actionsRender: () => [ actionsRender: () => [
<Question key="doc" />, <Question key="doc" />,
<SelectLang key="SelectLang" />, <SelectLang key="SelectLang" />,
], ],
menu: { menu: {
locale: false, locale: false,
// 关闭国际化-
// request: async () => {
// const currentUser = wsCache.get(CACHE_KEY.USER);
// console.log("菜单请求被调用", initialState?.menus, currentUser);
// if (currentUser.menus) {
// const menuData = loopMenuItem(currentUser.menus);
// // console.log('转换后的菜单数据:', menuData);
// // const r = loopMenuItem(currentUser.menus);
// return menuData;
// }
// return [];
// },
}, },
avatarProps: { avatarProps: {
src: initialState?.currentUser?.user.avatar, src: initialState?.currentUser?.user.avatar,
@@ -159,8 +146,8 @@ export const layout: RunTimeLayoutConfig = ({
useRoutes: true, useRoutes: true,
}, },
menuHeaderRender: undefined, menuHeaderRender: undefined,
// 自定义 403 页面 // // 自定义 403 页面
unAccessible: <div>unAccessible</div>, // unAccessible: <div>unAccessible</div>,
// 增加一个 loading 的状态 // 增加一个 loading 的状态
childrenRender: (children) => { childrenRender: (children) => {
// if (initialState?.loading) return <PageLoading />; // if (initialState?.loading) return <PageLoading />;

View File

@@ -36,6 +36,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
const [currentId, setCurrentId] = useState<number>(); const [currentId, setCurrentId] = useState<number>();
const [tagsModalValue, setTagsModalValue] = useState<{ const [tagsModalValue, setTagsModalValue] = useState<{
tagName?: string; tagName?: string;
groupName?: string;
groupIds?: number[]; groupIds?: number[];
id?: number; id?: number;
}>({}); }>({});
@@ -86,7 +87,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
useEffect(() => { useEffect(() => {
if (modalType === 'edit' && visible) { if (modalType === 'edit' && visible) {
if (type === 'group' && currentGroup) { if (type === 'group' && currentGroup) {
setName(currentGroup.groupName); setName(currentGroup.groupName || '');
} else if (type === 'tag' && tagsModalValue) { } else if (type === 'tag' && tagsModalValue) {
setName(tagsModalValue.tagName || ''); setName(tagsModalValue.tagName || '');
} }
@@ -95,12 +96,16 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
setName(''); setName('');
} }
}, [type, modalType, currentGroup, tagsModalValue, visible]); }, [type, modalType, currentGroup, tagsModalValue, visible]);
const handleGroup = (type: 'add' | 'edit' | 'delete') => { const handleGroup = (type: 'add' | 'edit' | 'delete', group?: GroupItem) => {
setType('group'); setType('group');
setModalType(type); setModalType(type);
if (type === 'add' || type === 'edit') { if (type === 'add' || type === 'edit') {
setVisible(true); setVisible(true);
} }
if (type === 'edit') {
console.log('group', group);
setTagsModalValue({ groupName: group?.groupName, id: group?.id });
}
}; };
const handleTag = (type: 'add' | 'edit' | 'delete', tag?: TagItem) => { const handleTag = (type: 'add' | 'edit' | 'delete', tag?: TagItem) => {
@@ -115,9 +120,8 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
}; };
const handleAdd = async (value: { const handleAdd = async (value: {
groupName?: string;
groupIds?: number[]; groupIds?: number[];
tagName?: string; groupName?: string;
}) => { }) => {
if (type === 'group') { if (type === 'group') {
const id = await groupsApi.create({ groupName: value.groupName }); const id = await groupsApi.create({ groupName: value.groupName });
@@ -132,15 +136,18 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
const handleEdit = async (value: { const handleEdit = async (value: {
tagName?: string; tagName?: string;
groupName?: string;
groupIds?: number[]; groupIds?: number[];
}) => { }) => {
if (type === 'group') { if (type === 'group') {
try { try {
setLoading(true); await groupsApi.update({
await groupsApi.update({ id: currentGroup?.id, groupName: name }); id: currentGroup?.id,
groupName: value.groupName,
});
const newData = groups.map((item) => { const newData = groups.map((item) => {
if (item.id === currentGroup?.id) { if (item.id === currentGroup?.id) {
const itemData = { ...item, groupName: name }; const itemData = { ...item, groupName: value.groupName };
setCurrentGroup(itemData); setCurrentGroup(itemData);
return itemData; return itemData;
} else { } else {
@@ -148,8 +155,8 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
} }
}); });
setGroups(newData); setGroups(newData);
} finally { } catch (error) {
setLoading(false); message.success('修改失败');
} }
} else { } else {
await tagsApi.update({ await tagsApi.update({
@@ -157,7 +164,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
id: tagsModalValue?.id, id: tagsModalValue?.id,
...value, ...value,
}); });
message.success('修改成功');
const newTag = currentGroup?.tags?.map((tag) => { const newTag = currentGroup?.tags?.map((tag) => {
if (tag.id === tagsModalValue?.id) { if (tag.id === tagsModalValue?.id) {
return { ...tag, tagName: value.tagName }; return { ...tag, tagName: value.tagName };
@@ -170,6 +177,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
setCurrentGroup(newGroup as GroupItem); setCurrentGroup(newGroup as GroupItem);
} }
setVisible(false); setVisible(false);
message.success('修改成功');
}; };
const handleDelete = async (type: 'group' | 'tag', id: number) => { const handleDelete = async (type: 'group' | 'tag', id: number) => {
@@ -187,7 +195,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
}; };
const handleConfirm = useCallback( const handleConfirm = useCallback(
async (value: { tagName?: string; groupIds?: number[] }) => { async (value: { groupIds?: number[]; name?: string }) => {
if (modalType === 'add') { if (modalType === 'add') {
await handleAdd(value); await handleAdd(value);
} }
@@ -201,6 +209,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
const handleCancle = useCallback(() => { const handleCancle = useCallback(() => {
setVisible(false); setVisible(false);
setTagsModalValue({});
}, [visible]); }, [visible]);
const onTagItemChange = (tag: TagItem, e: CheckboxChangeEvent) => { const onTagItemChange = (tag: TagItem, e: CheckboxChangeEvent) => {
@@ -284,7 +293,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
groups, groups,
currentId, currentId,
onGroupClick, onGroupClick,
onEdit: () => handleGroup('edit'), onEdit: (groud) => handleGroup('edit', groud),
onDelete: (id) => handleDelete('group', id), onDelete: (id) => handleDelete('group', id),
})} })}
</div> </div>

View File

@@ -6,14 +6,17 @@ interface TagsModalProps {
type: 'group' | 'tag'; type: 'group' | 'tag';
modalType?: 'add' | 'edit' | 'delete'; modalType?: 'add' | 'edit' | 'delete';
onCancel: () => void; onCancel: () => void;
groups: { id: number; groupName: string }[]; groups: { id?: number; groupName?: string }[];
value: { value: {
id?: number; id?: number;
tagName?: string; tagName?: string;
groupIds?: number[]; groupIds?: number[];
groupName?: string; groupName?: string;
}; };
onConfirm: (values: { tagName: string; groupIds?: number[] }) => void; onConfirm: (
values: { groupIds?: number[]; name: string },
type: 'group' | 'tag',
) => void;
} }
const TagsModal = (props: TagsModalProps) => { const TagsModal = (props: TagsModalProps) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
@@ -32,7 +35,7 @@ const TagsModal = (props: TagsModalProps) => {
try { try {
setLoading(true); setLoading(true);
const values = await form.validateFields(); const values = await form.validateFields();
await onConfirm(values); await onConfirm(values, type);
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -19,7 +19,7 @@ interface GroupsProps {
total?: number; total?: number;
loadMoreData?: () => void; loadMoreData?: () => void;
pageSize?: number; pageSize?: number;
onEdit?: () => void; onEdit?: (group: GroupItem) => void;
onDelete?: (id: number) => void; onDelete?: (id: number) => void;
} }
export const renderGroups = (data: GroupsProps) => { export const renderGroups = (data: GroupsProps) => {
@@ -67,7 +67,7 @@ export const renderGroups = (data: GroupsProps) => {
icon={<EditFilled />} icon={<EditFilled />}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onEdit?.(); onEdit?.(item);
}} }}
/> />
<Button <Button

View File

@@ -8,7 +8,7 @@ export interface TagItem {
export interface GroupItem { export interface GroupItem {
id: number; id: number;
groupName: string; groupName?: string;
createTime?: string; createTime?: string;
tags?: TagItem[]; tags?: TagItem[];
} }

View File

@@ -80,7 +80,7 @@ const AudioUploader: React.FC<AudioUploaderProps> = ({
onProgress?.({ percent: 10 }); onProgress?.({ percent: 10 });
// 调用后端接口 // 调用后端接口
const result = await uploadToServer(file as File); const result = await uploadToServer(file as File);
console.log(result, 'res'); // console.log(result, 'res');
onProgress?.({ percent: 100 }); onProgress?.({ percent: 100 });
if (result) { if (result) {
// 构造返回数据 // 构造返回数据
@@ -92,6 +92,7 @@ const AudioUploader: React.FC<AudioUploaderProps> = ({
response: result, response: result,
}; };
onSuccess?.(responseData); onSuccess?.(responseData);
onChange?.(responseData);
} else { } else {
throw new Error(result.message || '上传失败'); throw new Error(result.message || '上传失败');
} }

View File

@@ -1,7 +1,7 @@
.tag-content { .tag-content {
display: flex; display: flex;
width: 100%;
background: #fff; background: #fff;
width: 100%;
overflow: auto; overflow: auto;
:global { :global {
.ant-pro-table { .ant-pro-table {

View File

@@ -1,5 +1,7 @@
import type { ActionType } from '@ant-design/pro-components'; import type { ActionType } from '@ant-design/pro-components';
import type { RowSelectionType } from 'antd/es/table/interface'; import type { RowSelectionType } from 'antd/es/table/interface';
import type { UploadFile } from 'antd/es/upload';
import type { UploadProps } from 'antd/lib/upload';
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import EnhancedProTable from '@/components/EnhancedProTable'; import EnhancedProTable from '@/components/EnhancedProTable';
import type { ToolbarAction } from '@/components/EnhancedProTable/types'; import type { ToolbarAction } from '@/components/EnhancedProTable/types';
@@ -68,9 +70,13 @@ const SampleTag: React.FC = () => {
tableRef.current?.onValuesChange({}, {}); tableRef.current?.onValuesChange({}, {});
type && setSelectedRows([]); type && setSelectedRows([]);
}; };
const onChangeVideo = (file: UploadFile[] | UploadFile | null) => {
tableRef.current?.reload();
};
return ( return (
<> <>
<UploadCard /> <UploadCard onChange={onChangeVideo} />
<div className={styles['tag-content']}> <div className={styles['tag-content']}>
<EnhancedProTable<AiSampleRespVO> <EnhancedProTable<AiSampleRespVO>
ref={tableRef} ref={tableRef}
@@ -80,6 +86,7 @@ const SampleTag: React.FC = () => {
headerTitle="样本列表" headerTitle="样本列表"
showIndex={false} showIndex={false}
enableRowClick={true} enableRowClick={true}
scroll={{ x: 'max-content' }}
rowSelection={{ rowSelection={{
type: selectTableType, type: selectTableType,
selectedRowKeys: selectedRows.map((item) => item.id) as React.Key[], selectedRowKeys: selectedRows.map((item) => item.id) as React.Key[],
@@ -88,6 +95,7 @@ const SampleTag: React.FC = () => {
}, },
}} }}
/> />
{selectedRows.length > 0 && ( {selectedRows.length > 0 && (
<div className="detail"> <div className="detail">
<SampleTagDetail<AiSampleRespVO> <SampleTagDetail<AiSampleRespVO>

View File

@@ -37,28 +37,11 @@ export const loopMenuItem = (
</React.Suspense> </React.Suspense>
); );
} else if (item.children && item.children.length > 0) { } else if (item.children && item.children.length > 0) {
// routeItem.redirect = "/prod/list";
// // 只有当没有 Component 但有子菜单时,才添加重定向
// const firstLeafPath = getFirstLeafPath(item.children);
// // 确保 firstLeafPath 存在,且不是一个会导致循环的路径
// if (
// firstLeafPath &&
// firstLeafPath !== item.path &&
// firstLeafPath.length > 0
// ) {
// // 在 UmiJS 中,路径是相对的,不需要构建完整路径
// const separator =
// item.path.endsWith("/") || firstLeafPath.startsWith("/") ? "" : "/";
// const fullPath = `${item.path}${separator}${firstLeafPath}`;
// console.log(`Redirecting from ${item.path} to ${fullPath}`);
// routeItem.element = <Navigate to={fullPath} replace={true} />;
// }
} }
// 处理子菜单 // 处理子菜单
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {
routeItem.children = loopMenuItem(item.children, item.id); routeItem.children = loopMenuItem(item.children, item.id);
} }
return routeItem; return routeItem;
}); });
}; };