视频宣传
This commit is contained in:
		
							
								
								
									
										36
									
								
								project/xiushan/apps/AppVideoPublic/AppVideoPublic.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								project/xiushan/apps/AppVideoPublic/AppVideoPublic.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <template> | ||||
|   <section class="AppVideoPublic"> | ||||
|     <component :is="currentComponent" :instance="instance" :dict="dict" :permissions="permissions"/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|  | ||||
| import ProductList from "./vpList"; | ||||
| import ProductAdd from "./vpAdd"; | ||||
|  | ||||
| export default { | ||||
|   name: "AppVideoPublic", | ||||
|   components: {ProductAdd, ProductList}, | ||||
|   label: "视频宣传", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     currentComponent() { | ||||
|       return this.$route.hash == "#add" ? ProductAdd : ProductList | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.dict.load("videoNewsStatus") | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppVideoPublic { | ||||
|   height: 100%; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										209
									
								
								project/xiushan/apps/AppVideoPublic/vpAdd.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								project/xiushan/apps/AppVideoPublic/vpAdd.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| <template> | ||||
|   <section class="vpAdd"> | ||||
|     <ai-detail> | ||||
|       <ai-title slot="title" :title="addTitle" isShowBottomBorder isShowBack @onBackClick="back"/> | ||||
|       <template #content> | ||||
|         <el-form size="small" label-width="120px" :model="form" ref="VideoForm" :rules="rules"> | ||||
|           <ai-card title="基本信息"> | ||||
|             <template #content> | ||||
|               <el-form-item label="标题" prop="title"> | ||||
|                 <el-input v-model="form.title" placeholder="请输入" clearable show-word-limit maxlength="30"/> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="视频" prop="videoUrl"> | ||||
|                 <video v-if="hasVideo" class="video-com" muted :src="form.videoUrl" controls="controls"/> | ||||
|                 <el-upload :show-file-list="false" ref="upload1" action :http-request="submitUpload" | ||||
|                            :accept="accept" :limit="1"> | ||||
|                   <div class="video" v-if="!hasVideo"> | ||||
|                     <div class="icon"> | ||||
|                       <ai-icon type="svg" icon="iconVideo"/> | ||||
|                       <span>上传视频</span> | ||||
|                     </div> | ||||
|                     <span class="tips">支持mp4格式,单个文件最大100MB</span> | ||||
|                   </div> | ||||
|                   <el-button v-else style="margin-top: 10px;">重新选择</el-button> | ||||
|                 </el-upload> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="视频封面" prop="thumbUrl"> | ||||
|                 <ai-uploader :instance="instance" :value="thumb" @change="handleUploader" key="file" :limit="1"> | ||||
|                   <template slot="tips"> | ||||
|                     <p>最多上传1张图片,单个文件最大10MB,支持jpg、jpeg、png格式</p> | ||||
|                   </template> | ||||
|                 </ai-uploader> | ||||
|               </el-form-item> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|         </el-form> | ||||
|       </template> | ||||
|       <template #footer> | ||||
|         <el-button @click="back">取消</el-button> | ||||
|         <el-button type="primary" @click="submit">保存</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import mp4box from "mp4box"; | ||||
|  | ||||
| export default { | ||||
|   name: "vpAdd", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     addTitle() { | ||||
|       return !!this.$route.query.id ? "编辑视频" : "添加视频" | ||||
|     }, | ||||
|     rules() { | ||||
|       return { | ||||
|         title: [{required: true, message: "请输入标题"}], | ||||
|         thumbUrl: [{required: true, message: "请上传视频封面"}], | ||||
|         videoUrl: [{required: true, message: "请上传视频封面"}], | ||||
|       } | ||||
|     }, | ||||
|     hasVideo() { | ||||
|       return !!this.form.videoUrl | ||||
|     }, | ||||
|     thumb(){ | ||||
|       return this.form.thumbUrl?[{url:this.form.thumbUrl}]:[] | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       dialog: false, | ||||
|       form: {videoUrl: ""}, | ||||
|       accept: ".mp4" | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getDetail() { | ||||
|       let {id} = this.$route.query | ||||
|       id && this.instance.post("/appvideonews/getById", null, { | ||||
|         params: {id} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.form = res.data | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     submit() { | ||||
|       this.$refs.VideoForm.validate(v => { | ||||
|         if (v) { | ||||
|           let {form} = this | ||||
|           this.instance.post("/appvideonews/addOrUpdate", form).then(res => { | ||||
|             if (res?.code == 0) { | ||||
|               this.$message.success("提交成功!") | ||||
|               this.back() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     back() { | ||||
|       this.$router.push({}) | ||||
|     }, | ||||
|     submitUpload(file) { | ||||
|       this.$refs.upload1?.clearFiles(); | ||||
|       this.$refs.VideoForm?.clearValidate('videoFile'); | ||||
|       const fileType = file.file.name.split(".")[1]; | ||||
|       const size = file.file.size / 1024 / 1024 > 100; | ||||
|       let mp4boxfile = mp4box.createFile(); | ||||
|       const reader = new FileReader(); | ||||
|       reader.readAsArrayBuffer(file.file); | ||||
|       reader.onload = (e) => { | ||||
|         const arrayBuffer = e.target.result; | ||||
|         arrayBuffer.fileStart = 0; | ||||
|         mp4boxfile.appendBuffer(arrayBuffer); | ||||
|       }; | ||||
|       mp4boxfile.onReady = (info) => { | ||||
|         let codec = info.mime.match(/codecs="(\S*),/)[1] | ||||
|         if (codec.indexOf('avc') === -1) { | ||||
|           return this.$message.error("视频编码格式不支持") | ||||
|         } | ||||
|         if (size) { | ||||
|           return this.$message.error("视频大小不能超过100M"); | ||||
|         } | ||||
|         if (fileType && this.accept.indexOf(fileType.toLocaleLowerCase()) > -1) { | ||||
|           let formData = new FormData() | ||||
|           formData.append('file', file.file); | ||||
|           this.instance.post(`/admin/file/add-unlimited`, formData).then(res => { | ||||
|             if (res && res.data) { | ||||
|               let videoList = res.data[0].split(";"); | ||||
|               this.form.videoUrl = videoList[0] | ||||
|             } | ||||
|           }) | ||||
|         } else { | ||||
|           return this.$message.error("视频格式错误") | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     handleUploader(list) { | ||||
|       this.form.thumbUrl = list?.[0]?.url | ||||
|       this.$refs.VideoForm.validateField("thumbUrl") | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.getDetail() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .vpAdd { | ||||
|   height: 100%; | ||||
|  | ||||
|   video { | ||||
|     width: 100%; | ||||
|     height: 100%; | ||||
|     object-fit: fill; | ||||
|   } | ||||
|  | ||||
|   ::v-deep input[type="number"] { | ||||
|     line-height: 1px !important; | ||||
|  | ||||
|     &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { | ||||
|       -webkit-appearance: none !important; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .video { | ||||
|     width: 640px; | ||||
|     height: 360px; | ||||
|     border-radius: 4px; | ||||
|     border: 1px dashed #D0D4DC; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|  | ||||
|     .icon { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|  | ||||
|       span:nth-child(2) { | ||||
|         display: inline-block; | ||||
|         font-size: 16px; | ||||
|         color: #333333; | ||||
|         line-height: 30px; | ||||
|       } | ||||
|  | ||||
|       .iconfont { | ||||
|         display: inline-block; | ||||
|         font-size: 40px; | ||||
|         color: #2266FF; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .tips { | ||||
|       display: inline-block; | ||||
|       font-size: 12px; | ||||
|       color: #999999; | ||||
|       line-height: 26px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										128
									
								
								project/xiushan/apps/AppVideoPublic/vpList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								project/xiushan/apps/AppVideoPublic/vpList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| <template> | ||||
|   <section class="vpList"> | ||||
|     <ai-list> | ||||
|       <ai-title slot="title" title="视频宣传" isShowBottomBorder/> | ||||
|       <template #content> | ||||
|         <ai-search-bar> | ||||
|           <template #left> | ||||
|             <el-button type="primary" icon="iconfont iconAdd" @click="handleEdit()">添加</el-button> | ||||
|           </template> | ||||
|           <template #right> | ||||
|             <el-input size="small" placeholder="搜索标题" v-model="search.productName" clearable | ||||
|                       @change="page.current=1,getTableData()"/> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" | ||||
|                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> | ||||
|           <el-table-column slot="options" label="操作" fixed="right" align="center" width="200px"> | ||||
|             <template slot-scope="{row}"> | ||||
|               <el-button v-if="row.status==0" type="text" @click="handlePublic(row)">发布</el-button> | ||||
|               <el-button v-else-if="row.status==1" type="text" @click="handlePublic(row)">取消发布</el-button> | ||||
|               <el-button type="text" @click="handleEdit(row.id)">编辑</el-button> | ||||
|               <el-button type="text" @click="handleDelete(row.id)">删除</el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
|  | ||||
| export default { | ||||
|   name: "vpList", | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|     permissions: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     isFinanceUser() { | ||||
|       return !!this.user.financeUser?.id | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       search: {productName: ""}, | ||||
|       page: {current: 1, size: 10, total: 0}, | ||||
|       tableData: [], | ||||
|       colConfigs: [ | ||||
|         {label: "标题", prop: "title"}, | ||||
|         {label: "浏览数量", prop: "viewCount", align: "center", width: 100}, | ||||
|         {label: "发布人", prop: "publishUserName", width: 120}, | ||||
|         {label: "发布时间", prop: "publishTime"}, | ||||
|         {label: "状态", prop: "status", dict: "videoNewsStatus", align: "center"}, | ||||
|         {slot: "options"} | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getTableData() { | ||||
|       this.instance.post("/appvideonews/list", null, { | ||||
|         params: {...this.page, ...this.search} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.tableData = res.data?.records | ||||
|           this.page.total = res.data.total | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     showDetail(id) { | ||||
|       this.$router.push({query: {id}}) | ||||
|     }, | ||||
|     handleEdit(id) { | ||||
|       this.$router.push({query: {id}, hash: "#add"}) | ||||
|     }, | ||||
|     handleDelete(ids) { | ||||
|       this.$confirm("是否要删除该视频?").then(() => { | ||||
|         this.instance.post("/appvideonews/delete", null, { | ||||
|           params: {ids} | ||||
|         }).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success("删除成功!") | ||||
|             this.getTableData() | ||||
|           } | ||||
|         }) | ||||
|       }).catch(() => 0) | ||||
|     }, | ||||
|     handleIsHot(row) { | ||||
|       let {id, isHot} = row | ||||
|       this.instance.post("appfinancialproduct/setIsHot", null, { | ||||
|         params: {id, isHot} | ||||
|       }).then(res => { | ||||
|         if (res?.code == 0) { | ||||
|           this.$message.success("修改成功!") | ||||
|           this.getTableData() | ||||
|         } else { | ||||
|  | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     handlePublic(row) { | ||||
|       let openLabel = row.status == 1 ? "取消发布" : "发布", status = (Number(row.status) + 1) % 2 | ||||
|       this.$confirm(`是否要${openLabel}视频?`).then(() => { | ||||
|         this.instance.post("/appvideonews/setStatus", null, { | ||||
|           params: {id: row.id, status} | ||||
|         }).then(res => { | ||||
|           if (res?.code == 0) { | ||||
|             this.$message.success(openLabel + "成功!") | ||||
|             this.getTableData() | ||||
|           } | ||||
|         }) | ||||
|       }).catch(() => 0) | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.getTableData() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .vpList { | ||||
|   height: 100%; | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user