Commit bf5dcdd582fde3080605fda8475596781c88f661

Authored by YunaiV
1 parent 5a1d02df

mp:素材管理,增加【语音】【视频】

yudao-ui-admin/src/views/mp/components/wx-voice-play/main.vue
... ... @@ -12,7 +12,7 @@
12 12 <template>
13 13 <div class="wx-voice-div" @click="playVoice">
14 14 <i :class="playing !== true ? 'el-icon-video-play': 'el-icon-video-pause'">
15   - <span class="amr-duration" v-if="duration">{{ duration }}</span>
  15 + <span class="amr-duration" v-if="duration">{{ duration }} 秒</span>
16 16 </i>
17 17 <div v-if="content">
18 18 <el-tag type="success" size="mini">语音识别</el-tag>
... ...
yudao-ui-admin/src/views/mp/material/index.vue
... ... @@ -20,6 +20,10 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 22 SOFTWARE.
  23 + 芋道源码:
  24 + ① 清理冗余 css 内容,清理冗余 data 变量
  25 + ② 美化样式,支持播放,提升使用体验
  26 + ③ 优化代码,特别是方法名和变量,提升可读性
23 27 -->
24 28 <template>
25 29 <div class="app-container">
... ... @@ -63,152 +67,102 @@ SOFTWARE.
63 67 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
64 68 @pagination="getList"/>
65 69 </el-tab-pane>
  70 +
  71 + <!-- tab 2:语音 -->
66 72 <el-tab-pane name="voice">
67 73 <span slot="label"><i class="el-icon-microphone"></i> 语音</span>
68   - <div class="add_but">
69   - <el-upload
70   - :action="actionUrl"
71   - :headers="headers"
72   - multiple
73   - :limit="1"
74   - :on-success="handleUploadSuccess"
75   - :file-list="fileList"
76   - :before-upload="beforeVoiceUpload"
77   - :data="uploadData">
  74 + <div class="add_but" v-hasPermi="['mp:material:upload-permanent']">
  75 + <el-upload :action="actionUrl" :headers="headers" multiple :limit="1" :file-list="fileList" :data="uploadData"
  76 + :on-success="handleUploadSuccess" :before-upload="beforeVoiceUpload">
78 77 <el-button size="mini" type="primary">点击上传</el-button>
79   - <div slot="tip" class="el-upload__tip">
80   - 格式支持mp3/wma/wav/amr,文件大小不超过2M,播放长度不超过60s
81   - </div>
  78 + <span slot="tip" class="el-upload__tip" style="margin-left: 5px">格式支持 mp3/wma/wav/amr,文件大小不超过 2M,播放长度不超过 60s</span>
82 79 </el-upload>
83 80 </div>
84   - <el-table
85   - :data="list"
86   - stripe
87   - border
88   - v-loading="loading">
89   - <el-table-column
90   - prop="mediaId"
91   - label="media_id">
92   - </el-table-column>
93   - <el-table-column
94   - prop="name"
95   - label="名称">
  81 + <el-table :data="list" stripe border v-loading="loading" style="margin-top: 10px;">
  82 + <el-table-column label="编号" align="center" prop="mediaId" />
  83 + <el-table-column label="文件名" align="center" prop="name" />
  84 + <el-table-column label="语音" align="center">
  85 + <template v-slot="scope">
  86 + <wx-voice-player :url="scope.row.url" />
  87 + </template>
96 88 </el-table-column>
97   - <el-table-column
98   - prop="updateTime"
99   - label="更新时间">
  89 + <el-table-column label="上传时间" align="center" prop="createTime" width="180">
  90 + <template v-slot="scope">
  91 + <span>{{ parseTime(scope.row.createTime) }}</span>
  92 + </template>
100 93 </el-table-column>
101   - <el-table-column
102   - fixed="right"
103   - label="操作">
  94 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
104 95 <template slot-scope="scope">
105   - <el-button type="text"
106   - icon="el-icon-download"
107   - size="small"
108   - plain
109   - @click="handleDown(scope.row)">下载</el-button>
110   - <el-button type="text"
111   - icon="el-icon-delete"
112   - size="small"
113   - plain
114   - @click="handleDelete(scope.row)">删除</el-button>
  96 + <el-button type="text" icon="el-icon-download" size="small" plain @click="handleDownload(scope.row)">下载</el-button>
  97 + <el-button type="text" icon="el-icon-delete" size="small" plain @click="handleDelete(scope.row)"
  98 + v-hasPermi="['mp:material:delete']">删除</el-button>
115 99 </template>
116 100 </el-table-column>
117 101 </el-table>
118   - <el-pagination
119   - @size-change="sizeChange"
120   - @current-change="currentChange"
121   - :current-page.sync="queryParams.currentPage"
122   - :page-sizes="[10, 20]"
123   - :page-size="queryParams.pageSize"
124   - layout="total, sizes, prev, pager, next, jumper"
125   - :total="queryParams.total"
126   - class="pagination"
127   - >
128   - </el-pagination>
  102 + <!-- 分页组件 -->
  103 + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  104 + @pagination="getList"/>
129 105 </el-tab-pane>
  106 +
  107 + <!-- tab 3:视频 -->
130 108 <el-tab-pane name="video">
131 109 <span slot="label"><i class="el-icon-video-play"></i> 视频</span>
132   - <div class="add_but">
133   - <el-button size="mini" type="primary" @click="handleAddVideo">新建</el-button>
  110 + <div class="add_but" v-hasPermi="['mp:material:upload-permanent']">
  111 + <el-button size="mini" type="primary" @click="handleAddVideo">新建视频</el-button>
134 112 </div>
135   - <el-dialog title="新建视频" :visible.sync="dialogVideoVisible" v-loading="addMaterialLoading">
136   - <el-upload
137   - ref="uploadVideo"
138   - :action="actionUrl"
139   - :headers="headers"
140   - multiple
141   - :limit="1"
142   - :on-success="handleUploadSuccess"
143   - :file-list="fileList"
144   - :before-upload="beforeVideoUpload"
145   - :auto-upload="false"
146   - :data="uploadData">
  113 + <!-- 新建视频的弹窗 -->
  114 + <el-dialog title="新建视频" :visible.sync="dialogVideoVisible" append-to-body width="600px"
  115 + v-loading="addMaterialLoading">
  116 + <el-upload :action="actionUrl" :headers="headers" multiple :limit="1" :file-list="fileList" :data="uploadData"
  117 + :before-upload="beforeVideoUpload" :on-success="handleUploadSuccess"
  118 + ref="uploadVideo" :auto-upload="false">
147 119 <el-button slot="trigger" size="mini" type="primary">选择视频</el-button>
148   - <div class="el-upload__tip">
149   - 格式支持MP4,文件大小不超过10MB
150   - </div>
  120 + <span class="el-upload__tip" style="margin-left: 10px;">格式支持 MP4,文件大小不超过 10MB</span>
151 121 </el-upload>
152   - <el-form :model="uploadData"
153   - :rules="uploadRules"
154   - ref="uploadForm">
155   - <el-form-item label="标题" prop="title">
156   - <el-input v-model="uploadData.title" placeholder="标题将展示在相关播放页面,建议填写清晰、准确、生动的标题"></el-input>
157   - </el-form-item>
158   - <el-form-item label="描述" prop="introduction">
159   - <el-input :rows="3" type="textarea" v-model="uploadData.introduction" placeholder="介绍语将展示在相关播放页面,建议填写简洁明确、有信息量的内容"></el-input>
160   - </el-form-item>
  122 + <el-form :model="uploadData" :rules="uploadRules" ref="uploadForm" label-width="80px">
  123 + <el-row>
  124 + <el-form-item label="标题" prop="title">
  125 + <el-input v-model="uploadData.title" placeholder="标题将展示在相关播放页面,建议填写清晰、准确、生动的标题" />
  126 + </el-form-item>
  127 + </el-row>
  128 + <el-row>
  129 + <el-form-item label="描述" prop="introduction">
  130 + <el-input :rows="3" type="textarea" v-model="uploadData.introduction"
  131 + placeholder="介绍语将展示在相关播放页面,建议填写简洁明确、有信息量的内容" />
  132 + </el-form-item>
  133 + </el-row>
161 134 </el-form>
162 135 <div slot="footer" class="dialog-footer">
163   - <el-button @click="dialogVideoVisible = false">取 消</el-button>
164   - <el-button type="primary" @click="subVideo">提 交</el-button>
  136 + <el-button @click="cancelVideo">取 消</el-button>
  137 + <el-button type="primary" @click="submitVideo">提 交</el-button>
165 138 </div>
166 139 </el-dialog>
167   - <el-table
168   - :data="list"
169   - stripe
170   - border
171   - v-loading="loading">
172   - <el-table-column
173   - prop="mediaId"
174   - label="media_id">
175   - </el-table-column>
176   - <el-table-column
177   - prop="name"
178   - label="名称">
  140 + <el-table :data="list" stripe border v-loading="loading" style="margin-top: 10px;">
  141 + <el-table-column label="编号" align="center" prop="mediaId" />
  142 + <el-table-column label="文件名" align="center" prop="name" />
  143 + <el-table-column label="标题" align="center" prop="title" />
  144 + <el-table-column label="介绍" align="center" prop="introduction" />
  145 + <el-table-column label="视频" align="center">
  146 + <template v-slot="scope">
  147 + <wx-video-player :url="scope.row.url" />
  148 + </template>
179 149 </el-table-column>
180   - <el-table-column
181   - prop="updateTime"
182   - label="更新时间">
  150 + <el-table-column label="上传时间" align="center" prop="createTime" width="180">
  151 + <template v-slot="scope">
  152 + <span>{{ parseTime(scope.row.createTime) }}</span>
  153 + </template>
183 154 </el-table-column>
184   - <el-table-column
185   - fixed="right"
186   - label="操作">
187   - <template slot-scope="scope">
188   - <el-button type="text"
189   - icon="el-icon-view"
190   - size="small"
191   - plain
192   - @click="handleInfo(scope.row)">查看</el-button>
193   - <el-button type="text"
194   - icon="el-icon-delete"
195   - size="small"
196   - plain
197   - @click="handleDelete(scope.row)">删除</el-button>
  155 + <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
  156 + <template v-slot="scope">
  157 + <el-button type="text" icon="el-icon-download" size="small" plain @click="handleDownload(scope.row)">下载</el-button>
  158 + <el-button type="text" icon="el-icon-delete" size="small" plain @click="handleDelete(scope.row)"
  159 + v-hasPermi="['mp:material:delete']">删除</el-button>
198 160 </template>
199 161 </el-table-column>
200 162 </el-table>
201   - <el-pagination
202   - @size-change="sizeChange"
203   - @current-change="currentChange"
204   - :current-page.sync="queryParams.currentPage"
205   - :page-sizes="[10, 20]"
206   - :page-size="queryParams.pageSize"
207   - layout="total, sizes, prev, pager, next, jumper"
208   - :total="queryParams.total"
209   - class="pagination"
210   - >
211   - </el-pagination>
  163 + <!-- 分页组件 -->
  164 + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  165 + @pagination="getList"/>
212 166 </el-tab-pane>
213 167 </el-tabs>
214 168 </div>
... ... @@ -243,26 +197,23 @@ export default {
243 197 pageNo: 1,
244 198 pageSize: 10,
245 199 accountId: undefined,
  200 + permanent: true,
246 201 },
247 202  
248 203 actionUrl: process.env.VUE_APP_BASE_API + '/admin-api/mp/material/upload-permanent',
249 204 headers: { Authorization: "Bearer " + getAccessToken() }, // 设置上传的请求头部
250 205 fileList:[],
251   - dialogVideoVisible:false,
252   - dialogNewsVisible:false,
253   - addMaterialLoading:false,
254 206 uploadData: {
255 207 "type": 'image',
256 208 "title":'',
257 209 "introduction":''
258 210 },
259   - uploadRules:{
260   - title: [
261   - { required: true, message: '请输入标题', trigger: 'blur' }
262   - ],
263   - introduction: [
264   - { required: true, message: '请输入描述', trigger: 'blur' }
265   - ],
  211 + // === 视频上传,独有变量 ===
  212 + dialogVideoVisible: false,
  213 + addMaterialLoading: false,
  214 + uploadRules: { // 视频上传的校验规则
  215 + title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
  216 + introduction: [{ required: true, message: '请输入描述', trigger: 'blur' }],
266 217 },
267 218  
268 219 // 公众号账号列表
... ... @@ -284,7 +235,6 @@ export default {
284 235 // ======================== 列表查询 ========================
285 236 /** 设置账号编号 */
286 237 setAccountId(accountId) {
287   - console.log('奥特曼!')
288 238 this.queryParams.accountId = accountId;
289 239 this.uploadData.accountId = accountId;
290 240 },
... ... @@ -333,53 +283,6 @@ export default {
333 283 },
334 284  
335 285 // ======================== 文件上传 ========================
336   -
337   - handleInfo(row){
338   - this.loading = true
339   - getMaterialVideo({
340   - mediaId:row.mediaId
341   - }).then((response) => {
342   - this.loading = false
343   - if(response.code == 200){
344   - let downUrl = response.data.downUrl
345   - window.open(downUrl, '_blank');
346   - }else{
347   - this.$message.error('获取微信视频素材出错:' + response.data.msg)
348   - }
349   - }).catch(() => {
350   - this.loading = false
351   - })
352   - },
353   - handleDown(row){
354   - this.loading = true
355   - getMaterialOther({
356   - mediaId:row.mediaId,
357   - fileName:row.name
358   - }).then(response => {
359   - this.loading = false
360   - let url = window.URL.createObjectURL(new Blob([response.data]))
361   - let link = document.createElement('a')
362   - link.style.display = 'none'
363   - link.href = url
364   - link.setAttribute('download', row.name)
365   - document.body.appendChild(link)
366   - link.click()
367   - }).catch(() => {
368   - this.loading = false
369   - })
370   - },
371   - subVideo(){
372   - this.$refs['uploadForm'].validate((valid) => {
373   - if (valid) {
374   - this.$refs.uploadVideo.submit()
375   - } else {
376   - return false
377   - }
378   - })
379   - },
380   - handleAddVideo(){
381   - this.dialogVideoVisible = true
382   - },
383 286 beforeImageUpload(file) {
384 287 const isType = file.type === 'image/jpeg'
385 288 || file.type === 'image/png'
... ... @@ -388,42 +291,46 @@ export default {
388 291 || file.type === 'image/jpg';
389 292 if (!isType) {
390 293 this.$message.error('上传图片格式不对!')
391   - this.loading = false
392 294 return false;
393 295 }
394 296 const isLt = file.size / 1024 / 1024 < 2
395 297 if (!isLt) {
396 298 this.$message.error('上传图片大小不能超过 2M!')
397   - this.loading = false
398 299 return false;
399 300 }
400 301 this.loading = true
401 302 return true;
402 303 },
403 304 beforeVoiceUpload(file){
404   - const isType = file.type === 'audio/mp3' || file.type === 'audio/wma' || file.type === 'audio/wav' || file.type === 'audio/amr';
  305 + const isType = file.type === 'audio/mp3'
  306 + || file.type === 'audio/wma'
  307 + || file.type === 'audio/wav'
  308 + || file.type === 'audio/amr';
405 309 const isLt = file.size / 1024 / 1024 < 2
406 310 if (!isType) {
407 311 this.$message.error('上传语音格式不对!')
  312 + return false;
408 313 }
409 314 if (!isLt) {
410   - this.$message.error('上传语音大小不能超过2M!')
  315 + this.$message.error('上传语音大小不能超过 2M!')
  316 + return false;
411 317 }
412   - this.loading = false
413   - return isType && isLt;
  318 + this.loading = true
  319 + return true;
414 320 },
415 321 beforeVideoUpload(file){
416   - this.addMaterialLoading = true
417 322 const isType = file.type === 'video/mp4'
418   - const isLt = file.size / 1024 / 1024 < 10
419 323 if (!isType) {
420 324 this.$message.error('上传视频格式不对!')
  325 + return false;
421 326 }
  327 + const isLt = file.size / 1024 / 1024 < 10
422 328 if (!isLt) {
423   - this.$message.error('上传视频大小不能超过10M!')
  329 + this.$message.error('上传视频大小不能超过 10M!')
  330 + return false
424 331 }
425   - this.addMaterialLoading = false
426   - return isType && isLt;
  332 + this.addMaterialLoading = true
  333 + return true
427 334 },
428 335 handleUploadSuccess(response, file, fileList) {
429 336 this.loading = false
... ... @@ -442,6 +349,35 @@ export default {
442 349 // 加载数据
443 350 this.getList()
444 351 },
  352 + // 下载文件
  353 + handleDownload(row) {
  354 + window.open(row.url,'_blank')
  355 + },
  356 + // 提交 video 新建的表单
  357 + submitVideo() {
  358 + this.$refs['uploadForm'].validate((valid) => {
  359 + if (!valid) {
  360 + return false;
  361 + }
  362 + this.$refs.uploadVideo.submit()
  363 + })
  364 + },
  365 + handleAddVideo() {
  366 + this.resetVideo();
  367 + this.dialogVideoVisible = true
  368 + },
  369 + /** 取消按钮 */
  370 + cancelVideo() {
  371 + this.dialogVideoVisible = false;
  372 + this.resetVideo();
  373 + },
  374 + /** 表单重置 */
  375 + resetVideo() {
  376 + this.fileList = []
  377 + this.uploadData.title = ''
  378 + this.uploadData.introduction = ''
  379 + this.resetForm("uploadForm");
  380 + },
445 381  
446 382 // ======================== 其它操作 ========================
447 383 handleDelete(item) {
... ...