概述
将上传基类命名为MOS(Mine Object Storage)
mos.ts代码
import {MosType} from './mosConfig'
import {Loading} from '../loading'
import {type BinaryFile, type MosFile} from './fileUtil'
import type { PathTemplate } from './pathTemplate'
import axios, { type AxiosResponse } from 'axios'
import {loadUser} from '../user'
export interface MosSettings{
cdn:string | null
bucket:string
endpoint:string
}
export interface UploadOptions{
cover:boolean
progress?:Function
failed?:Function
}
export abstract class Mos{
settings : MosSettings
finished : boolean = false
loading : Loading
pathTemplate:string
constructor(settings:MosSettings,template:PathTemplate){
this.settings = settings
this.loading = new Loading()
this.pathTemplate = `${template.appId}/@ownerId/@fileName`
}
abstract init() : void
abstract uploadFile(file:BinaryFile,options:UploadOptions,token:string) : Promise<MosFile|null>
async upload(file:BinaryFile,options:UploadOptions) : Promise<MosFile|null> {
const user=loadUser()
this.pathTemplate=this.pathTemplate.replace('@ownerId',user?.userId.toString() ?? '0')
return await this.uploadFile(file,options,user?.token ?? '')
}
async getCredential(token:string,bucket:string,type: MosType) : Promise<AxiosResponse<any, any>>{
const params = { bucket: bucket, ossSource: type }
const url = `https://api.mos.com/api/v1/Credential` // 接口会根据不同的ossSource参数值返回不同的数据结构,因此可以放在基类
return axios.get(url, { params ,headers:{
'Authorization':token,
'Content-Type':'application/json'
}})
}
}
oss.ts代码
import axios from "axios";
import type { BinaryFile, MosFile } from "./fileUtil";
import { Mos, type UploadOptions } from "./mos";
import { MosType, type OssConfig } from "./mosConfig";
import type { OssCredential } from "./mosCredential";
import type { PathTemplate } from "./pathTemplate";
export class Oss extends Mos{
policy : string = ''
signature : string = ''
accessKeyId:string
host:string
constructor(config:OssConfig,template:PathTemplate) {
super({bucket:config.bucket,endpoint:config.endpoint,cdn:config.cdn},template)
this.accessKeyId = config.accessKeyId
this.host=`https://${config.bucket}.${config.endpoint}`
}
init() {
return
}
async getSTSToken(token:string){
if (this.policy) return Promise.resolve()
return await this.getCredential(token,this.settings.bucket,MosType.Oss).then(result => {
const data = result.data.data as OssCredential;
this.policy = data.policy;
this.signature = data.signature;
})
}
async uploadFile(file: BinaryFile, options: UploadOptions,token:string): Promise<MosFile|null> {
this.finished = false
this.loading.startLoading()
await this.getSTSToken(token)
const fileName = file.name
const ossPrefix = 'TempFiles/'
const saveKey = ossPrefix + this.pathTemplate.replace('@fileName',fileName)
const formData = new FormData();
formData.append("policy", this.policy);
formData.append("Signature", this.signature);
formData.append("bucket", this.settings.bucket);
formData.append("key", saveKey);
formData.append("OSSAccessKeyId", this.accessKeyId);
formData.append("success_action_status", "201");
formData.append("Content-Disposition", "attachment;filename=" + fileName + ";filename*=UTF-8''" + fileName);
formData.append("file", file.binary);
return axios.post(this.host, formData, {
responseType: 'document',
onUploadProgress: evt => options.progress && options.progress(evt),
}).then(result => {
this.finished = true;
this.loading.endLoading();
console.log("上传成功");
const data = result.data;
const url = data.getElementsByTagName("Location")[0].childNodes[0].nodeValue;
return url ? Promise.resolve({ url, fileName }) : Promise.reject(result);
}).catch(error => {
this.finished = true;
this.loading.endLoading()
console.log("上传失败");
options.failed &&options.failed(error);
return null
})
}
}
cos.ts 代码
import type { BinaryFile, MosFile } from './fileUtil'
import { Mos, type UploadOptions } from './mos'
import { MosType, type CosConfig } from './mosConfig'
import type { PathTemplate } from './pathTemplate'
import COS from 'cos-js-sdk-v5'
import type { CosCredential } from './mosCredential'
export class TencentCOS extends Mos {
cos: COS | null = null
currentToken:string = ''
constructor(config: CosConfig, template: PathTemplate) {
super({ bucket: config.bucket, endpoint: config.endpoint, cdn: config.cdn }, template)
}
init() {
this.cos = new COS({
getAuthorization: (options, callback) => this.getAuthorizationCredential(callback),
UploadCheckContentMd5: true
})
}
async uploadFile(file: BinaryFile, options: UploadOptions, token: string): Promise<MosFile | null> {
this.currentToken = token
this.finished = false;
this.loading.startLoading()
const fileName = file.name
const savekey = this.pathTemplate.replace('@fileName',fileName)
return new Promise((resolve, reject) => {
this.cos!.uploadFile({
Bucket: this.settings.bucket,
Region: this.settings.endpoint,
Key: savekey,
Body: file.binary,
SliceSize: 1024 * 1024 * 5,
Headers: {
'content-disposition': "attachment;filename=" + fileName + ";filename*=UTF-8''" + fileName
},
onProgress: evt => options.progress && options.progress(evt),
}, (err, data) => {
this.finished = true;
this.loading.endLoading()
if (err) {
console.log("上传失败");
options.failed && options.failed(err);
reject(err);
}
if (data) {
console.log("上传成功");
resolve({ url, fileName });
}
});
})
}
getAuthorizationCredential(callback:Function){
this.getCredential(this.currentToken, this.settings.bucket, MosType.Cos).then((result) => {
const data = result.data.data as CosCredential
callback({
TmpSecretId: data.tmpSecretId,
TmpSecretKey: data.tmpSecretKey,
SecurityToken: data.token,
StartTime: data.startTime,
ExpiredTime: data.expiredTime
})
})
}
}
mosFactory.ts 代码
import { TencentCOS as Cos } from "./cos";
import type { Mos } from "./mos";
import {MosConfig, MosType } from "./mosConfig";
import { Oss } from "./oss";
import type { PathTemplate } from "./pathTemplate";
export function CreateMos (template:PathTemplate,type:MosType = MosType.Cos) : Mos {
const config:MosConfig = new MosConfig()
let mos:Mos
switch (type) {
case MosType.Cos:
mos= new Cos(config.cos,template)
break;
case MosType.Oss:
mos= new Oss(config.oss,template)
break
default:
mos= new Cos(config.cos,template)
break;
}
mos.init()
return mos
}
export function CreateDefaultMos(type:MosType = MosType.Cos) : Mos {
return CreateMos({appId:'demo'},type)
}
其他代码
PathTemplate.ts
export interface PathTemplate{
appId:string //应用Id
}
mossCredential.ts
export interface OssCredential{
policy:string
signature:string
accessKeyId:string|null
}
export interface CosCredential{
tmpSecretId:string
tmpSecretKey:string
token:string
startTime:number
expiredTime:number
}
fileUtil.ts
export interface MosFile {
url: string | null
fileName: string
}
export interface BinaryFile{
binary: Blob
name:string
}
mosConfig.ts
export interface OssConfig {
isTemp: boolean
bucket: string
endpoint: string
cdn: string
accessKeyId: string
}
export interface CosConfig{
bucket: string
endpoint: string
cdn: string
}
export class MosConfig {
oss: OssConfig = {
bucket: 'demo-bucket',
endpoint: 'oss-cn.aliyuncs.com',
cdn: '',
accessKeyId: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
cos:CosConfig = {
bucket: 'demo-bucket',
endpoint: 'beijing',
cdn: ""
}
}
export enum MosType{
Oss = 1,
Cos
}
在vue3.0是使用
在App.vue中
import {provide} from 'vue'
import {CreateDefaultMos} from './assets/ts/mos/mosFactory'
provide('mos',CreateDefaultMos())
在组件中注入使用
import {inject } from 'vue'
const mos:Mos = inject('mos')!
标签:cos,string,data,oss,bucket,ts,export,import,type
From: https://www.cnblogs.com/Saints/p/17813016.html