239 lines
8.8 KiB
TypeScript
239 lines
8.8 KiB
TypeScript
import React from 'react'
|
|
import { useEffect, useState } from 'react';
|
|
import { Table, Button } from 'amis';
|
|
|
|
export default function DestPicker({
|
|
isRichtext,
|
|
fetcher,
|
|
breadcrumb,
|
|
setBreadcrumb,
|
|
bucket,
|
|
onConfirm,
|
|
onCancel,
|
|
}) {
|
|
const [source, setSource] = useState([]);
|
|
|
|
useEffect(() => {
|
|
fetchSource(null);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
reload();
|
|
}, [breadcrumb]);
|
|
|
|
async function fetchSource(prefix) {
|
|
const result = await fetcher({
|
|
method: 'post',
|
|
url: `/storage/v1/object/list/${bucket}`,
|
|
data: {
|
|
prefix: prefix ? prefix : '',
|
|
sortBy: {
|
|
column: 'name',
|
|
order: 'asc',
|
|
},
|
|
},
|
|
});
|
|
let source = result.data
|
|
.filter((item) => item.name.charAt(0) !== '.')
|
|
.map((item) => {
|
|
return {
|
|
...item,
|
|
...item.metadata,
|
|
mimetype: item.metadata
|
|
? item.metadata.mimetype.split('/')[1]
|
|
: '文件夹',
|
|
size: item.metadata
|
|
? '' + Math.floor(item.metadata.size / 1024) + 'KB'
|
|
: null,
|
|
updated_at: item.updated_at
|
|
? item.updated_at.slice(0, 16).replace('T', ' ')
|
|
: null,
|
|
};
|
|
});
|
|
setSource(source);
|
|
}
|
|
|
|
function getPath(breadcrumb) {
|
|
return breadcrumb.slice(1).toString().replaceAll(',', '/');
|
|
}
|
|
|
|
function reload() {
|
|
fetchSource(getPath(breadcrumb));
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div
|
|
id="dialog"
|
|
className="amis-dialog-widget cxd-Modal cxd-Modal--xl cxd-Modal--1th"
|
|
>
|
|
<div className="cxd-Modal-overlay in"></div>
|
|
<div className="cxd-Modal-content in">
|
|
<div className="cxd-Modal-header">
|
|
<div className="cxd-Modal-title">选取目标目录</div>
|
|
</div>
|
|
<div className="cxd-Modal-body">
|
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
<span>
|
|
{breadcrumb.map((item, index) => {
|
|
if (index) {
|
|
if (index === breadcrumb.length - 1) {
|
|
return <span key={`${index}-${item}`}>/{item}</span>;
|
|
}
|
|
|
|
return (
|
|
<span key={`${index}-${item}`}>
|
|
/
|
|
<a
|
|
href="#"
|
|
onClick={() => {
|
|
let temp_breadcrumb = JSON.parse(
|
|
JSON.stringify(breadcrumb)
|
|
);
|
|
temp_breadcrumb = temp_breadcrumb.slice(
|
|
0,
|
|
index + 1
|
|
);
|
|
setBreadcrumb(temp_breadcrumb);
|
|
}}
|
|
>
|
|
{item}
|
|
</a>
|
|
</span>
|
|
);
|
|
} else {
|
|
if (index === breadcrumb.length - 1) {
|
|
return <span key={`${index}-${item}`}>{item}</span>;
|
|
}
|
|
|
|
return (
|
|
<a
|
|
href="#"
|
|
key={`${index}-${item}`}
|
|
onClick={() => {
|
|
let temp_breadcrumb = JSON.parse(
|
|
JSON.stringify(breadcrumb)
|
|
);
|
|
temp_breadcrumb = temp_breadcrumb.slice(0, index + 1);
|
|
setBreadcrumb(temp_breadcrumb);
|
|
}}
|
|
>
|
|
{item}
|
|
</a>
|
|
);
|
|
}
|
|
})}
|
|
</span>
|
|
</div>
|
|
<Table
|
|
className={`m-t-xs`}
|
|
dataSource={source}
|
|
columns={[
|
|
{
|
|
title: '名称',
|
|
render: (item, rowData, rowIndex, i) => {
|
|
return {
|
|
props: { rowSpan: 1, colSpan: 1 },
|
|
children: (
|
|
<div key={`${rowIndex}-${rowData.name}`}>
|
|
{rowData.id ? (
|
|
isRichtext ? (
|
|
<Button
|
|
level="link"
|
|
size="sm"
|
|
className={`m-l-xs`}
|
|
onClick={() => {
|
|
const path = getPath(breadcrumb)
|
|
const filePath = path ? `${path}/${rowData.name}` : `${rowData.name}`
|
|
const src = path ? `/api/storage/v1/object/public/mooc/${path}/${rowData.name}` : `/api/storage/v1/object/public/mooc/${rowData.name}`
|
|
const type =
|
|
rowData.metadata.mimetype.split('/')[0];
|
|
console.log(src)
|
|
|
|
switch (type) {
|
|
case 'image':
|
|
onConfirm(`<img src="${src}" />`);
|
|
break;
|
|
case 'video':
|
|
onConfirm(
|
|
`<video controls src="${src}" />`
|
|
);
|
|
break;
|
|
default:
|
|
fetcher({
|
|
method: 'post',
|
|
url: `/storage/v1/object/sign/${bucket}`,
|
|
data: {
|
|
expiresIn: 60000,
|
|
paths: [filePath],
|
|
},
|
|
headers: {
|
|
post2rest: false,
|
|
},
|
|
})
|
|
.then(({ data }) => {
|
|
if (data && data.length > 0) {
|
|
const presignedurl = `${location.origin}/api/storage/v1${data[0].signedURL}&download=${filePath}`;
|
|
const href = `${
|
|
location.origin
|
|
}/preview/onlinePreview?url=${encodeURIComponent(
|
|
window.btoa(unescape(encodeURIComponent(presignedurl)))
|
|
)}`;
|
|
onConfirm(`<a href=${href}>${rowData.name}</a>`);
|
|
} else {
|
|
this.props.env.notify(
|
|
'error',
|
|
'选取文件失败'
|
|
);
|
|
}
|
|
})
|
|
.catch((err) => console.log(err));
|
|
}
|
|
}}
|
|
>
|
|
{rowData.name}
|
|
</Button>
|
|
) : (
|
|
<span>{rowData.name}</span>
|
|
)
|
|
) : (
|
|
<Button
|
|
level="link"
|
|
size="sm"
|
|
onClick={() => {
|
|
let temp_breadcrumb = JSON.parse(
|
|
JSON.stringify(breadcrumb)
|
|
);
|
|
temp_breadcrumb.push(rowData.name);
|
|
setBreadcrumb(temp_breadcrumb);
|
|
}}
|
|
>
|
|
{rowData.name}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
),
|
|
};
|
|
},
|
|
},
|
|
{ key: 'mimetype', title: '类型' },
|
|
{ key: 'size', title: '大小' },
|
|
{ key: 'updated_at', title: '修改日期' },
|
|
]}
|
|
rowClassName={(item) => !item.id && 'font-bold text-primary'}
|
|
/>
|
|
</div>
|
|
<div className="cxd-Modal-footer">
|
|
<Button onClick={onCancel}>取消</Button>
|
|
{!isRichtext && (
|
|
<Button level="primary" onClick={onConfirm}>
|
|
确认
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|