hwobs.service.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. * HwobsProvider 华为OBS文件服务
  26. * @public
  27. */
  28. export class HwobsProvider {
  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. console.log(this.globalPrefix, key)
  92. // key 文件上传后的全部路径
  93. // /storage/<公司账套>/<应用名称>/年月日/<文件名>.<文件后缀>
  94. // /storage/web2023/<学号>/年月日/<文件名>.<文件后缀>
  95. let attach = await this.checkFileExists(file);
  96. if (attach?.id) return attach
  97. return new Promise((resolve, reject) => {
  98. this.obsClient.putObject({
  99. Bucket: this.bucketName,
  100. Key: this.globalPrefix + key,
  101. SourceFile: file
  102. }, async (err: any, result: any) => {
  103. if (err) {
  104. console.error('Error-->' + err);
  105. reject(err)
  106. } else {
  107. console.log('Status-->' + result.CommonMsg.Status);
  108. let attach = await this.saveAttachment(file, this.globalPrefix + key)
  109. const fileUrl = this.host + this.globalPrefix + key;
  110. console.log(fileUrl)
  111. resolve(attach)
  112. }
  113. });
  114. })
  115. }
  116. Attachment = Parse.Object.extend("Attachment")
  117. async checkFileExists(file: any): Promise<Parse.Object> {
  118. let hash = await this.getFileHash(file)
  119. // 文件HASH查重,避免重复上传
  120. let attach: Parse.Object
  121. let query = new Parse.Query("Attachment")
  122. query.equalTo("hash", hash);
  123. query.equalTo("size", file.size);
  124. let exists: any = await query.first();
  125. if (!exists?.id) exists = new this.Attachment()
  126. attach = exists
  127. return attach
  128. }
  129. async saveAttachment(file: File, key: string) {
  130. console.log("saveAttachment", key)
  131. let hash = await this.getFileHash(file)
  132. let attach = await this.checkFileExists(file)
  133. attach.set("name", file.name)
  134. attach.set("size", file.size)
  135. attach.set("mime", file.type)
  136. attach.set("url", this.host + key)
  137. attach.set("hash", hash)
  138. attach = await attach.save()
  139. return attach
  140. }
  141. async getFileHash(file: File) {
  142. return new Promise((resolve, reject) => {
  143. const reader = new FileReader();
  144. reader.onload = async (event: any) => {
  145. const buffer = event.target.result;
  146. const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
  147. const hashArray = Array.from(new Uint8Array(hashBuffer));
  148. const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
  149. resolve(hashHex);
  150. };
  151. reader.onerror = (event: any) => {
  152. reject(event.target.error);
  153. };
  154. reader.readAsArrayBuffer(file);
  155. });
  156. }
  157. }