UploadServices.js
Home
/
FileServer /
SPA /
src /
JS /
Services /
UploadServices.js
import ApiQuery from '../Tools/ApiQuery'
import Configuration from '../Tools/Configuration'
import Log from '../Tools/LogTools'
export default class UploadServices {
constructor() {
this.URL_Start = "/api/UploadFiles/StartUpload";
this.URL_Upload = "/api/UploadFiles/UploadBlob";
this.URL_Cansel = "/api/UploadFiles/Cansel";
this.upload_chunk_size = Configuration.upload_chunk_size;
this.ID = -1;
this._ContinueDownload = false;
this._file = null;
this._ParentID = null;
//Callback события
//(number progresse)
this.OnProggresseChange = null;
//(number id)
this.OnIDReceived = null;
}
//Считывает часть файла
//startByte - int позиция начала чтения
//stopByte - int позиция окончания чтения
async _ReadBlobAsync(startByte, stopByte) {
return new Promise(function (resolve, reject) {
//Считываем часть файла
let blob = this._file.slice(startByte, stopByte);
let reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
};
reader.onerror = function (event) {
reject("js Read file error", event);
};
reader.readAsDataURL(blob);
}.bind(this));
}
//Сообщает серверу о начале загрузки файла, получает ID загрузки
async _StartUploadAsync() {
return await ApiQuery(this.URL_Start, "Post",
{
//ID папки
ParentID: this._ParentID,
//Имя файла
Name: this._file.name,
//Размеры
Size: this._file.size
}).then(function (data) {
return data;
}.bind(this));
}
//Выполняет загрузка блока
async _UploadBlobAsync(bin_data, ChunkNumb) {
Log("UploadServices", "_UploadBlobAsync" + ChunkNumb);
if (!this._ContinueDownload)
return { Successe: true };
if (bin_data != '') {
Log("UploadServices", this.URL_Upload + ChunkNumb);
let res;
await ApiQuery(this.URL_Upload, "Post",
{
//ID загрузки
ID: this.ID,
//Кусок файла
chunk: bin_data
//Номер куска
//'ChunkNumb': ChunkNumb
}).then(function (data) {
res = data;
}.bind(this));
return res;
}
}
//Инициирует загрузку файла
//parent_id - int ID папки для загрузки
async UploadFileAsync(file, parent_id) {
if (this.OnProggresseChange != null)
this.OnProggresseChange(0, 0);
this._file = file;
this._ParentID = parent_id;
let start_info = await this._StartUploadAsync();
if (!start_info.Successe) {
throw start_info;
}
this._ContinueDownload = true;
this.ID = start_info.UploadID;
if (this.OnIDReceived != null)
this.OnIDReceived(this.ID);
for (let pos = 0, ChunkNumb = 0; pos < this._file.size; pos += this.upload_chunk_size, ChunkNumb++) {
if (!this._ContinueDownload)
return;
let bin_data = await this._ReadBlobAsync(pos, pos + this.upload_chunk_size);
let upload_state = await this._UploadBlobAsync(bin_data, ChunkNumb);
if (!upload_state.Successe) {
throw upload_state;
}
// Вычисляем процент отправленного
let p = Math.round(pos * 100 / file.size);
Log("UploadServices", 'p = ' + p);
if (this.OnProggresseChange != null)
this.OnProggresseChange(p, pos);
}
this._ContinueDownload = false;
}
Cansel() {
this._ContinueDownload = false;
//Костыль задержка, чтобы асинхронный загрузчик точно прервал работу
//и не попытался получить доступ к ужаленному проекту загрузки
//Возможно зависит от размера блока
setTimeout(function () {
ApiQuery(this.URL_Cansel, "Post",
{
//ID файла
ID: this.ID,
});
}.bind(this),
500);
}
}