add crawl file

This commit is contained in:
seaheart
2023-07-22 16:07:45 +08:00
parent 1e89f8f706
commit e77efc4613
7 changed files with 258 additions and 54 deletions
+8
View File
@@ -160,6 +160,13 @@ let LangEn = {
canIUse: 'To see if the current browser supports it',
intoRecycleBin: 'Recycle bin',
finishingTip: 'Please wait while files are sorted...',
crawl: 'Crawl File',
crawlLink: 'Link',
crawlLinkTip: 'Please enter link',
crawlFilename: 'Filename',
crawlFilenameTip: 'Please enter filename',
crawlBackground: 'Background',
crawlSuccessTip: 'Crawl successfully',
},
router: {
allFiles: 'All Files',
@@ -415,6 +422,7 @@ let LangEn = {
refresh: 'refresh',
inputRequired: 'Input required',
selectRequired: 'Select required',
more: 'More',
};
export default LangEn;
+8
View File
@@ -154,6 +154,13 @@ let LangZh = {
canIUse: '查看当前浏览器是否支持,点击跳转',
intoRecycleBin: '放入回收站',
finishingTip: '后台文件整理中,请稍候...',
crawl: '抓取文件',
crawlLink: '链接',
crawlLinkTip: '请输入链接',
crawlFilename: '文件名',
crawlFilenameTip: '请输入文件名',
crawlBackground: '后台抓取',
crawlSuccessTip: '抓取成功',
},
router: {
allFiles: '全部文件',
@@ -408,6 +415,7 @@ let LangZh = {
refresh: '刷新',
inputRequired: '该项必填',
selectRequired: '该项必选',
more: '更多',
};
export default LangZh;
+23 -1
View File
@@ -68,9 +68,9 @@ export default class Matter extends BaseEntity {
static URL_MATTER_RENAME = '/api/matter/rename';
static URL_CHANGE_PRIVACY = '/api/matter/change/privacy';
static URL_MATTER_MOVE = '/api/matter/move';
static URL_MATTER_DOWNLOAD = '/api/matter/download';
static URL_MATTER_UPLOAD = '/api/matter/upload';
static URL_MATTER_ZIP = '/api/matter/zip';
static URL_MATTER_CRAWL = '/api/matter/crawl';
static MATTER_ROOT = 'root';
@@ -244,6 +244,28 @@ export default class Matter extends BaseEntity {
);
}
static httpCrawl(
body: {
url: string;
puuid: string;
filename: string;
spaceUuid: string;
},
successCallback?: any,
errorCallback?: any,
finallyCallback?: any
) {
new HttpBase().httpPost(
Matter.URL_MATTER_CRAWL,
body,
function (response: any) {
typeof successCallback === 'function' && successCallback(response);
},
errorCallback,
finallyCallback
);
}
static httpDeleteBatch(
uuids: string,
spaceUuid: string,
+4 -2
View File
@@ -1,9 +1,11 @@
export const debounce = (func: Function, wait: number) => {
let timer: any = null;
return () => {
return (args?: any) => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(func, wait);
timer = setTimeout(() => {
func.call(this, args);
}, wait);
};
};
-1
View File
@@ -1,7 +1,6 @@
import React from 'react';
import { Progress } from 'antd';
import TankComponent from '../../../common/component/TankComponent';
import FileUtil from '../../../common/util/FileUtil';
import Moon from '../../../common/model/global/Moon';
import User from '../../../common/model/user/User';
import { debounce } from '../../../common/util/OptimizeUtil';
+118 -50
View File
@@ -11,8 +11,11 @@ import UploadMatterPanel from './widget/UploadMatterPanel';
import {
Button,
Col,
Dropdown,
Empty,
Input,
Menu,
message,
Modal,
Pagination,
Row,
@@ -21,12 +24,14 @@ import {
} from 'antd';
import MessageBoxUtil from '../../common/util/MessageBoxUtil';
import {
CloudDownloadOutlined,
CloudUploadOutlined,
DeleteOutlined,
DownloadOutlined,
DragOutlined,
ExclamationCircleFilled,
FolderOutlined,
MenuOutlined,
MinusSquareOutlined,
PlusSquareOutlined,
ShareAltOutlined,
@@ -49,6 +54,7 @@ import MatterSortPanel from './widget/MatterSortPanel';
import { UploadRequestOption as RcCustomRequestOptions } from 'rc-upload/lib/interface';
import Capacity from '../layout/widget/Capacity';
import Space from '../../common/model/space/Space';
import MatterCrawlModal, { ICrawlFormValues } from './widget/MatterCrawlModal';
interface IProps {
spaceUuid?: string;
@@ -59,6 +65,7 @@ interface IState {}
export default class List extends TankComponent<IProps, IState> {
// 当前空间
space = new Space();
isInSpace = !!this.props.spaceUuid; // 是否在空间中
// 当前目录
currentDirectory = new Matter();
//准备新建的文件
@@ -83,6 +90,7 @@ export default class List extends TankComponent<IProps, IState> {
// 最外层div
wrapperRef = React.createRef<HTMLDivElement>();
uploadDirectoryBtnRef = React.createRef<HTMLElement>();
//用来判断是否展示遮罩层
dragEnterCount = 0;
@@ -97,6 +105,9 @@ export default class List extends TankComponent<IProps, IState> {
uploadMattersMap: Record<string, Matter[]> =
Moon.getSingleton().uploadMattersMap;
// 抓取模态窗状态
crawlModalVisible = false;
//持有全局唯一的实例。
static instance: List | null = null;
@@ -507,11 +518,20 @@ export default class List extends TankComponent<IProps, IState> {
ImagePreviewer.showMultiPhoto(imageArray, startIndex);
}
delete() {
pagerAndCapacityRefresh() {
Capacity.instance?.refresh();
this.refresh();
}
checkHandlePermission() {
return true;
}
handleCloseMatterCrawlModal() {
this.crawlModalVisible = false;
this.pagerAndCapacityRefresh();
}
goToDirectory(id: string) {
this.searchText = null;
this.pager.setFilterValue('puuid', id);
@@ -587,6 +607,29 @@ export default class List extends TankComponent<IProps, IState> {
return this.breadcrumbModels;
}
getDropdownMenu() {
return (
<Menu>
<Menu.Item
icon={<CloudUploadOutlined />}
onClick={() => this.uploadDirectoryBtnRef.current?.click()}
>
{Lang.t('matter.uploadDir')}
</Menu.Item>
<Menu.Item
icon={<CloudDownloadOutlined />}
onClick={() => {
this.crawlModalVisible = true;
this.updateUI();
}}
>
{Lang.t('matter.crawl')}
</Menu.Item>
</Menu>
);
}
render() {
const { pager, director, selectedMatters, dragEnterCount } = this;
return (
@@ -624,14 +667,6 @@ export default class List extends TankComponent<IProps, IState> {
) : null}
{selectedMatters.length ? (
<>
<Button
type="primary"
className="mb10"
onClick={() => this.deleteBatch()}
>
<DeleteOutlined />
{Lang.t('delete')}
</Button>
<Button
type="primary"
className="mb10"
@@ -640,17 +675,29 @@ export default class List extends TankComponent<IProps, IState> {
<DownloadOutlined />
{Lang.t('download')}
</Button>
<Button
type="primary"
className="mb10"
onClick={() => this.toggleMoveBatch()}
>
<DragOutlined />
{Lang.t('matter.move')}
</Button>
{this.checkHandlePermission() && (
<>
<Button
type="primary"
className="mb10"
onClick={() => this.deleteBatch()}
>
<DeleteOutlined />
{Lang.t('delete')}
</Button>
<Button
type="primary"
className="mb10"
onClick={() => this.toggleMoveBatch()}
>
<DragOutlined />
{Lang.t('matter.move')}
</Button>
</>
)}
{/*共享空间下暂不支持分享功能*/}
{!this.props.spaceUuid && (
{!this.isInSpace && (
<Button
type="primary"
className="mb10"
@@ -663,36 +710,38 @@ export default class List extends TankComponent<IProps, IState> {
</>
) : null}
<Upload
className="ant-upload"
customRequest={(e) => this.triggerUpload(e)}
showUploadList={false}
multiple
>
<Button type="primary" className="mb10">
<CloudUploadOutlined />
{Lang.t('matter.upload')}
</Button>
</Upload>
<Upload
className="ant-upload"
customRequest={this.triggerUploadDir}
showUploadList={false}
directory
>
<Button type="primary" className="mb10">
<CloudUploadOutlined />
{Lang.t('matter.uploadDir')}
</Button>
</Upload>
<Button
type="primary"
className="mb10"
onClick={() => this.createDirectory()}
>
<FolderOutlined />
{Lang.t('matter.create')}
</Button>
{this.checkHandlePermission() && (
<>
<Upload
className="ant-upload"
customRequest={(e) => this.triggerUpload(e)}
showUploadList={false}
multiple
>
<Button type="primary" className="mb10">
<CloudUploadOutlined />
{Lang.t('matter.upload')}
</Button>
</Upload>
<Button
type="primary"
className="mb10"
onClick={() => this.createDirectory()}
>
<FolderOutlined />
{Lang.t('matter.create')}
</Button>
<Dropdown
trigger={['hover']}
overlay={this.getDropdownMenu()}
>
<Button type="primary" className="mb10">
<MenuOutlined />
{Lang.t('more')}
</Button>
</Dropdown>
</>
)}
<Button
type="primary"
@@ -702,6 +751,18 @@ export default class List extends TankComponent<IProps, IState> {
<SyncOutlined />
{Lang.t('refresh')}
</Button>
<Upload
className="ant-upload display-none"
customRequest={this.triggerUploadDir}
showUploadList={false}
directory
>
<Button type="primary" ref={this.uploadDirectoryBtnRef}>
<CloudUploadOutlined />
{Lang.t('matter.uploadDir')}
</Button>
</Upload>
</AntdSpace>
</Col>
<Col xs={24} sm={24} md={10} lg={8} className="mt10">
@@ -740,9 +801,9 @@ export default class List extends TankComponent<IProps, IState> {
key={matter.uuid!}
director={director}
matter={matter}
isSpace={!!this.props.spaceUuid}
isSpace={this.isInSpace}
onGoToDirectory={(id) => this.goToDirectory(id)}
onDeleteSuccess={() => this.delete()}
onDeleteSuccess={() => this.pagerAndCapacityRefresh()}
onCheckMatter={(m) => this.checkMatter(m)}
onPreviewImage={(m) => this.previewImage(m)}
/>
@@ -759,6 +820,13 @@ export default class List extends TankComponent<IProps, IState> {
pageSize={pager.pageSize}
hideOnSinglePage
/>
{this.crawlModalVisible && (
<MatterCrawlModal
spaceUuid={this.getSpaceUuid()}
puuid={this.currentDirectory.uuid!}
onClose={this.handleCloseMatterCrawlModal.bind(this)}
/>
)}
</div>
);
}
@@ -0,0 +1,97 @@
import React, { useState } from 'react';
import { Form, Input, message, Modal, Spin } from 'antd';
import Lang from '../../../common/model/global/Lang';
import { FORM_LAYOUT } from '../../../common/const/Form';
import { debounce } from '../../../common/util/OptimizeUtil';
import Matter from '../../../common/model/matter/Matter';
export interface ICrawlFormValues {
link: string;
filename: string;
}
interface IProps {
spaceUuid: string;
puuid: string;
onClose: () => void;
}
const MatterCrawlModal = ({ spaceUuid, puuid, onClose }: IProps) => {
const [form] = Form.useForm<ICrawlFormValues>();
const [filenameFocusFlag, setFilenameFocusFlag] = useState<boolean>(false);
const [confirmLoading, setConfirmLoading] = useState<boolean>(false);
const handleChangeCrawlLink = debounce((link: string) => {
if (filenameFocusFlag) return; // 如果用户光标移入过filename输入框,则不自动填充filename
try {
const url = new URL(link);
const filename = url.pathname.split('/').pop();
form.setFieldsValue({
filename,
});
} catch (e) {
form.setFieldsValue({
filename: undefined,
});
}
}, 200);
const handleConfirm = () => {
const values = form.getFieldsValue(true);
setConfirmLoading(true);
Matter.httpCrawl(
{
url: values.link,
filename: values.filename,
spaceUuid,
puuid,
},
() => {
message.success(Lang.t('matter.crawlSuccessTip'));
onClose();
},
null,
() => {
setConfirmLoading(false);
}
);
};
return (
<Modal
visible
title={Lang.t('matter.crawl')}
onOk={form.submit}
onCancel={onClose}
confirmLoading={confirmLoading}
okText={Lang.t('confirm')}
cancelText={
confirmLoading ? Lang.t('matter.crawlBackground') : Lang.t('cancel')
}
>
<Form form={form} {...FORM_LAYOUT} onFinish={handleConfirm}>
<Form.Item
label={Lang.t('matter.crawlLink')}
name="link"
rules={[{ required: true }]}
>
<Input
placeholder={Lang.t('matter.crawlLinkTip')}
onChange={(e) => handleChangeCrawlLink(e.target.value)}
/>
</Form.Item>
<Form.Item
label={Lang.t('matter.crawlFilename')}
name="filename"
rules={[{ required: true }]}
>
<Input
placeholder={Lang.t('matter.crawlFilenameTip')}
onFocus={() => setFilenameFocusFlag(true)}
/>
</Form.Item>
</Form>
</Modal>
);
};
export default MatterCrawlModal;