review:【antd】【mp】material、message 的迁移 v2

This commit is contained in:
YunaiV
2025-11-13 20:31:46 +08:00
parent 80bb508e78
commit e092ec737e
10 changed files with 27 additions and 5 deletions

View File

@@ -189,10 +189,7 @@
],
"github.copilot.enable": {
"*": true,
"markdown": true,
"plaintext": false,
"yaml": false
"*": false
},
"cssVariables.lookupFiles": ["packages/core/base/design/src/**/*.css"],

View File

@@ -290,6 +290,7 @@ watch(
<template>
<Page :bordered="false" class="pb-8">
<!-- 类型image -->
<!-- TODO @dylan看看图片的小卡片是不是可以整齐点类似微信公众号图片的高度是一致的哈https://mp.weixin.qq.com/cgi-bin/filepage?type=2&begin=0&count=12&token=1646383362&lang=zh_CN -->
<template v-if="props.type === 'image'">
<Spin :spinning="loading">
<div class="waterfall">

View File

@@ -137,6 +137,7 @@ function selectMaterial(item: any) {
</Button>
</div>
</div>
<!-- TODO @dylan这里应该不是图片哇 -->
<Modal
v-model:open="showDialog"
title="选择图片"
@@ -152,6 +153,7 @@ function selectMaterial(item: any) {
</Modal>
</Col>
<Col :span="18">
<!-- TODO @dylaninput 两个之间的间距可以调整下现在和左侧的图片距离有点远了 -->
<div class="input-group">
<Input
:value="reply.title || undefined"

View File

@@ -56,6 +56,7 @@ export const useBeforeUpload = (type: UploadType, maxSizeMB?: number) => {
const finalMaxSize = maxSizeMB ?? config.maxSizeMB;
// 格式不正确
// TODO @dylan貌似没国际化
if (!config.allowTypes.includes(rawFile.type)) {
message.error($t('mp.upload.invalidFormat', [config.name]));
return false;

View File

@@ -23,6 +23,7 @@ const { hasAccessByCodes } = useAccess();
<div class="waterfall">
<div v-for="item in props.list" :key="item.id" class="waterfall-item">
<a :href="item.url" target="_blank">
<!-- TODO @dylan要不用 Image 组件 -->
<img :src="item.url" class="material-img" />
<div class="item-name">{{ item.name }}</div>
</a>

View File

@@ -25,6 +25,8 @@ const emit = defineEmits<{
const { hasAccessByCodes } = useAccess();
// TODO @dylan这里有个告警哈
// TODO @dylan放到 data.ts 里;
const columns: VxeTableGridOptions<any>['columns'] = [
{
field: 'mediaId',
@@ -50,6 +52,7 @@ const columns: VxeTableGridOptions<any>['columns'] = [
align: 'center',
minWidth: 220,
},
// TODO @dylan视频的样式有点奇怪。
{
field: 'video',
title: '视频',
@@ -87,7 +90,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
isHover: true,
},
showOverflow: 'tooltip',
} as VxeTableGridOptions<any>, // TODO @dylan这里有个告警哈
} as VxeTableGridOptions<any>, // TODO @dylan这里有个告警哈
});
function handleDownload(url: string) {
@@ -121,9 +124,11 @@ watch(
<template #video="{ row }">
<WxVideoPlayer v-if="row.url" :url="row.url" />
</template>
<!-- TODO @dylan应该 data.ts formatDate 就好了别的模块有的哈 -->
<template #createTime="{ row }">
{{ formatDate2(row.createTime) }}
</template>
<!-- TODO @dylan tableaction yudao-ui-admin-vben-v5/apps/web-antd/src/views/system/user/index.vue -->
<template #actions="{ row }">
<Button type="link" @click="handleDownload(row.url)">
<IconifyIcon icon="mdi:download" />

View File

@@ -14,6 +14,8 @@ import { WxVoicePlayer } from '#/views/mp/components/wx-voice-play';
// TODO @dylanvue 组件名小写 + 中划线
// TODO @dylan组件内尽量用 modules 哈。只有对外共享,才用 components
const props = defineProps<{
list: any[];
loading: boolean;
@@ -25,6 +27,8 @@ const emit = defineEmits<{
const { hasAccessByCodes } = useAccess();
// TODO @dylan这里有个告警哈
// TODO @dylan放到 data.ts 里;
const columns: VxeTableGridOptions<any>['columns'] = [
{
field: 'mediaId',
@@ -38,6 +42,7 @@ const columns: VxeTableGridOptions<any>['columns'] = [
align: 'center',
minWidth: 200,
},
// TODO @dylan语音的样式有点奇怪。
{
field: 'voice',
title: '语音',
@@ -109,10 +114,12 @@ watch(
<template #voice="{ row }">
<WxVoicePlayer v-if="row.url" :url="row.url" />
</template>
<!-- TODO @dylan应该 data.ts formatDate 就好了别的模块有的哈 -->
<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 -->
<Button type="link" @click="handleDownload(row.url)">
<IconifyIcon icon="mdi:download" />
下载

View File

@@ -85,6 +85,7 @@ function onTabChange() {
/** 处理删除操作 */
async function handleDelete(id: number) {
// TODO @dylan参考别的模块的 dylan 哈;
Modal.confirm({
content: '此操作将永久删除该文件, 是否继续?',
title: '提示',
@@ -98,6 +99,7 @@ async function handleDelete(id: number) {
</script>
<template>
<!-- TODO @dylan这里不太对哈应该是 doc-alert 展示文档 -->
<Page
description="公众号素材"
doc-link="https://doc.iocoder.cn/mp/material/"
@@ -144,6 +146,7 @@ async function handleDelete(id: number) {
</div>
</Tabs.TabPane>
<!-- TODO @dylan语音和视频的 tab 有了两个外框需要优化下 -->
<!-- tab 2语音 -->
<Tabs.TabPane :key="UploadType.Voice">
<template #tab>
@@ -190,6 +193,7 @@ async function handleDelete(id: number) {
新建视频
</Button>
<!-- 新建视频的弹窗 -->
<!-- TODO @dlyan是不是用 Modal 自带的 api 就好啦modal.open 哪个 -->
<UploadVideo v-model:open="showCreateVideo" @uploaded="getList" />
<!-- 列表 -->
<VideoTable :list="list" :loading="loading" @delete="handleDelete" />

View File

@@ -30,6 +30,7 @@ const loading = ref(false);
const total = ref(0); // 数据的总页数
const list = ref<any[]>([]); // 当前页的列表数据
// TODO @dylan是不是参考别的模块简化哈。尽量使用 Grid
const queryParams = reactive<{
accountId: number;
createTime: [Dayjs, Dayjs] | undefined;
@@ -166,6 +167,7 @@ function showTotal(total: number) {
<!-- 列表 -->
<div class="flex-1 rounded-lg bg-white p-4">
<!-- TODO @dylan Grid -->
<MessageTable :list="list" :loading="loading" @send="handleSend" />
<div v-show="total > 0" class="mt-4 flex justify-end">
<a-pagination

View File

@@ -163,8 +163,10 @@ function selectMaterial(item: any) {
<!-- 选择素材 -->
<Col :span="12">
<Button type="primary" @click="showDialog = true">
<!-- TODO @dylanIconifyIcon 里的 icon 尽量用中立的例如说lucide 开头的这样 el 项目继续复用 -->
素材库选择 <IconifyIcon icon="ep:circle-check" />
</Button>
<!-- TODO @dylan貌似 modal 打开后列表长度无限延伸 -->
<Modal
title="选择视频"
v-model:open="showDialog"