oak-general-business/src/components/extraFile/forUrl/index.ts

277 lines
9.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { generateNewId } from 'oak-domain/lib/utils/uuid';
import { assert } from 'oak-domain/lib/utils/assert';
import { EntityDict } from '../../../oak-app-domain';
import { OpSchema as ExtraFile } from '../../../oak-app-domain/ExtraFile/Schema';
import { isEqual } from 'oak-domain/lib/utils/lodash';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
import { ReactComponentProps } from 'oak-frontend-base';
type MethodsType = 'original' | 'url' | 'uploadLocalImg';
type RenderImgItem = { renderUrl: any, originUrl: string, id: number, isBridge: boolean };
export default OakComponent({
entity: 'extraFile',
isList: true,
projection: {
id: 1,
tag1: 1,
tag2: 1,
origin: 1,
bucket: 1,
objectId: 1,
filename: 1,
extra1: 1,
extension: 1,
type: 1,
entity: 1,
entityId: 1,
fileType: 1,
sort: 1,
isBridge: 1,
},
filters: [
{
filter() {
const { tag1, tag2 } = this.props;
const filter1 = {};
if (tag1) {
Object.assign(filter1, { tag1 });
}
if (tag2) {
Object.assign(filter1, { tag2 });
}
return filter1;
},
},
],
formData({ data: originalFiles, features }) {
let file;
const notDeleteFiles = originalFiles?.filter((ele) => !ele.$$deleteAt$$);
if (this.props.tag1) {
file = notDeleteFiles?.filter((ele) => ele?.tag1 === this.props.tag1)?.[0];
}
if (this.props.tag2) {
file = notDeleteFiles?.filter((ele) => ele?.tag2 === this.props.tag2)?.[0];
}
return {
file,
src: features.extraFile.getUrl(file as ExtraFile),
isBridge: file?.isBridge,
};
},
data: {
isModalOpen: false,
isModalOpen1: false,
renderImgs: [] as RenderImgItem[], // 读取的原文图片在modal使用
methodsType: '' as MethodsType,
bridgeUrl: '', // 通过桥接方式获得的url
selectedId: -1,
},
properties: {
type: '',
tag1: '',
tag2: '',
entity: '' as keyof EntityDict,
entityId: '',
imgUrls: [] as string[],
},
lifetimes: {
},
listeners: {
async imgUrls(prev, next) {
// 所以此处增加前后项imgUrls里都有值且不等的条件再去clean
if (prev?.imgUrls.length && next?.imgUrls.length && !isEqual(prev.imgUrls, next.imgUrls)) {
this.clean();
}
}
},
methods: {
async chooseMethod(method: MethodsType) {
switch (method) {
case 'uploadLocalImg':
const fileInput = document.createElement('input');
const imgElement = document.getElementById('previewImg') as HTMLImageElement;
fileInput.type = 'file';
fileInput.accept = 'image/png, image/jpeg'
fileInput.style.display = 'none';
fileInput.addEventListener('change', (e) => {
if (!fileInput.files || fileInput.files.length === 0) {
return;
}
this.myUpdateItem(fileInput.files[0]);
});
fileInput.click();
this.setState({
methodsType: method
})
this.setSelectedId(-1);
break;
case 'url':
this.setState({
isModalOpen: true,
methodsType: method
})
break;
case 'original':
this.setState({
isModalOpen1: true,
methodsType: method
})
const { imgUrls } = this.props;
const { renderImgs } = this.state;
let renderImgs2: RenderImgItem[] = new Array(...renderImgs);
if (imgUrls && imgUrls.length) {
for (let i = 0; i < imgUrls.length; i++) {
if (renderImgs2[i] && renderImgs2[i].originUrl === imgUrls[i]) {
return;
}
else if (renderImgs2[i] && renderImgs2[i].originUrl !== imgUrls[i]) {
renderImgs2 = [];
}
let renderUrl: string;
const isWechatUrl = this.isWechatUrlFn(imgUrls[i]);
if (isWechatUrl) {
renderUrl = this.features.extraFile.getUrl({ isBridge: true, extra1: imgUrls[i] } as ExtraFile);
}
else {
renderUrl = imgUrls[i]
}
renderImgs2.push({
renderUrl,
originUrl: imgUrls[i],
id: i,
isBridge: isWechatUrl
});
}
this.setState({
renderImgs: renderImgs2,
})
}
break;
}
},
closeModal() {
this.setState({
isModalOpen: false,
})
},
closeModal1() {
this.setState({
isModalOpen1: false,
});
},
createExtraFileData(params: File | string) {
const { methodsType } = this.state;
const { tag1, tag2, entity, entityId } = this.props;
let extension = '';
let filename = '';
const createData = {
extra1: params,
entity,
entityId,
type: 'image',
tag1,
tag2,
bucket: '',
id: generateNewId(),
} as EntityDict['extraFile']['CreateSingle']['data'];
assert(entity, '必须传入entity');
switch (methodsType) {
case 'uploadLocalImg':
const { name, size, type } = params as File;
extension = name.substring(name.lastIndexOf('.') + 1);
filename = name.substring(0, name.lastIndexOf('.'));
Object.assign(createData, {
origin: 'qiniu',
extension,
filename,
size,
fileType: type,
});
break;
case 'url':
Object.assign(createData, {
origin: 'unknown',
extension,
filename,
isBridge: this.isWechatUrlFn(params)
});
break;
case 'original':
Object.assign(createData, {
origin: 'unknown',
extension,
filename,
isBridge: this.isWechatUrlFn(params)
})
break;
}
return createData;
},
async myAddItem(createData: EntityDict['extraFile']['CreateSingle']['data']) {
// 目前只支持七牛上传
const { methodsType } = this.state;
this.addItem(Object.assign(createData, {
extra1: null,
}), async () => {
if (createData.bucket) {
// 说明本函数已经执行过了
return;
}
}, async () => {
await this.features.extraFile.upload(
createData, createData.extra1!
)
});
},
async myUpdateItem(params: File | string) {
const { file } = this.state;
if (file) {
this.removeItem(file.id);
}
if (!!params) {
const createData = this.createExtraFileData(params);
this.myAddItem(createData);
}
},
onModalConfirm(value: string) {
const reg = new RegExp(/(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/);
if (!reg.test(value)) {
return
}
this.myUpdateItem(value);
this.setSelectedId(-1);
},
onModal1Confirm(value: number) {
const { renderImgs } = this.state;
const img = renderImgs.find((ele) => ele.id === value);
this.myUpdateItem(img?.originUrl);
this.closeModal1();
},
isWechatUrlFn(url: string) {
return (url.startsWith('https://mmbiz.qpic.cn') || url.startsWith('http://mmbiz.qpic.cn'));
},
setSelectedId(id: number) {
this.setState({
selectedId: id
});
}
}
}) as <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(
props: ReactComponentProps<
ED2,
T2,
true,
{
type: string,
origin: string,
tag1: string,
tag2: string,
entity: keyof ED2,
entityId: string,
imgUrls: string[],
}
>
) => React.ReactElement;