PostList.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. <template>
  2. <el-row>
  3. <el-col :md="2">
  4. <el-menu
  5. :default-active="this.$route.path"
  6. router
  7. class="el-menu-vertical-demo"
  8. >
  9. <el-menu-item v-for="(item,i) in navList" :key="i" :index="item.path">
  10. <i :class="item.icon" />
  11. <span slot="title">{{ item.name }}</span>
  12. </el-menu-item>
  13. </el-menu>
  14. </el-col>
  15. <el-col :md="22">
  16. <el-row>
  17. <el-tabs v-model="activeName" @tab-click='tabClick'>
  18. <el-tab-pane label="视频" name="video">
  19. <el-row :md="6" :sm="12" :xs="12">
  20. <el-table
  21. :data="dataList"
  22. style="width: 100%"
  23. >
  24. <el-table-column
  25. type="index">
  26. </el-table-column>
  27. <el-table-column
  28. prop="pubDate"
  29. label="发布时间">
  30. </el-table-column>
  31. <el-table-column
  32. prop="coverUrl"
  33. label="封面"
  34. width="80">
  35. <template slot-scope="scope">
  36. <el-image :src="scope.row.coverUrl" min-width="40" height="30" />
  37. </template>
  38. </el-table-column>
  39. <el-table-column
  40. prop="videoId"
  41. label="视频 ID">
  42. <template slot-scope="scope">
  43. <router-link target="_blank" :to="`/video/${scope.row.videoId}`">
  44. <span>{{scope.row.videoId}}</span>
  45. </router-link>
  46. </template>
  47. </el-table-column>
  48. <el-table-column
  49. prop="title"
  50. label="标题">
  51. </el-table-column>
  52. <el-table-column
  53. prop="description"
  54. label="描述">
  55. </el-table-column>
  56. <el-table-column
  57. prop="scope"
  58. label="可见范围">
  59. <template slot-scope="scope">
  60. <el-tooltip class="item" effect="dark" content="点击修改视频可见范围" placement="top-end">
  61. <el-button
  62. v-if="scope.row.scope === 1"
  63. size="mini"
  64. @click="handleScope(scope.$index, scope.row)">所有人可见</el-button>
  65. <el-button
  66. v-else-if="scope.row.scope === 2"
  67. size="mini"
  68. type="success"
  69. @click="handleScope(scope.$index, scope.row)">VIP 可见</el-button>
  70. <el-button
  71. v-else-if="scope.row.scope === 3"
  72. size="mini"
  73. type="warning"
  74. @click="handleScope(scope.$index, scope.row)">验证码可见</el-button>
  75. <el-button
  76. v-else
  77. size="mini"
  78. type="danger"
  79. @click="handleScope(scope.$index, scope.row)">本人可见</el-button>
  80. </el-tooltip>
  81. </template>
  82. </el-table-column>
  83. <el-table-column
  84. prop="scope"
  85. label="审核状态">
  86. <template slot-scope="scope">
  87. <el-tag v-if="scope.row.status === 1" :type="'warning'" disable-transitions>
  88. 审核中
  89. </el-tag>
  90. <el-tag v-else-if="scope.row.status === 2" :type="'success'" disable-transitions>
  91. 审核通过
  92. </el-tag>
  93. <el-tag v-else :type="'danger'" disable-transitions>
  94. 审核未通过
  95. </el-tag>
  96. </template>
  97. </el-table-column>
  98. <el-table-column label="操作" width="210">
  99. <template slot-scope="scope">
  100. <el-button
  101. size="mini"
  102. @click="handlePreview(scope.$index, scope.row)">预览</el-button>
  103. <el-button
  104. size="mini"
  105. @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
  106. <el-button
  107. size="mini"
  108. type="danger"
  109. @click="handleDelete(scope.$index, scope.row)">删除</el-button>
  110. </template>
  111. </el-table-column>
  112. </el-table>
  113. </el-row>
  114. </el-tab-pane>
  115. <el-tab-pane label="相册" name="image">
  116. <el-row :md="6" :sm="12" :xs="12">
  117. <el-table
  118. :data="dataList"
  119. style="width: 100%"
  120. >
  121. <el-table-column
  122. type="index">
  123. </el-table-column>
  124. <el-table-column
  125. prop="coverUrl"
  126. label="相册封面"
  127. width="150">
  128. <template slot-scope="scope">
  129. <el-image :src="scope.row.coverUrl" min-width="40" height="30" />
  130. </template>
  131. </el-table-column>
  132. <el-table-column
  133. prop="pubDate"
  134. label="发布时间">
  135. </el-table-column>
  136. <el-table-column
  137. prop="albumName"
  138. label="相册名字"
  139. width="180">
  140. </el-table-column>
  141. <el-table-column
  142. prop="total"
  143. label="图片数量">
  144. </el-table-column>
  145. <el-table-column
  146. prop="scope"
  147. label="可见范围">
  148. <template slot-scope="scope">
  149. <el-tag v-if="scope.row.viewCount === 1" disable-transitions>
  150. 全部可见
  151. </el-tag>
  152. <el-tag v-else-if="scope.row.viewCount === 2" :type="'success'" disable-transitions>
  153. VIP 可见
  154. </el-tag>
  155. <el-tag v-else-if="scope.row.viewCount === 3" :type="'warning'" disable-transitions>
  156. 验证码可见
  157. </el-tag>
  158. <el-tag v-else :type="'danger'" disable-transitions>
  159. 本人可见
  160. </el-tag>
  161. </template>
  162. </el-table-column>
  163. <el-table-column label="操作">
  164. <template slot-scope="scope">
  165. <el-button
  166. size="mini"
  167. @click="handleEditImage(scope.$index, scope.row)">编辑</el-button>
  168. <el-button
  169. size="mini"
  170. type="danger"
  171. @click="handleDeleteImage(scope.$index, scope.row)">删除</el-button>
  172. </template>
  173. </el-table-column>
  174. </el-table>
  175. </el-row>
  176. </el-tab-pane>
  177. <el-tab-pane label="音频" name="audio">
  178. <el-row :md="6" :sm="12" :xs="12">
  179. <el-table
  180. :data="dataList"
  181. style="width: 100%"
  182. >
  183. <el-table-column
  184. type="index">
  185. </el-table-column>
  186. <el-table-column
  187. prop="coverUrl"
  188. label="音频封面"
  189. width="150">
  190. <template slot-scope="scope">
  191. <el-image :src="scope.row.coverUrl" min-width="40" height="30" />
  192. </template>
  193. </el-table-column>
  194. <el-table-column
  195. prop="pubDate"
  196. label="发布时间">
  197. </el-table-column>
  198. <el-table-column
  199. prop="title"
  200. label="音频名字">
  201. </el-table-column>
  202. <!-- <el-table-column
  203. prop="description"
  204. label="音频简介">
  205. </el-table-column>-->
  206. <el-table-column
  207. prop="scope"
  208. label="可见范围">
  209. <template slot-scope="scope">
  210. <el-tag v-if="scope.row.viewCount === 1" disable-transitions>
  211. 全部可见
  212. </el-tag>
  213. <el-tag v-else-if="scope.row.viewCount === 2" :type="'success'" disable-transitions>
  214. VIP 可见
  215. </el-tag>
  216. <el-tag v-else-if="scope.row.viewCount === 3" :type="'warning'" disable-transitions>
  217. 验证码可见
  218. </el-tag>
  219. <el-tag v-else :type="'danger'" disable-transitions>
  220. 本人可见
  221. </el-tag>
  222. </template>
  223. </el-table-column>
  224. <el-table-column label="操作">
  225. <template slot-scope="scope">
  226. <el-button
  227. size="mini"
  228. @click="handleEditAudio(scope.$index, scope.row)">编辑</el-button>
  229. <el-button
  230. size="mini"
  231. type="danger"
  232. @click="handleDeleteAudio(scope.$index, scope.row)">删除</el-button>
  233. </template>
  234. </el-table-column>
  235. </el-table>
  236. </el-row>
  237. </el-tab-pane>
  238. <el-tab-pane label="文章" name="article">
  239. <span>
  240. <h4>文章稿件</h4>
  241. </span>
  242. </el-tab-pane>
  243. </el-tabs>
  244. </el-row>
  245. <el-row>
  246. <el-col :span="22" class="pagination">
  247. <el-pagination
  248. background
  249. :small="screenWidth <= 768"
  250. layout="prev, pager, next"
  251. :page-size="pageSize"
  252. :current-page="currentPage"
  253. :total="totalSize"
  254. @current-change="handleCurrentChange"
  255. @prev-click="handleCurrentChange"
  256. @next-click="handleCurrentChange"
  257. />
  258. </el-col>
  259. </el-row>
  260. </el-col>
  261. <!-- 修改视频可见范围对话框 -->
  262. <el-dialog
  263. append-to-body
  264. :visible.sync="showEditScopeDialog"
  265. width="30%"
  266. center
  267. >
  268. <el-card class="box-card">
  269. <div slot="header" class="clearfix">
  270. <span>修改视频可见范围</span>
  271. <el-button style="float: right; padding: 3px 0" type="text" @click="onUpdateVideoScope">更新</el-button>
  272. </div>
  273. <div class="text item">
  274. <el-form ref="form" :model="form" label-width="80px">
  275. <el-form-item label="可见范围">
  276. <el-select v-model="form.scope" placeholder="选择可见范围">
  277. <el-option label="所有人可见" value="1" />
  278. <el-option label="验证码可见" value="2" />
  279. <el-option label="VIP 可见" value="3" />
  280. <el-option label="仅自己可见" value="4" />
  281. </el-select>
  282. </el-form-item>
  283. </el-form>
  284. </div>
  285. </el-card>
  286. </el-dialog>
  287. <!-- 视频预览对话框 -->
  288. <el-dialog
  289. title="预览视频"
  290. append-to-body
  291. :visible.sync="showPreviewDialog"
  292. :before-close="handleDialogClose"
  293. width="70%"
  294. center
  295. >
  296. <template>
  297. <video-preview-player :video-prop.sync="this.videoProp"/>
  298. </template>
  299. </el-dialog>
  300. </el-row>
  301. </template>
  302. <script>
  303. import VideoPreviewPlayer from 'components/VideoPreviewPlayer'
  304. import {userVideoPost, updateVideoScope, videoInfo, deleteVideo} from "@/api/video";
  305. import {getUserAlbums} from "@/api/image";
  306. import { getUserAudio } from "@/api/audio";
  307. export default {
  308. name: 'PostList',
  309. components: { VideoPreviewPlayer },
  310. data() {
  311. return {
  312. // 屏幕宽度, 为了控制分页条的大小
  313. screenWidth: document.body.clientWidth,
  314. currentPage: 1,
  315. pageSize: 12,
  316. totalSize: 0,
  317. dataList: [],
  318. /*************************************************************************/
  319. navList: [
  320. { path: '/post/publish', name: '发布', icon: 'el-icon-upload' },
  321. { path: '/post/list', name: '稿件', icon: 'el-icon-files' },
  322. { path: '/post/analysis', name: '数据', icon: 'el-icon-data-analysis' }
  323. ],
  324. activeName: 'video',
  325. userId: 10001,
  326. showPreviewDialog: false,
  327. videoProp: null,
  328. showEditScopeDialog: false,
  329. form: {
  330. videoId: null,
  331. scope: null
  332. }
  333. }
  334. },
  335. created() {
  336. document.title = "稿件列表"
  337. const path = this.$route.path
  338. if (path.endsWith("video")) {
  339. this.activeName = 'video'
  340. document.title = '视频稿件'
  341. } else if (path.endsWith("image")) {
  342. this.activeName = 'image'
  343. document.title = '图片稿件'
  344. } else if (path.endsWith("audio")) {
  345. this.activeName = 'audio'
  346. document.title = '音频稿件'
  347. } else if (path.endsWith("article")) {
  348. this.activeName = 'article'
  349. document.title = '文章稿件'
  350. }
  351. this.getData()
  352. },
  353. watch: {
  354. $route(){
  355. this.$router.go()
  356. }
  357. },
  358. methods: {
  359. handleCurrentChange(pageNumber) {
  360. this.currentPage = pageNumber
  361. this.getData()
  362. // 回到顶部
  363. scrollTo(0, 0)
  364. },
  365. handleScope(index, row) {
  366. this.form.videoId = row.videoId
  367. this.form.scope = row.scope
  368. this.showEditScopeDialog = true
  369. },
  370. handleDialogClose(done) {
  371. this.showPreviewDialog = false
  372. this.videoProp = {
  373. videoId: null,
  374. play: false
  375. }
  376. done()
  377. },
  378. handlePreview(index, row) {
  379. videoInfo(row.videoId).then(res => {
  380. if (res.code === 0) {
  381. this.showPreviewDialog = true
  382. this.videoProp = {
  383. videoId: res.data.videoId,
  384. play: true
  385. }
  386. }
  387. })
  388. console.log('预览 ' + row.videoId);
  389. },
  390. handleEdit(index, row) {
  391. console.log(row.videoId);
  392. const path = '/post/edit/video/' + row.videoId
  393. this.$router.push(path)
  394. },
  395. handleDelete(index, row) {
  396. deleteVideo(row.videoId).then(res => {
  397. if (res.code === 0) {
  398. this.$notify({
  399. title: '提示',
  400. message: '视频稿件已删除',
  401. type: 'warning',
  402. duration: 3000
  403. })
  404. this.$router.go(0)
  405. }
  406. })
  407. },
  408. handleEditImage(index, row) {
  409. console.log(row.videoId);
  410. const path = '/post/edit/album/' + row.albumId
  411. this.$router.push(path)
  412. },
  413. handleDeleteImage(index, row) {
  414. console.log(row.videoId);
  415. },
  416. handleEditAudio(index, row) {
  417. console.log(row.videoId);
  418. const path = '/post/edit/audio/' + row.audioId
  419. this.$router.push(path)
  420. },
  421. handleDeleteAudio(index, row) {
  422. console.log(row.videoId);
  423. },
  424. tabClick(tab) {
  425. this.activeName = tab.name
  426. this.goToTab(this.activeName)
  427. },
  428. goToTab(activeName) {
  429. const path = '/post/' + activeName
  430. if (this.$route.path === path) {
  431. this.$router.go(0)
  432. return
  433. }
  434. this.$router.push(path)
  435. },
  436. getData() {
  437. this.dataList = []
  438. if (this.activeName === 'video') {
  439. userVideoPost(this.currentPage).then(res => {
  440. if (res.code === 0) {
  441. const resData = res.data
  442. this.dataList = resData.list
  443. this.totalSize = resData.totalSize
  444. if (this.totalSize !== 0) {
  445. this.showEmpty = false
  446. } else {
  447. this.showEmpty = true
  448. }
  449. } else {
  450. this.$notify({
  451. title: '提示',
  452. message: res.msg,
  453. type: 'warning',
  454. duration: 3000
  455. })
  456. }
  457. }).catch(error => {
  458. this.$notify({
  459. title: '提示',
  460. message: error.message,
  461. type: 'error',
  462. duration: 3000
  463. })
  464. })
  465. } else if (this.activeName === 'image') {
  466. getUserAlbums(this.userId).then(res => {
  467. if (res.code === 0) {
  468. const resData = res.data
  469. if (resData.length !== 0) {
  470. this.showEmpty = false
  471. for (const item of resData) {
  472. this.dataList.push(item)
  473. }
  474. } else {
  475. this.showEmpty = true
  476. }
  477. }
  478. })
  479. } else if (this.activeName === 'audio') {
  480. this.currentPage = 1
  481. this.lastId = 0
  482. getUserAudio(this.userId).then(res => {
  483. if (res.code === 0) {
  484. const resData = res.data.list
  485. if (resData.length !== 0) {
  486. this.showEmpty = false
  487. for (const item of resData) {
  488. this.dataList.push(item)
  489. }
  490. } else {
  491. this.showEmpty = true
  492. }
  493. }
  494. })
  495. } else if (this.activeName === 'article') {
  496. this.currentPage = 1
  497. this.lastId = 0
  498. }
  499. },
  500. onUpdateVideoScope() {
  501. this.showEditScopeDialog = false
  502. updateVideoScope(this.form).then(res => {
  503. if (res.code === 0) {
  504. this.$notify({
  505. title: '提示',
  506. message: '视频可见范围已更新',
  507. type: 'warning',
  508. duration: 3000
  509. })
  510. }
  511. }).catch(error => {
  512. this.$notify({
  513. title: '提示',
  514. message: error.message,
  515. type: 'warning',
  516. duration: 3000
  517. })
  518. })
  519. }
  520. }
  521. }
  522. </script>
  523. <style>
  524. .uploader-example {
  525. width: 500px;
  526. padding: 15px;
  527. margin: 40px auto 0;
  528. font-size: 12px;
  529. box-shadow: 0 0 10px rgba(0, 0, 0, .4);
  530. }
  531. .uploader-example .uploader-btn {
  532. margin-right: 4px;
  533. }
  534. .uploader-example .uploader-list {
  535. max-height: 440px;
  536. overflow: auto;
  537. overflow-x: hidden;
  538. overflow-y: auto;
  539. }
  540. .avatar-uploader .el-upload {
  541. border: 1px dashed #d9d9d9;
  542. border-radius: 6px;
  543. cursor: pointer;
  544. position: relative;
  545. overflow: hidden;
  546. }
  547. .avatar-uploader .el-upload:hover {
  548. border-color: #409EFF;
  549. }
  550. .avatar-uploader-icon {
  551. font-size: 28px;
  552. color: #8c939d;
  553. width: 320px;
  554. height: 240px;
  555. line-height: 178px;
  556. text-align: center;
  557. }
  558. .avatar {
  559. width: 320px;
  560. height: 240px;
  561. display: block;
  562. }
  563. </style>