common.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. // import getBrowser from './getBrowser';
  2. // import getNetworkType from './getNetworkType';
  3. // import getSystemInfo from './getSystemInfo';
  4. import {Message} from "element-ui"
  5. import{getOSSSign} from "@/api/api.js"
  6. //or <script src="https://sdk.amazonaws.com/js/aws-sdk-2.744.0.min.js"></script>
  7. import AWS from 'aws-sdk'
  8. const Minio = require('minio')
  9. const stream = require('stream')
  10. // 根据字节流下载文件
  11. /**
  12. * @param {Blob} data 流数据
  13. * @param {String} type 下载的文件类型
  14. * @param {String} fileName 下载的文件名
  15. */
  16. export function downloadByFlow(data,type,fileName) {
  17. let fileTypeMime ='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  18. switch (type) { // 获取后缀对应的 mimeType
  19. case 'png': fileTypeMime = 'image/png'; break;
  20. case 'doc': fileTypeMime = 'application/msword'; break;
  21. case 'docx': fileTypeMime = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; break;
  22. case 'jpg': case 'jpeg': fileTypeMime = 'image/jpeg'; break;
  23. case 'gif': fileTypeMime = 'image/gif'; break;
  24. case 'svg': fileTypeMime = 'image/svg+xml'; break;
  25. case 'tif': case 'tiff': fileTypeMime = 'image/tiff'; break;
  26. case 'txt': fileTypeMime = 'text/plain'; break;
  27. case 'ppt': fileTypeMime = 'application/vnd.ms-powerpoint'; break;
  28. case 'pptx': fileTypeMime = 'application/vnd.openxmlformats-officedocument.presentationml.presentation'; break;
  29. case 'xls': fileTypeMime = 'application/vnd.ms-excel'; break;
  30. case 'xlsx': fileTypeMime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; break;
  31. case 'zip': fileTypeMime = 'application/zip'; break;
  32. case '7z': fileTypeMime = 'application/x-7z-compressed'; break;
  33. }
  34. let blob = window.URL.createObjectURL(new Blob([data], {
  35. 'type': fileTypeMime
  36. }))
  37. let link = document.createElement('a')
  38. link.style.display = 'none'
  39. link.href = blob
  40. link.setAttribute('download', fileName.indexOf('.')?fileName:`${fileName}.${type}`)
  41. document.body.appendChild(link)
  42. link.click()
  43. document.body.removeChild(link) //下载完成移除元素
  44. window.URL.revokeObjectURL(blob) //释放掉 blob 对象
  45. }
  46. /* 获取地址栏参数值 */
  47. export function getUrlParams(str=window.location.href,key) {
  48. let obj = {};
  49. str.split('?')[1].split('&').map(i => obj[(i.split('=')[0])] = i.split('=')[1]);
  50. return obj[key]
  51. }
  52. /**
  53. *
  54. * @param {*} objectStorageClient oss-走oss 2-走minio string
  55. * @param {*} file 上传文件
  56. * @param {*} temName 文件路径/文件名字
  57. * @param {*} options 文件路径/文件名字
  58. * @param {*} options.OSS 上传至阿里云的配置
  59. * @param {*} options.MINIO 上传至MINIO的配置
  60. */
  61. // 上传文件 直接走对象存取服务器
  62. export function uploadFileDirect(objectStorageClient,file,temName,options={}){
  63. const objectStorageType= (objectStorageClient || JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient || 'oss')
  64. // console.log(objectStorageType,'objectStorageType');
  65. // return
  66. if(!objectStorageType){
  67. Message.error("ObjectStorageClient参数丢失")
  68. return new Promise((resolve,reject) => reject("ObjectStorageClient参数丢失"))
  69. }
  70. if(!file){
  71. Message.error("file参数错误")
  72. return new Promise((resolve,reject) => reject("file参数错误"))
  73. }
  74. if(!temName){
  75. Message.error("temName参数错误")
  76. return new Promise((resolve,reject) => reject("temName参数错误"))
  77. }
  78. // console.log(objectStorageType,file,temName,options,'objectStorageType,file,temName,options');
  79. switch (objectStorageType) {
  80. case "oss":
  81. let ossOptions = {}
  82. if(options.OSS){
  83. ossOptions=options.OSS
  84. }
  85. return handleUploadToOSS(file,temName,ossOptions)
  86. // break;
  87. case "minio":
  88. let minioOptions = {}
  89. if(options.MINIO){
  90. minioOptions=options.MINIO
  91. }
  92. return handleUploadToMinIO(file,temName,minioOptions)
  93. // break;
  94. case "s3":
  95. let s3Options = {}
  96. if(options.S3){
  97. s3Options = options.S3
  98. }
  99. return handleUploadToS3(file,temName,s3Options)
  100. default:
  101. break;
  102. }
  103. }
  104. const handleUploadToOSS= (file,fileName,options={})=>{
  105. return new Promise(async (resolve,reject)=>{
  106. // 获取oss临时签名
  107. const res=await getOSSSign({StorageSource:1})
  108. // console.log(res);
  109. if(res.Ret!==200) reject("获取阿里云oss临时签名错误,res.Ret="+res.Ret)
  110. try {
  111. let oss_params = {
  112. // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  113. region: res.Data.RegionId,
  114. // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
  115. accessKeyId: res.Data.AccessKeyId,
  116. accessKeySecret: res.Data.AccessKeySecret,
  117. // 从STS服务获取的安全令牌(SecurityToken)。
  118. stsToken: res.Data.SecurityToken,
  119. // 填写Bucket名称,例如examplebucket。
  120. bucket: res.Data.Bucketname,
  121. endpoint: res.Data.Endpoint,
  122. cname:true,
  123. timeout:6000000
  124. }
  125. let imgHost = res.Data.Imghost;
  126. const ALOSSINS=new OSS(oss_params);
  127. const resp=await ALOSSINS.multipartUpload(fileName,file,{...options})
  128. console.log('上传结果',resp);
  129. if(resp.res.status===200){
  130. let url=imgHost+resp.name
  131. resolve(url)
  132. console.log('oss文件地址',url);
  133. }else{
  134. throw new Error('上传到阿里云失败:res.status'+resp.res.status)
  135. }
  136. } catch (error) {
  137. console.error(error);
  138. if (error.name !== "cancel") {
  139. Message.warning('上传失败,请刷新重试')
  140. }
  141. reject(error)
  142. }
  143. })
  144. }
  145. // minio sdk 文档 https://min.io/docs/minio/linux/developers/javascript/API.html
  146. const handleUploadToMinIO=(file,fileName,options={})=>{
  147. return new Promise(async (resolve,reject)=>{
  148. const res=await getOSSSign({StorageSource:2})
  149. // console.log(res);
  150. if(res.Ret!==200) reject("获取minio临时签名错误,res.Ret="+res.Ret)
  151. // return
  152. const minioClient = new Minio.Client({
  153. endPoint: res.Data.Endpoint.split(':')[0],
  154. port: Number(res.Data.Port)||undefined,
  155. useSSL: res.Data.UseSSL.toLocaleLowerCase()=="false"?false:true,
  156. accessKey: res.Data.AccessKeyId,
  157. secretKey: res.Data.SecretKeyId,
  158. })
  159. console.log(minioClient);
  160. try {
  161. var metaData = {...{
  162. 'Content-Type': file.type||'application/octet-stream',
  163. "Content-Length": file.size,
  164. },...options}
  165. minioClient.bucketExists(res.Data.Bucketname, function (err, exists) {
  166. if (err) {
  167. throw "minio 查看桶是否存在失败"+err
  168. // return console.log(err);
  169. }
  170. if (!exists) {
  171. // 不存在桶,创建桶
  172. console.log("桶不存在,先创建桶",res.Data.Bucketname);
  173. minioClient.makeBucket(res.Data.Bucketname, res.Data.RegionId,function (err) {
  174. if (err) {
  175. throw "minio 创建桶失败"+err
  176. }
  177. let reader = new FileReader();
  178. // console.log(reader);
  179. reader.readAsArrayBuffer(file);
  180. reader.onloadend = function (e) {
  181. const dataurl = e.target.result;
  182. let bufferStream = new stream.PassThrough();
  183. // 转化成数据流 minio接受数据流格式
  184. bufferStream.end(Buffer.from(dataurl))
  185. // console.log(bufferStream);
  186. minioClient.putObject(res.Data.Bucketname, fileName, bufferStream,file.size, metaData, function (err, etag) {
  187. if (err){
  188. throw "上传到minio失败:"+err
  189. }
  190. })
  191. }
  192. })
  193. }
  194. if (exists) {
  195. // console.log("桶存在",res.Data.Bucketname);
  196. let reader = new FileReader();
  197. console.log(reader);
  198. reader.readAsArrayBuffer(file);
  199. reader.onloadend = function (e) {
  200. const dataurl = e.target.result;
  201. let bufferStream = new stream.PassThrough();
  202. bufferStream.end(Buffer.from(dataurl))
  203. minioClient.putObject(res.Data.Bucketname, fileName, bufferStream, metaData, function (err, etag) {
  204. if (err){
  205. throw "上传到minio失败:"+err
  206. }
  207. let fileUrl = fileName.startsWith('/')?res.Data.ImgHost+fileName:res.Data.ImgHost+"/"+fileName
  208. resolve(fileUrl)
  209. })
  210. }
  211. }
  212. })
  213. } catch (error) {
  214. console.error(error);
  215. if (error.name !== "cancel") {
  216. //不是取消上传的则给错误提示
  217. this.$message.warning("上传失败,请刷新重试");
  218. }
  219. reject(error)
  220. }
  221. })
  222. }
  223. //https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property
  224. const handleUploadToS3=(file,fileName,options={})=>{
  225. return new Promise(async(resolve,reject)=>{
  226. const res=await getOSSSign({StorageSource:3})
  227. if(res.Ret!==200) reject("获取s3签名错误,res.Ret="+res.Ret)
  228. const { Endpoint,
  229. AccessKeyId,
  230. AccessKeySecret,
  231. Port,
  232. Bucketname,
  233. RegionId,
  234. S3ForceStyle,
  235. S3Protocol
  236. } = res.Data
  237. const s3Client = new AWS.S3({
  238. apiVersion: '2006-03-01',
  239. endpoint:Endpoint,
  240. region:RegionId,
  241. s3ForcePathStyle:S3ForceStyle,
  242. credentials:{
  243. accessKeyId:AccessKeyId,
  244. secretAccessKey:AccessKeySecret,
  245. }
  246. })
  247. /* window.s3Client = s3Client
  248. console.log('s3:',s3Client) */
  249. try {
  250. let reader = new FileReader();
  251. //console.log(reader);
  252. reader.readAsArrayBuffer(file);
  253. reader.onloadend = function (e) {
  254. const dataurl = e.target.result;
  255. let bufferStream = new stream.PassThrough();
  256. bufferStream.end(Buffer.from(dataurl))
  257. //s3 上传
  258. /* s3Client.putObject({
  259. Bucket: Bucketname,
  260. ContentType: file.type || 'application/octet-stream',
  261. Body: file,
  262. ACL: "public-read",
  263. Key: fileName
  264. }, function (err, data) {
  265. if (err) {
  266. console.log("Error! err =====> ", err);
  267. } else {
  268. console.log("Successfully uploaded! data =====> ", data);
  269. }
  270. }); */
  271. //upload会返回完整路径
  272. s3Client.upload({
  273. Bucket: Bucketname,
  274. ContentType: file.type || 'application/octet-stream',
  275. Body: file,
  276. ACL: "public-read",
  277. Key: fileName
  278. },options, function (err, data) {
  279. if (err) {
  280. console.log("Error! err =====> ", err);
  281. throw new Error("上传到s3失败!")
  282. } else {
  283. let url = data['Location'];
  284. console.log("Successfully uploaded! URL =====> ", url);
  285. resolve(url)
  286. }
  287. });
  288. }
  289. } catch (error) {
  290. console.error(error);
  291. if (error.name !== "cancel") {
  292. //不是取消上传的则给错误提示
  293. this.$message.warning("上传失败,请刷新重试");
  294. }
  295. reject(error)
  296. }
  297. })
  298. }
  299. /**
  300. * 等待几个请求返回才能进行下一步的中间函数
  301. * @param {*} flag 执行下一步的标志 需要取到最新的值,传入返回值函数
  302. * @param {*} callBack 回调
  303. * @param {*} timeout 间隔
  304. */
  305. export const waitRequestReturn=(flag,callBack,timeout)=>{
  306. if(typeof(flag)!='function' || typeof(callBack)!='function'){
  307. return console.error('waitRequestReturn--参数错误')
  308. }
  309. let timer=null
  310. if(!flag()){
  311. timer=setInterval(()=>{
  312. // console.log(flag());
  313. if(flag()){
  314. clearInterval(timer)
  315. callBack()
  316. }
  317. },+timeout||10)
  318. }else{
  319. callBack()
  320. }
  321. }