hwobs.service.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { Injectable } from '@angular/core';
  2. // @ts-ignore
  3. import ObsClient from "esdk-obs-browserjs"
  4. import Parse from "parse";
  5. /**
  6. * HwobsDir 华为OBS目录接口
  7. * @public
  8. */
  9. export interface HwobsDir{
  10. Prefix:string // "storage/2023/"
  11. }
  12. /**
  13. * HwobsDir 华为OBS文件接口
  14. * @public
  15. */
  16. export interface HwobsFile{
  17. ETag: "\"f0ec968fe51ab48348307e06476122eb\""
  18. Key:string //"storage/3mkf41033623275.png"
  19. LastModified:string //"2023-11-08T12:03:13.008Z"
  20. Owner:object // {ID: '09971a1979800fb60fbbc00ada51f7e0'}
  21. Size:string //"25839"
  22. StorageClass:string //"STANDARD"
  23. }
  24. /**
  25. * HwobsService 华为OBS文件服务
  26. * @public
  27. */
  28. export class HwobsService {
  29. obsClient:ObsClient
  30. bucketName:string
  31. host:string
  32. globalPrefix:string = ""
  33. constructor(options:{
  34. host:string
  35. bucketName:string
  36. access_key_id:string
  37. secret_access_key:string
  38. prefix?:string
  39. server?:string
  40. }) {
  41. this.globalPrefix = options.prefix || ""
  42. this.host = options?.host
  43. this.bucketName = options?.bucketName
  44. this.obsClient = new ObsClient({
  45. access_key_id: options.access_key_id,
  46. secret_access_key: options.secret_access_key,
  47. // 这里以华南-广州为例,其他地区请按实际情况填写
  48. server: options?.server||'https://obs.cn-south-1.myhuaweicloud.com'
  49. });
  50. }
  51. /**
  52. * 目录及检索相关函数
  53. */
  54. listDir(prefix:any):Promise<{
  55. dirs:Array<HwobsDir>,
  56. files:Array<HwobsFile>
  57. }>{
  58. return new Promise((resolve,reject)=>{
  59. this.obsClient.listObjects({
  60. Bucket : this.bucketName,
  61. Prefix : prefix,
  62. Delimiter: '/'
  63. }, (err:any, result:any) => {
  64. if(err){
  65. console.error('Error-->' + err);
  66. reject(err)
  67. }else{
  68. console.log('Status-->' + result.CommonMsg.Status);
  69. console.log(result)
  70. if(result.CommonMsg.Status < 300 && result.InterfaceResult){
  71. for(var j in result.InterfaceResult.Contents){
  72. console.log('Contents[' + j + ']:');
  73. console.log('Key-->' + result.InterfaceResult.Contents[j]['Key']);
  74. console.log('Owner[ID]-->' + result.InterfaceResult.Contents[j]['Owner']['ID']);
  75. }
  76. }
  77. let dirs:HwobsDir[] = result.InterfaceResult.CommonPrefixes
  78. let files:HwobsFile[] = result.InterfaceResult.Contents
  79. resolve({dirs:dirs,files:files})
  80. }
  81. });
  82. })
  83. }
  84. /**
  85. * 文件上传相关函数
  86. * @param file
  87. * @param key
  88. * @returns
  89. */
  90. async uploadFile(file:File,key:string):Promise<Parse.Object>{
  91. // key 文件上传后的全部路径
  92. // /storage/<公司账套>/<应用名称>/年月日/<文件名>.<文件后缀>
  93. // /storage/web2023/<学号>/年月日/<文件名>.<文件后缀>
  94. let attach = await this.checkFileExists(file);
  95. if(attach?.id) return attach
  96. return new Promise((resolve,reject)=>{
  97. this.obsClient.putObject({
  98. Bucket : this.bucketName,
  99. Key : this.globalPrefix+key,
  100. SourceFile : file
  101. }, async (err:any, result:any) => {
  102. if(err){
  103. console.error('Error-->' + err);
  104. reject(err)
  105. }else{
  106. console.log('Status-->' + result.CommonMsg.Status);
  107. let attach = await this.saveAttachment(file,key)
  108. resolve(attach)
  109. }
  110. });
  111. })
  112. }
  113. Attachment = Parse.Object.extend("Attachment")
  114. async checkFileExists(file:any):Promise<Parse.Object>{
  115. let hash = await this.getFileHash(file)
  116. // 文件HASH查重,避免重复上传
  117. let attach:Parse.Object
  118. let query = new Parse.Query("Attachment")
  119. query.equalTo("hash",hash);
  120. query.equalTo("size",file.size);
  121. let exists:any = await query.first();
  122. if(!exists?.id) exists = new this.Attachment()
  123. attach = exists
  124. return attach
  125. }
  126. async saveAttachment(file:File,key:string){
  127. let hash = await this.getFileHash(file)
  128. let attach = await this.checkFileExists(file)
  129. attach.set("name",file.name)
  130. attach.set("size",file.size)
  131. attach.set("mime",file.type)
  132. attach.set("url",this.host + key)
  133. attach.set("hash",hash)
  134. attach = await attach.save()
  135. return attach
  136. }
  137. async getFileHash(file:File) {
  138. return new Promise((resolve, reject) => {
  139. const reader = new FileReader();
  140. reader.onload = async (event:any) => {
  141. const buffer = event.target.result;
  142. const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
  143. const hashArray = Array.from(new Uint8Array(hashBuffer));
  144. const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
  145. resolve(hashHex);
  146. };
  147. reader.onerror = (event:any) => {
  148. reject(event.target.error);
  149. };
  150. reader.readAsArrayBuffer(file);
  151. });
  152. }
  153. }