|
@@ -0,0 +1,164 @@
|
|
|
+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"
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * HwobsService 华为OBS文件服务
|
|
|
+ * @public
|
|
|
+ */
|
|
|
+export class HwobsService {
|
|
|
+ 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<HwobsDir>,
|
|
|
+ files:Array<HwobsFile>
|
|
|
+ }>{
|
|
|
+ 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<Parse.Object>{
|
|
|
+ // 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,key)
|
|
|
+ resolve(attach)
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ }
|
|
|
+ Attachment = Parse.Object.extend("Attachment")
|
|
|
+
|
|
|
+ async checkFileExists(file:any):Promise<Parse.Object>{
|
|
|
+ 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){
|
|
|
+ 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);
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|