diff --git a/web-fe/mock/images.ts b/web-fe/mock/images.ts
index c9e6f20..8a9b056 100644
--- a/web-fe/mock/images.ts
+++ b/web-fe/mock/images.ts
@@ -1,5 +1,5 @@
export default {
- 'POST /api/files/queryimagesList': (req: any, res: any) => {
+ 'POST /api/nex/v1/queryimagesList': (req: any, res: any) => {
const { page_size, page_num } = req.body;
const data = [];
function getRandomFormat() {
@@ -15,13 +15,15 @@ export default {
}
for (let i = 1; i <= page_size; i++) {
data.push({
- image_id: i,
- image_name: `周俊星${(page_num - 1) * page_size + i}`,
+ id: i,
+ image_name: `Win版 PR 2024 【支持win10、win11】.zip${
+ (page_num - 1) * page_size + i
+ }`,
image_type: getRandomFormat(),
bt_path: `/serve/logs`,
image_version: '1.0.0',
os_version: 'Ubuntu 20.04',
- image_status:Math.random() > 0.5 ? 1 : 2,
+ image_status: Math.random() > 0.5 ? 1 : 2,
storage_path: '/mock/images',
create_time: +new Date(),
});
@@ -30,11 +32,9 @@ export default {
code: '200',
message: '操作成功',
data: {
- paging: {
- total: 520,
- page_num: page_num,
- page_size: page_size,
- },
+ total: 520,
+ page_num: page_num,
+ page_size: page_size,
data: data,
},
};
diff --git a/web-fe/src/pages/images/components/modalShow/modalShow.tsx b/web-fe/src/pages/images/components/modalShow/modalShow.tsx
index 8c148eb..d77b773 100644
--- a/web-fe/src/pages/images/components/modalShow/modalShow.tsx
+++ b/web-fe/src/pages/images/components/modalShow/modalShow.tsx
@@ -1,9 +1,7 @@
-import { IMAGES_TYPE_MAP } from '@/constants/images.constants';
-import { uploadChunkAPI } from '@/services/images';
+import { uploadChunkAPI, cancelUploadImagesAPI } from '@/services/images';
import { Alert, Button, message, Modal, Progress, Upload } from 'antd';
import { UploadProps } from 'antd/lib/upload';
import React, { useEffect, useRef, useState } from 'react';
-import SparkMD5 from 'spark-md5';
import { v4 as uuidv4 } from 'uuid';
import {
IMAGE_DETAIL_FIELDS,
@@ -13,10 +11,10 @@ import {
import {
getChunkSize,
calculateMD5InChunks,
+ calculateMD5InChunksWorkers,
formatTime,
-} from '@/utils/images';
+} from '@/pages/images/utils/images';
-const { MAX_CONCURRENT, MAX_FILE_SIZE, ALLOWED_EXTENSIONS } = UPLOAD_CONFIG;
const { READY, UPLOADING, SUCCESS, ERROR } = UPLOAD_STATUS_MAP;
const { Dragger } = Upload;
@@ -77,8 +75,7 @@ const ImportModal: React.FC = ({
const fileSize = useRef(0); // 文件大小
const abortController = useRef(null); // 用于取消上传
// 上传镜像时间相关
- const [uploadStartTime, setUploadStartTime] = useState(null);
- const [elapsedTime, setElapsedTime] = useState(0);
+ const [elapsedTime, setElapsedTime] = useState(0); // 上传时间
const timerRef = useRef(null);
// 添加重置状态函数
@@ -95,7 +92,6 @@ const ImportModal: React.FC = ({
uploadQueue.current = [];
// 重置计时器
- setUploadStartTime(null);
setElapsedTime(0);
if (timerRef.current) {
clearInterval(timerRef.current);
@@ -123,8 +119,17 @@ const ImportModal: React.FC = ({
if (abortController.current?.signal.aborted) {
return false;
}
+
+ // 更新状态,提示正在计算MD5
+ // setUploadMessage(`正在计算第${index}个分片的MD5...`);
+
// 使用 spark-md5 计算当前分片的MD5
- const chunkMD5 = await calculateMD5InChunks(chunk, fileSize.current);
+ const chunkMD5 = await calculateMD5InChunks(
+ chunk,
+ fileSize.current,
+ );
+ // 更新状态,提示正在上传
+ // setUploadMessage(`正在上传第${index}个分片...`);
const formData = new FormData();
formData.append('file_id', fileId.current);
@@ -300,18 +305,17 @@ const ImportModal: React.FC = ({
setUploadProgress(0);
// 启动计时器
- const startTime = Date.now();
- setUploadStartTime(startTime);
setElapsedTime(0);
// 立即更新一次时间
- setElapsedTime(Math.floor((Date.now() - startTime) / 1000));
+ setElapsedTime(Math.floor((Date.now() - Date.now()) / 1000));
if (timerRef.current) {
clearInterval(timerRef.current);
}
timerRef.current = setInterval(() => {
- setElapsedTime(Math.floor((Date.now() - startTime) / 1000));
+ // 重新计算开始时间,基于当前时间和已用时间
+ setElapsedTime((prev) => prev + 1);
}, 1000);
// 初始化状态
@@ -389,10 +393,18 @@ const ImportModal: React.FC = ({
};
// 取消上传
- const cancelUpload = () => {
+ const cancelUpload = async() => {
if (abortController.current) {
abortController.current.abort();
}
+ // 如果有正在上传的文件,调用后端取消上传API
+ if (fileId.current) {
+ try {
+ await cancelUploadImagesAPI({ file_id: fileId.current });
+ } catch (error) {
+ console.error('取消上传API调用失败:', error);
+ }
+ }
setIsUploading(false);
setUploadStatus(READY);
setUploadMessage('上传已取消');
@@ -432,7 +444,7 @@ const ImportModal: React.FC = ({
// accept=".tar.gz,.iso,.qcow2"
>
-
⇧
+ ⇧
点击选择文件或拖拽文件到此区域上传
diff --git a/web-fe/src/pages/images/hook/hook.ts b/web-fe/src/pages/images/hook/hook.ts
new file mode 100644
index 0000000..0842756
--- /dev/null
+++ b/web-fe/src/pages/images/hook/hook.ts
@@ -0,0 +1,112 @@
+import type { TableProps } from 'antd';
+import { useCallback, useState } from 'react';
+
+const useTableParams = (
+ initialParams: IMAGES.TableParams = {
+ pagination: { current: 1, pageSize: 10 },
+ filters: {},
+ sort: {},
+ },
+) => {
+ const [tableParams, setTableParams] =
+ useState(initialParams);
+
+ const getApiParams = useCallback(() => {
+ console.log('getApiParams', tableParams);
+
+ const { pagination, filters, sort, ...rest } = tableParams;
+ const apiParams: Record = {
+ page_size: pagination?.pageSize,
+ page_num: pagination?.current,
+ ...rest,
+ };
+
+ if (sort?.field) {
+ apiParams.orderby = sort.field;
+ apiParams.order = sort.order === 'ascend' ? 'asc' : 'desc';
+ }
+
+ Object.entries(filters || {}).forEach(([key, value]) => {
+ if (value !== undefined && value !== null) {
+ apiParams[key] = value;
+ }
+ });
+
+ console.log('getApiParams apiParams', apiParams);
+ return apiParams;
+ }, [tableParams]);
+
+ const updateParams = useCallback((newParams: Partial) => {
+ console.log('updateParams', newParams);
+ setTableParams((prev) => ({
+ ...prev,
+ ...newParams,
+ pagination: {
+ ...prev.pagination,
+ ...newParams.pagination,
+ },
+ }));
+ }, []);
+
+ /**
+ * 处理表格的分页、排序、过滤等变化
+ * @param pagination 分页信息
+ * @param filters 过滤条件 这里面直接将filters为空的条件过滤掉
+ * @param sorter 排序信息
+ * @param extra 其他信息
+ * @returns void
+ * */
+ const handleTableChange = useCallback<
+ NonNullable['onChange']>
+ >(
+ (pagination, filters, sorter, extra) => {
+ // 过滤掉空值的filters
+ const filteredFilters: Record = {};
+ Object.entries(filters || {}).forEach(([key, value]) => {
+ if (key === 'image_type') {
+ if (Array.isArray(value) && value.length > 0 && value[0] !== '全部') {
+ filteredFilters[key] = Number(value[0]);
+ }
+ } else {
+ if (Array.isArray(value) && value.length > 0) {
+ filteredFilters[key] = value[0];
+ } else if (value !== undefined && value !== null) {
+ if (!Array.isArray(value) && value !== '') {
+ filteredFilters[key] = value;
+ }
+ }
+ }
+ });
+ const newParams: Partial = {
+ pagination: {
+ current: pagination.current || 1,
+ pageSize: pagination.pageSize || 10,
+ },
+ filters: filteredFilters,
+ };
+
+ if (!Array.isArray(sorter)) {
+ newParams.sort = {
+ field: sorter.field as string,
+ order:
+ sorter.order === 'ascend' || sorter.order === 'descend'
+ ? sorter.order
+ : undefined,
+ };
+ }
+ console.log('handleTableChange', newParams);
+
+ updateParams(newParams);
+ },
+ [updateParams],
+ );
+
+ return {
+ tableParams,
+ getApiParams,
+ updateParams,
+ handleTableChange,
+ };
+};
+
+export default useTableParams;
diff --git a/web-fe/src/pages/images/index.less b/web-fe/src/pages/images/index.less
index 9194601..4a0140e 100644
--- a/web-fe/src/pages/images/index.less
+++ b/web-fe/src/pages/images/index.less
@@ -36,48 +36,55 @@
flex-direction: column;
overflow: hidden;
.images-list-table {
- display: flex;
- flex: 1;
- overflow: hidden;
- }
- }
- // 表格适应样式
- .ant-table-wrapper {
- flex: 1;
- display: flex;
- flex-direction: column;
- overflow: hidden;
-
- .ant-spin-nested-loading {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
-
- .ant-spin-container {
- flex: 1;
+ // 表格适应样式
+ .ant-table-wrapper {
display: flex;
flex-direction: column;
- overflow: hidden;
+ flex: 1;
+ overflow: hidden;
- .ant-table {
+ .ant-spin-nested-loading {
flex: 1;
display: flex;
flex-direction: column;
- overflow: hidden;
+ overflow: hidden;
- .ant-table-container {
+ .ant-spin-container {
flex: 1;
display: flex;
flex-direction: column;
- overflow: hidden;
+ overflow: hidden;
- .ant-table-body {
+ .ant-table {
+ display: flex;
+ flex-direction: column;
flex: 1;
- overflow-y: auto !important;
+ overflow: hidden;
- table {
- height: 100%;
+ .ant-table-container {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ overflow: hidden;
+ .ant-table-header {
+ flex-shrink: 0;
+ }
+ .ant-table-body {
+ flex: 1;
+ overflow: auto !important;
+
+ }
+ }
+ // 确保分页器在底部正确显示
+ .ant-table-pagination {
+ flex-shrink: 0;
+ // 确保分页器始终可见
+ position: relative;
+ z-index: 1;
}
}
}
@@ -85,6 +92,7 @@
}
}
}
+
.image-detail {
.detail-item {
margin-bottom: 16px;
diff --git a/web-fe/src/pages/images/index.tsx b/web-fe/src/pages/images/index.tsx
index 7885900..a3a55f2 100644
--- a/web-fe/src/pages/images/index.tsx
+++ b/web-fe/src/pages/images/index.tsx
@@ -1,12 +1,10 @@
import { CODE, IMAGES_TYPE_MAP } from '@/constants/images.constants';
-import { getImagesList } from '@/services/images';
+import { delImagesAPI, getImagesList } from '@/services/images';
import {
DeleteOutlined,
EyeOutlined,
SettingOutlined,
} from '@ant-design/icons';
-import type { TableProps } from 'antd';
-import dayjs from 'dayjs';
import {
Button,
Checkbox,
@@ -17,11 +15,13 @@ import {
Popover,
Space,
Table,
- Tooltip,
Tag,
+ Tooltip,
} from 'antd';
-import React, { useEffect, useState } from 'react';
+import dayjs from 'dayjs';
+import React, { useCallback, useEffect, useRef, useState } from 'react';
import { ImportModal, ModalDetailShow } from './components/modalShow/modalShow';
+import useTableParams from './hook/hook';
import './index.less';
import { ReactComponent as RefreshIcon } from '@/assets/icons/refresh.svg';
@@ -36,6 +36,10 @@ type ColumnConfig = {
fixed?: 'left' | 'right';
defaultVisible: boolean; // 默认是否显示
alwaysVisible?: boolean; // 始终显示的列
+ filters?: { text: string; value: string }[];
+ filterMultiple?: boolean; // 是否多选过滤
+ defaultFilteredValue?: string[]; // 默认过滤值
+ onFilter?: (value: string, record: any) => boolean;
};
type TableColumn = {
@@ -48,21 +52,37 @@ type TableColumn = {
hidden?: boolean;
};
+// 在组件顶部添加防抖函数
+const debounce = (func: Function, delay: number) => {
+ let timer: NodeJS.Timeout;
+ return (...args: any[]) => {
+ clearTimeout(timer);
+ timer = setTimeout(() => func(...args), delay);
+ };
+};
+
const ImageList: React.FC = () => {
const [images, setImages] = useState([]);
const [loading, setLoading] = useState(false);
const [selectedImage, setSelectedImage] = useState(
null,
);
- const [searchText, setSearchText] = useState('');
const [detailVisible, setDetailVisible] = useState(false);
const [importModalVisible, setImportModalVisible] = useState(false);
- const [tableParams, setTableParams] = useState({
- pagination: {
- current: 1,
- pageSize: 10,
- },
- });
+ const [searchText, setSearchText] = useState(''); // 添加本地搜索状态
+ const searchInputRef = useRef(''); // 保存已发送请求的搜索文本
+
+ const { tableParams, getApiParams, updateParams, handleTableChange } =
+ useTableParams({
+ pagination: {
+ current: 1,
+ pageSize: 10,
+ },
+ });
+
+ // 在组件顶部添加一个 ref 来保存最新的 tableParams
+ const tableParamsRef = useRef(tableParams);
+ tableParamsRef.current = tableParams; // 每次渲染时更新 ref 的值
const [columnSettingsVisible, setColumnSettingsVisible] = useState(false);
@@ -75,7 +95,6 @@ const ImageList: React.FC = () => {
tableParams?.sortOrder,
tableParams?.sortField,
JSON.stringify(tableParams.filters),
- JSON.stringify(tableParams.image_name),
]);
// 定义所有列的配置
@@ -83,7 +102,7 @@ const ImageList: React.FC = () => {
{
key: 'index',
title: '序号',
- width: 120,
+ width: 60,
render: (text: any, row: any, index: number) =>
(tableParams.pagination?.current - 1) *
tableParams.pagination?.pageSize +
@@ -96,20 +115,52 @@ const ImageList: React.FC = () => {
key: 'image_name',
title: '镜像名称',
dataIndex: 'image_name',
- width: 120,
+ width: 200,
defaultVisible: true,
alwaysVisible: true,
+ render: (text: string) => (
+
+
+ {text || '--'}
+
+
+ ),
},
{
key: 'image_type',
title: '桌面类型',
dataIndex: 'image_type',
- width: 80,
+ width: 100,
render: (text: number) => {
const key = text as keyof typeof IMAGES_TYPE_MAP;
return {IMAGES_TYPE_MAP[key] || '--'};
},
defaultVisible: true,
+ filters: [
+ { text: '全部', value: '全部' },
+ ...Object.entries(IMAGES_TYPE_MAP).map(([key, value]) => ({
+ text: value,
+ value: key, // 保持 key 为字符串
+ })),
+ ],
+ filterMultiple: false,
+ defaultFilteredValue: ['全部'],
+ // onFilter: (value, record) => {
+ // // 当选择"全部"时显示所有记录
+ // if (value === '全部') {
+ // return true;
+ // }
+ // // 比较时将字符串 value 转换为数字
+ // return record.image_type === Number(value);
+ // },
},
{
key: 'storage_path',
@@ -205,70 +256,31 @@ const ImageList: React.FC = () => {
setVisibleColumns(initialVisibleColumns);
};
- /**
- * 表格参数转换
- * @param params - 表格参数对象,包含分页、过滤、排序等信息
- * @returns 转换后的接口参数对象
- */
- const getRandomuserParams = (params: IMAGES.TableParams) => {
- const {
- pagination,
- filters,
- sortField,
- sortOrder,
- image_name,
- ...restParams
- } = params;
- const result: Record = {};
-
- result.page_size = pagination?.pageSize;
- result.page_num = pagination?.current;
-
- if (image_name) {
- result.image_name = image_name;
- }
-
- if (filters) {
- Object.entries(filters).forEach(([key, value]) => {
- if (value !== undefined && value !== null) {
- result[key] = value;
- }
- });
- }
-
- if (sortField) {
- result.orderby = sortField;
- result.order = sortOrder === 'ascend' ? 'asc' : 'desc';
- }
-
- // 处理其他参数
- Object.entries(restParams).forEach(([key, value]) => {
- if (value !== undefined && value !== null) {
- result[key] = value;
- }
- });
-
- return result;
- };
- const params = getRandomuserParams(tableParams);
-
const loadImages = async () => {
setLoading(true);
try {
- const imagesRes = await getImagesList(params);
+ // 将搜索文本合并到API参数中
+ const apiParams = {
+ ...getApiParams(),
+ };
+ if (searchInputRef.current) {
+ apiParams.image_name = searchInputRef.current;
+ }
+ const imagesRes = await getImagesList(apiParams);
if (imagesRes.code == CODE) {
- setImages(imagesRes.data.data || []);
+ setImages(imagesRes.data?.data || []);
setLoading(false);
- // 直接使用后端返回的分页信息
- setTableParams((prev) => ({
- ...prev,
+ console.log('imagesRes', imagesRes);
+
+ // 正确处理后端返回的分页信息
+ updateParams({
pagination: {
- ...prev.pagination,
- current: imagesRes.data.paging.page_num || 1,
- total: imagesRes.data.paging.total || 0,
- pageSize: imagesRes.data.paging.page_size || 10,
+ ...tableParams.pagination,
+ current: imagesRes.data?.page_num || 1,
+ total: imagesRes.data?.total || 0,
+ pageSize: tableParams.pagination.pageSize|| 10,
},
- }));
+ });
} else {
message.error(imagesRes.message || '获取镜像列表失败');
setLoading(false);
@@ -297,9 +309,14 @@ const ImageList: React.FC = () => {
title: '确认删除',
content: `确定要删除镜像 "${record.image_name}" 吗?`,
onOk: () => {
- // TODO: 调用删除接口
- setImages(images.filter((img) => img.image_id !== record.image_id));
- message.success('删除成功');
+ delImagesAPI(record.id).then((res) => {
+ if (res.code == CODE) {
+ message.success('删除成功');
+ loadImages();
+ } else {
+ message.error(res.message || '删除失败');
+ }
+ });
},
});
};
@@ -347,52 +364,19 @@ const ImageList: React.FC = () => {
// 对于始终显示的列
if (config.alwaysVisible) {
return {
- title: config.title,
- dataIndex: config.dataIndex,
- key: config.key,
- width: config.width,
- render: config.render,
- fixed: config.fixed,
+ ...config,
hidden: undefined,
};
}
// 对于可控制显示/隐藏的列
return {
- title: config.title,
- dataIndex: config.dataIndex,
- key: config.key,
- width: config.width,
- render: config.render,
- fixed: config.fixed,
+ ...config,
...(visibleColumns[config.key] ? {} : { hidden: true }),
};
})
.filter((column) => !column.hidden) as TableColumn[];
- // 处理表格分页、过滤和排序变化
- const handleTableChange: TableProps['onChange'] = (
- pagination,
- filters,
- sorter,
- ) => {
- setTableParams({
- pagination: {
- current: pagination.current || 1,
- pageSize: pagination.pageSize || 10,
- },
- filters,
- sortOrder: Array.isArray(sorter) ? undefined : sorter.order,
- sortField: Array.isArray(sorter)
- ? undefined
- : (sorter.field as string | number | undefined),
- });
-
- if (pagination.pageSize !== tableParams.pagination?.pageSize) {
- setImages([]);
- }
- };
-
const handleRefresh = () => {
loadImages();
};
@@ -413,6 +397,33 @@ const ImageList: React.FC = () => {
pageSizeOptions: ['10', '20', '50', '100'],
};
+ const handleSearch = useCallback(
+ (searchValue: string) => {
+ console.log('handleSearch', searchValue, tableParams);
+
+ // 使用 ref 中的最新值
+ const currentTableParams = tableParamsRef.current;
+
+ // 只有当搜索值变化时才更新参数和触发请求
+ if (searchInputRef.current !== searchValue) {
+ searchInputRef.current = searchValue;
+ updateParams({
+ pagination: {
+ current: 1,
+ pageSize: currentTableParams.pagination?.pageSize || 10,
+ },
+ filters: {
+ ...currentTableParams.filters,
+ image_name: searchValue ? searchValue : undefined,
+ },
+ });
+ }
+ },
+ [updateParams],
+ );
+
+ const debouncedSearch = useRef(debounce(handleSearch, 500)).current;
+
return (
@@ -421,18 +432,18 @@ const ImageList: React.FC = () => {
setSearchText(e.target.value)}
- style={{ width: 300 }}
- onSearch={(value) => {
- setTableParams((prev) => ({
- ...prev,
- pagination: {
- ...prev.pagination,
- current: 1,
- },
- image_name: value,
- }));
+ onChange={(e) => {
+ const value = e.target.value;
+ setSearchText(value);
+ // 只有当输入为空时立即触发搜索,否则使用防抖
+ if (value === '') {
+ handleSearch('');
+ } else {
+ debouncedSearch(value);
+ }
}}
+ style={{ width: 300 }}
+ onSearch={handleSearch}
/>
diff --git a/web-fe/src/utils/images.ts b/web-fe/src/pages/images/utils/images.ts
similarity index 74%
rename from web-fe/src/utils/images.ts
rename to web-fe/src/pages/images/utils/images.ts
index f89e2cc..b269dd3 100644
--- a/web-fe/src/utils/images.ts
+++ b/web-fe/src/pages/images/utils/images.ts
@@ -43,41 +43,45 @@ export const getMD5ChunkSize = (fileSize: number): number => {
export const calculateMD5InChunks = (
file: Blob,
fileSize: number,
- chunkSize: number = getMD5ChunkSize(fileSize)
+ chunkSize: number = getMD5ChunkSize(fileSize),
): Promise => {
return new Promise((resolve, reject) => {
const spark = new SparkMD5.ArrayBuffer();
- const fileReader = new FileReader();
let currentChunk = 0;
const chunks = Math.ceil(file.size / chunkSize);
- fileReader.onload = (e) => {
- try {
- spark.append(e.target?.result as ArrayBuffer);
- currentChunk++;
-
- if (currentChunk < chunks) {
- loadNext();
- } else {
- const hash = spark.end();
- spark.destroy(); // 释放内存
- resolve(hash);
- }
- } catch (error) {
- spark.destroy();
- reject(error);
- }
- };
-
- fileReader.onerror = () => {
- spark.destroy();
- reject(new Error('计算MD5失败'));
- };
-
const loadNext = () => {
const start = currentChunk * chunkSize;
const end = Math.min(start + chunkSize, file.size);
- fileReader.readAsArrayBuffer(file.slice(start, end));
+ const chunk = file.slice(start, end);
+
+ const reader = new FileReader();
+
+ reader.onload = (e) => {
+ try {
+ spark.append(e.target?.result as ArrayBuffer);
+ currentChunk++;
+
+ if (currentChunk < chunks) {
+ // 使用 setTimeout 让出主线程,避免长时间阻塞
+ setTimeout(loadNext, 1);
+ } else {
+ const hash = spark.end();
+ spark.destroy(); // 释放内存
+ resolve(hash);
+ }
+ } catch (error) {
+ spark.destroy();
+ reject(error);
+ }
+ };
+
+ reader.onerror = () => {
+ spark.destroy();
+ reject(new Error('计算MD5失败'));
+ };
+
+ reader.readAsArrayBuffer(chunk);
};
loadNext();
diff --git a/web-fe/src/services/images.ts b/web-fe/src/services/images.ts
index 39d2f54..7c87ca7 100644
--- a/web-fe/src/services/images.ts
+++ b/web-fe/src/services/images.ts
@@ -1,26 +1,38 @@
import { request } from '@umijs/max';
-const BASE_URL = '/api/files';
+const BASE_URL_FILE = '/api/files';
+const BASE_URL = '/api/nex/v1';
-// 根据终端序列号查询镜像列表
+// 查询镜像列表
export async function getImagesList(params:any) {
- // console.log('镜像列表 params', params);
- return request(`${BASE_URL}/queryimagesList`, {
+ // return request(`${BASE_URL}/queryimagesList`, {
+ return request(`${BASE_URL}/image/select/page`, {
method: 'POST',
- // headers: {
- // 'Content-Type': 'application/json',
- // },
data: params,
});
}
-export async function uploadChunkAPI(formData: FormData, signal?: AbortSignal) {
- console.log('formData', formData);
-
- // return request(`/api/v1/images/file/chunk/upload`, {
- return request(`${BASE_URL}/upload-chunk`, {
+// 删除镜像
+export async function delImagesAPI(params:any) {
+ return request(`${BASE_URL}/image/delete`, {
method: 'POST',
- data: formData,
- signal, // 添加 signal 支持
+ data: params,
+ });
+}
+
+// 上传镜像
+export async function uploadChunkAPI(formData: FormData, signal?: AbortSignal) {
+ return request(`${BASE_URL_FILE}/upload-chunk`, {
+ method: 'POST',
+ data: formData,
+ signal, // 添加 signal 支持
+ });
+}
+
+// 取消上传:调用后端,删除已上传的分片
+export async function cancelUploadImagesAPI(params:any) {
+ return request(`${BASE_URL_FILE}/cancel/upload`, {
+ method: 'POST',
+ data: params,
});
}
\ No newline at end of file
diff --git a/web-fe/src/types/images.d.ts b/web-fe/src/types/images.d.ts
index c988857..7607fc8 100644
--- a/web-fe/src/types/images.d.ts
+++ b/web-fe/src/types/images.d.ts
@@ -1,7 +1,6 @@
-
declare namespace IMAGES {
interface ImageItem {
- image_id: number;
+ id: number;
image_name: string;
image_type: number;
storage_path: string;
@@ -21,11 +20,17 @@ declare namespace IMAGES {
pagination: {
current: number;
pageSize: number;
+ total?: number;
};
+ image_name?: string;
+ image_type?: number | string; // 修改为联合类型
filters?: Record;
+ sort?: {
+ field?: string;
+ order?: 'ascend' | 'descend';
+ };
sortOrder?: 'ascend' | 'descend' | null;
sortField?: string | number | null;
- image_name?: string; // 添加关键词字段
image_status?: string;
}
@@ -33,11 +38,9 @@ declare namespace IMAGES {
code: string;
message: string;
data: {
- paging: {
- total: number;
- page_num: number;
- page_size: number;
- };
+ total: number;
+ page_num: number;
+ page_size: number;
data: ImageItem[];
};
}