Files
yudao-ui-admin-vben/apps/web-antd/src/views/mp/material/components/VoiceTable.vue

139 lines
3.1 KiB
Vue
Raw Normal View History

2025-11-04 17:32:12 +08:00
<script lang="ts" setup>
2025-11-07 13:21:42 +08:00
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import { watch } from 'vue';
2025-11-04 17:32:12 +08:00
import { useAccess } from '@vben/access';
import { IconifyIcon } from '@vben/icons';
import { formatDate2 } from '@vben/utils';
2025-11-07 13:21:42 +08:00
import { Button } from 'ant-design-vue';
2025-11-06 15:25:11 +08:00
2025-11-07 13:21:42 +08:00
import { useVbenVxeGrid } from '#/adapter/vxe-table';
2025-11-06 15:36:08 +08:00
import { WxVoicePlayer } from '#/views/mp/components/wx-voice-play';
2025-11-04 17:32:12 +08:00
// TODO @dylanvue 组件名小写 + 中划线
// TODO @dylan组件内尽量用 modules 哈。只有对外共享,才用 components
2025-11-04 17:32:12 +08:00
const props = defineProps<{
list: any[];
loading: boolean;
}>();
const emit = defineEmits<{
delete: [v: number];
}>();
const { hasAccessByCodes } = useAccess();
// TODO @dylan这里有个告警哈
// TODO @dylan放到 data.ts 里;
2025-11-07 13:21:42 +08:00
const columns: VxeTableGridOptions<any>['columns'] = [
2025-11-06 15:25:11 +08:00
{
2025-11-07 13:21:42 +08:00
field: 'mediaId',
2025-11-06 15:25:11 +08:00
title: '编号',
2025-11-07 13:21:42 +08:00
align: 'center',
width: 160,
},
{
field: 'name',
title: '文件名',
align: 'center',
minWidth: 200,
2025-11-06 15:25:11 +08:00
},
// TODO @dylan语音的样式有点奇怪。
2025-11-06 15:25:11 +08:00
{
2025-11-07 13:21:42 +08:00
field: 'voice',
title: '语音',
align: 'center',
width: 220,
slots: { default: 'voice' },
},
{
field: 'createTime',
2025-11-06 15:25:11 +08:00
title: '上传时间',
2025-11-07 13:21:42 +08:00
align: 'center',
2025-11-06 15:25:11 +08:00
width: 180,
2025-11-07 13:21:42 +08:00
slots: { default: 'createTime' },
2025-11-06 15:25:11 +08:00
},
{
2025-11-07 13:21:42 +08:00
field: 'actions',
2025-11-06 15:25:11 +08:00
title: '操作',
2025-11-07 13:21:42 +08:00
align: 'center',
fixed: 'right',
width: 160,
slots: { default: 'actions' },
2025-11-06 15:25:11 +08:00
},
2025-11-04 17:32:12 +08:00
];
2025-11-07 13:21:42 +08:00
const [Grid, gridApi] = useVbenVxeGrid({
gridOptions: {
border: true,
columns,
keepSource: true,
pagerConfig: {
enabled: false,
},
rowConfig: {
keyField: 'id',
isHover: true,
},
showOverflow: 'tooltip',
} as VxeTableGridOptions<any>, // TODO @dylan这里有个告警哈
2025-11-07 13:21:42 +08:00
});
2025-11-06 23:23:25 +08:00
function handleDownload(url: string) {
2025-11-04 17:32:12 +08:00
window.open(url, '_blank');
2025-11-06 23:23:25 +08:00
}
2025-11-07 13:21:42 +08:00
watch(
() => props.list,
(list: any[]) => {
const data = Array.isArray(list) ? list : [];
if (gridApi.grid?.loadData) {
gridApi.grid.loadData(data);
} else {
gridApi.setGridOptions({ data });
}
},
{ immediate: true },
);
watch(
() => props.loading,
(loading: boolean) => {
gridApi.setLoading(loading);
2025-11-07 13:21:42 +08:00
},
{ immediate: true },
);
2025-11-04 17:32:12 +08:00
</script>
<template>
2025-11-07 13:21:42 +08:00
<Grid class="mt-4">
<template #voice="{ row }">
<WxVoicePlayer v-if="row.url" :url="row.url" />
</template>
<!-- TODO @dylan应该 data.ts formatDate 就好了别的模块有的哈 -->
2025-11-07 13:21:42 +08:00
<template #createTime="{ row }">
{{ formatDate2(row.createTime) }}
</template>
<template #actions="{ row }">
<!-- TODO @dylan tableaction yudao-ui-admin-vben-v5/apps/web-antd/src/views/system/user/index.vue -->
2025-11-07 13:21:42 +08:00
<Button type="link" @click="handleDownload(row.url)">
<IconifyIcon icon="mdi:download" />
下载
</Button>
<Button
v-if="hasAccessByCodes(['mp:material:delete'])"
danger
type="link"
@click="emit('delete', row.id)"
>
<IconifyIcon icon="mdi:delete" />
删除
</Button>
2025-11-04 17:32:12 +08:00
</template>
2025-11-07 13:21:42 +08:00
</Grid>
2025-11-04 17:32:12 +08:00
</template>