alioss 批量断点续传 开箱即用

前言

这个项目也是优化一个开源项目得来的,本着开源精神也将源码放出。优化了原项目的页面,业务逻辑。改成了移动端界面,只要你的项目弹出一个移动端窗口,后台实现3个接口,就直接可用。

界面展示

原项目地址

git clone github.com/hu-snail/vu...

优化后项目地址

gitee.com/woaianqi/vu...

开发要求

markdown 复制代码
> node版本必须18以下
> npm run dev 开发模式
> npm run build 构建项目

修改的api文件

/src/api/index.js

api1 获取ali-oss令牌

这个j-spring是我自己的项目,用TS重写了java的springBoot,业务逻辑就是下面的,可以自己手动装配。

ts 复制代码
import { Component, Value } from 'j-spring';
import StsClient from '@alicloud/sts-sdk';
import OSS from 'ali-oss';
import CryptoJS from 'crypto-js';

let stsClient: StsClient | undefined;
let ossClient: OSS | undefined;

function encrypt(text: string, key: string): string {
  return CryptoJS.AES.encrypt(text, key).toString();
}

@Component()
export class AliOssConfig {
  @Value({ path: 'ali-oss.accessKeyId', remark: '密匙id' })
  accessKeyId: string;
  @Value({ path: 'ali-oss.accessKeySecret', remark: '密钥' })
  accessKeySecret: string;
  @Value({ path: 'ali-oss.roleArn', remark: '角色凭证' })
  roleArn: string;
  @Value({ path: 'ali-oss.roleSessionName', remark: '会话' })
  roleSessionName: string;
  @Value({ path: 'ali-oss.bucket', remark: 'oss-bucket' })
  bucket: string;
  @Value({ path: 'ali-oss.region', remark: '区域' })
  region: string;

  public getStsClient() {
    if (!stsClient) {
      stsClient = new StsClient({
        endpoint: 'sts.aliyuncs.com',
        accessKeyId: this.accessKeyId,
        accessKeySecret: this.accessKeySecret,
      });
    }
    return stsClient;
  }

  public getOssClient() {
    if (!ossClient) {
      ossClient = new OSS({
        region: this.region,
        accessKeyId: this.accessKeyId,
        accessKeySecret: this.accessKeySecret,
        bucket: this.bucket,
      });
    }
    return ossClient;
  }

}

type TokenCache = {
  time: number;
  data: any;
};

@Component()
export class AliOssCredentialsService {
  @Autowired()
  aliOssConfig: AliOssConfig;

  @Autowired()
  logger: Logger;

  //缓存时间 3000秒
  chacheSeconds: number = 3000;

  //token 缓存
  tokenCache: TokenCache = {
    time: 0,
    data: {},
  };

  /**
   * 获取前端上传的令牌
   */
  public async getCredential(): Promise<{ status: number; data: any }> {
    //在令牌有效期  间隔小于2500秒
    if (
      new Date().getTime() - this.tokenCache.time <
      this.chacheSeconds * 1000
    ) {
      return this.tokenCache.data;
    }
    try {
      const { roleArn, roleSessionName } = this.aliOssConfig;
      const sts = this.aliOssConfig.getStsClient();
      const data = await sts.assumeRole(
        roleArn,
        roleSessionName,
        '',
        this.chacheSeconds //令牌有效期3000秒  50分钟
      );
      if (!data.Credentials) {
        return {
          status: 201,
          data: {
            msg: '获取STS凭证失败,请检查参数,<a style="color: #409EFF;" href="https://help.aliyun.com/document_detail/371864.htm?spm=a2c4g.11186623.0.0.5feb73bdpwWLVu" target="_blank">查看文档</a>',
          },
        };
      } else {
        //更新缓存
        this.tokenCache = {
          time: new Date().getTime(),
          data: { status: 200, data },
        };
        return this.tokenCache.data;
      }
    } catch (e) {
      this.logger.error(e);
      return {
        status: 201,
        data: {
          msg: '获取STS凭证失败,请检查参数,<a style="color: #409EFF;" href="https://help.aliyun.com/document_detail/371864.htm?spm=a2c4g.11186623.0.0.5feb73bdpwWLVu" target="_blank">查看文档</a>',
        },
      };
    }
  }
}

    

api2-获取后台配置

返回结果必须是 {error:string,value:CwRecordConfig}

java 复制代码
//返回代码
@Setter
@Getter
@Accessors(chain = true)
public class CwRecordConfig {
    String title;//上传名称
    String brief;//简介
    List<String> existFileNameList = new ArrayList<>();//已经存在的文件名
    String fileNameReg;//文件正则  默认''  ;不要求
    String fileNameRegTemplate;//名称模板  默认:''
    String model;//分类 bucket顶层目录
    Integer type;//app类型  <这个是前台传递的自定义业务参数>
    String uid;//传递的uid  <这个是前台传递的自定义业务参数>
    String accept;//上传的文件限制 例如 ".png,x.mp4" ; 默认'' 不限制
}

api3-处理单个上传成功业务

返回结果必须是 {error:string,value:string}

java 复制代码
    @RequestMapping("api3")
    @ResponseBody
    public Result<String> api3(@SessionAttribute User user, CwRecordUploadSuccess cwRecordUploadSuccess){
        if(cwRecordUploadSuccess.getType() == 0){
            CwRecordChapter cwRecordChapter = CwRecordChapterSearch.of(cwRecordUploadSuccess.getUid()).safeGet();
            String[] parts = cwRecordUploadSuccess.getFileName().split("-");
            Integer sort = Integer.valueOf(parts[0]);
            CwRecordFile cwRecordFile = new CwRecordFile();
            cwRecordFile.setCwRecordChapter(cwRecordChapter)
                    .setSort(sort)
                    .setFileName(cwRecordUploadSuccess.getFileName())
                    .setFileSize(cwRecordUploadSuccess.getSize())
                    .setOssFilePath(cwRecordUploadSuccess.getOssKey())
                    .setCreateUser(user.getUserName()+"-"+user.getUnitName())
                    .doSave();
            return Result.of("创建成功!");
        }
        return Result.error("type参数错误");
    }

nginx配置

shell 复制代码
    #开发时的配置,直接通过原项目端口打开开发页面,可以避免端口跨域的麻烦
    location /vue-oss-upload {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_pass   http://localhost:7085/vue-oss-upload;
         proxy_redirect off;
     }
     
    # 线上配置,就是将静态目录挂载到nginx的docker容器中, 配个项目url路径就完事了
    location /vue-oss-upload {
        # 使用 alias 而不是 root
        alias /vue-oss-upload;
        index index.html;
        try_files $uri $uri/ /vue-oss-upload/index.html;
    }
     
相关推荐
LCG元31 分钟前
Vue.js组件开发-如何实现异步组件
前端·javascript·vue.js
wl851143 分钟前
vue入门到实战 三
前端·javascript·vue.js
ljz20161 小时前
本地搭建deepseek-r1
前端·javascript·vue.js
傻小胖2 小时前
vue3中Teleport的用法以及使用场景
前端·javascript·vue.js
wl85112 小时前
Vue 入门到实战 七
前端·javascript·vue.js
LCG元3 小时前
Vue.js组件开发-使用Vue3如何实现上传word作为打印模版
前端·vue.js·word
一 乐4 小时前
基于vue船运物流管理系统设计与实现(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端·船运系统
m0_528723815 小时前
在React中使用redux
前端·javascript·react.js
傻小胖5 小时前
vue3中customRef的用法以及使用场景
前端·javascript·vue.js
谦谦橘子5 小时前
手把手教你实现一个富文本
前端·javascript