fix: 样本管理
This commit is contained in:
@@ -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 修改样式
|
||||||
// 设置内容区域的边距
|
// 设置内容区域的边距
|
||||||
|
|||||||
21
src/app.tsx
21
src/app.tsx
@@ -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 />;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 || '上传失败');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user