peng.peng 2 years ago
parent
commit
cace2595a9
  1. 7
      api/app/lib/controllers/dataQuality/index.js
  2. BIN
      web/client/assets/files/common/1687657483581_2.jpg
  3. 2
      web/client/src/sections/dataQuality/components/fileModal.js
  4. 4
      web/client/src/sections/dataQuality/components/groupModal.js
  5. 2
      web/client/src/sections/dataQuality/components/ruleModal.js
  6. 14
      web/client/src/sections/dataQuality/containers/documentLibrary.js
  7. 6
      web/client/src/sections/safetySpecification/components/fileModal.js
  8. 20
      web/client/src/sections/safetySpecification/containers/specificationLibrary.js
  9. 32
      web/client/src/utils/webapi.js
  10. 2
      web/package.json
  11. 488
      web/routes/attachment/index.js

7
api/app/lib/controllers/dataQuality/index.js

@ -73,7 +73,7 @@ function getStandardDocFolders (opts) {
// 标准文档目录新增失败
function postStandardDocFolders (opts) {
return async function (ctx, next) {
@ -157,6 +157,11 @@ function postBusinessRules (opts) {
const { id, name, description, problemType, problemLevel, ruleBasis } = ctx.request.body;
let findOne = await models.BusinessRule.findOne({ where: { name: name } })
if ((!id && findOne) || (id && findOne && findOne.id != id)) {
message = '业务规则名称重复'
throw ''
}
if (id) {
await models.BusinessRule.update({
name, description, problemType, problemLevel, ruleBasis

BIN
web/client/assets/files/common/1687657483581_2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

2
web/client/src/sections/dataQuality/components/fileModal.js

@ -78,7 +78,7 @@ function FileModal ({ loading, parent, user, actions, editData = {}, dispatch, c
/>
</Form.Item>
<Form.Item label="标签" name="tags" >
<Input allowClear placeholder='请输入标签' style={{ width: 300, marginRight: 16 }} />
<Input allowClear placeholder='请输入标签' maxLength={50} style={{ width: 300, marginRight: 16 }} />
</Form.Item>
<Form.Item
label='文件'

4
web/client/src/sections/dataQuality/components/groupModal.js

@ -45,8 +45,8 @@ function GroupModal ({ loading, parent, user, actions, dispatch, close, success,
}}
autoComplete="off"
>
<Form.Item label="名称" name="name" rules={[{ required: true, message: '请输入分组名称' }]}>
<Input allowClear placeholder='请输入分组名称' style={{ width: 300, }} />
<Form.Item label="名称" name="name" rules={[{ required: true, message: '请输入分组名称,最多50字', max: 50 },]}>
<Input allowClear placeholder='请输入分组名称' style={{ width: 300, }} />
</Form.Item>
</Form>
</Modal >

2
web/client/src/sections/dataQuality/components/ruleModal.js

@ -52,7 +52,7 @@ function RuleModal ({ loading, parent, user, actions, dispatch, close, success,
autoComplete="off"
labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}
>
<Form.Item label="名称" name="name" initialValue={editData?.name} rules={[{ required: true, message: '请输入分组名称' }]}>
<Form.Item label="名称" name="name" initialValue={editData?.name} rules={[{ required: true, message: '请输入分组名称,最多50字', max: 50}]}>
<Input allowClear placeholder='请输入分组名称' style={{ width: 300 }} />
</Form.Item>
<Form.Item label="描述" name="description" initialValue={editData?.description} rules={[{ required: true, message: '请输入分组名称' }]}>

14
web/client/src/sections/dataQuality/containers/documentLibrary.js

@ -77,7 +77,13 @@ function Approve ({ loading, clientHeight, actions, dispatch, }) {
<Button type="primary" onClick={() => {
setFileModal(true)
}}>上传</Button>
<Button type="primary">下载</Button>
<Button type="primary" onClick={() => {
// let fileUrlList = fileData.filter(d => fileId.current.includes(d.id))?.map(s => s.path)
// console.log(fileUrlList);
}}>下载</Button>
<Popconfirm
title="是否删除文件夹或文件?当有创建的业务规则与标准文档关联时则不允许删除。"
@ -86,7 +92,7 @@ function Approve ({ loading, clientHeight, actions, dispatch, }) {
if (folderId.current?.length || fileId.current?.length) {
dispatch(dataQuality.postFolderFile({ folderId: folderId.current, fileId: fileId.current })).then(res => {
if (res.success) {
resourceData(parent,keywords)
resourceData(parent, keywords)
setCheckAll(false)
console.log(res);
res.payload.data?.map(v => {
@ -239,7 +245,7 @@ function Approve ({ loading, clientHeight, actions, dispatch, }) {
}
success={
() => {
resourceData(parent,keywords)
resourceData(parent, keywords)
}
}
/> : ""
@ -252,7 +258,7 @@ function Approve ({ loading, clientHeight, actions, dispatch, }) {
setFileModal(false);
}}
success={() => {
resourceData(parent,keywords)
resourceData(parent, keywords)
}}
remove={url => {
RouteRequest.delete(RouteTable.cleanUpUploadTrash, { url: url });

6
web/client/src/sections/safetySpecification/components/fileModal.js

@ -10,7 +10,7 @@ import { Tabs, Form, Input, DatePicker, Button, Modal, Select, Tag } from 'antd'
function FileModal ({ loading, parent, user, actions, editData = {}, dispatch, close, success, remove }) {
const { resourceRetrieval } = actions
const { safetySpecification } = actions
const [tabsKey, setTabsKey] = useState("stay")
const [query, setQuery] = useState({ page: 0, limit: 10 });
const [proTableList, setProTableList] = useState({ rows: [], count: 0 });
@ -46,7 +46,7 @@ function FileModal ({ loading, parent, user, actions, editData = {}, dispatch, c
onOk={e => {
form.validateFields().then(v => {
dispatch(resourceRetrieval.postSpecifications({
dispatch(safetySpecification.postSpecifications({
...v,
fileName: v?.files[0]?.name,path:v?.files[0]?.url,
})).then(res => {
@ -74,7 +74,7 @@ function FileModal ({ loading, parent, user, actions, editData = {}, dispatch, c
labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}
>
<Form.Item label="标签" name="tags" >
<Input allowClear placeholder='请输入标签' style={{ width: 300, marginRight: 16 }} />
<Input allowClear placeholder='请输入标签' maxLength={50} style={{ width: 300, marginRight: 16 }} />
</Form.Item>
<Form.Item
label='文件'

20
web/client/src/sections/safetySpecification/containers/specificationLibrary.js

@ -10,11 +10,12 @@ const { Search } = Input;
import { CreditCardFilled, FilePdfOutlined } from '@ant-design/icons';
import { agent } from 'superagent';
const CheckboxGroup = Checkbox.Group;
import JSZip from 'jszip'
import { savAes } from 'file-saver'
function SpecificationLibrary ({ loading, clientHeight, actions, dispatch, }) {
const { resourceRetrieval } = actions
const { safetySpecification } = actions
const [checkAll, setCheckAll] = useState(false)
const [query, setQuery] = useState({ page: 0, limit: 20 });
const [fileData, setFileData] = useState({ data: [], count: 0 })
@ -32,13 +33,14 @@ function SpecificationLibrary ({ loading, clientHeight, actions, dispatch, }) {
let resourceData = (data) => {
let params = data || query
dispatch(resourceRetrieval.getSpecifications({ keyword: keyword, ...params, })).then(res => {
dispatch(safetySpecification.getSpecifications({ keyword: keyword, ...params, })).then(res => {
if (res.success) {
setFileData({ data: res.payload.data?.rows, count: res.payload.data?.count })
}
})
}
return <>
@ -58,10 +60,16 @@ function SpecificationLibrary ({ loading, clientHeight, actions, dispatch, }) {
<Button type="primary" onClick={() => {
setFileModal(true)
}}>上传</Button>
<Button type="primary">下载</Button>
<Button type="primary" onClick={() => {
// let fileUrlList = fileData?.data?.filter(d => fileId.current.includes(d.id))?.map(s => s.path)
// RouteRequest.post(RouteTable.packBulk, { fileUrl: fileUrlList });
}}>下载</Button>
<Button type="primary" onClick={() => {
if (fileId.current?.length) {
dispatch(resourceRetrieval.delSpecifications(fileId.current)).then(res => {
dispatch(safetySpecification.delSpecifications(fileId.current)).then(res => {
if (res.success) {
let url = []
fileData?.data?.map(f => {
@ -115,7 +123,7 @@ function SpecificationLibrary ({ loading, clientHeight, actions, dispatch, }) {
>
{
fileData?.data?.map((v, i) => {
return <div style={{ width: 310, display: 'inline-block', margin:'0 18px 10px 0', }}>
return <div style={{ width: 310, display: 'inline-block', margin: '0 18px 10px 0', }}>
<div style={{ display: 'flex', padding: '10px 0', border: `1px solid ${fileId.current?.includes(v.id) ? 'rgb(42 207 98)' : '#fff'}` }} onClick={() => {
if (fileId.current?.includes(v.id)) {
fileId.current = fileId.current?.filter(c => c != v.id)

32
web/client/src/utils/webapi.js

@ -88,27 +88,31 @@ export const ApiTable = {
//数据质量
standardDocFolders: 'standard-doc-folders',
standardDocs: 'standard-docs',
postFolderFile:'postFolderFile',
businessRules:'business-rules',
delBusinessRules:'business-rules/{id}',
regularBasis:'regular-basis',
postFolderFile: 'postFolderFile',
businessRules: 'business-rules',
delBusinessRules: 'business-rules/{id}',
regularBasis: 'regular-basis',
//数据安全规范上传
specifications:'data-security/specifications',
delSpecifications:'data-security/specifications/{fileIds}',
//元数据检索
searchMetadata: "meta/data/search",
//备份恢复
getBackupsList: 'meta/backups',
addBackups: 'meta/backups',
modifyBackups: 'meta/backups/{id}',
restoreBackups:'backups/restore'
specifications: 'data-security/specifications',
delSpecifications: 'data-security/specifications/{fileIds}',
packBulk: 'packBulk',
//元数据检索
searchMetadata: "meta/data/search",
//备份恢复
getBackupsList: 'meta/backups',
addBackups: 'meta/backups',
modifyBackups: 'meta/backups/{id}',
restoreBackups: 'backups/restore'
};
export const RouteTable = {
fileUpload: '/_upload/new',
cleanUpUploadTrash: '/_upload/cleanup',
packBulk: '/packBulk/{}',
};
const resultHandler = (resolve, reject) => (err, res) => {

2
web/package.json

@ -83,11 +83,13 @@
"file-saver": "^2.0.5",
"fs-attachment": "^1.0.0",
"fs-web-server-scaffold": "^1.0.6",
"jszip": "^3.10.1",
"koa-better-http-proxy": "^0.2.5",
"koa-proxy": "^1.0.0-alpha.3",
"koa-view": "^2.1.4",
"moment": "^2.22.0",
"npm": "^7.20.6",
"path": "^0.12.7",
"react-router-breadcrumbs-hoc": "^4.0.1",
"simplebar-react": "^3.2.4",
"superagent": "^6.1.0",

488
web/routes/attachment/index.js

@ -5,235 +5,295 @@ const path = require('path')
const fs = require('fs');
const OSS = require('ali-oss');
const uuid = require('uuid');
const JSZip = require('jszip');
const UploadPath = {
project: ['.txt', '.dwg', '.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf', '.pptx', '.png', '.jpg', '.svg', '.rar', '.zip', '.jpeg', '.mp4'],
report: ['.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf'],
data: ['.txt', '.xls', '.xlsx', ".csv"],
image: ['.png', '.jpg', '.svg'],
three: ['.js'],
video: ['.mp4']
project: ['.txt', '.dwg', '.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf', '.pptx', '.png', '.jpg', '.svg', '.rar', '.zip', '.jpeg', '.mp4'],
report: ['.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf'],
data: ['.txt', '.xls', '.xlsx', ".csv"],
image: ['.png', '.jpg', '.svg'],
three: ['.js'],
video: ['.mp4']
};
const ext = {
project: ['.txt', '.dwg', '.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf', '.pptx', '.png', '.jpg', '.gif', '.svg', '.rar', '.zip', '.jpeg', '.mp4'],
report: [".doc", ".docx", ".xls", ".xlsx", ".pdf"],
data: [".txt", ".xls", ".xlsx"],
image: [".png", ".jpg", ".svg"],
three: [".js"],
video: [".mp4"],
bpmn: [".bpmn", ".bpmn20.xml", ".zip", ".bar"],
app: [".apk"]
project: ['.txt', '.dwg', '.doc', '.docx', '.xls', '.xlsx', ".csv", '.pdf', '.pptx', '.png', '.jpg', '.gif', '.svg', '.rar', '.zip', '.jpeg', '.mp4'],
report: [".doc", ".docx", ".xls", ".xlsx", ".pdf"],
data: [".txt", ".xls", ".xlsx"],
image: [".png", ".jpg", ".svg"],
three: [".js"],
video: [".mp4"],
bpmn: [".bpmn", ".bpmn20.xml", ".zip", ".bar"],
app: [".apk"]
}
module.exports = {
entry: function (app, router, opts) {
let download_ = async function (ctx, next) {
const { fetchUrl } = opts.qiniu;
const { fetchUrl: aliFetchUrl, bucket, region } = opts.aliOss
if (ctx.path && ctx.path.includes(fetchUrl)) {
try {
const { filename } = ctx.request.query;
const fkey = decodeURI(ctx.path.slice(fetchUrl.length + 1)).replace(/\.json$/, '.js');
if (ctx.path) {
const extNames = ctx.path.split('.');
app.fs.logger.log('info', 'extNames', extNames);
if (extNames.length > 0) {
let fileType = extNames[extNames.length - 1].toLowerCase();
if (fileType === 'pdf') {
ctx.type = 'application/pdf';
app.fs.logger.log('info', 'application/pdf', fileType);
}
}
}
const publicDownloadUrl = await app.fs.attachment.download(fkey);
ctx.status = 200;
if (filename) ctx.attachment(filename);
ctx.body = request.get(publicDownloadUrl);
} catch (err) {
ctx.fs.logger.error(err);
ctx.status = 404;
ctx.body = { error: 'file not found.' };
}
} else if (ctx.path && ctx.path.includes(aliFetchUrl)) {
const { filename } = ctx.request.query;
const fkey = decodeURI(ctx.path.slice(aliFetchUrl.length + 1)).replace(/\.json$/, '.js');
if (ctx.path) {
const extNames = ctx.path.split('.');
app.fs.logger.log('info', 'extNames', extNames);
if (extNames.length > 0) {
let fileType = extNames[extNames.length - 1].toLowerCase();
if (fileType === 'pdf') {
ctx.type = 'application/pdf';
app.fs.logger.log('info', 'application/pdf', fileType);
}
}
}
const publicDownloadUrl = `http://${bucket}.${region}.aliyuncs.com/${encodeURIComponent(fkey)}`
ctx.status = 200;
ctx.body = request.get(publicDownloadUrl);
} else {
await next();
}
};
let upload = async function (ctx, next) {
entry: function (app, router, opts) {
let download_ = async function (ctx, next) {
const { fetchUrl } = opts.qiniu;
const { fetchUrl: aliFetchUrl, bucket, region } = opts.aliOss
if (ctx.path && ctx.path.includes(fetchUrl)) {
try {
const { files } = await parse(ctx.req);
const file = files[0];
const extname = path.extname(file.filename).toLowerCase();
const fileType = ctx.query.type || "image";
const fileFolder = ctx.query.fileFolder || 'common';
if (ext[fileType].indexOf(extname) < 0) {
ctx.status = 400;
ctx.body = JSON.stringify({ name: 'UploadFailed', message: '文件格式无效' });
return;
}
const date = new Date().toLocaleDateString();
const time = new Date().getTime();
let fileName = time + '_' + file.filename;
let saveFile = path.join(__dirname, '../../', `/client/assets/files/${fileFolder}`, fileName);
const pathUrl = `./client/assets/files/${fileFolder}`;
const res1 = fs.existsSync(`./client/assets/files/${fileFolder}`);
!res1 && fs.mkdirSync(`./client/assets/files/${fileFolder}`);
const res = fs.existsSync(pathUrl);
!res && fs.mkdirSync(pathUrl);
let stream = fs.createWriteStream(saveFile);
fs.createReadStream(file.path).pipe(stream);
stream.on('error', function (err) {
app.fs.logger.log('error', '[Upload Heatmap]', err);
});
ctx.status = 200;
ctx.body = { filename: path.join(`/assets/files/${fileFolder}`, fileName), name: 'UploadSuccess', message: '上传成功' };
const { filename } = ctx.request.query;
const fkey = decodeURI(ctx.path.slice(fetchUrl.length + 1)).replace(/\.json$/, '.js');
if (ctx.path) {
const extNames = ctx.path.split('.');
app.fs.logger.log('info', 'extNames', extNames);
if (extNames.length > 0) {
let fileType = extNames[extNames.length - 1].toLowerCase();
if (fileType === 'pdf') {
ctx.type = 'application/pdf';
app.fs.logger.log('info', 'application/pdf', fileType);
}
}
}
const publicDownloadUrl = await app.fs.attachment.download(fkey);
ctx.status = 200;
if (filename) ctx.attachment(filename);
ctx.body = request.get(publicDownloadUrl);
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload error.' };
ctx.fs.logger.error(err);
ctx.status = 404;
ctx.body = { error: 'file not found.' };
}
} else if (ctx.path && ctx.path.includes(aliFetchUrl)) {
const { filename } = ctx.request.query;
const fkey = decodeURI(ctx.path.slice(aliFetchUrl.length + 1)).replace(/\.json$/, '.js');
if (ctx.path) {
const extNames = ctx.path.split('.');
app.fs.logger.log('info', 'extNames', extNames);
if (extNames.length > 0) {
let fileType = extNames[extNames.length - 1].toLowerCase();
if (fileType === 'pdf') {
ctx.type = 'application/pdf';
app.fs.logger.log('info', 'application/pdf', fileType);
}
}
}
}
const publicDownloadUrl = `http://${bucket}.${region}.aliyuncs.com/${encodeURIComponent(fkey)}`
ctx.status = 200;
ctx.body = request.get(publicDownloadUrl);
} else {
await next();
}
};
let remove = async function (ctx, next) {
try {
const fkeys = ctx.request.body;
let removeUrl = path.join(__dirname, '../../', './client', fkeys.url);
const res = fs.existsSync(removeUrl);
if (!res) {
ctx.status = 400;
ctx.body = JSON.stringify({ name: 'DeleteFailed', message: '文件地址不存在' });
return;
}
fs.unlink(removeUrl, function (error) {
if (error) {
console.log(error);
}
})
ctx.status = 200;
ctx.body = { name: 'DeleteSuccess.', message: '删除成功' };
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload cleanup error.' };
let upload = async function (ctx, next) {
try {
const { files } = await parse(ctx.req);
const file = files[0];
const extname = path.extname(file.filename).toLowerCase();
const fileType = ctx.query.type || "image";
const fileFolder = ctx.query.fileFolder || 'common';
if (ext[fileType].indexOf(extname) < 0) {
ctx.status = 400;
ctx.body = JSON.stringify({ name: 'UploadFailed', message: '文件格式无效' });
return;
}
}
let upload_ = async function (ctx, next) {
let fkey = null;
try {
const { p } = ctx.params;
const { files } = await parse(ctx.req);
const file = files[0];
const extname = path.extname(file.filename).toLowerCase();
if (!UploadPath[p]) {
ctx.status = 400;
ctx.body = JSON.stringify({ error: '附件存放的文件夹名称无效' });
return;
} else if (UploadPath[p].indexOf(extname) < 0) {
ctx.status = 400;
ctx.body = JSON.stringify({ error: '文件格式无效' });
return;
} else {
const fileInfo = await ctx.app.fs.attachment.upload(file, { uploadPath: p });
fkey = fileInfo.key;
ctx.body = { uploaded: fkey };
}
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload error.' };
const date = new Date().toLocaleDateString();
const time = new Date().getTime();
let fileName = time + '_' + file.filename;
let saveFile = path.join(__dirname, '../../', `/client/assets/files/${fileFolder}`, fileName);
const pathUrl = `./client/assets/files/${fileFolder}`;
const res1 = fs.existsSync(`./client/assets/files/${fileFolder}`);
!res1 && fs.mkdirSync(`./client/assets/files/${fileFolder}`);
const res = fs.existsSync(pathUrl);
!res && fs.mkdirSync(pathUrl);
let stream = fs.createWriteStream(saveFile);
fs.createReadStream(file.path).pipe(stream);
stream.on('error', function (err) {
app.fs.logger.log('error', '[Upload Heatmap]', err);
});
ctx.status = 200;
ctx.body = { filename: path.join(`/assets/files/${fileFolder}`, fileName), name: 'UploadSuccess', message: '上传成功' };
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload error.' };
}
}
let remove = async function (ctx, next) {
try {
const fkeys = ctx.request.body;
let removeUrl = path.join(__dirname, '../../', './client', fkeys.url);
const res = fs.existsSync(removeUrl);
if (!res) {
ctx.status = 400;
ctx.body = JSON.stringify({ name: 'DeleteFailed', message: '文件地址不存在' });
return;
}
}
fs.unlink(removeUrl, function (error) {
if (error) {
console.log(error);
}
})
ctx.status = 200;
ctx.body = { name: 'DeleteSuccess.', message: '删除成功' };
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload cleanup error.' };
}
}
let upload_ = async function (ctx, next) {
let fkey = null;
try {
const { p } = ctx.params;
const { files } = await parse(ctx.req);
const file = files[0];
const extname = path.extname(file.filename).toLowerCase();
if (!UploadPath[p]) {
ctx.status = 400;
ctx.body = JSON.stringify({ error: '附件存放的文件夹名称无效' });
return;
} else if (UploadPath[p].indexOf(extname) < 0) {
ctx.status = 400;
ctx.body = JSON.stringify({ error: '文件格式无效' });
return;
} else {
const fileInfo = await ctx.app.fs.attachment.upload(file, { uploadPath: p });
fkey = fileInfo.key;
ctx.body = { uploaded: fkey };
}
} catch (err) {
ctx.status = 500;
ctx.fs.logger.error(err);
ctx.body = { err: 'upload error.' };
}
}
const uploadAliOSS = async (ctx,) => {
// 这个是上传到阿里
try {
const { aliOss } = opts
const { p = 'default' } = ctx.params;
const { files } = await parse(ctx.req);
const file = files[0];
const filename = file.filename || path.basename(file);
const client = new OSS({
// yourRegion填写Bucket所在地域.以华东1(杭州)为例,Region填写为oss-cn-hangzhou.
region: aliOss.region,
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高.强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户.
accessKeyId: aliOss.accessKey,
accessKeySecret: aliOss.secretKey,
// 填写Bucket名称,例如examplebucket.
bucket: aliOss.bucket,
});
let uploadPath = path.posix.join(p, uuid.v4(), filename);
let result = await client.putStream(
uploadPath,
file,
// { contentLength: size }
);
ctx.status = 200;
ctx.body = {
key: result.name,
uploaded: result.name,
url: result.url,
};
} catch (error) {
ctx.status = 400;
ctx.fs.logger.error(error);
ctx.body = { err: 'upload error.' };
const uploadAliOSS = async (ctx,) => {
// 这个是上传到阿里
try {
const { aliOss } = opts
const { p = 'default' } = ctx.params;
const { files } = await parse(ctx.req);
const file = files[0];
const filename = file.filename || path.basename(file);
const client = new OSS({
// yourRegion填写Bucket所在地域.以华东1(杭州)为例,Region填写为oss-cn-hangzhou.
region: aliOss.region,
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高.强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户.
accessKeyId: aliOss.accessKey,
accessKeySecret: aliOss.secretKey,
// 填写Bucket名称,例如examplebucket.
bucket: aliOss.bucket,
});
let uploadPath = path.posix.join(p, uuid.v4(), filename);
let result = await client.putStream(
uploadPath,
file,
// { contentLength: size }
);
ctx.status = 200;
ctx.body = {
key: result.name,
uploaded: result.name,
url: result.url,
};
} catch (error) {
ctx.status = 400;
ctx.fs.logger.error(error);
ctx.body = { err: 'upload error.' };
}
}
const downloadFromAli = async (ctx) => {
try {
const { aliOss } = opts
const { path, filename } = ctx.query
const client = new OSS({
// yourRegion填写Bucket所在地域.以华东1(杭州)为例,Region填写为oss-cn-hangzhou.
region: aliOss.region,
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高.强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户.
accessKeyId: aliOss.accessKey,
accessKeySecret: aliOss.secretKey,
// 填写Bucket名称,例如examplebucket.
bucket: aliOss.bucket,
});
const filename_ = filename || path.split('/').pop()
const result = await client.get(path);
ctx.status = 200;
ctx.set('Content-Type', 'application/x-xls');
ctx.set('Content-disposition', 'attachment; filename=' + filename_);
ctx.body = result.content;
} catch (error) {
ctx.status = 400;
ctx.fs.logger.error(error);
ctx.body = { err: 'download error.' };
}
}
const getFileBlob = (url) => {
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest()
request.open("GET", url, true)
request.responseType = "blob"
request.onload = (res) => {
if (res.target.status == 200) {
resolve(res.target.response)
} else {
reject(res)
}
}
}
request.send()
})
}
const downloadFromAli = async (ctx) => {
try {
const { aliOss } = opts
const { path, filename } = ctx.query
const client = new OSS({
// yourRegion填写Bucket所在地域.以华东1(杭州)为例,Region填写为oss-cn-hangzhou.
region: aliOss.region,
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高.强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户.
accessKeyId: aliOss.accessKey,
accessKeySecret: aliOss.secretKey,
// 填写Bucket名称,例如examplebucket.
bucket: aliOss.bucket,
});
const filename_ = filename || path.split('/').pop()
const result = await client.get(path);
ctx.status = 200;
ctx.set('Content-Type', 'application/x-xls');
ctx.set('Content-disposition', 'attachment; filename=' + filename_);
ctx.body = result.content;
} catch (error) {
ctx.status = 400;
ctx.fs.logger.error(error);
ctx.body = { err: 'download error.' };
const packBulk = async (ctx) => {
console.log(11111,);
try {
const { fileUrl, folderId } = parse(ctx.req)
const zip = new JSZip()
let result = []
let files = []
console.log(22,fileUrl);
fileUrl.map(a => {
let url = path.join(__dirname, '../../', './client', a);
files.push({ url, name: 111 })
})
for (let i in files) {
let promise = getFileBlob(files[i].url).then((res) => {
let format = files[i].url.substring(files[i].url.lastIndexOf("."), files[i].url.length)
zip.file(files[i].name + format, res, { binary: true })
})
result.push(promise)
console.log(77, promise);
}
}
router.use(download_);
router.post('/_upload/new', upload);
router.delete('/_upload/cleanup', remove);
router.post('/_upload/attachments/ali/:p', uploadAliOSS);
router.get('/_download/attachments/ali', downloadFromAli);
router.post('/_upload/attachments/:p', upload_);
}
console.log(33,);
Promise.all(result).then(() => {
zip.generateAsync({ type: "blob" }).then((res) => {
console.log(55,);
saveAs(res, `${111}.zip`)
})
})
console.log(44,);
ctx.status = 200;
ctx.body = {};
} catch (error) {
ctx.status = 400;
ctx.fs.logger.error(error);
ctx.body = { err: 'download error.' };
}
}
router.use(download_);
router.post('/_upload/new', upload);
router.delete('/_upload/cleanup', remove);
router.post('/_upload/attachments/ali/:p', uploadAliOSS);
router.get('/_download/attachments/ali', downloadFromAli);
router.post('/_upload/attachments/:p', upload_);
router.post('/packBulk/:p', packBulk);
}
};

Loading…
Cancel
Save