From 5d5b0f7ab0f34019e11901ddcd59cd8b51ea9ff9 Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期五, 23 五月 2025 10:37:12 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- manager/src/views/video/VideoList.vue | 551 +++++++++++++++++++++++++++++++++++++++++++++ manager/src/api/video.js | 96 ++++++++ manager/src/api/videoTag.js | 5 manager/src/api/file.js | 14 + 4 files changed, 664 insertions(+), 2 deletions(-) diff --git a/manager/src/api/file.js b/manager/src/api/file.js new file mode 100644 index 0000000..8cdbd88 --- /dev/null +++ b/manager/src/api/file.js @@ -0,0 +1,14 @@ +import service from "@/libs/axios"; +import {commonUrl} from '@/libs/axios'; + + +// 鑾峰彇鏂囦欢涓存椂璁块棶url +export const getFilePreview = (fileKey) => { + return service({ + baseURL: commonUrl, + url: "/common/lmk/file/preview", + method: "POST", + data: {"fileKey": fileKey} + }) +} + diff --git a/manager/src/api/video.js b/manager/src/api/video.js new file mode 100644 index 0000000..42693bf --- /dev/null +++ b/manager/src/api/video.js @@ -0,0 +1,96 @@ +import service from "@/libs/axios"; + +// 鑾峰彇瑙嗛鍐呭鍒嗛〉 +export const getVideos = (data) => { + return service({ + url: "/lmk/video/page", + method: "POST", + data: data + }) +} + +// 鑾峰彇瑙嗛鍐呭鍒楄〃 +export const getVideoList = () => { + return service({ + url: "/lmk/video/list", + method: "GET" + }) +} + +// 閫氳繃id鑾峰彇瑙嗛鍐呭 +export const getVideoById = (params) => { + return service({ + url: "/lmk/video/" + params, + method: "GET" + }) +} + +// 閫氳繃id鍒犻櫎瑙嗛鍐呭 +export const deleteVideoById = (params) => { + return service({ + url: "/lmk/video/" + params, + method: "DELETE" + }) +} + +// 鎵归噺鍒犻櫎瑙嗛鍐呭 +export const deleteVideoByIds = (params) => { + return service({ + url: "/lmk/video/batch", + method: "DELETE", + data: params + }) +} + +// 淇敼瑙嗛鍐呭 +export const editVideo = (params) => { + return service({ + url: "/lmk/video/", + method: "PUT", + data: params + }) +} + +// 娣诲姞瑙嗛鍐呭 +export const addVideo = (params) => { + return service({ + url: "/lmk/video/", + method: "POST", + data: params + }) +} + +// 瀹℃牳瑙嗛 +export const auditingVideo = (data) => { + return service({ + url: "/lmk/video/auditing", + method: "POST", + data: data + }) +} + +// 棣栭〉鎺ㄨ崘璁剧疆 +export const recommendSet = (data) => { + return service({ + url: "/lmk/video/recommend", + method: "PUT", + data: data + }) +} + +// 瑙嗛涓婃灦 +export const up = (id) => { + return service({ + url: "/lmk/video/up/" + id, + method: "POST" + }) +} + +// 瑙嗛涓嬫灦 +export const down = (data) => { + return service({ + url: "/lmk/video/down", + method: "POST", + data: data + }) +} diff --git a/manager/src/api/videoTag.js b/manager/src/api/videoTag.js index 61d5323..fb04303 100644 --- a/manager/src/api/videoTag.js +++ b/manager/src/api/videoTag.js @@ -10,10 +10,11 @@ } // 鑾峰彇瑙嗛鏍囩鍒楄〃 -export const getVideoTagList = () => { +export const getVideoTagList = (params) => { return service({ url: "/lmk/video-tag/list", - method: "GET" + method: "GET", + params: params }) } diff --git a/manager/src/views/video/VideoList.vue b/manager/src/views/video/VideoList.vue new file mode 100644 index 0000000..b704db2 --- /dev/null +++ b/manager/src/views/video/VideoList.vue @@ -0,0 +1,551 @@ +<template> + <div> + <Card> + <Form + ref="searchForm" + @keydown.enter.native="handleSearch" + :model="searchForm" + inline + :label-width="70" + class="search-form" + > + <Form-item label="鏍囬" prop="title"> + <Input + type="text" + v-model="searchForm.title" + clearable + @on-clear="handleSearch" + @on-change="handleSearch" + style="width: 160px" + /> + </Form-item> + <Form-item label="鏍囩" prop="tagList"> + <Select + v-model="searchForm.tagList" + clearable + filterable + multiple + @on-clear="handleSearch" + @on-change="handleSearch" + style="width: 160px" + > + <Option v-for="tag in tagList" :key="tag.id" :value="tag.id">{{tag.tagName}}</Option> + </Select> + </Form-item> + <Form-item label="瑙嗛鐘舵��" prop="status"> + <Select + v-model="searchForm.status" + clearable + @on-clear="handleSearch" + @on-change="handleSearch" + style="width: 160px" + > + <Option value="99">寰呭鏍�</Option> + <Option value="1">宸插彂甯�</Option> + <Option value="0">宸蹭笅鏋�</Option> + <Option value="-1">瀹℃牳鏈�氳繃</Option> + </Select> + </Form-item> + <Button + @click="handleSearch" + type="primary" + icon="ios-search" + class="search-btn" + >鎼滅储</Button + > + </Form> + + <Modal + v-model="playVideoShow" + :title="playVideoTitle" + width="800" + :mask-closable="false" + > + <div class="video-warp"> + <video :src="playVideoUrl" autoplay controls style="width: 768px;height: 432px"/> + </div> + <div slot="footer"> + <Button type="text" @click="playVideoClose">鍏抽棴</Button> + </div> + </Modal> + + <Modal + v-model="auditingShow" + title="瑙嗛瀹℃牳" + width="800" + :loading="auditingLoading" + :mask-closable="false" + > + <Form + ref="auditingForm" + :model="auditingForm" + :label-width="70" + :rules="auditingRule" + > + <Form-item label="鏍囬锛�"> + <div>{{detail.title}}</div> + </Form-item> + <Form-item label="鏍囩锛�"> + <div style="display: flex;flex-wrap: wrap"> + <div v-for="(tag, index) in detail.tagList" :key="'tag' + index" style="margin-right: 5px"> + <Tag color="red">{{tag.tagName}}</Tag> + </div> + </div> + </Form-item> + <Form-item class="video-warp" :label-width="0"> + <video :src="detail.videoUrl" autoplay controls style="width: 768px;height: 432px"/> + </Form-item> + <Form-item label="瀹℃牳缁撴灉锛�" :label-width="100" prop="result"> + <RadioGroup v-model="auditingForm.result"> + <Radio :label="1">閫氳繃</Radio> + <Radio :label="0">涓嶉�氳繃</Radio> + </RadioGroup> + </Form-item> + <Form-item v-show="auditingForm.result === 0" label="涓嶉�氳繃鍘熷洜锛�" :label-width="100" prop="reason"> + <Input + type="textarea" + v-model="auditingForm.reason" + clearable + style="width: 100%" + /> + </Form-item> + </Form> + <div slot="footer"> + <Button type="text" @click="closeAuditing">鍏抽棴</Button> + <Button type="primary" @click="submitAuditing">纭</Button> + </div> + </Modal> + + <Modal + v-model="videoDownShow" + title="瑙嗛涓嬫灦" + width="800" + :mask-closable="false" + > + <Form :model="videoDownForm" :rules="videoDownRule" ref="videoDownForm"> + <FormItem label="涓嬫灦鍘熷洜锛�" :labelWidth="100" prop="reason"> + <editor ref="editor" @input="getReason" /> + </FormItem> + </Form> + <div slot="footer"> + <Button type="text" @click="closeVideoDown">鍏抽棴</Button> + <Button type="primary" @click="videoDown">纭</Button> + </div> + </Modal> + + <Table + :loading="loading" + border + :columns="columns" + :data="data" + ref="table" + sortable="custom" + @on-sort-change="changeSort" + @on-selection-change="showSelect" + > + <template slot-scope="{ row, index }" slot="tagList"> + <div v-for="(tag, index) in row.tagList" :key="'tag' + index" style="margin-top: 5px"> + <Tag color="red">{{tag.tagName}}</Tag> + </div> + </template> + <template slot-scope="{ row, index }" slot="videoFileKey"> + <div class="play-text" @click="playVideo(row.videoFileKey, row.title)">鐐瑰嚮鎾斁</div> + </template> + <template slot-scope="{ row, index }" slot="recommend"> + <i-switch v-model="row.recommend" :before-change="() => handleBeforeChange(row)" true-color="#13ce66"/> + </template> + <template slot-scope="{ row, index }" slot="status"> + {{transStatus(row.status)}} + </template> + <template slot-scope="{ row, index }" slot="action"> + <Button type="primary" size="small" style="margin-right: 5px" v-if="row.status === '99'" @click="openAuditing(row)">瀹℃牳</Button> + <Button type="error" size="small" style="margin-right: 5px" v-if="row.status === '1'" @click="openVideoDown(row)">涓嬫灦</Button> + <Button type="success" size="small" style="margin-right: 5px" v-else-if="row.status === '0'" @click="videoUp(row)">涓婃灦</Button> + </template> + </Table> + + <Row type="flex" justify="end" class="mt_10"> + <Page + :current="searchForm.pageNumber" + :total="total" + :page-size="searchForm.pageSize" + @on-change="changePage" + @on-page-size-change="changePageSize" + :page-size-opts="[10, 20, 50]" + size="small" + show-total + show-elevator + show-sizer + ></Page> + </Row> + </Card> + </div> +</template> + +<script> +import {getVideos, recommendSet, getVideoById, auditingVideo, up, down} from "@/api/video"; +import {getVideoTagList} from "@/api/videoTag"; +import {getFilePreview} from "@/api/file"; +import Editor from '@/components/editor/index.vue' +export default { + name: "VideoList", + components: {Editor}, + data() { + return { + videoDownForm: { + id: '', + reason: '' + }, + videoDownRule: { + reason: [ + { + require: true, + message: '璇疯緭鍏ヤ笅鏋跺師鍥�', + trigger: 'blur', + validator: (rule, value, callback) => { + if (value === null || value === '') { + callback(new Error('璇疯緭鍏ヤ笅鏋跺師鍥�')); + } else { + callback(); + } + } + } + ] + }, + videoDownShow: false, // 瑙嗛涓嬫灦 + videoDownMsg: '', // 涓嬫灦鎻愮ず淇℃伅 + auditingForm: { // 瀹℃牳琛ㄥ崟 + id: null, + result: null, + reason: '' + }, + auditingRule: { + result: [ + { + required: true, + message: '璇烽�夋嫨瑙嗛瀹℃牳缁撴灉', + trigger: 'change', + validator: (rule, value, callback) => { + if (value === null || value === undefined) { + callback(new Error('璇烽�夋嫨瑙嗛瀹℃牳缁撴灉')); + } else { + callback(); + } + } + } + ], + }, + detail: {}, // 瑙嗛璇︽儏淇℃伅 + auditingShow: false, // 瀹℃牳寮圭獥 + auditingLoading: false, // 瀹℃牳寮圭獥 + playVideoShow: false, // 瑙嗛鎾斁寮圭獥 + playVideoTitle: '', // 瑙嗛鎾斁鏍囬 + playVideoUrl: '', // 褰撳墠姝e湪鎾斁鐨勮棰戝湴鍧� + modelShow: false, // 寮圭獥鏄鹃殣 + modelTitle: '', // 寮圭獥title + loading: false, // 琛ㄥ崟鍔犺浇鐘舵�� + searchForm: { + // 鎼滅储妗嗗垵濮嬪寲瀵硅薄 + pageNumber: 1, // 褰撳墠椤垫暟 + pageSize: 10, // 椤甸潰澶у皬 + title: '', // 鏍囬 + tagList: [], // 鏍囩 + status: '99' + }, + tagList: [], // 鏍囩鍒楄〃 + columns: [ + { + type: 'selection', + width: 60, + align: 'center' + }, + { + title: "鏍囬", + key: "title", + minWidth: 240, + tooltip: true, + }, + { + title: "浣滆��", + key: "authorName", + width: 130, + tooltip: true, + }, + { + title: "瑙嗛鏍囩", + key: "tagList", + width: 180, + slot: "tagList", + }, + { + title: "瑙嗛鍐呭", + key: "videoFileKey", + width: 170, + slot: "videoFileKey" + }, + { + title: "鎾斁閲�", + key: "playNum", + width: 80, + align: 'center' + }, + { + title: "鏀惰棌鏁�", + key: "collectNum", + width: 80, + align: 'center' + }, + { + title: "璇勮鏁�", + key: "commentNum", + width: 80, + align: 'center' + }, + { + title: "棣栭〉鎺ㄨ崘", + key: "recommend", + slot: "recommend", + width: 100, + align: 'center' + }, + { + title: "鏉冮噸", + key: "weight", + width: 170, + }, + { + title: "鐘舵��", + key: "status", + slot: "status", + width: 120, + align: 'center' + }, + { + title: "鎿嶄綔", + key: "action", + slot: "action", + align: "center", + width: 200, + }, + ], + data: [], // 琛ㄥ崟鏁版嵁 + total: 0, // 琛ㄥ崟鏁版嵁鎬绘暟 + selectCount: 0, // 宸查�夋暟閲� + selectList: [], // 宸查�夋暟鎹垪琛� + } + }, + created() { + this.getDataList(); + this.getTags('') + }, + methods: { + // 鑾峰彇鏍囩鍒楄〃 + getTags(tagName) { + let params = { + 'tagName': tagName + } + getVideoTagList(params).then(res => { + this.tagList = res.data + }) + }, + // 鑾峰彇瀵屾枃鏈紪杈戝櫒鐨勫唴瀹� + getReason(content) { + this.videoDownForm.reason = content + }, + // 瑙嗛涓婃灦 + videoUp(row) { + this.$Modal.confirm({ + title: "鎿嶄綔纭", + content: "鎮ㄧ‘璁よ涓婃灦瑙嗛銆� " + row.title + "銆戝悧?", + loading: true, + onOk: () => { + up(row.id).then(res => { + this.$Modal.remove(); + if (res.code == 200) { + this.$Message.success("瑙嗛涓婃灦鎴愬姛"); + this.getDataList(); + } + }); + } + }); + }, + // 瑙嗛涓嬫灦 + videoDown() { + this.$refs.videoDownForm.validate((valid) => { + if (valid) { + down(this.videoDownForm).then(res => { + this.$Message.success("涓嬫灦鎴愬姛") + this.closeVideoDown() + this.getDataList() + }) + } + }) + }, + // 鍏抽棴瑙嗛涓嬫灦 + closeVideoDown() { + this.videoDownShow = false + this.videoDownForm = { + id: '', + reason: '' + } + this.$refs.editor.setContent('') + }, + // 瑙嗛涓嬫灦 + openVideoDown(row) { + this.videoDownForm.id = row.id + this.videoDownShow = true + }, + // 鎻愪氦瀹℃牳缁撴灉 + submitAuditing() { + console.log(this.auditingForm, "sb") + this.$refs.auditingForm.validate((valid) => { + if (valid) { + auditingVideo(this.auditingForm).then(res => { + this.$Message.success("瀹℃牳瀹屾垚") + this.closeAuditing() + this.getDataList() + }) + } + }) + }, + // 瀹℃牳缁撴灉鍙樺寲 + resultChange(selected) { + this.auditingForm.result = selected === '閫氳繃' ? 1 : 0 + console.log(this.auditingForm.result) + }, + closeAuditing() { + this.auditingForm = { + id: null, + result: null, + reason: '' + } + this.detail = {} + this.auditingShow = false + }, + // 鎵撳紑瀹℃牳寮圭獥 + openAuditing(row) { + this.auditingShow = true + this.auditingLoading = true + this.auditingForm.id = row.id + getVideoById(row.id).then(res => { + this.detail = res.data + this.auditingLoading = false + }) + }, + // 缈昏瘧鐘舵�� + transStatus(status) { + switch (status) { + case '99': + return '寰呭鏍�' + case '1': + return '宸插彂甯�' + case '0': + return '宸蹭笅鏋�' + case '-1': + return '瀹℃牳鏈�氳繃' + default: + return '鏈煡' + } + }, + // 寮�鍚垨鍏抽棴鎺ㄨ崘鐨勬柟娉� + handleBeforeChange(row) { + let content = "" + if (row.recommend) { + content = '纭瑕佸叧闂椤垫帹鑽愬悧锛�' + } else { + content = '纭瑕佸紑鍚椤垫帹鑽愬悧锛�' + } + return new Promise((resolve) => { + this.$Modal.confirm({ + title: '鎿嶄綔鎻愰啋', + content: content, + onOk: () => { + recommendSet({id: row.id, recommend: !row.recommend}).then(res => { + this.$Message.success(res.msg); + resolve(); + }) + } + }); + }); + }, + // 鍏抽棴瑙嗛鎾斁 + playVideoClose() { + this.playVideoTitle = ''; + this.playVideoUrl = ''; + this.playVideoShow = false + }, + // 鐐瑰嚮鎾斁瑙嗛 + playVideo(fileKey, title) { + this.playVideoTitle = title; + + getFilePreview(fileKey).then(res => { + this.playVideoUrl = res.data + this.playVideoShow = true + }) + }, + // 鎼滅储 + handleSearch() { + this.searchForm.pageNumber = 1; + this.searchForm.pageSize = 10; + this.getDataList(); + }, + // 鑾峰彇鍒楄〃鏁版嵁 + getDataList() { + this.loading = true; + getVideos(this.searchForm).then((res) => { + console.log(res) + this.loading = false; + if (res.code == 200) { + this.data = res.data; + this.total = res.total; + } + }); + this.total = this.data.length; + this.loading = false; + }, + showSelect(e) { + this.selectList = e.map(d => d.id); + this.selectCount = e.length; + }, + // 鎺掑簭 + changeSort(e) { + this.searchForm.sort = e.key; + this.searchForm.order = e.order; + if (e.order == "normal") { + this.searchForm.order = ""; + } + this.getDataList(); + }, + // 鍒嗛〉 鏀瑰彉椤电爜 + changePage(v) { + this.searchForm.pageNumber = v; + this.getDataList(); + }, + // 鍒嗛〉 鏀瑰彉椤垫暟 + changePageSize(v) { + this.searchForm.pageNumber = 1; + this.searchForm.pageSize = v; + this.getDataList(); + }, + } +} +</script> + +<style scoped> +.play-text { + width: 100%; + text-align: center; + color: #2d8cf0; +} +.play-text:hover { + cursor: pointer; +} +.video-warp { + width: 786px; + height: 432px; +} +.data-item { + display: flex; + align-items: center; +} +</style> -- Gitblit v1.8.0