index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. <template>
  2. <div class="p-2">
  3. <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
  4. :leave-active-class="proxy?.animate.searchAnimate.leave">
  5. <div v-show="showSearch" class="mb-[10px]">
  6. <el-card shadow="hover" :style="{ height: '70px' }">
  7. <el-row :gutter="20" align="middle">
  8. <!-- 内容总数 -->
  9. <el-col :span="6" style="display: flex; justify-content: center; align-items: center">
  10. <el-statistic :value="totalNum">
  11. <template #title>
  12. <div style="display: inline-flex; align-items: center">文件总数</div>
  13. </template>
  14. </el-statistic>
  15. </el-col>
  16. <!-- 图片总数 -->
  17. <el-col :span="6" style="display: flex; justify-content: center; align-items: center">
  18. <el-statistic :value="imageNum">
  19. <template #title>
  20. <div style="display: inline-flex; align-items: center">图片总数</div>
  21. </template>
  22. </el-statistic>
  23. </el-col>
  24. <!-- 视频总数 -->
  25. <el-col :span="6" style="display: flex; justify-content: center; align-items: center">
  26. <el-statistic :value="videoNum">
  27. <template #title>
  28. <div style="display: inline-flex; align-items: center">视频总数</div>
  29. </template>
  30. </el-statistic>
  31. </el-col>
  32. <!-- 其它文件 -->
  33. <el-col :span="6" style="display: flex; justify-content: center; align-items: center">
  34. <el-statistic :value="otherNum">
  35. <template #title>
  36. <div style="display: inline-flex; align-items: center">其它</div>
  37. </template>
  38. </el-statistic>
  39. </el-col>
  40. </el-row>
  41. </el-card>
  42. <el-card shadow="hover" :style="{ marginTop: '10px', height: '60px' }">
  43. <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="40px">
  44. <el-form-item label="名称" prop="originalName">
  45. <el-input v-model="queryParams.originalName" placeholder="请输入文件名" clearable style="width: 150px" />
  46. </el-form-item>
  47. <el-form-item label="类型" prop="type">
  48. <el-select v-model="queryParams.type" style="width: 150px" placeholder="请选择类型" clearable>
  49. <el-option v-for="dict in smsb_source_type" :key="dict.value" :label="dict.label" :value="dict.value" />
  50. </el-select>
  51. </el-form-item>
  52. <el-form-item label="分类" prop="tag">
  53. <el-select v-model="queryParams.tag" style="width: 150px" placeholder="请选择分类" clearable>
  54. <el-option v-for="dict in smsb_source_classify" :key="dict.value" :label="dict.label"
  55. :value="dict.value" />
  56. </el-select>
  57. </el-form-item>
  58. <el-form-item label="目录" prop="treeId">
  59. <el-tree-select v-model="queryParams.treeId" :data="sourceTreeOptions"
  60. :props="{ value: 'id', label: 'name', children: 'children' }" value-key="id" placeholder="请选择归属目录"
  61. check-strictly @change="handleQuery" style="width: 200px" clearable />
  62. </el-form-item>
  63. <el-form-item label="时间" style="width: 250px">
  64. <el-date-picker v-model="dateRangeCreateTime" value-format="YYYY-MM-DD HH:mm:ss" type="daterange"
  65. range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
  66. :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"></el-date-picker>
  67. </el-form-item>
  68. <el-form-item>
  69. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  70. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  71. <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['source:minioData:add']"> 上传
  72. </el-button>
  73. <el-button type="primary" plain icon="Switch" @click="handleTrans" v-hasPermi="['source:minioData:add']">
  74. 转码进度
  75. </el-button>
  76. <!-- <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['source:minioData:edit']"
  77. >修改
  78. </el-button>
  79. <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['source:minioData:remove']"
  80. >删除
  81. </el-button>-->
  82. </el-form-item>
  83. </el-form>
  84. </el-card>
  85. </div>
  86. </transition>
  87. <el-card shadow="never">
  88. <div class="table-content">
  89. <el-table v-loading="loading" :data="minioDataList" @selection-change="handleSelectionChange">
  90. <el-table-column type="selection" width="55" align="center" />
  91. <el-table-column label="资源" align="left" prop="keyName" width="200" :show-overflow-tooltip="true" />
  92. <el-table-column label="类型" align="center" prop="type" width="120">
  93. <template #default="scope">
  94. <dict-tag :options="smsb_source_type" :value="scope.row.type" />
  95. </template>
  96. </el-table-column>
  97. <el-table-column label="原名" align="left" prop="originalName" width="150" :show-overflow-tooltip="true" />
  98. <el-table-column label="大小" align="left" prop="size" />
  99. <el-table-column label="分辨率" align="left" prop="resolution" />
  100. <el-table-column label="码率(kbps)" align="left" prop="codeRate" />
  101. <el-table-column label="时长" align="left" prop="durationStr" />
  102. <el-table-column label="预览" align="center" prop="screenshot">
  103. <template #default="scope">
  104. <div v-if="scope.row.type === 1">
  105. <!-- 图片类型 -->
  106. <image-preview :src="scope.row.screenshot" style="width: 40px; height: 40px; cursor: pointer" />
  107. </div>
  108. <div v-else-if="scope.row.type === 2">
  109. <!-- 视频类型 -->
  110. <!-- <image-preview :src="scope.row.screenshot" style="width: 40px; height: 40px; cursor: pointer" -->
  111. <!-- @click="viewVideo(scope.row.url)" /> -->
  112. <el-icon class="VideoPlay" @click="viewVideo(scope.row.screenshot)" size="40" style="cursor: pointer">
  113. <VideoPlay />
  114. </el-icon>
  115. </div>
  116. </template>
  117. </el-table-column>
  118. <el-table-column label="转码" align="center" prop="transState">
  119. <template #default="scope">
  120. <dict-tag :options="smsb_trans_result" :value="scope.row.transState" />
  121. </template>
  122. </el-table-column>
  123. <el-table-column label="分类" align="center" prop="tag">
  124. <template #default="scope">
  125. <dict-tag :options="smsb_source_classify" :value="scope.row.tag" />
  126. </template>
  127. </el-table-column>
  128. <el-table-column label="创建人" align="left" prop="createUser" />
  129. <el-table-column label="创建时间" align="left" prop="createTime" width="180">
  130. <template #default="scope">
  131. <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
  132. </template>
  133. </el-table-column>
  134. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  135. <template #default="scope">
  136. <!-- <el-tooltip content="修改" placement="top">
  137. <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['source:minioData:edit']"></el-button>
  138. </el-tooltip>-->
  139. <el-tooltip content="删除" placement="top">
  140. <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
  141. v-hasPermi="['source:minioData:remove']"></el-button>
  142. </el-tooltip>
  143. <el-tooltip content="引用情况" placement="top">
  144. <el-button link type="primary" icon="List" @click="handleUse(scope.row)"
  145. v-hasPermi="['source:minioData:edit']"></el-button>
  146. </el-tooltip>
  147. </template>
  148. </el-table-column>
  149. </el-table>
  150. </div>
  151. <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
  152. v-model:limit="queryParams.pageSize" @pagination="getList" />
  153. </el-card>
  154. <!-- 添加或修改文件资源对话框 -->
  155. <el-dialog :title="dialog.title" v-model="dialog.visible" append-to-body
  156. :style="{ maxWidth: '90vw', maxHeight: '90vh' }">
  157. <el-row :gutter="20" style="display: flex">
  158. <el-col :span="10" style="height: 100%; overflow: auto; border-right: 1px solid #eee; padding-right: 10px">
  159. <el-tree ref="sourceTreeRef" :data="sourceTreeOptions" show-checkbox node-key="id"
  160. :props="{ value: 'id', label: 'name', children: 'children' }" :check-strictly="true"
  161. :default-expand-all="true" @check="handleTreeCheck" style="height: 100%"></el-tree>
  162. </el-col>
  163. <el-col :span="14"
  164. style="height: 100%; display: flex; flex-direction: column; overflow: auto; padding-left: 10px">
  165. <el-form ref="minioDataFormRef" :model="form" :rules="rules" label-width="80px"
  166. style="flex: 1 1 auto; height: 100%; display: flex; flex-direction: column">
  167. <el-form-item label="分类" prop="tag">
  168. <el-select v-model="form.tag" placeholder="请选择分类">
  169. <el-option v-for="dict in smsb_source_classify" :key="dict.value" :label="dict.label"
  170. :value="parseInt(dict.value)"></el-option>
  171. </el-select>
  172. </el-form-item>
  173. <el-form-item label=""
  174. style="flex: 1 1 auto; display: flex; flex-direction: column; justify-content: flex-start">
  175. <!-- 原始上传组件保留,供参考:
  176. <smsb-file-upload v-model="form.ossId" />
  177. -->
  178. <!-- 替换为新版上传组件 SmsbFileUploader -->
  179. <SmsbFileUploader ref="fileUploaderRef" v-model="form.ossId" />
  180. </el-form-item>
  181. </el-form>
  182. </el-col>
  183. </el-row>
  184. <template #footer>
  185. <div class="dialog-footer">
  186. <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
  187. <el-button @click="cancel">取 消</el-button>
  188. </div>
  189. </template>
  190. </el-dialog>
  191. <!-- 转码进度弹窗 -->
  192. <el-dialog :title="trans.title" v-model="trans.visible" width="1000px" append-to-body :style="{ height: '700px' }">
  193. <el-card shadow="never">
  194. <div class="table-content">
  195. <el-table v-loading="loading" :data="transRecordList">
  196. <el-table-column label="资源名称" align="left" prop="fileName" width="200" :show-overflow-tooltip="true" />
  197. <el-table-column label="转码类型" align="center" prop="transType">
  198. <template #default="scope">
  199. <dict-tag :options="smsb_trans_type" :value="scope.row.transType" />
  200. </template>
  201. </el-table-column>
  202. <el-table-column label="转码进度" align="center" prop="transProgress">
  203. <template #default="scope">
  204. <dict-tag :options="smsb_trans_progress" :value="scope.row.transProgress" />
  205. </template>
  206. </el-table-column>
  207. <el-table-column label="转码结果" align="center" prop="result">
  208. <template #default="scope">
  209. <dict-tag :options="smsb_trans_result" :value="scope.row.result" />
  210. </template>
  211. </el-table-column>
  212. <el-table-column label="用户名" align="left" prop="createUser" width="100" :show-overflow-tooltip="true" />
  213. <el-table-column label="创建时间" align="left" prop="createTime" width="160" />
  214. </el-table>
  215. </div>
  216. <pagination v-show="transTotal > 0" :total="transTotal" v-model:page="transQueryParams.pageNum"
  217. v-model:limit="transQueryParams.pageSize" @pagination="getTransList" />
  218. </el-card>
  219. </el-dialog>
  220. <!-- 用于展示播放的视频 -->
  221. <el-dialog v-model="videoDialogVisible">
  222. <video width="100%" controls :src="videoUrl"></video>
  223. </el-dialog>
  224. <!-- 引用情况弹窗 -->
  225. <el-dialog :title="useDialog.title" v-model="useDialog.visible" width="1000px" append-to-body
  226. :style="{ height: '700px' }">
  227. <el-card shadow="never">
  228. <div class="table-content" style="min-height: 525px">
  229. <el-table v-loading="loading" :data="itemRecordList">
  230. <el-table-column label="名称" align="left" prop="itemName" />
  231. <el-table-column label="类型" align="center" prop="itemType" width="100">
  232. <template #default="scope">
  233. <dict-tag :options="smsb_item_type" :value="scope.row.itemType" />
  234. </template>
  235. </el-table-column>
  236. <el-table-column label="分屏" align="center" prop="splitScreen" width="100">
  237. <template #default="scope">
  238. <span v-if="scope.row.splitScreen == 0"> --- </span>
  239. <dict-tag v-else :options="smsb_split_screen" :value="scope.row.splitScreen" />
  240. </template>
  241. </el-table-column>
  242. <el-table-column label="资源数量" align="center" prop="sourceNum" width="100" />
  243. <el-table-column label="创建人" align="left" prop="createUser" width="120" :show-overflow-tooltip="true" />
  244. <el-table-column label="创建时间" align="left" prop="createTime" width="160" />
  245. </el-table>
  246. </div>
  247. <pagination v-show="itemTotal > 0" :total="itemTotal" v-model:page="dialogQueryParams.pageNum"
  248. v-model:limit="dialogQueryParams.pageSize" @pagination="getItemListByFileId" />
  249. </el-card>
  250. </el-dialog>
  251. </div>
  252. </template>
  253. <script setup name="MinioData" lang="ts">
  254. import SmsbFileUploader from '@/components/SmsbFileUpload/SmsbFileUploader.vue';
  255. import { listMinioData, getMinioData, delMinioData, addMinioData, updateMinioData, fileStatistics } from '@/api/smsb/source/minioData';
  256. import { MinioDataVO, MinioDataQuery, MinioDataForm } from '@/api/smsb/source/minioData_type';
  257. import { listSourceTree } from '@/api/smsb/source/sourceTree';
  258. import { listMinioTransRecord } from '@/api/smsb/source/transRecord';
  259. import { MinioTransRecordQuery, MinioTransRecordVO } from '@/api/smsb/source/transRecord_type';
  260. import { ItemQuery, ItemVO } from '@/api/smsb/source/item_type';
  261. import { itemListByFileId } from '@/api/smsb/source/item';
  262. type SourceTreeOption = {
  263. id: number;
  264. name: string;
  265. children?: SourceTreeOption[];
  266. };
  267. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  268. const { smsb_source_classify, smsb_source_type, smsb_trans_type, smsb_trans_progress, smsb_trans_result, smsb_item_type, smsb_split_screen } =
  269. toRefs<any>(
  270. proxy?.useDict(
  271. 'smsb_source_classify',
  272. 'smsb_source_type',
  273. 'smsb_trans_type',
  274. 'smsb_trans_progress',
  275. 'smsb_trans_result',
  276. 'smsb_item_type',
  277. 'smsb_split_screen'
  278. )
  279. );
  280. const minioDataList = ref<MinioDataVO[]>([]);
  281. const transRecordList = ref<MinioTransRecordVO[]>([]);
  282. const itemRecordList = ref<ItemVO[]>([]);
  283. const buttonLoading = ref(false);
  284. const loading = ref(true);
  285. const showSearch = ref(true);
  286. const ids = ref<Array<string | number>>([]);
  287. const single = ref(true);
  288. const multiple = ref(true);
  289. const total = ref(0);
  290. const transTotal = ref(0);
  291. const itemTotal = ref(0);
  292. const sourceTreeOptions = ref<SourceTreeOption[]>([]);
  293. const queryFormRef = ref<ElFormInstance>();
  294. const minioDataFormRef = ref<ElFormInstance>();
  295. const totalNum = ref(0);
  296. const imageNum = ref(0);
  297. const videoNum = ref(0);
  298. const otherNum = ref(0);
  299. const videoDialogVisible = ref(false);
  300. const videoUrl = ref('');
  301. const dateRangeCreateTime = ref<[DateModelType, DateModelType]>(['', '']);
  302. const dialog = reactive<DialogOption>({
  303. visible: false,
  304. title: ''
  305. });
  306. const trans = reactive<DialogOption>({
  307. visible: false,
  308. title: ''
  309. });
  310. const useDialog = reactive<DialogOption>({
  311. visible: false,
  312. title: ''
  313. });
  314. const initFormData: MinioDataForm = {
  315. tag: 1,
  316. marketing: undefined,
  317. ossId: undefined,
  318. sourceTreeIds: undefined
  319. };
  320. const data = reactive<PageData<MinioDataForm, MinioDataQuery>>({
  321. form: { ...initFormData },
  322. queryParams: {
  323. pageNum: 1,
  324. pageSize: 10,
  325. originalName: undefined,
  326. type: undefined,
  327. tag: undefined,
  328. marketing: undefined,
  329. treeId: undefined,
  330. params: {}
  331. },
  332. rules: {}
  333. });
  334. const transData = reactive<TransPageData<MinioTransRecordQuery>>({
  335. transQueryParams: {
  336. pageNum: 1,
  337. pageSize: 10,
  338. params: {}
  339. }
  340. });
  341. const itemData = reactive<DialogPageData<ItemQuery>>({
  342. dialogQueryParams: {
  343. pageNum: 1,
  344. pageSize: 10,
  345. fileId: undefined,
  346. params: {}
  347. }
  348. });
  349. const { queryParams, form, rules } = toRefs(data);
  350. const { transQueryParams } = toRefs(transData);
  351. const { dialogQueryParams } = toRefs(itemData);
  352. // 播放视频
  353. const viewVideo = (url: string) => {
  354. videoUrl.value = url;
  355. console.log(videoUrl.value);
  356. videoDialogVisible.value = true;
  357. };
  358. /** 查询文件资源列表 */
  359. const getList = async () => {
  360. loading.value = true;
  361. // const res = await listMinioData(queryParams.value);
  362. const res = await listMinioData(proxy?.addDateRange(queryParams.value, dateRangeCreateTime.value, 'CreateTime'));
  363. minioDataList.value = res.rows;
  364. minioDataList.value.forEach((data) => {
  365. data.size = parseFloat(data.size / 1024).toFixed(3) + 'MB';
  366. const minutes = Math.floor(data.duration / 60); // 获取分钟数
  367. const remainingSeconds = data.duration % 60; // 获取剩余的秒数
  368. data.durationStr = `${minutes}分${remainingSeconds}秒`;
  369. });
  370. total.value = res.total;
  371. loading.value = false;
  372. };
  373. const getTransList = async () => {
  374. const res = await listMinioTransRecord(transQueryParams.value);
  375. transRecordList.value = res.rows;
  376. transTotal.value = res.total;
  377. };
  378. const getItemListByFileId = async () => {
  379. const res = await itemListByFileId(dialogQueryParams.value);
  380. itemRecordList.value = res.rows;
  381. itemTotal.value = res.total;
  382. };
  383. /** 查询文件目录下拉树结构 */
  384. const getTreeselect = async () => {
  385. const res = await listSourceTree();
  386. sourceTreeOptions.value = [];
  387. const data: SourceTreeOption = { id: 0, name: '顶级节点', children: [] };
  388. data.children = proxy?.handleTree<SourceTreeOption>(res.data, 'id', 'parentId');
  389. sourceTreeOptions.value.push(data);
  390. };
  391. const handleTreeCheck = (_, { checkedKeys }) => {
  392. // 获取用户选中的节点(父节点和子节点不会关联)
  393. form.value.sourceTreeIds = checkedKeys;
  394. console.log('当前选中的文件:', form.value.sourceTreeIds);
  395. };
  396. /** 取消按钮 */
  397. const cancel = () => {
  398. reset();
  399. dialog.visible = false;
  400. videoDialogVisible.value = false;
  401. };
  402. /** 表单重置 */
  403. const reset = () => {
  404. form.value = { ...initFormData };
  405. minioDataFormRef.value?.resetFields();
  406. };
  407. /** 搜索按钮操作 */
  408. const handleQuery = () => {
  409. queryParams.value.pageNum = 1;
  410. getList();
  411. };
  412. /** 重置按钮操作 */
  413. const resetQuery = () => {
  414. queryFormRef.value?.resetFields();
  415. handleQuery();
  416. };
  417. /** 多选框选中数据 */
  418. const handleSelectionChange = (selection: MinioDataVO[]) => {
  419. ids.value = selection.map((item) => item.id);
  420. single.value = selection.length != 1;
  421. multiple.value = !selection.length;
  422. };
  423. /** 新增按钮操作 */
  424. const handleAdd = () => {
  425. reset();
  426. dialog.visible = true;
  427. dialog.title = '添加文件资源';
  428. };
  429. const handleTrans = () => {
  430. trans.visible = true;
  431. trans.title = '转码进度';
  432. getTransList();
  433. };
  434. /** 修改按钮操作 */
  435. const handleUpdate = async (row?: MinioDataVO) => {
  436. reset();
  437. const _id = row?.id || ids.value[0];
  438. const res = await getMinioData(_id);
  439. Object.assign(form.value, res.data);
  440. dialog.visible = true;
  441. dialog.title = '修改文件资源';
  442. };
  443. const handleUse = async (row?: MinioDataVO) => {
  444. const fileId = row.id;
  445. useDialog.title = '资源引用';
  446. useDialog.visible = true;
  447. dialogQueryParams.value.fileId = fileId;
  448. getItemListByFileId();
  449. };
  450. /** 提交按钮 */
  451. // 通过ref访问SmsbFileUploader实例
  452. import { ref as vueRef } from 'vue';
  453. const fileUploaderRef = vueRef();
  454. const submitForm = () => {
  455. minioDataFormRef.value?.validate(async (valid: boolean) => {
  456. if (valid) {
  457. buttonLoading.value = true;
  458. // 调用文件上传逻辑(不关闭dialog)
  459. console.log('[submitForm] 尝试调用handleUpload', fileUploaderRef.value);
  460. if (fileUploaderRef.value && typeof fileUploaderRef.value.handleUpload === 'function') {
  461. await fileUploaderRef.value.handleUpload();
  462. console.log('[submitForm] handleUpload已调用');
  463. }
  464. // 下面的逻辑可以根据需要决定是否保留
  465. // if (form.value.id) {
  466. // await updateMinioData(form.value).finally(() => (buttonLoading.value = false));
  467. // } else {
  468. // await addMinioData(form.value).finally(() => (buttonLoading.value = false));
  469. // }
  470. buttonLoading.value = false;
  471. // 强制保持弹窗不关闭
  472. dialog.visible = true;
  473. // proxy?.$modal.msgSuccess('操作成功');
  474. // dialog.visible = false;
  475. // await getList();
  476. }
  477. });
  478. };
  479. /** 删除按钮操作 */
  480. const handleDelete = async (row?: MinioDataVO) => {
  481. const _ids = row?.id || ids.value;
  482. await proxy?.$modal.confirm('是否确认删除文件资源编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
  483. await delMinioData(_ids);
  484. proxy?.$modal.msgSuccess('删除成功');
  485. await getList();
  486. };
  487. /** 导出按钮操作 */
  488. const handleExport = () => {
  489. proxy?.download(
  490. 'source/minioData/export',
  491. {
  492. ...queryParams.value
  493. },
  494. `minioData_${new Date().getTime()}.xlsx`
  495. );
  496. };
  497. const getFileStatistics = async () => {
  498. const res = await fileStatistics();
  499. console.log(res.data);
  500. totalNum.value = res.data.totalNum;
  501. imageNum.value = res.data.imageNum;
  502. videoNum.value = res.data.videoNum;
  503. otherNum.value = res.data.otherNum;
  504. };
  505. onMounted(() => {
  506. getList();
  507. getTreeselect();
  508. getFileStatistics();
  509. });
  510. </script>
  511. <style scoped>
  512. :deep(.el-card__body) {
  513. padding: 10px !important;
  514. }
  515. </style>