1, Course final release information display - back end
1. Entity class - used to encapsulate the data displayed on the page
@ApiModel(value = "Course final release") @Data public class CoursePublishVo implements Serializable { private static final long serialVersionUID = 1L; //Course title private String title; //Course cover private String cover; //Class hours private Integer lessonNum; //Primary classification private String subjectLevelOne; //Secondary classification private String subjectLevelTwo; //Lecturer name private String teacherName; //Course price private String price;//For display only }
2. Write Controller class
//Course release //Query the publishing information of the course according to the course id @ApiOperation("Query course publishing information") @GetMapping("getPublishCourseInfo/{id}") public R getPublishCourseInfo(@PathVariable String id){ CoursePublishVo courseInfo = courseService.getPublishCourseInfo(id); return R.ok().data("courseInfo",courseInfo); }
3. Write Service class
//Query course publishing information according to id @Override public CoursePublishVo getPublishCourseInfo(String id) { CoursePublishVo coursePublishVo = this.baseMapper.getPublishCourseInfo(id); return coursePublishVo; }
Since the data displayed on our final release page comes from four tables (course schedule, course description table, lecturer table and classification table), we need to write SQL statements manually.
4. Write mapper interface
public interface EduCourseMapper extends BaseMapper<EduCourse> { public CoursePublishVo getPublishCourseInfo(String id); }
5. Write mapper class xml configuration file
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.rg.eduservice.mapper.EduCourseMapper"> <select id="getPublishCourseInfo" resultType="com.rg.eduservice.entity.vo.CoursePublishVo" parameterType="string"> SELECT ec.id,ec.`title`,ec.`price`,ec.`lesson_num` AS lessonNum,ec.`cover`, et.`name` teacherName, es1.`title` AS subjectLevelOne, es2.`title` AS subjectLevelTwo FROM edu_course ec LEFT OUTER JOIN edu_subject es1 ON ec.`subject_parent_id`= es1.`id` LEFT OUTER JOIN edu_subject es2 ON ec.`subject_id` = es2.`id` LEFT OUTER JOIN edu_teacher et ON ec.`teacher_id` = et.`id` WHERE ec.id=#{id} </select> </mapper>
6. Errors in project operation and Solutions
The project creates the mapper interface, writes the sql statement of the xml file, and there is an error in the execution
This error is caused by maven's default loading mechanism. When maven is loaded, put it in the java folder java type files are compiled. If other types of files are used, they will not be loaded.
Solution:
1. Copy xml to target directory
2. Put the xml file in the resources directory
3. Recommended: through configuration file
(1)pom.xml
(2) Project application properties
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
In the application of the service module In properties
# The path to the configuration mapper xml file mybatis-plus.mapper-locations=classpath:com/kuang/eduservice/mapper/xml/*.xml
Restart the service to run successfully!
2, Course final release information display - front end
1. Define api interface
//Query the basic information published by the course according to the course id getPublishCourseInfo(id) { return request({ url: `/eduservice/course/getPublishCourseInfo/${id}`, method: 'get' }) }
2. Front end pages and styles
<template> <div class="app-container"> <h2 style="text-align: center;">Publish new courses</h2> <el-steps :active="3" process-status="wait" align-center style="margin-bottom: 40px;"> <el-step title="Fill in the basic information of the course"/> <el-step title="Create syllabus"/> <el-step title="Publish courses"/> </el-steps> <div class="ccInfo"> <img :src="coursePublish.cover"> <div class="main"> <h2>{{ coursePublish.title }}</h2> <p class="gray"><span>common{{ coursePublish.lessonNum }}class hour</span></p> <p><span>Classification:{{ coursePublish.subjectLevelOne }} — {{ coursePublish.subjectLevelTwo }}</span></p> <p>Course instructor:{{ coursePublish.teacherName }}</p> <h3 class="red">¥{{ coursePublish.price }}</h3> </div> </div> <div> <el-button @click="previous">Return to modify</el-button> <el-button :disabled="saveBtnDisabled" type="primary" @click="publish">Publish courses</el-button> </div> </div> </template>
<style scoped> .ccInfo { background: #f5f5f5; padding: 20px; overflow: hidden; border: 1px dashed #DDD; margin-bottom: 40px; position: relative; } .ccInfo img { background: #d6d6d6; width: 500px; height: 278px; display: block; float: left; border: none; } .ccInfo .main { margin-left: 520px; } .ccInfo .main h2 { font-size: 28px; margin-bottom: 30px; line-height: 1; font-weight: normal; } .ccInfo .main p { margin-bottom: 10px; word-wrap: break-word; line-height: 24px; max-height: 48px; overflow: hidden; } .ccInfo .main p { margin-bottom: 10px; word-wrap: break-word; line-height: 24px; max-height: 48px; overflow: hidden; } .ccInfo .main h3 { left: 540px; bottom: 20px; line-height: 1; font-size: 28px; color: #d32f24; font-weight: normal; position: absolute; } </style>
3. Introduction interface
import course from '@/api/edu/course'
4. Write front-end js
data() { return { //.... saveBtnDisabled:false, courseId: '', coursePublish: {} } }, created() { //Get the id value in the route if(this.$route.params && this.$route.params.id) { this.courseId = this.$route.params.id //Call the interface method to query according to the course id this.getPublishCourseInfo() } }, methods: { //Query course information according to course id getPublishCourseInfo(){ course.getPublishCourseInfo(this.courseId).then(response=>{ this.coursePublish = response.data.courseInfo }) } //..... }
5. Page rendering
3, Course final release – front and back
1. Write Controller class
//Course release @PutMapping("publishCourse/{id}") public R publishCourse(@PathVariable String id){ EduCourse course = new EduCourse(); course.setId(id); course.setStatus("Normal"); boolean update = courseService.updateById(course); if(update){ return R.ok(); }else{ return R.error(); } }
2. Define api interface
//Publish course information publishCourse(id) { return request({ url: `/eduservice/course/publishCourse/${id}`, method: 'put' }) }
3. Write front-end js
publish(){ course.publishCourse(this.courseId).then(response=>{ this.$confirm('Are you sure to publish this course,Continue?','Tips',{ confirmButtonText:'determine', cancelButtonText:'cancel', type:'warning' }).then(()=>{//Click OK this.$message({ type:'success', message:'Course published successfully!' }) //Jump to the course list page this.$router.push({path:'/course/list'}) }).catch(()=>{ this.$message({ type: 'info', message: 'Publish canceled!' }) }) }).catch(()=>{ this.$message({ type: 'error', message: 'Course publishing failed!' }) }) }
4, Course list – back end
1. Write query entity class
@Data public class CourseQuery implements Serializable { private static final long serialVersionUID = 1L; //Primary classification id private String subjectParentId; //Secondary classification id private String subjectId; //Course name private String title; //Instructor id private String teacherId; }
2. Controller class
//Paging query course @PostMapping("pageQuery/{current}/{limit}") public R pageQuery(@PathVariable Integer current, @PathVariable Integer limit, @RequestBody CourseQuery courseQuery) { Page<EduCourse> page = courseService.pageQuery(current,limit,courseQuery); return R.ok().data("total",page.getTotal()).data("list",page.getRecords()); } //Delete course @DeleteMapping("removeCourse/{id}") public R removeCourse(@PathVariable String id){ courseService.removeCourse(id); return R.ok(); }
3. Service class
//Pagination query of courses @Override public Page <EduCourse> pageQuery(Integer current, Integer limit, CourseQuery courseQuery) { Page <EduCourse> page = new Page <>(current,limit); QueryWrapper <EduCourse> wrapper = new QueryWrapper <>(); String title = courseQuery.getTitle(); String subjectId = courseQuery.getSubjectId(); String subjectParentId = courseQuery.getSubjectParentId(); String teacherId = courseQuery.getTeacherId(); //Empty judgment and construct query conditions if(!StringUtils.isEmpty(title)){ wrapper.like("title",title); } if(!StringUtils.isEmpty(subjectId)){ wrapper.eq("subject_id",subjectId); } if(!StringUtils.isEmpty(subjectParentId)){ wrapper.eq("subject_parent_id",subjectParentId); } if(!StringUtils.isEmpty(teacherId)){ wrapper.eq("teacher_id",teacherId); } wrapper.orderByDesc("gmt_create"); //Paging query this.baseMapper.selectPage(page, wrapper);//After paging query, it is automatically encapsulated in page return page; } //Delete course information according to id @Override public void removeCourse(String id) { //1. Delete section videoService.removeVideoByCourseId(id); //2. Delete chapter chapterService.removeChapterByCourseId(id); //3. Delete course description information courseDescriptionService.removeById(id); //4. Delete course information this.baseMapper.deleteById(id); }
5, Course list – front end
1. Define api interface
//Delete course removeCourse(id) { return request({ url: `/eduservice/course/removeCourse/${id}`, method: 'delete' }) }, //Paging query course pageQuery(current, limit, courseQuery) { return request({ url: `/eduservice/course/pageQuery/${current}/${limit}`, method: 'post', data: courseQuery }) }
2. Front page - list vue
<template> <div class="app-container"> <!--query form --> <el-form :inline="true" class="demo-form-inline"> <!-- Category: cascade drop-down list --> <!-- Primary classification --> <el-form-item label="Course category"> <el-select v-model="searchObj.subjectParentId" placeholder="Please select" @change="subjectLevelOneChanged"> <el-option v-for="subject in subjectNestedList" :key="subject.id" :label="subject.title" :value="subject.id"/> </el-select> <!-- Secondary classification --> <el-select v-model="searchObj.subjectId" placeholder="Please select"> <el-option v-for="subject in subSubjectList" :key="subject.id" :label="subject.title" :value="subject.id"/> </el-select> </el-form-item> <!-- title --> <el-form-item> <el-input v-model="searchObj.title" placeholder="Course title"/> </el-form-item> <!-- lecturer --> <el-form-item> <el-select v-model="searchObj.teacherId" placeholder="Please select a lecturer"> <el-option v-for="teacher in teacherList" :key="teacher.id" :label="teacher.name" :value="teacher.id"/> </el-select> </el-form-item> <el-button type="primary" icon="el-icon-search" @click="getList()">query</el-button> <el-button type="default" @click="resetData()">empty</el-button> </el-form> <!-- form --> <el-table v-loading="listLoading" :data="list" element-loading-text="Data loading" border fit highlight-current-row row-class-name="myClassList"> <el-table-column label="Serial number" width="70" align="center"> <template slot-scope="scope"> {{ (page - 1) * limit + scope.$index + 1 }} </template> </el-table-column> <el-table-column label="Course information" width="470" align="center"> <template slot-scope="scope"> <div class="info"> <div class="pic"> <img :src="scope.row.cover" alt="scope.row.title" width="150px"> </div> <div class="title"> <a href="">{{ scope.row.title }}</a> <p>{{ scope.row.lessonNum }}class hour</p> </div> </div> </template> </el-table-column> <el-table-column label="Creation time" align="center"> <template slot-scope="scope"> {{ scope.row.gmtCreate.substr(0, 10) }} </template> </el-table-column> <el-table-column label="Release time" align="center"> <template slot-scope="scope"> {{ scope.row.gmtModified.substr(0, 10) }} </template> </el-table-column> <el-table-column label="Price" width="100" align="center" > <template slot-scope="scope"> {{ Number(scope.row.price) === 0 ? 'free' : '¥' + scope.row.price.toFixed(2) }} </template> </el-table-column> <el-table-column prop="buyCount" label="Paid student" width="100" align="center" > <template slot-scope="scope"> {{ scope.row.buyCount }}people </template> </el-table-column> <el-table-column prop="viewCount" label="Playback times" width="100" align="center" > <template slot-scope="scope"> {{ scope.row.viewCount }}second </template> </el-table-column> <el-table-column label="operation" width="150" align="center"> <template slot-scope="scope"> <router-link :to="'/course/info/'+scope.row.id"> <el-button type="text" size="mini" icon="el-icon-edit" >Edit course information</el-button> </router-link> <router-link :to="'/course/chapter/'+scope.row.id"> <el-button type="text" size="mini" icon="el-icon-edit" >Edit syllabus</el-button> </router-link> <el-button type="text" size="mini" icon="el-icon-delete" @click="removeCourse(scope.row.id)">delete</el-button> </template> </el-table-column> </el-table> <!-- paging --> <el-pagination :current-page="page" :page-size="limit" :total="total" style="padding: 30px 0; text-align: center;" layout="total, prev, pager, next, jumper" @current-change="getList" /> </div> </template>
3. Page style
<style scoped> .myClassList .info { width: 450px; overflow: hidden; } .myClassList .info .pic { width: 150px; height: 90px; overflow: hidden; float: left; } .myClassList .info .pic a { display: block; width: 100%; height: 100%; margin: 0; padding: 0; } .myClassList .info .pic img { display: block; width: 100%; } .myClassList td .info .title { width: 280px; float: right; height: 90px; } .myClassList td .info .title a { display: block; height: 48px; line-height: 24px; overflow: hidden; color: #00baf2; margin-bottom: 12px; } .myClassList td .info .title p { line-height: 20px; margin-top: 5px; color: #818181; } </style>
4. Write front-end js
<script> import course from '@/api/edu/course' import subject from '@/api/edu/subject' export default { data() { return { listLoading: false, // Whether to display loading information list: null, // Data list total: 0, // Total records page: 1, // Page number limit: 10, // Records per page searchObj: { subjectParentId: '', subjectId: '', title: '', teacherId: '' }, // query criteria teacherList: [], // Instructor list subjectNestedList: [], // Primary classification list subSubjectList: [] // Secondary classification list, } }, created() { this.init() }, methods: { //Edit syllabus updateChapter(id){ this.$router.push({path:'/course/chapter/'+id}) }, //Edit course basic information updateCourse(id){ this.$router.push({path:'/course/info/'+id}) }, removeCourse(id){ this.$confirm('This action will permanently delete all contents of this course,Continue?','Tips',{ confirmButtonText:'determine', cancelButtonText:'cancel', type:'warning' }).then(()=>{//Click OK course.removeCourse(id).then((response)=>{ this.$message({ type:'success', message:'Deleted successfully!' }) //Return to the list page this.getList() }).catch(()=>{ this.$message({ type:'error', message:'Delete failed!' }) }) }).catch(() => { // Click Cancel this.$message({ type: 'info', message: 'Deletion cancelled!' }) }) }, //Paging + conditional query getList(page = 1){//The default value of page is 1. When the paging component is used, a new page parameter will be passed in this.page = page course.pageQuery(this.page,this.limit,this.searchObj).then(response=>{ this.list = response.data.list this.total = response.data.total }) }, //Query form reset method resetData(){ this.searchObj = {}, this.subSubjectList = [] }, //Method when the primary classification drop-down menu changes subjectLevelOneChanged(id){ // console.log(id); for(var i = 0;i < this.subjectNestedList.length;i++){ if(this.subjectNestedList[i].id == id){ this.subSubjectList = this.subjectNestedList[i].children } } }, //Initialization method init(){ //1. Query primary classification subject.getAllSubject().then(response=>{ this.subjectNestedList = response.data.list }) //2. Query all lecturers course.getTeacherList().then(response=>{ this.teacherList = response.data.items }) //3. Query course list this.getList() } } } </script>
5, Page rendering
6, Alibaba cloud video on demand service
ApsaraVideo for VoD is a one-stop audio and video on demand solution integrating audio and video acquisition, editing, uploading, automatic transcoding processing, media resource management and distribution acceleration.
1. Video on demand
Enter Alibaba cloud's official website: https://www.aliyun.com/ , find video on demand
Open video on demand service (choose to charge by traffic)
2. Tariff description
https://www.aliyun.com/price/product?spm=a2c4g.11186623.2.12.7fbd59b9vmXVN6#/vod/detail
3. Overall process
The overall process of audio and video upload, storage, processing and playback using video on demand is as follows:
4. Basic use of video on demand service
Complete reference documents https://help.aliyun.com/product/29932.html?spm=a2c4g.11186623.6.540.3c356a58OEmVZJ
-
Server: back end interface
-
Client: browser, Android, ios
-
API: Alibaba cloud provides a fixed address. You only need to call the fixed address and pass parameters to the address to realize the function.
-
SDK: SDK encapsulates the api mode, which is more convenient to use. Previously, we used EayExcel to call the methods in the classes or interfaces provided by Alibaba cloud to realize video functions.
5. How to use Java code and SDK
Note: the uploaded video can be encrypted. After encryption, the encrypted address cannot be used for video playback. Therefore, the video id is stored in the database instead of the address.
(1) Create sub module service under service_vod module
POM.xml
<dependencies> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-vod</artifactId> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-sdk-vod-upload</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> </dependency> </dependencies>
(2) Initialize the operation and create the DefaultAcsClient object
public class InitVodClient { public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException { String regionId = "cn-shanghai"; // VOD access region DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret); DefaultAcsClient client = new DefaultAcsClient(profile); return client; } }
(3) Obtain the video playback address according to the video id
//Obtain the video playback address according to the id public static void getPlayUrl()throws ClientException{ //Create initialization object DefaultAcsClient client = InitVodClient.initVodClient("your keyId", "your keySecret"); //Create and obtain video address request and response GetPlayInfoRequest request = new GetPlayInfoRequest(); GetPlayInfoResponse response = new GetPlayInfoResponse(); request.setVideoId("efc88346e5dd45fda5b161c9ddbd0d9d"); //Call the method in the initialization object, pass the request and get the data response = client.getAcsResponse(request); List <GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList(); //Playback address for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) { System.out.print("PlayInfo.PlayURL = " + playInfo.getPlayURL() + "\n"); } //Base information video name System.out.print("VideoBase.Title = " + response.getVideoBase().getTitle() + "\n"); }
(4) Obtain video playback certificate
//Obtain video playback certificate according to id public static void getPlayAuth()throws ClientException{ //Create initialization object DefaultAcsClient client = InitVodClient.initVodClient("your keyId", "your keySecret"); GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest(); GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse(); request.setVideoId("003a83891a7b444d93727d83a5ba7d3a"); response = client.getAcsResponse(request); System.out.println("palyAuth:"+response.getPlayAuth()); }
(5) Upload video to Alibaba cloud video on demand service
//Upload in the form of file stream public static void testUploadFileStream(){ String accessKeyId = "your keyId"; String accessKeySecret = "your keySecret"; String title = "6 - What If I Want to Move Faster123.mp4 "; String fileName = "F:/self-study course/Project data/02 Grain Academy(Distributed project)/Project data/1-Alibaba cloud upload test video/6 - What If I Want to Move Faster.mp4"; UploadFileStreamRequest request = new UploadFileStreamRequest(accessKeyId, accessKeySecret, title, fileName); UploadVideoImpl uploader = new UploadVideoImpl(); UploadFileStreamResponse response = uploader.uploadFileStream(request); System.out.print("RequestId=" + response.getRequestId() + "\n"); //Request ID for requesting video on demand service if (response.isSuccess()) { System.out.print("VideoId=" + response.getVideoId() + "\n"); } else { /* If the setting callback URL is invalid, it will not affect the video upload. You can return VideoId and error code. When the upload fails in other cases, the VideoId is empty. At this time, the specific error reason needs to be analyzed according to the returned error code */ System.out.print("VideoId=" + response.getVideoId() + "\n"); System.out.print("ErrorCode=" + response.getCode() + "\n"); System.out.print("ErrorMessage=" + response.getMessage() + "\n"); } }
7, Add a section to upload and delete Videos - back end
1. Introduce dependency
2. Create application profile
#Service port server: port: 8003 #service name spring: application: name: service-vod #Environment settings: dev,test,prod profiles: active: dev servlet: multipart: max-file-size: 1024MB # Maximum upload single file size: 1M by default max-request-size: 1024MB # Maximum total uploaded data size: 10M by default #Alibaba cloud VOD address aliyun: vod: file: keyid: your keyId keysecret: your keySecret
3. Constant tool class
@Component //Leave the property settings to Spring public class ConstantPropertiesUtil implements InitializingBean {// InitializingBean: this class is executed during initialization //Read values from the configuration file and assign values to these attributes //Note that @ value cannot inject values into static attributes @Value("${aliyun.vod.file.keyid}") private String keyId; @Value("${aliyun.vod.file.keysecret}") private String keySecret; //Define public static methods public static String ACCESS_KEY_ID; public static String ACCESS_KEY_SECRET; //This method is executed after the attribute value is set @Override public void afterPropertiesSet() throws Exception { ACCESS_KEY_ID = keyId; ACCESS_KEY_SECRET = keySecret; } }
4. Main startup class
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @ComponentScan("com.rg")//To scan the external swagger public class VodApplication { public static void main(String[] args) { SpringApplication.run(VodApplication.class, args); } }
5. Write Controller class
@RestController @RequestMapping("/vodService/video") @CrossOrigin public class VodController { @Autowired private VodService vodService; //Upload video to Alibaba cloud VOD @PostMapping("uploadVideoAly") public R uploadVideoAly(@RequestBody MultipartFile file){ String videoId = vodService.uploadVideoAly(file); return R.ok().data("videoId",videoId); } //Delete video from alicloud according to video id @DeleteMapping("removeAlyVideo/{id}") public R removeAlyVideo(@PathVariable String id){ vodService.removeAlyVideo(id); return R.ok(); } }
6. Write Service class
@Service public class VodServiceImpl implements VodService { //Upload video to Alibaba cloud VOD @Override public String uploadVideoAly(MultipartFile file) { String accessKeyId = ConstantPropertiesUtil.ACCESS_KEY_ID; String accessKeySecret = ConstantPropertiesUtil.ACCESS_KEY_SECRET; String title = file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));//Display name after uploading String fileName = file.getOriginalFilename();//Original name of uploaded file try { InputStream inputStream = file.getInputStream();//Upload file stream UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, inputStream); UploadVideoImpl uploader = new UploadVideoImpl(); UploadStreamResponse response = uploader.uploadStream(request); String videoId = response.getVideoId(); return videoId; } catch (Exception e) { e.printStackTrace(); throw new GuLiException(20001, "File upload failed!"); } } //Delete videos on Alibaba cloud based on id @Override public void removeAlyVideo(String id) { try { DefaultAcsClient client = InitVodClient.initVodClient(ConstantPropertiesUtil.ACCESS_KEY_ID, ConstantPropertiesUtil.ACCESS_KEY_SECRET); // DeleteVideoRequest request = new DeleteVideoRequest(); DeleteVideoResponse response = new DeleteVideoResponse(); //Want to set the video id in the request request.setVideoIds(id); response = client.getAcsResponse(request); } catch (ClientException e) { e.printStackTrace(); throw new GuLiException(20001, "Video deletion failed!"); } } }
8, Add a section to upload and delete Videos - front end
1. Define api
//Delete video by id removeAlyVideo(id) { return request({ url: `/vodService/video/removeAlyVideo/${id}`, method: 'delete' }) }
2. Integrated upload component
<el-form-item label="Upload video"> <el-upload :on-success="handleVodUploadSuccess" :on-remove="handleVodRemove" :before-remove="beforeVodRemove" :on-exceed="handleUploadExceed" :file-list="fileList" :action="BASE_API+'/vodService/video/uploadVideoAly'" :limit="1" class="upload-demo"> <el-button size="small" type="primary">Upload video</el-button> <el-tooltip placement="right-end"> <div slot="content">Maximum support1 G,<br> Support 3 GP,ASF,AVI,DAT,DV,FLV,F4V,<br> GIF,M2T,M4V,MJ2,MJPEG,MKV,MOV,MP4,<br> MPE,MPG,MPEG,MTS,OGG,QT,RM,RMVB,<br> SWF,TS,VOB,WMV,WEBM Upload in other video formats</div> <i class="el-icon-question"/> </el-tooltip> </el-upload> </el-form-item>
3. Data definition
fileList: [],//Upload file list BASE_API: process.env.BASE_API // Interface API address video: {// Class object title: '', sort: 0, isFree: 0, videoSourceId: '', videoOriginalName:'' }
4. Page js method
//How to upload more than the maximum number of videos handleUploadExceed(file,fileList){ this.$message.warning('Want to upload the video again,Please delete the uploaded video first') }, //Click OK to call the method handleVodRemove(){ video.removeAlyVideo(this.video.videoSourceId).then(response=>{ this.$message({ type:'success', message:'Video deleted successfully!' }) //Empty the file list this.fileList = [] //The deleted video information is no longer stored in the database this.video.videoSourceId = '' this.video.videoOriginalName = '' }) }, //click × Method called beforeVodRemove(file,fileList){ return this.$confirm(`OK to remove ${file.name}?`) }, //Upload successful method handleVodUploadSuccess(response,file,fileList){ this.video.videoSourceId = response.data.videoId this.video.videoOriginalName = file.name }
5. Video echo when editing a section
6. Page effect display
If there is harvest!!! I hope the old fellow will come to three links, praise, collect and forward.
It's not easy to create. Don't forget to point a praise, which can let more people see this article and encourage me to write a better blog