diff --git a/es/components/article/upsert/index.js b/es/components/article/upsert/index.js index 639255248..6e29b2180 100644 --- a/es/components/article/upsert/index.js +++ b/es/components/article/upsert/index.js @@ -81,7 +81,7 @@ export default OakComponent({ // return result; // }, async uploadFile(extraFile) { - const result = await this.features.extraFile.createAndUpload(extraFile); + const result = await this.features.extraFile.createAndUpload(extraFile, extraFile.extra1); return result; }, setEditor(editor) { diff --git a/es/components/editor/index.js b/es/components/editor/index.js index 68e23121d..e94870bd0 100644 --- a/es/components/editor/index.js +++ b/es/components/editor/index.js @@ -105,9 +105,7 @@ export default OakComponent({ bucket: '', id: generateNewId(), }; - const { url, bucket } = await this.features.extraFile.createAndUpload(extraFile); - extraFile.bucket = bucket; - extraFile.extra1 = null; + const { url } = await this.features.extraFile.createAndUpload(extraFile, extraFile.extra1); // await this.addExtraFile(extraFile); this.editorCtx.insertImage({ src: 'http://' + url, diff --git a/es/components/extraFile/gallery/index.js b/es/components/extraFile/gallery/index.js index 426d8414e..f4b0152df 100644 --- a/es/components/extraFile/gallery/index.js +++ b/es/components/extraFile/gallery/index.js @@ -20,6 +20,7 @@ export default OakComponent({ fileType: 1, sort: 1, isBridge: 1, + uploadState: 1, }, formData({ data: originalFiles, features }) { console.log(originalFiles); @@ -96,7 +97,9 @@ export default OakComponent({ getUrl(extraFile) { const { fileList } = this.state; if (fileList[extraFile?.id]) { + console.log(fileList[extraFile?.id]); const url = this.features.extraFile.getUrl(Object.assign({}, extraFile, { extra1: fileList[extraFile?.id] })); + console.log(url); return url; } return this.features.extraFile.getUrl(extraFile); @@ -238,7 +241,6 @@ export default OakComponent({ assert(origin === 'qiniu', '目前只支持七牛上传'); // 目前只支持七牛上传 const id = generateNewId(); const updateData = { - extra1, origin, type: type || 'file', tag1, @@ -259,9 +261,7 @@ export default OakComponent({ callback(updateData, 'uploading'); } try { - this.addItem(Object.assign({}, updateData, { - extra1: null, - }), undefined, async () => { + this.addItem(updateData, undefined, async () => { await this.features.extraFile.upload(updateData, extra1); }); await this.execute(); @@ -278,9 +278,7 @@ export default OakComponent({ } } else { - this.addItem(Object.assign({}, updateData, { - extra1: null, - }), undefined, async () => { + this.addItem(updateData, undefined, async () => { await this.features.extraFile.upload(updateData, extra1); }); this.setState({ @@ -313,10 +311,17 @@ export default OakComponent({ }, async onDeleteByMp(event) { const { value } = event.currentTarget.dataset; - const { id, bucket, origin } = value; + const { id, bucket, origin, uploadState } = value; const { removeLater } = this.props; - if (removeLater || (origin !== 'unknown' && !bucket)) { + const { fileList } = this.state; + if (removeLater || !uploadState) { this.removeItem(id); + Object.assign(fileList, { + [id]: null, + }); + this.setState({ + fileList + }); } else { const result = await wx.showModal({ @@ -326,16 +331,29 @@ export default OakComponent({ const { confirm } = result; if (confirm) { this.removeItem(id); + Object.assign(fileList, { + id: null, + }); + this.setState({ + fileList + }); await this.execute(); } } }, async onDeleteByWeb(value) { - const { id, bucket, origin } = value; + const { id, bucket, origin, uploadState } = value; const { removeLater = true } = this.props; + const { fileList } = this.state; // 如果 removeLater为true 或 origin === 'qiniu' 且 bucket不存在 - if (removeLater || (origin !== 'unknown' && !bucket)) { + if (removeLater || !uploadState) { this.removeItem(id); + Object.assign(fileList, { + id: null, + }); + this.setState({ + fileList + }); } else { const confirm = Dialog.confirm({ @@ -345,6 +363,12 @@ export default OakComponent({ okText: '确定', onOk: async (e) => { this.removeItem(id); + Object.assign(fileList, { + id: null, + }); + this.setState({ + fileList + }); await this.execute(); confirm.destroy(); }, diff --git a/es/components/extraFile/gallery/web.d.ts b/es/components/extraFile/gallery/web.d.ts index f79ca1736..3006f11c8 100644 --- a/es/components/extraFile/gallery/web.d.ts +++ b/es/components/extraFile/gallery/web.d.ts @@ -3,6 +3,7 @@ import { WebComponentProps } from "oak-frontend-base"; import { EntityDict } from "../../../oak-app-domain"; interface NewUploadFile extends UploadFile { id?: string; + status?: 'done' | 'uploading' | 'error' | 'removed'; } type Theme = "file" | "image" | "image-flow" | "custom"; export default function render(props: WebComponentProps { + let status = undefined; + switch (extraFile.uploadState) { + case 'uploading': { + status = 'uploading'; + break; + } + case 'failed': { + status = 'error'; + break; + } + case 'success': { + status = 'done'; + break; + } + } return Object.assign({}, extraFile, { id: extraFile.id, url: getUrl(extraFile), @@ -71,8 +86,9 @@ export default function render(props) { fileName: getFileName(extraFile), size: extraFile.size, type: extraFile.fileType, - uid: extraFile.id, //upload 组件需要uid来维护fileList - // status: 'done', + uid: extraFile.id, + status, + percent: status === 'uploading' ? 50 : undefined, }); }; const setNewUploadFilesByStatus = (file, status) => { diff --git a/es/features/extraFile.d.ts b/es/features/extraFile.d.ts index b31173523..6a0bd0c8a 100644 --- a/es/features/extraFile.d.ts +++ b/es/features/extraFile.d.ts @@ -12,13 +12,10 @@ export declare class ExtraFile>, application: Application, locales: Locales); - createAndUpload(extraFile: EntityDict['extraFile']['CreateSingle']['data']): Promise<{ + createAndUpload(extraFile: EntityDict['extraFile']['CreateSingle']['data'], file: string | File): Promise<{ url: any; - bucket: ED["extraFile"]["Schema"]["bucket"] | undefined; - }>; - upload(extraFile: EntityDict['extraFile']['CreateSingle']['data'], file: string | File): Promise & { - uploadState: string; }>; + upload(extraFile: EntityDict['extraFile']['CreateSingle']['data'], file: string | File): Promise; getUrl(extraFile?: EntityDict['extraFile']['OpSchema'] | EntityDict['extraFile']['Schema'] | null, style?: string): any; /** * 使用该方法,要在使用完url时,通过URL.revokeObjectURL释放缓存 diff --git a/es/features/extraFile.js b/es/features/extraFile.js index c2ded723e..8b963eba3 100644 --- a/es/features/extraFile.js +++ b/es/features/extraFile.js @@ -14,22 +14,18 @@ export class ExtraFile extends Feature { this.application = application; this.locales = locales; } - async createAndUpload(extraFile) { + async createAndUpload(extraFile, file) { await this.cache.operate('extraFile', { action: 'create', - data: Object.assign({}, extraFile, { extra1: null }), + data: extraFile, id: generateNewId(), }); - const result = await this.upload(Object.assign({}, extraFile, { extra1: null }), extraFile.extra1); + await this.upload(extraFile, file); const application = this.application.getApplication(); const config = application?.system?.config || application?.system?.platform?.config; - const { bucket } = result; return { - url: this.getUrl(Object.assign({}, extraFile, { - extra1: null, - })), - bucket, + url: this.getUrl(extraFile), }; } async upload(extraFile, file) { @@ -73,7 +69,7 @@ export class ExtraFile extends Feature { }, id: generateNewId(), }); - return Object.assign(extraFileData, { uploadState: 'success' }); + this.publish(); } catch (err) { await this.cache.operate('extraFile', { @@ -86,6 +82,7 @@ export class ExtraFile extends Feature { }, id: generateNewId(), }); + this.publish(); throw err; } } diff --git a/es/pages/paper/upsert/index.js b/es/pages/paper/upsert/index.js index 7de881f56..1a2bd2bd5 100644 --- a/es/pages/paper/upsert/index.js +++ b/es/pages/paper/upsert/index.js @@ -81,7 +81,7 @@ export default OakComponent({ } }, uploadFile(extraFile) { - return this.features.extraFile.createAndUpload(extraFile); + return this.features.extraFile.createAndUpload(extraFile, extraFile.extra1); }, setEditor(editor) { this.setState({ diff --git a/es/types/Exception.d.ts b/es/types/Exception.d.ts index dd97847a1..498102e6f 100644 --- a/es/types/Exception.d.ts +++ b/es/types/Exception.d.ts @@ -40,6 +40,9 @@ export declare class OakMpHaveToSubscribeMessage extends Error { export declare class OakUserInfoLoadingException extends OakUserException { constructor(message?: string); } +export declare class OakUploadException extends OakUserException { + constructor(message?: string); +} export declare function makeException(data: { name: string; message?: string; diff --git a/es/types/Exception.js b/es/types/Exception.js index 148b12ed9..2b6a0aa69 100644 --- a/es/types/Exception.js +++ b/es/types/Exception.js @@ -88,6 +88,12 @@ export class OakUserInfoLoadingException extends OakUserException { } } ; +export class OakUploadException extends OakUserException { + constructor(message) { + super(message || '上传文件失败'); + } +} +; export function makeException(data) { const exception = makeException2(data); if (exception) { @@ -130,6 +136,11 @@ export function makeException(data) { e.setOpRecords(opRecords); return e; } + case 'OakUploadException': { + const e = new OakUploadException(message); + e.setOpRecords(opRecords); + return e; + } default: { return; } diff --git a/es/utils/uploader/qiniu.js b/es/utils/uploader/qiniu.js index 87ce32442..b1f0688fc 100644 --- a/es/utils/uploader/qiniu.js +++ b/es/utils/uploader/qiniu.js @@ -1,5 +1,6 @@ import { getConfig } from '../../utils/getContextConfig'; import { urlSafeBase64Encode } from '../sign'; +import { OakUploadException } from '../../types/Exception'; const QiniuSearchUrl = 'https://rs.qiniuapi.com/stat/EncodedEntryURI'; export default class Qiniu { name = 'qiniu'; @@ -16,14 +17,23 @@ export default class Qiniu { } async upload(extraFile, uploadFn, file) { const uploadMeta = extraFile.uploadMeta; - const result = await uploadFn(file, 'file', uploadMeta.uploadHost, { - key: uploadMeta.key, - token: uploadMeta.uploadToken, - }, true); - if (result.success === true || result.key) { - return; + try { + const result = await uploadFn(file, 'file', uploadMeta.uploadHost, { + key: uploadMeta.key, + token: uploadMeta.uploadToken, + }, true); + console.log(result); + // await new Promise( + // () => setTimeout(() => { return Promise.resolve() }, 10000) + // ) + if (result.success === true || result.key) { + return; + } } - throw new Error('图片上传失败'); + catch (err) { + throw new OakUploadException('图片上传失败'); + } + throw new OakUploadException('图片上传失败'); } composeFileUrl(extraFile, config, style) { const { objectId, extension, entity, } = extraFile || {}; diff --git a/lib/components/article/upsert/index.js b/lib/components/article/upsert/index.js index 5d85c9819..fadd8eaaf 100644 --- a/lib/components/article/upsert/index.js +++ b/lib/components/article/upsert/index.js @@ -83,7 +83,7 @@ exports.default = OakComponent({ // return result; // }, async uploadFile(extraFile) { - const result = await this.features.extraFile.createAndUpload(extraFile); + const result = await this.features.extraFile.createAndUpload(extraFile, extraFile.extra1); return result; }, setEditor(editor) { diff --git a/lib/components/editor/index.js b/lib/components/editor/index.js index 9e2e14bc5..3f45f6d53 100644 --- a/lib/components/editor/index.js +++ b/lib/components/editor/index.js @@ -107,9 +107,7 @@ exports.default = OakComponent({ bucket: '', id: (0, uuid_1.generateNewId)(), }; - const { url, bucket } = await this.features.extraFile.createAndUpload(extraFile); - extraFile.bucket = bucket; - extraFile.extra1 = null; + const { url } = await this.features.extraFile.createAndUpload(extraFile, extraFile.extra1); // await this.addExtraFile(extraFile); this.editorCtx.insertImage({ src: 'http://' + url, diff --git a/lib/components/extraFile/gallery/index.js b/lib/components/extraFile/gallery/index.js index e4049a988..77bfcc2a2 100644 --- a/lib/components/extraFile/gallery/index.js +++ b/lib/components/extraFile/gallery/index.js @@ -23,6 +23,7 @@ exports.default = OakComponent({ fileType: 1, sort: 1, isBridge: 1, + uploadState: 1, }, formData({ data: originalFiles, features }) { console.log(originalFiles); @@ -99,7 +100,9 @@ exports.default = OakComponent({ getUrl(extraFile) { const { fileList } = this.state; if (fileList[extraFile?.id]) { + console.log(fileList[extraFile?.id]); const url = this.features.extraFile.getUrl(Object.assign({}, extraFile, { extra1: fileList[extraFile?.id] })); + console.log(url); return url; } return this.features.extraFile.getUrl(extraFile); @@ -241,7 +244,6 @@ exports.default = OakComponent({ (0, assert_1.default)(origin === 'qiniu', '目前只支持七牛上传'); // 目前只支持七牛上传 const id = (0, uuid_1.generateNewId)(); const updateData = { - extra1, origin, type: type || 'file', tag1, @@ -262,9 +264,7 @@ exports.default = OakComponent({ callback(updateData, 'uploading'); } try { - this.addItem(Object.assign({}, updateData, { - extra1: null, - }), undefined, async () => { + this.addItem(updateData, undefined, async () => { await this.features.extraFile.upload(updateData, extra1); }); await this.execute(); @@ -281,9 +281,7 @@ exports.default = OakComponent({ } } else { - this.addItem(Object.assign({}, updateData, { - extra1: null, - }), undefined, async () => { + this.addItem(updateData, undefined, async () => { await this.features.extraFile.upload(updateData, extra1); }); this.setState({ @@ -316,10 +314,17 @@ exports.default = OakComponent({ }, async onDeleteByMp(event) { const { value } = event.currentTarget.dataset; - const { id, bucket, origin } = value; + const { id, bucket, origin, uploadState } = value; const { removeLater } = this.props; - if (removeLater || (origin !== 'unknown' && !bucket)) { + const { fileList } = this.state; + if (removeLater || !uploadState) { this.removeItem(id); + Object.assign(fileList, { + [id]: null, + }); + this.setState({ + fileList + }); } else { const result = await wx.showModal({ @@ -329,16 +334,29 @@ exports.default = OakComponent({ const { confirm } = result; if (confirm) { this.removeItem(id); + Object.assign(fileList, { + id: null, + }); + this.setState({ + fileList + }); await this.execute(); } } }, async onDeleteByWeb(value) { - const { id, bucket, origin } = value; + const { id, bucket, origin, uploadState } = value; const { removeLater = true } = this.props; + const { fileList } = this.state; // 如果 removeLater为true 或 origin === 'qiniu' 且 bucket不存在 - if (removeLater || (origin !== 'unknown' && !bucket)) { + if (removeLater || !uploadState) { this.removeItem(id); + Object.assign(fileList, { + id: null, + }); + this.setState({ + fileList + }); } else { const confirm = index_1.default.confirm({ @@ -348,6 +366,12 @@ exports.default = OakComponent({ okText: '确定', onOk: async (e) => { this.removeItem(id); + Object.assign(fileList, { + id: null, + }); + this.setState({ + fileList + }); await this.execute(); confirm.destroy(); }, diff --git a/lib/components/extraFile/gallery/web.d.ts b/lib/components/extraFile/gallery/web.d.ts index f79ca1736..3006f11c8 100644 --- a/lib/components/extraFile/gallery/web.d.ts +++ b/lib/components/extraFile/gallery/web.d.ts @@ -3,6 +3,7 @@ import { WebComponentProps } from "oak-frontend-base"; import { EntityDict } from "../../../oak-app-domain"; interface NewUploadFile extends UploadFile { id?: string; + status?: 'done' | 'uploading' | 'error' | 'removed'; } type Theme = "file" | "image" | "image-flow" | "custom"; export default function render(props: WebComponentProps { + let status = undefined; + switch (extraFile.uploadState) { + case 'uploading': { + status = 'uploading'; + break; + } + case 'failed': { + status = 'error'; + break; + } + case 'success': { + status = 'done'; + break; + } + } return Object.assign({}, extraFile, { id: extraFile.id, url: getUrl(extraFile), @@ -74,8 +89,9 @@ function render(props) { fileName: getFileName(extraFile), size: extraFile.size, type: extraFile.fileType, - uid: extraFile.id, //upload 组件需要uid来维护fileList - // status: 'done', + uid: extraFile.id, + status, + percent: status === 'uploading' ? 50 : undefined, }); }; const setNewUploadFilesByStatus = (file, status) => { diff --git a/lib/features/extraFile.d.ts b/lib/features/extraFile.d.ts index b31173523..6a0bd0c8a 100644 --- a/lib/features/extraFile.d.ts +++ b/lib/features/extraFile.d.ts @@ -12,13 +12,10 @@ export declare class ExtraFile>, application: Application, locales: Locales); - createAndUpload(extraFile: EntityDict['extraFile']['CreateSingle']['data']): Promise<{ + createAndUpload(extraFile: EntityDict['extraFile']['CreateSingle']['data'], file: string | File): Promise<{ url: any; - bucket: ED["extraFile"]["Schema"]["bucket"] | undefined; - }>; - upload(extraFile: EntityDict['extraFile']['CreateSingle']['data'], file: string | File): Promise & { - uploadState: string; }>; + upload(extraFile: EntityDict['extraFile']['CreateSingle']['data'], file: string | File): Promise; getUrl(extraFile?: EntityDict['extraFile']['OpSchema'] | EntityDict['extraFile']['Schema'] | null, style?: string): any; /** * 使用该方法,要在使用完url时,通过URL.revokeObjectURL释放缓存 diff --git a/lib/features/extraFile.js b/lib/features/extraFile.js index ec2654216..d4865134a 100644 --- a/lib/features/extraFile.js +++ b/lib/features/extraFile.js @@ -18,22 +18,18 @@ class ExtraFile extends oak_frontend_base_1.Feature { this.application = application; this.locales = locales; } - async createAndUpload(extraFile) { + async createAndUpload(extraFile, file) { await this.cache.operate('extraFile', { action: 'create', - data: Object.assign({}, extraFile, { extra1: null }), + data: extraFile, id: (0, uuid_1.generateNewId)(), }); - const result = await this.upload(Object.assign({}, extraFile, { extra1: null }), extraFile.extra1); + await this.upload(extraFile, file); const application = this.application.getApplication(); const config = application?.system?.config || application?.system?.platform?.config; - const { bucket } = result; return { - url: this.getUrl(Object.assign({}, extraFile, { - extra1: null, - })), - bucket, + url: this.getUrl(extraFile), }; } async upload(extraFile, file) { @@ -77,7 +73,7 @@ class ExtraFile extends oak_frontend_base_1.Feature { }, id: (0, uuid_1.generateNewId)(), }); - return Object.assign(extraFileData, { uploadState: 'success' }); + this.publish(); } catch (err) { await this.cache.operate('extraFile', { @@ -90,6 +86,7 @@ class ExtraFile extends oak_frontend_base_1.Feature { }, id: (0, uuid_1.generateNewId)(), }); + this.publish(); throw err; } } diff --git a/lib/pages/paper/upsert/index.js b/lib/pages/paper/upsert/index.js index d6acc26f0..9518068e6 100644 --- a/lib/pages/paper/upsert/index.js +++ b/lib/pages/paper/upsert/index.js @@ -83,7 +83,7 @@ exports.default = OakComponent({ } }, uploadFile(extraFile) { - return this.features.extraFile.createAndUpload(extraFile); + return this.features.extraFile.createAndUpload(extraFile, extraFile.extra1); }, setEditor(editor) { this.setState({ diff --git a/lib/types/Exception.d.ts b/lib/types/Exception.d.ts index dd97847a1..498102e6f 100644 --- a/lib/types/Exception.d.ts +++ b/lib/types/Exception.d.ts @@ -40,6 +40,9 @@ export declare class OakMpHaveToSubscribeMessage extends Error { export declare class OakUserInfoLoadingException extends OakUserException { constructor(message?: string); } +export declare class OakUploadException extends OakUserException { + constructor(message?: string); +} export declare function makeException(data: { name: string; message?: string; diff --git a/lib/types/Exception.js b/lib/types/Exception.js index 26d81d14b..bfdb3208b 100644 --- a/lib/types/Exception.js +++ b/lib/types/Exception.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.makeException = exports.OakUserInfoLoadingException = exports.OakMpHaveToSubscribeMessage = exports.OakTokenExpiredException = exports.OakUserDisabledException = exports.OakUserInfoUncompletedException = exports.OakMobileUnsetException = exports.OakChangeLoginWayException = exports.OakDistinguishUserException = exports.OakNotEnoughMoneyException = void 0; +exports.makeException = exports.OakUploadException = exports.OakUserInfoLoadingException = exports.OakMpHaveToSubscribeMessage = exports.OakTokenExpiredException = exports.OakUserDisabledException = exports.OakUserInfoUncompletedException = exports.OakMobileUnsetException = exports.OakChangeLoginWayException = exports.OakDistinguishUserException = exports.OakNotEnoughMoneyException = void 0; const types_1 = require("oak-domain/lib/types"); class OakNotEnoughMoneyException extends types_1.OakUserException { constructor(message) { @@ -100,6 +100,13 @@ class OakUserInfoLoadingException extends types_1.OakUserException { } exports.OakUserInfoLoadingException = OakUserInfoLoadingException; ; +class OakUploadException extends types_1.OakUserException { + constructor(message) { + super(message || '上传文件失败'); + } +} +exports.OakUploadException = OakUploadException; +; function makeException(data) { const exception = (0, types_1.makeException)(data); if (exception) { @@ -142,6 +149,11 @@ function makeException(data) { e.setOpRecords(opRecords); return e; } + case 'OakUploadException': { + const e = new OakUploadException(message); + e.setOpRecords(opRecords); + return e; + } default: { return; } diff --git a/lib/utils/uploader/qiniu.js b/lib/utils/uploader/qiniu.js index 5fddefb10..8e90aaab3 100644 --- a/lib/utils/uploader/qiniu.js +++ b/lib/utils/uploader/qiniu.js @@ -2,6 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const getContextConfig_1 = require("../../utils/getContextConfig"); const sign_1 = require("../sign"); +const Exception_1 = require("../../types/Exception"); const QiniuSearchUrl = 'https://rs.qiniuapi.com/stat/EncodedEntryURI'; class Qiniu { name = 'qiniu'; @@ -18,14 +19,23 @@ class Qiniu { } async upload(extraFile, uploadFn, file) { const uploadMeta = extraFile.uploadMeta; - const result = await uploadFn(file, 'file', uploadMeta.uploadHost, { - key: uploadMeta.key, - token: uploadMeta.uploadToken, - }, true); - if (result.success === true || result.key) { - return; + try { + const result = await uploadFn(file, 'file', uploadMeta.uploadHost, { + key: uploadMeta.key, + token: uploadMeta.uploadToken, + }, true); + console.log(result); + // await new Promise( + // () => setTimeout(() => { return Promise.resolve() }, 10000) + // ) + if (result.success === true || result.key) { + return; + } } - throw new Error('图片上传失败'); + catch (err) { + throw new Exception_1.OakUploadException('图片上传失败'); + } + throw new Exception_1.OakUploadException('图片上传失败'); } composeFileUrl(extraFile, config, style) { const { objectId, extension, entity, } = extraFile || {}; diff --git a/src/components/article/upsert/index.ts b/src/components/article/upsert/index.ts index 606f4cd3d..b52d03e24 100644 --- a/src/components/article/upsert/index.ts +++ b/src/components/article/upsert/index.ts @@ -90,7 +90,7 @@ export default OakComponent({ async uploadFile( extraFile: EntityDict['extraFile']['CreateSingle']['data'] ) { - const result = await this.features.extraFile.createAndUpload(extraFile); + const result = await this.features.extraFile.createAndUpload(extraFile, extraFile.extra1!); return result; }, diff --git a/src/components/editor/index.ts b/src/components/editor/index.ts index a17d14124..adf6d91c5 100644 --- a/src/components/editor/index.ts +++ b/src/components/editor/index.ts @@ -114,10 +114,9 @@ export default OakComponent({ bucket: '', id: generateNewId(), } as EntityDict['extraFile']['CreateSingle']['data']; - const { url, bucket } = - await this.features.extraFile.createAndUpload(extraFile); - extraFile.bucket = bucket; - extraFile.extra1 = null; + const { url } = + await this.features.extraFile.createAndUpload(extraFile, extraFile.extra1!); + // await this.addExtraFile(extraFile); (this as any).editorCtx.insertImage({ src: 'http://' + url, diff --git a/src/components/extraFile/gallery/index.ts b/src/components/extraFile/gallery/index.ts index 9ba1426f5..0cbc9d5a6 100644 --- a/src/components/extraFile/gallery/index.ts +++ b/src/components/extraFile/gallery/index.ts @@ -29,6 +29,7 @@ export default OakComponent({ fileType: 1, sort: 1, isBridge: 1, + uploadState: 1, }, formData({ data: originalFiles, features }) { console.log(originalFiles); @@ -111,7 +112,9 @@ export default OakComponent({ getUrl(extraFile: EntityDict['extraFile']['OpSchema']) { const { fileList } = this.state; if (fileList[extraFile?.id]) { + console.log(fileList[extraFile?.id]); const url = this.features.extraFile.getUrl(Object.assign({}, extraFile, { extra1: fileList[extraFile?.id] })); + console.log(url); return url; } return this.features.extraFile.getUrl(extraFile); @@ -278,7 +281,6 @@ export default OakComponent({ assert(origin === 'qiniu', '目前只支持七牛上传'); // 目前只支持七牛上传 const id = generateNewId(); const updateData = { - extra1, origin, type: type || 'file', tag1, @@ -299,9 +301,7 @@ export default OakComponent({ callback(updateData, 'uploading'); } try { - this.addItem(Object.assign({}, updateData, { - extra1: null, - }), undefined, async () => { + this.addItem(updateData, undefined, async () => { await this.features.extraFile.upload( updateData, extra1 ) @@ -319,9 +319,7 @@ export default OakComponent({ throw error; } } else { - this.addItem(Object.assign({}, updateData, { - extra1: null, - }), undefined, async () => { + this.addItem(updateData, undefined, async () => { await this.features.extraFile.upload( updateData, extra1 ) @@ -359,10 +357,19 @@ export default OakComponent({ }, async onDeleteByMp(event: WechatMiniprogram.Touch) { const { value } = event.currentTarget.dataset; - const { id, bucket, origin } = value; + const { id, bucket, origin, uploadState } = value; const { removeLater } = this.props; - if (removeLater || (origin !== 'unknown' && !bucket)) { + const { fileList } = this.state; + if (removeLater || !uploadState) { this.removeItem(id); + Object.assign( + fileList, { + [id]: null, + } + ); + this.setState({ + fileList + }); } else { const result = await wx.showModal({ title: '确认删除吗', @@ -371,16 +378,33 @@ export default OakComponent({ const { confirm } = result; if (confirm) { this.removeItem(id); + Object.assign( + fileList, { + id: null, + } + ); + this.setState({ + fileList + }); await this.execute(); } } }, async onDeleteByWeb(value: any) { - const { id, bucket, origin } = value; + const { id, bucket, origin, uploadState } = value; const { removeLater = true } = this.props; + const { fileList } = this.state; // 如果 removeLater为true 或 origin === 'qiniu' 且 bucket不存在 - if (removeLater || (origin !== 'unknown' && !bucket)) { + if (removeLater || !uploadState) { this.removeItem(id); + Object.assign( + fileList, { + id: null, + } + ); + this.setState({ + fileList + }); } else { const confirm = Dialog.confirm({ title: '确认删除当前文件?', @@ -389,6 +413,14 @@ export default OakComponent({ okText: '确定', onOk: async (e: any) => { this.removeItem(id); + Object.assign( + fileList, { + id: null, + } + ); + this.setState({ + fileList + }); await this.execute(); confirm.destroy(); }, diff --git a/src/components/extraFile/gallery/web.tsx b/src/components/extraFile/gallery/web.tsx index 3d4b385c3..b65c949f9 100644 --- a/src/components/extraFile/gallery/web.tsx +++ b/src/components/extraFile/gallery/web.tsx @@ -15,6 +15,7 @@ import { isPc } from "oak-frontend-base/es/utils/utils"; interface NewUploadFile extends UploadFile { id?: string; + status?: 'done' | 'uploading' | 'error' | 'removed'; } type Theme = "file" | "image" | "image-flow" | "custom"; @@ -158,6 +159,21 @@ export default function render( const extraFileToUploadFile = ( extraFile: EntityDict["extraFile"]["OpSchema"] ): NewUploadFile => { + let status = undefined as NewUploadFile['status']; + switch (extraFile.uploadState) { + case 'uploading': { + status = 'uploading'; + break; + } + case 'failed': { + status = 'error'; + break; + } + case 'success': { + status = 'done'; + break; + } + } return Object.assign({}, extraFile, { id: extraFile.id, url: getUrl(extraFile), @@ -167,7 +183,8 @@ export default function render( size: extraFile.size!, type: extraFile.fileType!, uid: extraFile.id, //upload 组件需要uid来维护fileList - // status: 'done', + status, + percent: status === 'uploading' ? 50 : undefined, }); }; diff --git a/src/features/extraFile.ts b/src/features/extraFile.ts index a4fd8bc91..c52a957d3 100644 --- a/src/features/extraFile.ts +++ b/src/features/extraFile.ts @@ -36,29 +36,26 @@ export class ExtraFile< } async createAndUpload( - extraFile: EntityDict['extraFile']['CreateSingle']['data'] + extraFile: EntityDict['extraFile']['CreateSingle']['data'], + file: string | File, ) { await this.cache.operate('extraFile', { action: 'create', - data: Object.assign({}, extraFile, { extra1: null }), + data: extraFile, id: generateNewId(), } as EntityDict['extraFile']['Operation']); - const result = await this.upload( - Object.assign({}, extraFile, { extra1: null }), - extraFile.extra1! + await this.upload( + extraFile, + file ); const application = this.application.getApplication(); const config = application?.system?.config || application?.system?.platform?.config; - const { bucket } = result; return { url: this.getUrl( - Object.assign({}, extraFile, { - extra1: null, - }) as EntityDict['extraFile']['OpSchema'] + extraFile as EntityDict['extraFile']['OpSchema'] ), - bucket, }; } @@ -110,7 +107,7 @@ export class ExtraFile< }, id: generateNewId(), } as EntityDict['extraFile']['Operation']); - return Object.assign(extraFileData, { uploadState: 'success' }); + this.publish(); } catch (err) { await this.cache.operate('extraFile', { action: 'update', @@ -122,6 +119,7 @@ export class ExtraFile< }, id: generateNewId(), } as EntityDict['extraFile']['Operation']); + this.publish(); throw err; } } diff --git a/src/pages/paper/upsert/index.ts b/src/pages/paper/upsert/index.ts index 7a4174442..db013e3a6 100644 --- a/src/pages/paper/upsert/index.ts +++ b/src/pages/paper/upsert/index.ts @@ -90,7 +90,7 @@ export default OakComponent({ }, uploadFile(extraFile: EntityDict['extraFile']['CreateSingle']['data']) { - return this.features.extraFile.createAndUpload(extraFile); + return this.features.extraFile.createAndUpload(extraFile, extraFile.extra1!); }, setEditor(editor: IDomEditor | null) { diff --git a/src/types/Exception.ts b/src/types/Exception.ts index c59dbfad9..7603b923e 100644 --- a/src/types/Exception.ts +++ b/src/types/Exception.ts @@ -101,6 +101,12 @@ export class OakUserInfoLoadingException } }; +export class OakUploadException extends OakUserException { + constructor(message?: string) { + super(message || '上传文件失败'); + } +}; + export function makeException(data: { name: string; message?: string; @@ -149,6 +155,11 @@ export function makeException(data: { e.setOpRecords(opRecords); return e; } + case 'OakUploadException': { + const e = new OakUploadException(message); + e.setOpRecords(opRecords); + return e; + } default: { return; } diff --git a/src/utils/uploader/qiniu.ts b/src/utils/uploader/qiniu.ts index 6a1a2ef3d..a2e2f25e2 100644 --- a/src/utils/uploader/qiniu.ts +++ b/src/utils/uploader/qiniu.ts @@ -12,6 +12,7 @@ import { QiniuCloudInstance } from 'oak-external-sdk'; import { get } from 'oak-domain/lib/utils/lodash'; import { Config } from '../../types/Config'; import { urlSafeBase64Encode } from '../sign'; +import { OakUploadException } from '../../types/Exception'; const QiniuSearchUrl = 'https://rs.qiniuapi.com/stat/EncodedEntryURI'; @@ -54,20 +55,28 @@ export default class Qiniu implements Up file: string | File ) { const uploadMeta = extraFile.uploadMeta! as QiniuUploadInfo; - const result = await uploadFn( - file, - 'file', - uploadMeta.uploadHost, - { - key: uploadMeta.key, - token: uploadMeta.uploadToken, - }, - true - ); + let result; + try { + result = await uploadFn( + file, + 'file', + uploadMeta.uploadHost, + { + key: uploadMeta.key, + token: uploadMeta.uploadToken, + }, + true + ); + } catch (err) { + // 网络错误 + throw new OakUploadException('图片上传失败'); + } + // 解析回调 if (result.success === true || result.key) { return; + } else { + throw new OakUploadException('图片上传失败'); } - throw new Error('图片上传失败'); } composeFileUrl( @@ -113,6 +122,7 @@ export default class Qiniu implements Up return false; } + async removeFile(extraFile: OpSchema, context: BackendRuntimeContext) { const { bucket, uploadMeta } = extraFile; }