百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

JAVA全栈CMS系统vue图片/视频上传组件,多图上传及删除功能11

ztj100 2024-11-13 14:02 22 浏览 0 评论

1.上一期文件头像上传的file表借鉴

# 12.文件资源管理表
DROP TABLE IF EXISTS `file`;
CREATE TABLE `file`(
	`uni_id` CHAR(8) NOT NULL DEFAULT '' COMMENT '唯一ID',
	`name` VARCHAR(100) NOT NULL COMMENT '文件名',
	`path` VARCHAR(100) NOT NULL COMMENT '文件相对路径',
	`module_id` CHAR(8) COMMENT '模块ID',
	`user_id` CHAR(8) COMMENT '上传用户ID',
	`suffix` VARCHAR(100) COMMENT '文件后缀',
	`size` INT COMMENT '大小|字节B',
	`content_type` VARCHAR(100) COMMENT '文件上传类型',
	`type_id` int(11) NOT NULL DEFAULT '0' COMMENT '资源类型',
	`use_type` CHAR(1) COMMENT '应用场景|P公共资源|I私有资源|D公司宣传资料|A公司活动资料|C公司产品资料|T其他',
	`is_show` int DEFAULT '1' COMMENT '显示1 || 不显示0',
	`create_time` datetime(3) DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
	PRIMARY KEY (`uni_id`),
	UNIQUE KEY `path_unique` (`path`)
)ENGINE=INNODB DEFAULT charset=utf8mb4 COMMENT='文件资源管理表';

本期功能实现预览


2.更新上传文件,自动创建递归二级目录:根据use_type创建一级目录,根据日期创建二级目录

Controller更新后端递归新增目录方法

package cevent.source.cloudcenter.source.controller.admin;/**
 * Created by Cevent on 2021/4/24.
 */

import cevent.source.cloudcenter.server.dto.FileDto;
import cevent.source.cloudcenter.server.dto.ResponseDataDto;
import cevent.source.cloudcenter.server.enums.UseTypeEnum;
import cevent.source.cloudcenter.server.service.FileService;
import cevent.source.cloudcenter.server.util.UUID8Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author cevent
 * @description 文件上传:单图
 * @date 2021/4/24 14:41
 */
@RestController
@RequestMapping("/admin")
public class UploadIconController {
    private static final Logger LOG= LoggerFactory.getLogger(UploadIconController.class);
    public static final String BUSINESS_NAME="文件上传模块";

    @Resource
    private FileService fileService;

    //注入properties中的file配置
    @Value("${file.targetPath}")
    private String FILE_TARGET_PATH;
    @Value("${file.getPath}")
    private String FILE_GET_PATH;
    /*1.单图上传:
    @RequestParam:基于文件是formData形式传输
    MultipartFile:富文本大文件
    file:formData.append('file',icon),前端formData中提交file参数名,包含元素查询中的icon文件
     */
    @RequestMapping("/test")
    public String test(){
        return "文件系统模块启动成功";
    }

    @RequestMapping("/upload/icon")
    public ResponseDataDto uploadIcon(@RequestParam MultipartFile file,String moduleId,String useType) throws IOException {
        LOG.info("上传的文件file:{}",file);
        LOG.info("上传的文件file名fileName:{}",file.getOriginalFilename());
        LOG.info("上传的文件file大小:{}",file.getSize());
        LOG.info("上传的文件file名name:{}",file.getName());
        LOG.info("上传的文件file类型:{}",file.getContentType());

        //保存文件到本地
        String fileName=file.getOriginalFilename();
        String fileKey= UUID8Util.getShortUUID();
        //获取文件后缀名(类型),全部转小写
        String suffix=fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
        String contentType=file.getContentType();
        Long size=file.getSize();

        //文件名配置
        Date now=new Date();
        String date=new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(now);

        //获取枚举类型,生成新的文件夹路径
        UseTypeEnum useTypeEnum=UseTypeEnum.getByCode(useType);
        //获取到枚举名SOURCE("","")
        String dateDir=new SimpleDateFormat("yyyy_MM_dd").format(now);
        String dir=useTypeEnum.name().toLowerCase();
        File fullDir=new File(FILE_TARGET_PATH+"source"+File.separator+dir+File.separator+dateDir);
        LOG.info("创建的fullDir目录:{}",fullDir);
        //创建文件夹
        if(!fullDir.exists()){
            fullDir.mkdirs();
            LOG.info("创建成功目录?:{}",fullDir.mkdirs());
        }
        String name=date+"_"+fileKey+"_"+fileName;
        //File.separator生成不同操作系统的/斜杠
        String path="source/"+dir+File.separator+dateDir+File.separator+name;
        LOG.info("上传的path:{}",path);
        //全路径
        String fullPath=FILE_TARGET_PATH+path;
        //放入日期目录
        File dest=new File(fullPath);
        file.transferTo(dest);
        LOG.info("获取destination目的位置完全路径:{}",dest.getAbsolutePath());

        //保存file
        FileDto fileDto=new FileDto();
        fileDto.setName(name);
        //返回相对路径
        //fileDto.setPath(path);
        //返回全路径
        fileDto.setPath(FILE_GET_PATH+path);
        fileDto.setSuffix(suffix);
        fileDto.setContentType(contentType);
        fileDto.setSize(Math.toIntExact(size));
        fileDto.setUseType(useType);
        fileDto.setIsShow(0);
        fileDto.setModuleId(moduleId);

        fileService.save(fileDto);
        ResponseDataDto responseData=new ResponseDataDto();
        responseData.setResponseData(fileDto);
        return responseData;
    }
}


文章模块更新图片上传:保存bug:pic_list为longTest类型,mybatis普通的insert无法保存该类型,需要


pageDto查询方法更新


3.前端上传视频更新fileIcon组件,引用后的接收请求格式即可

Template模块…
<el-form-item label="文章视频" prop="articleVideo">
    <file-icon :upload-tile="'上传视频'" :input-id="'upload-articleVideo-icon'" :suffix-type="['mp4']"
               :uniId="article.uniId" :use-type="SOURCE_USE_TYPE.SOURCE_PUBLIC.key"
               :after-upload="afterArticleVideoUpload"></file-icon>
    <el-row class="upload-icon">
        <el-col :span="12">
            <video class="articleVideo" :src="article.articleVideo" controls="controls" ></video>
        </el-col>
    </el-row>
</el-form-item>
Css部分
/*视频上传*/
.articleVideo{
    width: 100%;
}


4.自动获取视频时长

Template模块
<el-form-item label="文章视频" prop="articleVideo">
    <file-icon :upload-tile="'上传视频'" :input-id="'upload-articleVideo-icon'" :suffix-type="['mp4']"
               :uniId="article.uniId" :use-type="SOURCE_USE_TYPE.SOURCE_PUBLIC.key"
               :after-upload="afterArticleVideoUpload"></file-icon>
    <el-row class="upload-icon">
        <el-col :span="12">
            <video id="av" class="articleVideo" :src="article.articleVideo" controls="controls" ></video>
        </el-col>
    </el-row>
</el-form-item>
<el-form-item label="时长" prop="videoTime">
                    <el-input id="videoTime" class="inputLine" v-model="article.videoTime" disabled></el-input>
</el-form-item>

视频时长转换
afterArticleVideoUpload(resp){
    console.log("上传到的article视频地址:",resp.responseData);
    this.article.articleVideo=resp.responseData.path;
    this.getVideoTime();
    console.log("这里的picList:",this.article.articleVideo);
},

//获取视频时间
getVideoTime(){
    let video=document.getElementById("av");
    this.article.videoTime=parseInt(video.duration,10);
    console.log("videoTime转换:",this.article.videoTime);
}


5.多图上传回显,使用file表进行module关联更新

1)fileController更新,根据moduleId查询file列表

/*
根据moduleId查询文件列表
 */
@GetMapping("/list/{moduleId}")
public ResponseDataDto listByModuleId(@PathVariable String moduleId){
    ResponseDataDto responseData=new ResponseDataDto();
    List<FileDto> fileDtos=fileService.listByModuleId(moduleId);
    responseData.setResponseData(fileDtos);
    return responseData;
}

2)fileService更新实现

//7.根据传入的moduleId查询file文件列表
public List<FileDto> listByModuleId(String moduleId){
    FileExample fileExample=new FileExample();
    FileExample.Criteria criteria=fileExample.createCriteria();
    criteria.andModuleIdEqualTo(moduleId);
    List<File> files=fileMapper.selectByExample(fileExample);
    return DuplicateUtil.copyList(files,FileDto.class);
}

3) article更新edit方法,进入页面之前根据moduleId查询fileList

//4.修改
edit(article) {
    console.log("edit的article:", article);
    /*jquery继承对象: $.extend({新对象},旧对象)
    避免vue数据绑定漏洞,更改数据时,随之更改显示的data,但实际没有进行真实保存数据库
     */
    this.article = $.extend({}, article);
    //SessionStorage.set("article",article);
    SessionStorage.set(ARTICLE_MODULE_PARENTID,this.module.parentId);
    console.log("从moduleSub传入的module:",this.module);

    //加载article的文件列表
    Loadings.show();
    this.$axios.get(process.env.VUE_APP_SERVER + '/source/admin/file/list/'+ article.uniId)
        .then((response)=>{
            let resp=response.data;
            if(resp.success){
                SessionStorage.set(FILE_LIST,resp.responseData);
                console.log("缓存中的aticle-file-list:",SessionStorage.get(FILE_LIST));
                Loadings.hide();
            }
        });
    this.$router.push({
        name: "business/article/add",
        params: {article}
    });
},

4) addArticle在mounted时,获取sessionStorage中的FILE_LIST,同步到files

mounted() {
    console.log(this.message);
    console.log("传入的article==>params:", this.$route.params.article);
    let moduleParentId = SessionStorage.get(ARTICLE_MODULE_PARENTID) || "";
    if (this.$route.params.article != null) {
        this.article = this.$route.params.article;
        this.article.moduleUniId = moduleParentId;
        //2.获取当前article的富文本内容
        $("#content").summernote('code', this.article.articleContent);
        //缓存中的文件列表
        this.files= SessionStorage.get(FILE_LIST);
        console.log("传入的FILE_LIST:",this.files);
        console.log("article传入的moduleParentId:", moduleParentId);
        let optionArticle = document.getElementById("optionArticle");
        let submitBtn = document.getElementById("submitBtn");
        optionArticle.innerHTML = '更新文章数据';
        submitBtn.innerHTML = "立即更新";
    } else {
        //获取article在session中保存的articleModuleId
        let moduleId = SessionStorage.get(ARTICLE_MODULE_ID) || "";
        console.log("article传入的moduleId缓存session数据:", moduleId);
        if (moduleId !== null) {
            this.article = {};
            this.article.moduleId = moduleId;
            this.article.moduleUniId = moduleParentId;
        }
    }
    //富文本
    $("#content").summernote({
        focus: true,
        height: 300
    })

},

5) addArticle在上传picList时,更新files中的图片列表,再次写入缓存setSession,并调用savePicList方法,将files中的path保存到picList

//接收文件上传组件传入的resp
afterUpload(resp) {
    if (resp.success) {
        console.log("上传到的article图片列表地址:", resp.responseData);
        this.article.picList = resp.responseData.path;
        console.log("这里的picList:", this.article.picList);
        this.getFiles();
    }
},
getFiles(){
    this.$axios.get(process.env.VUE_APP_SERVER + '/source/admin/file/list/'+ this.article.uniId)
        .then((response)=>{
            let resp=response.data;
            if(resp.success){
                this.files=resp.responseData;
                this.savePicList(this.files);
                SessionStorage.set(FILE_LIST,this.files);
            }
        });
},
//存入picList
savePicList(files){
    let pics=[];
    for(let i=0;i<files.length;i++){
        pics.push(files[i].path);
        this.article.picList=JSON.stringify(pics);
    }
    console.log("存入的picList:",this.article.picList);
},

6)addArticle在删除时,调用tools中的删除数组对象方removeObj(array,file),再次调用getFiles更新picList

//删除文件
delFile(file){
    let _this = this;
    let fileParam =file;
    toast.showConfirm(file.name, function () {
        _this.$axios.delete(process.env.VUE_APP_SERVER + '/source/admin/file/del/' + fileParam.uniId)
            .then((response) => {
                let resp = response.data;
                if (resp.success) {
                    console.log("删除的模块-文件资源:", file.path);
                    _this.getFiles();
                    Tool.removeObj(_this.files,file);
                    console.log("files删除成功了吗?",Tool.removeObj(_this.files,file));
                    //_this.pageList(1);
                }
            })
    })
},


gitee提交,源码开放长期维护欢迎fork,关注,mark,点赞收藏转发

gitee地址:
https://gitee.com/cevent_OS/yameng-cevent-source-cloudcenter.git

相关推荐

sharding-jdbc实现`分库分表`与`读写分离`

一、前言本文将基于以下环境整合...

三分钟了解mysql中主键、外键、非空、唯一、默认约束是什么

在数据库中,数据表是数据库中最重要、最基本的操作对象,是数据存储的基本单位。数据表被定义为列的集合,数据在表中是按照行和列的格式来存储的。每一行代表一条唯一的记录,每一列代表记录中的一个域。...

MySQL8行级锁_mysql如何加行级锁

MySQL8行级锁版本:8.0.34基本概念...

mysql使用小技巧_mysql使用入门

1、MySQL中有许多很实用的函数,好好利用它们可以省去很多时间:group_concat()将取到的值用逗号连接,可以这么用:selectgroup_concat(distinctid)fr...

MySQL/MariaDB中如何支持全部的Unicode?

永远不要在MySQL中使用utf8,并且始终使用utf8mb4。utf8mb4介绍MySQL/MariaDB中,utf8字符集并不是对Unicode的真正实现,即不是真正的UTF-8编码,因...

聊聊 MySQL Server 可执行注释,你懂了吗?

前言MySQLServer当前支持如下3种注释风格:...

MySQL系列-源码编译安装(v5.7.34)

一、系统环境要求...

MySQL的锁就锁住我啦!与腾讯大佬的技术交谈,是我小看它了

对酒当歌,人生几何!朝朝暮暮,唯有己脱。苦苦寻觅找工作之间,殊不知今日之事乃我心之痛,难道是我不配拥有工作嘛。自面试后他所谓的等待都过去一段时日,可惜在下京东上的小金库都要见低啦。每每想到不由心中一...

MySQL字符问题_mysql中字符串的位置

中文写入乱码问题:我输入的中文编码是urf8的,建的库是urf8的,但是插入mysql总是乱码,一堆"???????????????????????"我用的是ibatis,终于找到原因了,我是这么解决...

深圳尚学堂:mysql基本sql语句大全(三)

数据开发-经典1.按姓氏笔画排序:Select*FromTableNameOrderByCustomerNameCollateChinese_PRC_Stroke_ci_as//从少...

MySQL进行行级锁的?一会next-key锁,一会间隙锁,一会记录锁?

大家好,是不是很多人都对MySQL加行级锁的规则搞的迷迷糊糊,一会是next-key锁,一会是间隙锁,一会又是记录锁。坦白说,确实还挺复杂的,但是好在我找点了点规律,也知道如何如何用命令分析加...

一文讲清怎么利用Python Django实现Excel数据表的导入导出功能

摘要:Python作为一门简单易学且功能强大的编程语言,广受程序员、数据分析师和AI工程师的青睐。本文系统讲解了如何使用Python的Django框架结合openpyxl库实现Excel...

用DataX实现两个MySQL实例间的数据同步

DataXDataX使用Java实现。如果可以实现数据库实例之间准实时的...

MySQL数据库知识_mysql数据库基础知识

MySQL是一种关系型数据库管理系统;那废话不多说,直接上自己以前学习整理文档:查看数据库命令:(1).查看存储过程状态:showprocedurestatus;(2).显示系统变量:show...

如何为MySQL中的JSON字段设置索引

背景MySQL在2015年中发布的5.7.8版本中首次引入了JSON数据类型。自此,它成了一种逃离严格列定义的方式,可以存储各种形状和大小的JSON文档,例如审计日志、配置信息、第三方数据包、用户自定...

取消回复欢迎 发表评论: