import { Injectable } from '@angular/core'; // @ts-ignore import ObsClient from "esdk-obs-browserjs" import Parse from "parse"; /** * HwobsDir 华为OBS目录接口 * @public */ export interface HwobsDir{ Prefix:string // "storage/2023/" } /** * HwobsDir 华为OBS文件接口 * @public */ export interface HwobsFile{ ETag: "\"f0ec968fe51ab48348307e06476122eb\"" Key:string //"storage/3mkf41033623275.png" LastModified:string //"2023-11-08T12:03:13.008Z" Owner:object // {ID: '09971a1979800fb60fbbc00ada51f7e0'} Size:string //"25839" StorageClass:string //"STANDARD" } /** * HwobsProvider 华为OBS文件服务 * @public */ export class HwobsProvider { obsClient:ObsClient bucketName:string host:string globalPrefix:string = "" constructor(options:{ host:string bucketName:string access_key_id:string secret_access_key:string prefix?:string server?:string }) { this.globalPrefix = options.prefix || "" this.host = options?.host this.bucketName = options?.bucketName this.obsClient = new ObsClient({ access_key_id: options.access_key_id, secret_access_key: options.secret_access_key, // 这里以华南-广州为例,其他地区请按实际情况填写 server: options?.server||'https://obs.cn-south-1.myhuaweicloud.com' }); } /** * 目录及检索相关函数 */ listDir(prefix:any):Promise<{ dirs:Array, files:Array }>{ return new Promise((resolve,reject)=>{ this.obsClient.listObjects({ Bucket : this.bucketName, Prefix : prefix, Delimiter: '/' }, (err:any, result:any) => { if(err){ console.error('Error-->' + err); reject(err) }else{ console.log('Status-->' + result.CommonMsg.Status); console.log(result) if(result.CommonMsg.Status < 300 && result.InterfaceResult){ for(var j in result.InterfaceResult.Contents){ console.log('Contents[' + j + ']:'); console.log('Key-->' + result.InterfaceResult.Contents[j]['Key']); console.log('Owner[ID]-->' + result.InterfaceResult.Contents[j]['Owner']['ID']); } } let dirs:HwobsDir[] = result.InterfaceResult.CommonPrefixes let files:HwobsFile[] = result.InterfaceResult.Contents resolve({dirs:dirs,files:files}) } }); }) } /** * 文件上传相关函数 * @param file * @param key * @returns */ async uploadFile(file:File,key:string):Promise{ console.log(this.globalPrefix,key) // key 文件上传后的全部路径 // /storage/<公司账套>/<应用名称>/年月日/<文件名>.<文件后缀> // /storage/web2023/<学号>/年月日/<文件名>.<文件后缀> let attach = await this.checkFileExists(file); if(attach?.id) return attach return new Promise((resolve,reject)=>{ this.obsClient.putObject({ Bucket : this.bucketName, Key : this.globalPrefix+key, SourceFile : file }, async (err:any, result:any) => { if(err){ console.error('Error-->' + err); reject(err) }else{ console.log('Status-->' + result.CommonMsg.Status); let attach = await this.saveAttachment(file,this.globalPrefix+key) resolve(attach) } }); }) } Attachment = Parse.Object.extend("Attachment") async checkFileExists(file:any):Promise{ let hash = await this.getFileHash(file) // 文件HASH查重,避免重复上传 let attach:Parse.Object let query = new Parse.Query("Attachment") query.equalTo("hash",hash); query.equalTo("size",file.size); let exists:any = await query.first(); if(!exists?.id) exists = new this.Attachment() attach = exists return attach } async saveAttachment(file:File,key:string){ console.log("saveAttachment",key) let hash = await this.getFileHash(file) let attach = await this.checkFileExists(file) attach.set("name",file.name) attach.set("size",file.size) attach.set("mime",file.type) attach.set("url",this.host + key) attach.set("hash",hash) attach = await attach.save() return attach } async getFileHash(file:File) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = async (event:any) => { const buffer = event.target.result; const hashBuffer = await crypto.subtle.digest('SHA-256', buffer); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join(''); resolve(hashHex); }; reader.onerror = (event:any) => { reject(event.target.error); }; reader.readAsArrayBuffer(file); }); } }