video.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <template>
  2. <div class="bg-white rounded-md p-4 rounded-6px">
  3. <div class="operateDiv flex justify-between">
  4. <div>
  5. <el-button type="primary" @click="linkTo">同步课堂管理</el-button>
  6. <el-button type="primary" @click="handleExport">批量下载</el-button>
  7. <el-button type="danger" @click="handleDelete()">删除</el-button>
  8. </div>
  9. <div class="flex items-center space-x-4">
  10. <el-input v-model="searchForm.keyword" placeholder="请输入搜索的关键词" size="small" :suffix-icon="Search" />
  11. <el-button type="primary" @click="initData">搜索</el-button>
  12. </div>
  13. </div>
  14. <el-divider />
  15. <el-table :data="tableData" @selection-change="handleSelectionChange">
  16. <el-table-column type="selection" width="55" />
  17. <el-table-column prop="ttv_id" label="#"></el-table-column>
  18. <el-table-column prop="tt_hdh" label="互动号" show-overflow-tooltip></el-table-column>
  19. <el-table-column prop="ttv_flv_file" label="录制视频源文件"></el-table-column>
  20. <el-table-column prop="ttv_datetime" label="录制时间"></el-table-column>
  21. <el-table-column prop="ttv_filesize" label="文件大小"></el-table-column>
  22. <el-table-column prop="ttv_zdymc" label="自定义名称"></el-table-column>
  23. <el-table-column prop="ttv_sfzh" label="是否转换"></el-table-column>
  24. <el-table-column label="操作" width="200">
  25. <template #default="{ row }">
  26. <el-button type="primary" text @click="handleEdit(row)">上传&编辑加工视频</el-button>
  27. <el-divider direction="vertical" />
  28. <el-popover placement="bottom" :width="160" trigger="click">
  29. <div class="text-center">
  30. <el-button type="text" @click="lookDetail(1, row.ttv_mp4_file)">观看原始视频</el-button>
  31. <el-button type="text" @click="lookDetail(2, row.ttv_flv_file, '原始FLV视频')">下载原始FLV视频</el-button>
  32. <el-button type="text" @click="lookDetail(2, row.ttv_mp4_file, '原始MP4视频')">下载原始MP4视频</el-button>
  33. <el-button type="text" @click="lookDetail(1, row.ttv_upload_file)">观看加工视频</el-button>
  34. <el-button type="text" @click="lookDetail(2, row.ttv_upload_file, '加工视频')">下载加工视频</el-button>
  35. </div>
  36. <template #reference>
  37. <el-button type="text">更多</el-button>
  38. </template>
  39. </el-popover>
  40. </template>
  41. </el-table-column>
  42. </el-table>
  43. <div class="flex justify-end my-10">
  44. <el-pagination v-model:current-page="currentPage" v-model:page-size="limit" :page-sizes="[10, 20, 50, 100]" :pager-count="5" :small="true" layout="total,sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  45. </div>
  46. <el-dialog v-model="dialogVisible" title="编辑" width="500px" destroy-on-close :close-on-click-modal="false" @close="handleClose">
  47. <el-form ref="ruleFormRef" label-position="right" label-width="100px" :model="ruleForm">
  48. <el-form-item label="自定义名称:" prop="ttv_zdymc">
  49. <el-input v-model="ruleForm.ttv_zdymc" size="small"></el-input>
  50. </el-form-item>
  51. <el-form-item label="上传文件:" prop="ttv_upload_file">
  52. <file-upload-progress v-model:part="ruleForm.ttv_upload_file" :limit="1" class="w-520px" accept=".mp4">
  53. <template #default>
  54. <el-button type="primary" size="large">点击上传</el-button>
  55. </template>
  56. </file-upload-progress>
  57. </el-form-item>
  58. </el-form>
  59. <div class="mt-5 text-center">
  60. <el-button type="primary" plain @click="handleClose()">取消</el-button>
  61. <el-button type="primary" @click="submit">确定</el-button>
  62. </div>
  63. </el-dialog>
  64. </div>
  65. </template>
  66. <script setup>
  67. import { getFullUrl } from "@/utils/helper";
  68. import { Search } from "@element-plus/icons-vue";
  69. import { useRouter } from "vue-router";
  70. const router = useRouter();
  71. const searchForm = ref({});
  72. watch(() => searchForm.value, () => {
  73. initData();
  74. }, { deep: true })
  75. const total = ref(0)
  76. const limit = ref(10)
  77. const currentPage = ref(1);
  78. const tableData = ref([]);
  79. initData();
  80. async function initData() {
  81. let obj = {
  82. page: currentPage.value,
  83. limit: limit.value,
  84. };
  85. let { code, data } = await request({ url: "/txwx/tbkt_video/index", data: Object.assign(obj, searchForm.value) });
  86. if (code == 1) {
  87. tableData.value = data.page_data;
  88. total.value = Number(data.total_rows);
  89. }
  90. }
  91. function handleSizeChange(val) {
  92. limit.value = val;
  93. currentPage.value = 1;
  94. initData();
  95. }
  96. function handleCurrentChange(val) {
  97. currentPage.value = val;
  98. initData();
  99. }
  100. const multiSelection = ref([]);
  101. const handleSelectionChange = (val) => {
  102. multiSelection.value = val;
  103. }
  104. const linkTo = () => {
  105. router.back();
  106. };
  107. const handleDelete = (row) => {
  108. if (!row && multiSelection.value.length == 0) {
  109. ElMessage.error("请先选择数据!");
  110. return
  111. }
  112. ElMessageBox.confirm('确定要删除该数据吗?', {
  113. confirmButtonText: '确定',
  114. cancelButtonText: '取消',
  115. type: "warning",
  116. })
  117. .then(async () => {
  118. let ttv_id;
  119. if (row) {
  120. ttv_id = row.ttv_id;
  121. } else {
  122. ttv_id = [];
  123. multiSelection.value.map(item => {
  124. ttv_id.push(item.ttv_id);
  125. })
  126. }
  127. let res = await request({ url: "/txwx/tbkt_video/delete", data: { ttv_id: ttv_id } });
  128. if (res.code == 1) {
  129. ElMessage.success("删除成功!");
  130. initData();
  131. }
  132. })
  133. .catch(() => { })
  134. }
  135. const handleExport = () => {
  136. let arr = [];
  137. multiSelection.value.map((item) => {
  138. arr.push(item.ttv_id);
  139. });
  140. let obj = {
  141. limit: "99999",
  142. ttv_id: arr.join(",")
  143. };
  144. download("/txwx/tbkt_video/index", obj);
  145. }
  146. const lookDetail = (type, file, name) => {
  147. if (!file) {
  148. ElMessage.error("暂无视频文件!");
  149. return
  150. }
  151. // type 1:查看;2:下载
  152. if (type == 1) {
  153. window.open(getFullUrl(file));
  154. } else if (type == 2) {
  155. const arr = file.split(".")
  156. const ext = arr[arr.length - 1];
  157. let blob = new Blob([getFullUrl(file)], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); //type为所需要下载的文件格式,以xlsx文件为例
  158. let url = window.URL.createObjectURL(blob);
  159. let fileName = `${name}.${ext}`;
  160. if ("download" in document.createElement("a")) {
  161. let a = document.createElement("a");
  162. a.href = url;
  163. a.download = fileName;
  164. a.style.display = "none";
  165. document.body.appendChild(a);
  166. a.click();
  167. URL.revokeObjectURL(a.href);
  168. document.body.removeChild(a);
  169. } else {
  170. navigator.msSaveBlob(blob, fileName);
  171. }
  172. }
  173. }
  174. const dialogVisible = ref(false);
  175. const ruleForm = ref({
  176. ttv_zdymc: "",
  177. ttv_upload_file: "",
  178. });
  179. const currentId = ref("");
  180. const handleClose = () => {
  181. dialogVisible.value = false;
  182. currentId.value = "";
  183. for (let key in ruleForm.value) {
  184. ruleForm.value[key] = "";
  185. }
  186. }
  187. const handleEdit = async (row) => {
  188. dialogVisible.value = true;
  189. currentId.value = row.ttv_id;
  190. let { code, data } = await request({ url: "/txwx/tbkt_video/detail", data: { ttv_id: row.ttv_id } });
  191. if (code == 1) {
  192. for (let key in ruleForm.value) {
  193. ruleForm.value[key] = data.one_info[key];
  194. }
  195. }
  196. }
  197. const submit = async () => {
  198. let obj = {
  199. ttv_id: currentId.value,
  200. txwx_tbkt_video: ruleForm.value
  201. }
  202. let { code } = await request({ url: "/txwx/tbkt_video/edit", data: obj });
  203. if (code == 1) {
  204. ElMessage.success("保存成功!");
  205. initData();
  206. handleClose();
  207. }
  208. }
  209. </script>
  210. <style lang="scss" scoped>
  211. @use "~/styles/table.scss";
  212. @use "~/styles/pagination.scss";
  213. </style>