Files
alab-amis-fix-exam/src/renderer/DestPicker.tsx

239 lines
8.8 KiB
TypeScript
Raw Normal View History

2024-11-13 09:05:45 +08:00
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>
</>
);
}