|
@@ -8,13 +8,14 @@ import {
|
|
Table,
|
|
Table,
|
|
Input,
|
|
Input,
|
|
InputRef,
|
|
InputRef,
|
|
|
|
+ Spin,
|
|
} from "antd";
|
|
} from "antd";
|
|
import React, { useEffect, useState, useRef } from "react";
|
|
import React, { useEffect, useState, useRef } from "react";
|
|
import { SearchOutlined, FolderOpenOutlined } from "@ant-design/icons";
|
|
import { SearchOutlined, FolderOpenOutlined } from "@ant-design/icons";
|
|
import {
|
|
import {
|
|
message as tauriMessage,
|
|
message as tauriMessage,
|
|
save as dialogSave,
|
|
save as dialogSave,
|
|
- open as dialogopen,
|
|
|
|
|
|
+ open as dialogOpen,
|
|
} from "@tauri-apps/api/dialog";
|
|
} from "@tauri-apps/api/dialog";
|
|
import { insertSearchFilesPasamsType } from "@/types/files";
|
|
import { insertSearchFilesPasamsType } from "@/types/files";
|
|
import dayjs from "dayjs";
|
|
import dayjs from "dayjs";
|
|
@@ -42,8 +43,7 @@ export default function CalculateListPage() {
|
|
const location = useLocation();
|
|
const location = useLocation();
|
|
const searchInput = useRef<InputRef>(null as any);
|
|
const searchInput = useRef<InputRef>(null as any);
|
|
const [data, setData] = useState<FileItem[]>([]);
|
|
const [data, setData] = useState<FileItem[]>([]);
|
|
- const [loading, setLoading] = useState<boolean>(false);
|
|
|
|
- // const [tip, setTip] = useState<string>('');
|
|
|
|
|
|
+ const [loading, setLoading] = useState<boolean>(true);
|
|
const [removeList, setRemoveList] = useState<string[]>([]);
|
|
const [removeList, setRemoveList] = useState<string[]>([]);
|
|
const [page, setPage] = useState(1);
|
|
const [page, setPage] = useState(1);
|
|
const [total, setTotal] = useState(0);
|
|
const [total, setTotal] = useState(0);
|
|
@@ -54,7 +54,9 @@ export default function CalculateListPage() {
|
|
const [searchText, setSearchText] = useState<any>({});
|
|
const [searchText, setSearchText] = useState<any>({});
|
|
const [isCancelled, setIsCancelled] = useState(false); // 离开页面时终止正在执行的逻辑
|
|
const [isCancelled, setIsCancelled] = useState(false); // 离开页面时终止正在执行的逻辑
|
|
const [hasMounted, setHasMounted] = useState(false);
|
|
const [hasMounted, setHasMounted] = useState(false);
|
|
-
|
|
|
|
|
|
+ const [spinTip, setSpinTip] = useState("");
|
|
|
|
+ //
|
|
|
|
+ const [settimeStart, setSettimeStart] = useState<NodeJS.Timeout>();
|
|
interface FileItem {
|
|
interface FileItem {
|
|
sourceId: number;
|
|
sourceId: number;
|
|
ids: string;
|
|
ids: string;
|
|
@@ -65,7 +67,43 @@ export default function CalculateListPage() {
|
|
children: insertSearchFilesPasamsType[];
|
|
children: insertSearchFilesPasamsType[];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ appendData();
|
|
|
|
+ }, []);
|
|
|
|
+
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ if (hasMounted) {
|
|
|
|
+ getFileList();
|
|
|
|
+ } else {
|
|
|
|
+ const startTime: NodeJS.Timeout = setTimeout(() => {
|
|
|
|
+ getFileList();
|
|
|
|
+ }, 5000);
|
|
|
|
+ setSettimeStart(startTime);
|
|
|
|
+ }
|
|
|
|
+ }, [page, pageSize, sorterColumnKey, sorterOrder]);
|
|
|
|
+
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ // 设置一个状态标志,表示组件已经挂载
|
|
|
|
+ setHasMounted(true);
|
|
|
|
+ }, 1000);
|
|
|
|
+ // 如果你需要在组件卸载时进行清理,可以在这里返回一个函数
|
|
|
|
+ // 当组件加载时,不做特殊操作
|
|
|
|
+ // 只在组件卸载时设置isCancelled为true
|
|
|
|
+ return () => {
|
|
|
|
+ if (hasMounted) {
|
|
|
|
+ console.log(47, " 当组件卸载时,设置isCancelled为true");
|
|
|
|
+ setIsCancelled(true);
|
|
|
|
+ stopStartFn();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ }, [hasMounted]);
|
|
|
|
+
|
|
|
|
+ function stopStartFn() {
|
|
|
|
+ clearTimeout(settimeStart);
|
|
|
|
+ }
|
|
async function getFileList() {
|
|
async function getFileList() {
|
|
|
|
+ stopStartFn();
|
|
setLoading(true);
|
|
setLoading(true);
|
|
try {
|
|
try {
|
|
const sorters = Object.keys(sorterColumnKey).map((key) => ({
|
|
const sorters = Object.keys(sorterColumnKey).map((key) => ({
|
|
@@ -97,12 +135,15 @@ export default function CalculateListPage() {
|
|
const newData = await processFiles(res.data, fileId);
|
|
const newData = await processFiles(res.data, fileId);
|
|
|
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
|
|
+ console.log(100, newData);
|
|
setData(newData);
|
|
setData(newData);
|
|
|
|
+ setSpinTip("");
|
|
setLoading(false);
|
|
setLoading(false);
|
|
}, 300);
|
|
}, 300);
|
|
} catch (error) {
|
|
} catch (error) {
|
|
console.error("Error loading file list:", error);
|
|
console.error("Error loading file list:", error);
|
|
setData([]);
|
|
setData([]);
|
|
|
|
+ setSpinTip("");
|
|
setLoading(false);
|
|
setLoading(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -111,13 +152,16 @@ export default function CalculateListPage() {
|
|
data: string | any[],
|
|
data: string | any[],
|
|
fileId: string | undefined,
|
|
fileId: string | undefined,
|
|
) {
|
|
) {
|
|
- if (!Array.isArray(data) || !data.length) {
|
|
|
|
|
|
+ if (!data || !Array.isArray(data) || !data?.length) {
|
|
return [];
|
|
return [];
|
|
}
|
|
}
|
|
const results = [];
|
|
const results = [];
|
|
for (const file of data) {
|
|
for (const file of data) {
|
|
const otherItems = await Promise.allSettled(
|
|
const otherItems = await Promise.allSettled(
|
|
- file.ids.split(",").map((id: string) => get_fileInfo_by_id(id, fileId)),
|
|
|
|
|
|
+ file.ids
|
|
|
|
+ .split(",")
|
|
|
|
+ .filter((elm: any, index: any) => index)
|
|
|
|
+ .map((id: string) => get_fileInfo_by_id(id, fileId)),
|
|
);
|
|
);
|
|
results.push({
|
|
results.push({
|
|
...file,
|
|
...file,
|
|
@@ -149,76 +193,60 @@ export default function CalculateListPage() {
|
|
type: "error",
|
|
type: "error",
|
|
}));
|
|
}));
|
|
}
|
|
}
|
|
|
|
+ if (
|
|
|
|
+ !searchDuplicateFileRes ||
|
|
|
|
+ !Array.isArray(searchDuplicateFileRes) ||
|
|
|
|
+ !searchDuplicateFileRes.length
|
|
|
|
+ ) {
|
|
|
|
+ // 执行可分页的接口数据请求
|
|
|
|
+ await getFileList();
|
|
|
|
+ setLoading(false);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
/**
|
|
/**
|
|
* count: 2
|
|
* count: 2
|
|
* hash: "fdd8051fcf884d8cc9a095cd77a58694e13b066aea68dc1fc353767ab0ebfe01"
|
|
* hash: "fdd8051fcf884d8cc9a095cd77a58694e13b066aea68dc1fc353767ab0ebfe01"
|
|
* ids: "25494,26393"
|
|
* ids: "25494,26393"
|
|
* sourceId: 6
|
|
* sourceId: 6
|
|
* */
|
|
* */
|
|
- if (Array.isArray(searchDuplicateFileRes)) {
|
|
|
|
- let index = -1;
|
|
|
|
- await searchDuplicateFileRes.reduce(
|
|
|
|
- async (prevPromise: any, currentFile: any) => {
|
|
|
|
- // 等待上一个 Promise 完成
|
|
|
|
- await prevPromise;
|
|
|
|
- if (
|
|
|
|
- isCancelled ||
|
|
|
|
- window.location.href.indexOf(location.pathname) < 0
|
|
|
|
- ) {
|
|
|
|
- // @ts-ignore
|
|
|
|
- throw "提前终止";
|
|
|
|
- return Promise.resolve(0);
|
|
|
|
- } // 如果设置了取消标志,则提前终止
|
|
|
|
- index++;
|
|
|
|
- const ids = currentFile.ids.split(",");
|
|
|
|
- const firstItem = await get_fileInfo_by_id(ids[0], `${fileId}`);
|
|
|
|
- try {
|
|
|
|
- // 写到本地的数据库中
|
|
|
|
- await setDuplicateFile(`${fileId}`, {
|
|
|
|
- ...firstItem[0],
|
|
|
|
- ids: currentFile.ids,
|
|
|
|
- });
|
|
|
|
- } catch (err) {
|
|
|
|
- console.log(109, err);
|
|
|
|
- }
|
|
|
|
- // setTip(`正在统计中: ${Math.floor((index / searchDuplicateFileRes.length) * 100)}% : ${searchDuplicateFileRes.length - index}`);
|
|
|
|
|
|
+ setLoading(true);
|
|
|
|
+ let index = -1;
|
|
|
|
+ await searchDuplicateFileRes.reduce(
|
|
|
|
+ async (prevPromise: any, currentFile: any) => {
|
|
|
|
+ // 等待上一个 Promise 完成
|
|
|
|
+ await prevPromise;
|
|
|
|
+ if (
|
|
|
|
+ isCancelled ||
|
|
|
|
+ window.location.href.indexOf(location.pathname) < 0
|
|
|
|
+ ) {
|
|
|
|
+ // @ts-ignore
|
|
|
|
+ throw "提前终止";
|
|
return Promise.resolve(0);
|
|
return Promise.resolve(0);
|
|
- },
|
|
|
|
- Promise.resolve(0),
|
|
|
|
- );
|
|
|
|
- // 执行可分页的接口数据请求
|
|
|
|
- await getFileList();
|
|
|
|
- } else {
|
|
|
|
- setLoading(false);
|
|
|
|
- // setTip('')
|
|
|
|
- }
|
|
|
|
|
|
+ } // 如果设置了取消标志,则提前终止
|
|
|
|
+ index++;
|
|
|
|
+ const ids = currentFile.ids.split(",");
|
|
|
|
+ const firstItem = await get_fileInfo_by_id(ids[0], `${fileId}`);
|
|
|
|
+ try {
|
|
|
|
+ // 写到本地的数据库中
|
|
|
|
+ await setDuplicateFile(`${fileId}`, {
|
|
|
|
+ ...firstItem[0],
|
|
|
|
+ ids: currentFile.ids,
|
|
|
|
+ idsNum: ids.length,
|
|
|
|
+ });
|
|
|
|
+ } catch (err) {
|
|
|
|
+ console.log(199, err);
|
|
|
|
+ }
|
|
|
|
+ setSpinTip(
|
|
|
|
+ `进度: ${Math.floor((index / searchDuplicateFileRes.length) * 100)}% / 剩余 ${searchDuplicateFileRes.length - index} 个文件`,
|
|
|
|
+ );
|
|
|
|
+ return Promise.resolve(0);
|
|
|
|
+ },
|
|
|
|
+ Promise.resolve(0),
|
|
|
|
+ );
|
|
|
|
+ // 执行可分页的接口数据请求
|
|
|
|
+ await getFileList();
|
|
};
|
|
};
|
|
|
|
|
|
- useEffect(() => {
|
|
|
|
- appendData();
|
|
|
|
- }, []);
|
|
|
|
-
|
|
|
|
- useEffect(() => {
|
|
|
|
- setTimeout(() => {
|
|
|
|
- // 设置一个状态标志,表示组件已经挂载
|
|
|
|
- setHasMounted(true);
|
|
|
|
- }, 300);
|
|
|
|
- // 如果你需要在组件卸载时进行清理,可以在这里返回一个函数
|
|
|
|
- // 当组件加载时,不做特殊操作
|
|
|
|
- // 只在组件卸载时设置isCancelled为true
|
|
|
|
- return () => {
|
|
|
|
- if (hasMounted) {
|
|
|
|
- console.log(47, " 当组件卸载时,设置isCancelled为true");
|
|
|
|
- setIsCancelled(true);
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- }, [hasMounted]);
|
|
|
|
-
|
|
|
|
- const onChange = (checkedValues: string[]) => {
|
|
|
|
- if (Array.isArray(checkedValues)) {
|
|
|
|
- setRemoveList(checkedValues);
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
const openFileShowInExplorer = async (path: string) => {
|
|
const openFileShowInExplorer = async (path: string) => {
|
|
const res = await File.showFileInExplorer(path);
|
|
const res = await File.showFileInExplorer(path);
|
|
};
|
|
};
|
|
@@ -289,7 +317,7 @@ export default function CalculateListPage() {
|
|
// const appDataDirPath = await appDataDir();
|
|
// const appDataDirPath = await appDataDir();
|
|
// console.log(190, appDataDirPath);
|
|
// console.log(190, appDataDirPath);
|
|
// 打开本地的系统目录,暂时不支持多选
|
|
// 打开本地的系统目录,暂时不支持多选
|
|
- const selected = await dialogopen({
|
|
|
|
|
|
+ const selected = await dialogOpen({
|
|
title: "请选择需要保存的目录",
|
|
title: "请选择需要保存的目录",
|
|
directory: true,
|
|
directory: true,
|
|
multiple: false,
|
|
multiple: false,
|
|
@@ -297,7 +325,7 @@ export default function CalculateListPage() {
|
|
});
|
|
});
|
|
|
|
|
|
await File.moveSpecificFiles(
|
|
await File.moveSpecificFiles(
|
|
- ["/Users/honghaitao/Downloads/Xnip2023-05-31_21-39-11_副本.png"],
|
|
|
|
|
|
+ ["/Users/sysadmin/Downloads/垃圾分类统计表_副本.xlsx"],
|
|
`${selected}`,
|
|
`${selected}`,
|
|
);
|
|
);
|
|
return;
|
|
return;
|
|
@@ -312,10 +340,6 @@ export default function CalculateListPage() {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- useEffect(() => {
|
|
|
|
- getFileList();
|
|
|
|
- }, [page, pageSize, sorterColumnKey, sorterOrder]);
|
|
|
|
-
|
|
|
|
const handleSearchReset = (dataIndex: string) => {
|
|
const handleSearchReset = (dataIndex: string) => {
|
|
setTotal(0);
|
|
setTotal(0);
|
|
setPage(1);
|
|
setPage(1);
|
|
@@ -326,6 +350,7 @@ export default function CalculateListPage() {
|
|
setSorterColumnKey({});
|
|
setSorterColumnKey({});
|
|
getFileList();
|
|
getFileList();
|
|
};
|
|
};
|
|
|
|
+
|
|
const handleSearch = (dataIndex: string, value: string) => {
|
|
const handleSearch = (dataIndex: string, value: string) => {
|
|
setSearchText({
|
|
setSearchText({
|
|
...searchText,
|
|
...searchText,
|
|
@@ -376,11 +401,7 @@ export default function CalculateListPage() {
|
|
<Row>
|
|
<Row>
|
|
<Col span={2}>
|
|
<Col span={2}>
|
|
<FolderOpenOutlined
|
|
<FolderOpenOutlined
|
|
- onClick={() =>
|
|
|
|
- openFileShowInExplorer(
|
|
|
|
- `${record.path}`
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
|
|
+ onClick={() => openFileShowInExplorer(`${record.path}`)}
|
|
/>
|
|
/>
|
|
</Col>
|
|
</Col>
|
|
<Col span={22}>
|
|
<Col span={22}>
|
|
@@ -409,6 +430,12 @@ export default function CalculateListPage() {
|
|
),
|
|
),
|
|
...getColumnSearchProps("path", "文件路径"),
|
|
...getColumnSearchProps("path", "文件路径"),
|
|
},
|
|
},
|
|
|
|
+ {
|
|
|
|
+ title: "重复数量",
|
|
|
|
+ dataIndex: "idsNum",
|
|
|
|
+ key: "idsNum",
|
|
|
|
+ sorter: true,
|
|
|
|
+ },
|
|
{
|
|
{
|
|
title: "文件大小",
|
|
title: "文件大小",
|
|
dataIndex: "file_size",
|
|
dataIndex: "file_size",
|
|
@@ -490,10 +517,6 @@ export default function CalculateListPage() {
|
|
},
|
|
},
|
|
selectedRowKeys: userSelectedRowKeys,
|
|
selectedRowKeys: userSelectedRowKeys,
|
|
};
|
|
};
|
|
- const expandable = {
|
|
|
|
- defaultExpandAllRows: true,
|
|
|
|
- };
|
|
|
|
- const [checkStrictly, setCheckStrictly] = useState(false);
|
|
|
|
|
|
|
|
const onTableChange: any = (
|
|
const onTableChange: any = (
|
|
pagination: {
|
|
pagination: {
|
|
@@ -544,50 +567,42 @@ export default function CalculateListPage() {
|
|
};
|
|
};
|
|
|
|
|
|
return (
|
|
return (
|
|
- <div className={styles.CalculateListPage}>
|
|
|
|
- <Space>
|
|
|
|
- <Button type="primary" danger onClick={() => removeFilesByDB()}>
|
|
|
|
- 删除选中的文件
|
|
|
|
- </Button>
|
|
|
|
- <Button type="primary" onClick={() => openDialogSave()}>
|
|
|
|
- 统一移动到指定目录
|
|
|
|
- </Button>
|
|
|
|
- {/*<Button type="primary">导出</Button>*/}
|
|
|
|
- </Space>
|
|
|
|
- <Table
|
|
|
|
- style={{
|
|
|
|
- width: "calc(100% - 48px)",
|
|
|
|
- }}
|
|
|
|
- columns={columns as any}
|
|
|
|
- loading={loading}
|
|
|
|
- pagination={{
|
|
|
|
- total,
|
|
|
|
- pageSize,
|
|
|
|
- current: page,
|
|
|
|
- showQuickJumper: true,
|
|
|
|
- }}
|
|
|
|
- rowSelection={{ ...rowSelection }}
|
|
|
|
- expandable={{
|
|
|
|
- defaultExpandAllRows: false,
|
|
|
|
- }}
|
|
|
|
- scroll={{
|
|
|
|
- scrollToFirstRowOnChange: true,
|
|
|
|
- x: true,
|
|
|
|
- }}
|
|
|
|
- key={"id"}
|
|
|
|
- dataSource={data}
|
|
|
|
- onChange={onTableChange}
|
|
|
|
- />
|
|
|
|
- {!data.length && !loading && (
|
|
|
|
- <div
|
|
|
|
|
|
+ <Spin spinning={loading} tip={spinTip}>
|
|
|
|
+ <div className={styles.CalculateListPage}>
|
|
|
|
+ <Space>
|
|
|
|
+ <Button type="primary" danger onClick={() => removeFilesByDB()}>
|
|
|
|
+ 删除选中的文件
|
|
|
|
+ </Button>
|
|
|
|
+ <Button type="primary" onClick={() => openDialogSave()}>
|
|
|
|
+ 统一移动到指定目录
|
|
|
|
+ </Button>
|
|
|
|
+ {!loading && spinTip && <div>{spinTip}</div>}
|
|
|
|
+ {/*<Button type="primary">导出</Button>*/}
|
|
|
|
+ </Space>
|
|
|
|
+ <Table
|
|
style={{
|
|
style={{
|
|
- padding: "48px 0",
|
|
|
|
- backgroundColor: "#fff",
|
|
|
|
|
|
+ width: "calc(100% - 48px)",
|
|
}}
|
|
}}
|
|
- >
|
|
|
|
- <Empty description={"当前目录没有找到重复的文件"} />
|
|
|
|
- </div>
|
|
|
|
- )}
|
|
|
|
- </div>
|
|
|
|
|
|
+ columns={columns as any}
|
|
|
|
+ pagination={{
|
|
|
|
+ total,
|
|
|
|
+ pageSize,
|
|
|
|
+ current: page,
|
|
|
|
+ showQuickJumper: true,
|
|
|
|
+ }}
|
|
|
|
+ rowSelection={{ ...rowSelection }}
|
|
|
|
+ expandable={{
|
|
|
|
+ defaultExpandAllRows: false,
|
|
|
|
+ }}
|
|
|
|
+ scroll={{
|
|
|
|
+ scrollToFirstRowOnChange: true,
|
|
|
|
+ x: true,
|
|
|
|
+ }}
|
|
|
|
+ key={"id"}
|
|
|
|
+ dataSource={data}
|
|
|
|
+ onChange={onTableChange}
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </Spin>
|
|
);
|
|
);
|
|
}
|
|
}
|