Merge remote-tracking branch 'origin/wuxichen' into wuxichen
Some checks failed
Auto Deploy / build-and-deploy (push) Has been cancelled

This commit is contained in:
2026-03-02 15:55:19 +08:00
11 changed files with 246 additions and 217 deletions

View File

@@ -35,7 +35,6 @@ function EnhancedProTable<T extends BaseRecord, U extends ParamsType = any>(
type={action.type} type={action.type}
danger={action.danger} danger={action.danger}
disabled={action.disabled} disabled={action.disabled}
// icon={action.icon ?? <PlusOutlined />}
onClick={() => action.onClick()} onClick={() => action.onClick()}
> >
{action.label} {action.label}
@@ -55,7 +54,6 @@ function EnhancedProTable<T extends BaseRecord, U extends ParamsType = any>(
toolBarRender={toolBarRender} toolBarRender={toolBarRender}
manualRequest={false} manualRequest={false}
showSorterTooltip showSorterTooltip
// scroll={{ x: "max-content" }}
scroll={scroll ? scroll : { x: 1200 }} scroll={scroll ? scroll : { x: 1200 }}
components={components} components={components}
search={ search={
@@ -83,7 +81,8 @@ function EnhancedProTable<T extends BaseRecord, U extends ParamsType = any>(
? { ? {
showSizeChanger: true, showSizeChanger: true,
showQuickJumper: true, showQuickJumper: true,
pageSize: 10, // pageSize: 10,
defaultPageSize: 10,
showTotal: formatPaginationTotal, showTotal: formatPaginationTotal,
} }
: false : false

View File

@@ -169,17 +169,7 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
id: tagsModalValue?.id, id: tagsModalValue?.id,
...value, ...value,
}); });
fetchTagsApi();
const newTag = currentGroup?.tags?.map((tag) => {
if (tag.id === tagsModalValue?.id) {
return { ...tag, tagName: value.tagName };
} else {
return tag;
}
});
const newGroup = { ...currentGroup, tags: newTag };
setCurrentGroup(newGroup as GroupItem);
} }
setVisible(false); setVisible(false);
message.success('修改成功'); message.success('修改成功');
@@ -195,7 +185,8 @@ const GroupTagCore: React.FC<GroupTagCoreProps> = (props) => {
setCurrentGroup(newGroups[0]); setCurrentGroup(newGroups[0]);
} }
} else { } else {
tagsApi.delete(id); await tagsApi.delete(id);
fetchTagsApi();
} }
}; };

View File

@@ -1,5 +1,6 @@
import { Form, Input, Modal, Select } from 'antd'; import { Form, Input, Modal, Select } from 'antd';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { getGroupListByYagId } from '@/services/ai/sample';
interface TagsModalProps { interface TagsModalProps {
visible: boolean; visible: boolean;
@@ -24,8 +25,19 @@ const TagsModal = (props: TagsModalProps) => {
const { value, visible, type, modalType, groups, onCancel, onConfirm } = const { value, visible, type, modalType, groups, onCancel, onConfirm } =
props; props;
const onGroupListByYagId = async (id: number) => {
const groupItem: { id?: number; groupName?: string }[] =
await getGroupListByYagId(id);
form.setFieldsValue({
groupIds: groupItem.map((item) => item.id),
});
};
useEffect(() => { useEffect(() => {
form.setFieldsValue(value); form.setFieldsValue(value);
console.log('value', value);
if (visible && type === 'tag' && value.id) {
onGroupListByYagId(value.id);
}
return () => { return () => {
form.resetFields(); form.resetFields();
setLoading(false); setLoading(false);
@@ -61,7 +73,7 @@ const TagsModal = (props: TagsModalProps) => {
wrapperCol={{ span: 20 }} wrapperCol={{ span: 20 }}
style={{ maxWidth: 600, marginTop: 30 }} style={{ maxWidth: 600, marginTop: 30 }}
> >
{type === 'tag' && modalType === 'add' && ( {type === 'tag' && (
<Form.Item <Form.Item
label="分组" label="分组"
name="groupIds" name="groupIds"

View File

@@ -1,5 +1,6 @@
.uploader-card { .uploader-card {
background-color: #fff; background-color: #fff;
padding: 10px;
:global { :global {
.ant-upload-drag { .ant-upload-drag {
background-color: #fff; background-color: #fff;

View File

@@ -5,7 +5,11 @@ import type {
} from '@ant-design/pro-components'; } from '@ant-design/pro-components';
import { Modal, message, Switch } from 'antd'; import { Modal, message, Switch } from 'antd';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { type AiModelRespVO, updateModelStatus } from '@/services/ai/model'; import {
type AiModelRespVO,
updateModel,
updateModelStatus,
} from '@/services/ai/model';
export const baseDeptColumns: ProColumns<AiModelRespVO>[] = [ export const baseDeptColumns: ProColumns<AiModelRespVO>[] = [
{ {
@@ -47,9 +51,9 @@ export const baseDeptColumns: ProColumns<AiModelRespVO>[] = [
}"类目吗?`, }"类目吗?`,
onOk: async () => { onOk: async () => {
console.log(checked); console.log(checked);
await updateModelStatus({ await updateModel({
...record,
status: checked ? 1 : 0, status: checked ? 1 : 0,
id: record.id,
}); });
message.success('修改成功'); message.success('修改成功');
action?.reload(); action?.reload();

View File

@@ -112,7 +112,7 @@ const ModelPage = () => {
columns={columns} columns={columns}
request={onFetch} request={onFetch}
toolbarActions={toolbarActions} toolbarActions={toolbarActions}
headerTitle="租户列表" headerTitle="模型管理"
showIndex={false} showIndex={false}
showSelection={false} showSelection={false}
search={false} search={false}

View File

@@ -72,7 +72,7 @@ export const baseTenantColumns: ProColumns<AiSampleRespVO>[] = [
}, },
}} }}
editable editable
placeholder="请选择技术栈" placeholder="请选择标签"
/> />
); );
}, },

View File

@@ -128,18 +128,6 @@ const SampleTagDetail = <T extends Record<string, any>>(
const handleDownloadAll = async () => { const handleDownloadAll = async () => {
const ids = data?.map((sample) => sample.id) as number[]; const ids = data?.map((sample) => sample.id) as number[];
downloadZipFile(ids); downloadZipFile(ids);
// const res = await downloadSample(ids);
// console.log(res);
// const downloadUrl = window.URL.createObjectURL(res);
// const link = document.createElement("a");
// link.href = downloadUrl;
// link.download = downloadUrl; // 设置下载的文件名
// link.style.display = "none";
// document.body.appendChild(link);
// link.click();
// document.body.removeChild(link);
// // const blob = new Blob([response.data], { type: 'application/pdf' });
// // const url = window.URL.createObjectURL(blob);
}; };
const handleTagManager = () => { const handleTagManager = () => {
@@ -187,165 +175,180 @@ const SampleTagDetail = <T extends Record<string, any>>(
}; };
return ( return (
<> <>
<ProForm name="validate_other" formRef={formRef} submitter={false}> {data!.length > 0 ? (
{type === 'radio' && ( <>
<ProFormGroup title="预览"> <ProForm name="validate_other" formRef={formRef} submitter={false}>
{data?.[0].sampleFilePath && ( {type === 'radio' && (
<audio <ProFormGroup title="预览">
controls {data?.[0].sampleFilePath && (
preload="true" <audio
crossOrigin="anonymous" controls
style={{ marginBottom: 24 }} preload="true"
> crossOrigin="anonymous"
<source src={data[0].sampleFilePath} /> style={{ marginBottom: 24 }}
<track kind="captions" /> >
</audio> <source src={data[0].sampleFilePath} />
<track kind="captions" />
</audio>
)}
</ProFormGroup>
)} )}
</ProFormGroup> <ProFormGroup title="基本信息">
)} {type === 'radio' && (
<ProFormGroup title="基本信息"> <ProFormText
{type === 'radio' && ( width="md"
<ProFormText name="sampleName"
width="md" placeholder="请输入样本名称"
name="sampleName" fieldProps={{
placeholder="请输入样本名称" onBlur: async (e) => {
fieldProps={{ if (e.target.value) {
onBlur: async (e) => { const newData =
if (e.target.value) { data?.map((sample) => {
const newData = return {
data?.map((sample) => { id: sample.id,
return { sampleName: e.target.value,
id: sample.id, };
sampleName: e.target.value, }) || [];
}; await updateSamples(newData);
}) || []; props?.onRefresh?.();
await updateSamples(newData); message.success('更新样本名称成功');
props?.onRefresh?.(); }
message.success('更新成功'); },
} }}
}, rules={[{ required: true, message: '样本名称不能为空' }]}
}} />
rules={[{ required: true, message: '样本名称不能为空' }]} )}
/> <ProFormText
)} width="md"
<ProFormText fieldProps={{
width="md" onBlur: async (e) => {
fieldProps={{ if (e.target.value) {
onBlur: async (e) => { const newData =
if (e.target.value) { data?.map((sample) => {
const newData = return {
data?.map((sample) => { id: sample.id,
return { remark: e.target.value,
id: sample.id, };
remark: e.target.value, }) || [];
}; await updateSamples(newData);
}) || []; props?.onRefresh?.();
await updateSamples(newData); message.success('更新注释成功');
props?.onRefresh?.(); }
} },
}}
name="remark"
placeholder="请输入注释"
/>
</ProFormGroup>
<ProFormGroup title="标签">
{/* <Form.Item name="tag"> */}
{forMap(value.tags || [])}
</ProFormGroup>
<Button
type="dashed"
block
style={{ marginBottom: 24 }}
onClick={handleAddTag}
>
</Button>
<ProFormGroup title="文本信息" block></ProFormGroup>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>
{dayjs(value.createTime).format('YYYY-MM-DD HH:mm:ss')}
</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span></span>
<span>
{dayjs(value.updateTime).format('YYYY-MM-DD HH:mm:ss')}
</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleSize}</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleMineType}</span>
</Space>
{type === 'checkbox' && (
<>
<ProFormGroup title="其他"></ProFormGroup>
<Button
block
style={{ marginBottom: 24 }}
onClick={handleTagManager}
>
</Button>
<Button
block
style={{ marginBottom: 24 }}
onClick={handleDownloadAll}
>
</Button>
<Button
block
color="danger"
style={{ marginBottom: 24 }}
onClick={handleDeleteAll}
>
</Button>
</>
)}
</ProForm>
<GroupTagModal
visible={modalVisible}
onCancel={() => setModalVisible(false)}
onChange={onListAddTag}
editable={false}
value={value?.tags}
request={{
groupsApi: {
get: getSampleTagGroup,
create: createSampleTagGroup,
delete: deleteSampleTagGroup,
update: updateSampleTagGroup,
},
tagsApi: {
get: getSampleTagPage,
create: createSampleTag,
delete: deleteSampleTag,
update: updateSampleTag,
}, },
}} }}
name="remark" title="管理技术标签"
placeholder="请输入注释" width={800}
height={500}
/> />
</ProFormGroup> <TagManager
visible={tagManagerVisible}
<ProFormGroup title="标签"> files={tagNames}
{/* <Form.Item name="tag"> */} onOk={onRename}
{forMap(value.tags || [])} onCancel={() => setTagManagerVisible(false)}
</ProFormGroup> ></TagManager>
<Button {type === 'radio' && (
type="dashed" <Space
block style={{ width: '100%', justifyContent: 'center', padding: 12 }}
style={{ marginBottom: 24 }}
onClick={handleAddTag}
>
</Button>
<ProFormGroup title="文本信息" block></ProFormGroup>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{dayjs(value.createTime).format('YYYY-MM-DD HH:mm:ss')}</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span></span>
<span>{dayjs(value.updateTime).format('YYYY-MM-DD HH:mm:ss')}</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleSize}</span>
</Space>
<Space size={10} style={{ width: '100%', marginBottom: 12 }}>
<span>: </span>
<span>{value.sampleMineType}</span>
</Space>
{type === 'checkbox' && (
<>
<ProFormGroup title="其他"></ProFormGroup>
<Button
block
style={{ marginBottom: 24 }}
onClick={handleTagManager}
> >
<Button color="danger" onClick={onDownload}>
</Button>
<Button </Button>
block <Button color="danger" variant="solid" onClick={handleDeleteAll}>
style={{ marginBottom: 24 }}
onClick={handleDownloadAll} </Button>
> </Space>
)}
</Button> </>
<Button ) : (
block '暂无数据-请选择样本'
color="danger" )}
style={{ marginBottom: 24 }}
onClick={handleDeleteAll}
>
</Button>
</>
)}
</ProForm>
<GroupTagModal
visible={modalVisible}
onCancel={() => setModalVisible(false)}
onChange={onListAddTag}
editable={false}
value={value?.tags}
request={{
groupsApi: {
get: getSampleTagGroup,
create: createSampleTagGroup,
delete: deleteSampleTagGroup,
update: updateSampleTagGroup,
},
tagsApi: {
get: getSampleTagPage,
create: createSampleTag,
delete: deleteSampleTag,
update: updateSampleTag,
},
}}
title="管理技术标签"
width={800}
height={500}
/>
<TagManager
visible={tagManagerVisible}
files={tagNames}
onOk={onRename}
onCancel={() => setTagManagerVisible(false)}
></TagManager>
<Space style={{ width: '100%', justifyContent: 'center', padding: 12 }}>
<Button color="danger" onClick={onDownload}>
</Button>
<Button color="danger" variant="solid" onClick={handleDeleteAll}>
</Button>
</Space>
</> </>
); );
}; };

View File

@@ -1,18 +1,28 @@
.tag-content { .tag-content {
display: flex;
background: #fff; background: #fff;
width: 100%; width: 100%;
overflow: auto; overflow: auto;
:global { :global {
.ant-pro-table { .left {
flex: 1 auto; padding-right: 385px;
} }
.uploader-card {
padding-right: 400px;
}
.detail { .detail {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-left: 1px solid #e8e8e8; border-left: 1px solid #e8e8e8;
border-top: 1px solid #e8e8e8;
width: 400px; width: 400px;
padding: 16px; padding: 16px;
top: 74px;
height: calc(100vh - 80px);
overflow: auto;
background: #fff;
position: fixed;
right: 0;
form { form {
flex: 1; flex: 1;
} }

View File

@@ -77,35 +77,37 @@ const SampleTag: React.FC = () => {
}; };
return ( return (
<> <>
<UploadCard onChange={onChangeVideo} />
<div className={styles['tag-content']}> <div className={styles['tag-content']}>
<EnhancedProTable<AiSampleRespVO> <div className="left">
ref={tableRef} <UploadCard onChange={onChangeVideo} />
columns={baseTenantColumns} <EnhancedProTable<AiSampleRespVO>
request={onFetch} ref={tableRef}
toolbarActions={toolbarActions} columns={baseTenantColumns}
headerTitle="样本列表" request={onFetch}
showIndex={false} toolbarActions={toolbarActions}
enableRowClick={true} headerTitle="样本列表"
scroll={{ x: 400 }} showIndex={false}
rowSelection={{ enableRowClick={true}
type: selectTableType, scroll={{ x: 400 }}
selectedRowKeys: selectedRows.map((item) => item.id) as React.Key[], rowSelection={{
onChange: (_, selectedRows) => { type: selectTableType,
setSelectedRows(selectedRows); selectedRowKeys: selectedRows.map(
}, (item) => item.id,
}} ) as React.Key[],
/> onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
/>
</div>
{selectedRows.length > 0 && ( <div className="detail">
<div className="detail"> <SampleTagDetail<AiSampleRespVO>
<SampleTagDetail<AiSampleRespVO> type={selectTableType}
type={selectTableType} data={selectedRows}
data={selectedRows} onRefresh={onRefresh}
onRefresh={onRefresh} />
/> </div>
</div>
)}
</div> </div>
<GroupTagModal <GroupTagModal
visible={modalVisible} visible={modalVisible}

View File

@@ -257,6 +257,13 @@ export const downloadSample = async (ids: number[]) => {
}); });
}; };
export const getGroupListByYagId = async (id: number) => {
return request("/ai/sampleTag/group-list-by-tag-id", {
method: "GET",
params: { tagId: id },
});
};
export async function downloadZipFile(ids: number[]) { export async function downloadZipFile(ids: number[]) {
try { try {
const response = await downloadSample(ids); const response = await downloadSample(ids);