index.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <!--
  2. @Datetime : 2024/8/30 17:42
  3. @Author : WANGKANG
  4. @Email : 1686617586@qq.com
  5. @Blog :
  6. @File : index.vue.vue
  7. @brief : 视频转图片
  8. -->
  9. <template>
  10. <div class="table-box">
  11. <ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listVideo2imageApi">
  12. <!-- 表格 header 按钮 -->
  13. <template #tableHeader="scope">
  14. <el-button type="primary" v-auth="['demo:video2image:add']" icon="CirclePlus" @click="openDialog(1, '新增')"> 新增 </el-button>
  15. <!-- <el-button type="primary" v-auth="['demo:video2image:import']" icon="Upload" plain @click="batchAdd" v-if="false"> 导入 </el-button>
  16. <el-button type="primary" v-auth="['demo:video2image:export']" icon="Download" plain @click="downloadFile" v-if="false"> 导出 </el-button> -->
  17. <el-button
  18. type="danger"
  19. v-auth="['demo:video2image:remove']"
  20. icon="Delete"
  21. plain
  22. :disabled="!scope.isSelected"
  23. @click="batchDelete(scope.selectedListIds)"
  24. >
  25. 批量删除
  26. </el-button>
  27. </template>
  28. <!-- 表格操作 -->
  29. <template #operation="scope">
  30. <el-button
  31. type="primary"
  32. link
  33. icon="View"
  34. v-auth="['demo:video2image:start']"
  35. @click="startVideo2image(scope.row)"
  36. v-if="scope.row.status == '0' || scope.row.status == '3'"
  37. >
  38. 开始
  39. </el-button>
  40. <el-popconfirm title="确定终止此任务吗?" @confirm="stopVideo2image(scope.row)" v-if="scope.row.status == '1'">
  41. <template #reference>
  42. <el-button type="primary" link icon="Delete"> 终止 </el-button>
  43. </template>
  44. </el-popconfirm>
  45. <el-button
  46. type="primary"
  47. link
  48. icon="View"
  49. v-auth="['demo:video2image:download']"
  50. @click="dowloadVideo2image(scope.row)"
  51. v-if="scope.row.status == '2'"
  52. >
  53. 下载
  54. </el-button>
  55. <!-- <el-button type="primary" link icon="View" v-auth="['demo:video2image:query']" @click="openDialog(3, '查看', scope.row)"> 查看 </el-button>
  56. <el-button type="primary" link icon="EditPen" v-auth="['demo:video2image:edit']" @click="openDialog(2, '编辑', scope.row)"> 编辑 </el-button> -->
  57. <el-button type="primary" link icon="Delete" v-auth="['demo:video2image:remove']" @click="deleteVideo2image(scope.row)"> 删除 </el-button>
  58. </template>
  59. </ProTable>
  60. <FormDialog ref="formDialogRef"></FormDialog>
  61. </div>
  62. </template>
  63. <script setup lang="tsx" name="Video2image">
  64. import { ref, reactive } from 'vue'
  65. import { useHandleData } from '@/hooks/useHandleData'
  66. import { useDownload } from '@/hooks/useDownload'
  67. import { ElMessageBox, ElMessage } from 'element-plus'
  68. import ProTable from '@/components/ProTable/index.vue'
  69. import ImportExcel from '@/components/ImportExcel/index.vue'
  70. import FormDialog from '@/components/FormDialog/index.vue'
  71. import { ProTableInstance, ColumnProps, EnumProps } from '@/components/ProTable/interface'
  72. import {
  73. listVideo2imageApi,
  74. delVideo2imageApi,
  75. addVideo2imageApi,
  76. updateVideo2imageApi,
  77. importTemplateApi,
  78. importVideo2imageDataApi,
  79. exportVideo2imageApi,
  80. getVideo2imageApi,
  81. startVideo2imageApi,
  82. downloadVideo2imageApi
  83. } from '@/api/modules/demo/video2image'
  84. const startVideo2image = async (params: any) => {
  85. const res = await startVideo2imageApi(params.id)
  86. if (res.code === 200) {
  87. ElMessage.success('任务已开始,请等待完成!')
  88. } else {
  89. ElMessage.error('任务开始失败,请检查!')
  90. }
  91. proTable.value?.getTableList()
  92. }
  93. const stopVideo2image = async (params: any) => {
  94. const res = await ElMessageBox.confirm('是否确认中止该任务?')
  95. if (res) {
  96. const res = await stopVideo2imageApi(params.id)
  97. if (res.code === 200) {
  98. ElMessage.success('终止任务成功!')
  99. } else {
  100. ElMessage.error('终止任务失败,请检查!')
  101. }
  102. proTable.value?.getTableList()
  103. }
  104. }
  105. const dowloadVideo2image = async (params: any) => {
  106. await useDownload(downloadVideo2imageApi, params.name, params.id, true, '.zip')
  107. }
  108. // ProTable 实例
  109. const proTable = ref<ProTableInstance>()
  110. // 删除视频转图片信息
  111. const deleteVideo2image = async (params: any) => {
  112. await useHandleData(delVideo2imageApi, params.id, '删除【' + params.id + '】视频转图片')
  113. proTable.value?.getTableList()
  114. }
  115. // 批量删除视频转图片信息
  116. const batchDelete = async (ids: string[]) => {
  117. await useHandleData(delVideo2imageApi, ids, '删除所选视频转图片信息')
  118. proTable.value?.clearSelection()
  119. proTable.value?.getTableList()
  120. }
  121. // 导出视频转图片列表
  122. const downloadFile = async () => {
  123. ElMessageBox.confirm('确认导出视频转图片数据?', '温馨提示', { type: 'warning' }).then(() =>
  124. useDownload(exportVideo2imageApi, '视频转图片列表', proTable.value?.searchParam)
  125. )
  126. }
  127. // 批量添加视频转图片
  128. const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
  129. const batchAdd = () => {
  130. const params = {
  131. title: '视频转图片',
  132. tempApi: importTemplateApi,
  133. importApi: importVideo2imageDataApi,
  134. getTableList: proTable.value?.getTableList
  135. }
  136. dialogRef.value?.acceptParams(params)
  137. }
  138. const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
  139. // 打开弹框的功能
  140. const openDialog = async (type: number, title: string, row?: any) => {
  141. let res = { data: {} }
  142. if (row?.id) {
  143. res = await getVideo2imageApi(row?.id || null)
  144. }
  145. // 重置表单
  146. setItemsOptions()
  147. const params = {
  148. title,
  149. width: 580,
  150. isEdit: type !== 3,
  151. itemsOptions: itemsOptions,
  152. model: type == 1 ? {} : res.data,
  153. api: type == 1 ? addVideo2imageApi : updateVideo2imageApi,
  154. getTableList: proTable.value?.getTableList,
  155. showVideoUpload: type == 1 ? true : false
  156. }
  157. formDialogRef.value?.openDialog(params)
  158. }
  159. const statusEnums: EnumProps[] = [
  160. {
  161. label: '未开始',
  162. value: '0',
  163. disabled: false,
  164. tagType: 'default'
  165. },
  166. {
  167. label: '进行中',
  168. value: '1',
  169. disabled: false,
  170. tagType: 'primary'
  171. },
  172. {
  173. label: '已结束',
  174. value: '2',
  175. disabled: false,
  176. tagType: 'success'
  177. },
  178. {
  179. label: '失败',
  180. value: '3',
  181. disabled: false,
  182. tagType: 'danger'
  183. }
  184. ]
  185. // 表格配置项
  186. const columns = reactive<ColumnProps<any>[]>([
  187. { type: 'selection', fixed: 'left', width: 70 },
  188. { prop: 'id', label: '主键ID', width: 180 },
  189. {
  190. prop: 'name',
  191. label: '任务名称',
  192. search: {
  193. el: 'input'
  194. },
  195. width: 150
  196. },
  197. {
  198. prop: 'status',
  199. label: '任务状态',
  200. search: {
  201. el: 'select'
  202. },
  203. tag: true,
  204. enum: statusEnums
  205. },
  206. {
  207. prop: 'outPath',
  208. label: '输出路径',
  209. width: 120
  210. },
  211. {
  212. prop: 'startTime',
  213. label: '开始时间',
  214. search: {
  215. el: 'date-picker',
  216. props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
  217. },
  218. width: 180
  219. },
  220. {
  221. prop: 'endTime',
  222. label: '结束时间',
  223. search: {
  224. el: 'date-picker',
  225. props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
  226. },
  227. width: 180
  228. },
  229. {
  230. prop: 'costSecond',
  231. label: '耗时',
  232. width: 120
  233. },
  234. {
  235. prop: 'log',
  236. label: '日志',
  237. width: 120
  238. },
  239. {
  240. prop: 'remarks',
  241. label: '备注',
  242. search: {
  243. el: 'input'
  244. },
  245. width: 120
  246. },
  247. {
  248. prop: 'path',
  249. label: '视频路径',
  250. width: 150
  251. },
  252. {
  253. prop: 'fps',
  254. label: '切割帧率',
  255. search: {
  256. el: 'input'
  257. },
  258. width: 120
  259. },
  260. { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
  261. ])
  262. // 表单配置项
  263. let itemsOptions: ProForm.ItemsOptions[] = []
  264. const setItemsOptions = () => {
  265. itemsOptions = [
  266. {
  267. label: '任务名称',
  268. prop: 'name',
  269. rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
  270. compOptions: {
  271. placeholder: '请输入任务名称'
  272. }
  273. },
  274. {
  275. label: '切割帧率',
  276. prop: 'fps',
  277. rules: [
  278. { required: true, message: '切割帧率不能为空', trigger: 'blur' }
  279. // {
  280. // type: 'number',
  281. // message: '切割帧率必须为数字',
  282. // trigger: 'blur'
  283. // },
  284. // { min: 1, message: '切割帧率必须大于等于1', trigger: 'blur' },
  285. // { max: 60, message: '切割帧率必须小于等于60', trigger: 'blur' }
  286. ],
  287. compOptions: {
  288. type: 'number',
  289. placeholder: '请输入切割帧率,范围:1-60'
  290. }
  291. },
  292. {
  293. label: '上传视频',
  294. prop: 'inputOssId',
  295. rules: [{ required: false, message: '视频不能为空', trigger: 'blur' }],
  296. compOptions: {
  297. elTagName: 'file-upload',
  298. fileSize: 4096,
  299. fileType: ['mp4', 'avi', 'rmvb', 'mov', 'wmv', 'flv'],
  300. placeholder: '请上传视频文件'
  301. }
  302. },
  303. {
  304. label: '备注',
  305. prop: 'remarks',
  306. rules: [{ required: false, message: '备注不能为空', trigger: 'blur' }],
  307. compOptions: {
  308. placeholder: '请输入备注'
  309. }
  310. }
  311. ]
  312. }
  313. </script>
  314. <style scoped></style>