From 12b0575ca160b674c86166b11151a5e20c73eedb Mon Sep 17 00:00:00 2001 From: dylanmay <670374839@qq.com> Date: Mon, 15 Dec 2025 10:13:13 +0800 Subject: [PATCH] fix: resolve todo --- .../wx-material-select/wx-material-select.vue | 450 ++++++++++++------ apps/web-antd/src/views/mp/material/index.vue | 317 ++++++------ .../src/views/mp/material/modules/data.ts | 12 + .../views/mp/material/modules/image-table.vue | 123 ----- .../views/mp/material/modules/video-table.vue | 120 ----- .../views/mp/material/modules/voice-table.vue | 120 ----- .../wx-material-select/wx-material-select.vue | 438 +++++++++++------ apps/web-ele/src/views/mp/material/index.vue | 333 ++++++------- .../src/views/mp/material/modules/data.ts | 12 + .../views/mp/material/modules/image-table.vue | 124 ----- .../views/mp/material/modules/video-table.vue | 121 ----- .../views/mp/material/modules/voice-table.vue | 121 ----- 12 files changed, 978 insertions(+), 1313 deletions(-) delete mode 100644 apps/web-antd/src/views/mp/material/modules/image-table.vue delete mode 100644 apps/web-antd/src/views/mp/material/modules/video-table.vue delete mode 100644 apps/web-antd/src/views/mp/material/modules/voice-table.vue delete mode 100644 apps/web-ele/src/views/mp/material/modules/image-table.vue delete mode 100644 apps/web-ele/src/views/mp/material/modules/video-table.vue delete mode 100644 apps/web-ele/src/views/mp/material/modules/voice-table.vue diff --git a/apps/web-antd/src/views/mp/components/wx-material-select/wx-material-select.vue b/apps/web-antd/src/views/mp/components/wx-material-select/wx-material-select.vue index 1ca1417ef9..aea34aa213 100644 --- a/apps/web-antd/src/views/mp/components/wx-material-select/wx-material-select.vue +++ b/apps/web-antd/src/views/mp/components/wx-material-select/wx-material-select.vue @@ -2,7 +2,7 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { MpMaterialApi } from '#/api/mp/material'; -import { reactive, ref, watch } from 'vue'; +import { computed, watch } from 'vue'; import { Page } from '@vben/common-ui'; import { NewsType } from '@vben/constants'; @@ -34,16 +34,6 @@ const emit = defineEmits<{ (e: 'selectMaterial', item: any): void; }>(); -// TODO @dlyan @AI:这里是不是应该都用 grid; -const loading = ref(false); // 遮罩层 -const total = ref(0); // 总条数 -const list = ref([]); // 数据列表 -const queryParams = reactive({ - accountId: props.accountId, - pageNo: 1, - pageSize: 10, -}); // 查询参数 - const voiceGridColumns: VxeTableGridOptions['columns'] = [ { @@ -123,6 +113,99 @@ const videoGridColumns: VxeTableGridOptions['columns'] = }, ]; +// Image Grid +const [ImageGrid, imageGridApi] = useVbenVxeGrid({ + gridOptions: { + columns: [], + height: 'auto', + keepSource: true, + pagerConfig: { + enabled: false, + }, + proxyConfig: { + ajax: { + query: async ({ page }, { accountId }) => { + const finalAccountId = accountId ?? props.accountId; + if (!finalAccountId) { + return { list: [], total: 0 }; + } + return await getMaterialPage({ + pageNo: page.currentPage, + pageSize: page.pageSize, + accountId: finalAccountId, + type: 'image', + }); + }, + }, + autoLoad: false, + }, + rowConfig: { + keyField: 'mediaId', + isHover: true, + }, + toolbarConfig: { + enabled: false, + }, + } as VxeTableGridOptions, +}); + +// News Grid +const [NewsGrid, newsGridApi] = useVbenVxeGrid({ + gridOptions: { + columns: [], + height: 'auto', + keepSource: true, + pagerConfig: { + enabled: false, + }, + proxyConfig: { + ajax: { + query: async ({ page }, { accountId }) => { + const finalAccountId = accountId ?? props.accountId; + if (!finalAccountId) { + return { list: [], total: 0 }; + } + if (props.newsType === NewsType.Published) { + const data = await getFreePublishPage({ + accountId: finalAccountId, + pageNo: page.currentPage, + pageSize: page.pageSize, + }); + data.list.forEach((item: any) => { + const articles = item.content.newsItem; + articles.forEach((article: any) => { + article.picUrl = article.thumbUrl; + }); + }); + return data; + } else { + const data = await getDraftPage({ + accountId: finalAccountId, + pageNo: page.currentPage, + pageSize: page.pageSize, + }); + data.list.forEach((draft: any) => { + const articles = draft.content.newsItem; + articles.forEach((article: any) => { + article.picUrl = article.thumbUrl; + }); + }); + return data; + } + }, + }, + autoLoad: false, + }, + rowConfig: { + keyField: 'mediaId', + isHover: true, + }, + toolbarConfig: { + enabled: false, + }, + } as VxeTableGridOptions, +}); + const [VoiceGrid, voiceGridApi] = useVbenVxeGrid({ gridOptions: { border: true, @@ -136,7 +219,7 @@ const [VoiceGrid, voiceGridApi] = useVbenVxeGrid({ proxyConfig: { ajax: { query: async ({ page }, { accountId }) => { - const finalAccountId = accountId ?? queryParams.accountId; + const finalAccountId = accountId ?? props.accountId; if (!finalAccountId) { return { list: [], total: 0 }; } @@ -172,7 +255,7 @@ const [VideoGrid, videoGridApi] = useVbenVxeGrid({ proxyConfig: { ajax: { query: async ({ page }, { accountId }) => { - const finalAccountId = accountId ?? queryParams.accountId; + const finalAccountId = accountId ?? props.accountId; if (finalAccountId === undefined || finalAccountId === null) { return { list: [], total: 0 }; } @@ -195,91 +278,164 @@ const [VideoGrid, videoGridApi] = useVbenVxeGrid({ } as VxeTableGridOptions, }); -function selectMaterialFun(item: any) { - emit('selectMaterial', item); -} +// 从 Grid 获取数据 +const imageList = computed(() => { + try { + const tableData = imageGridApi.grid?.getTableData(); + return (tableData?.tableData as MpMaterialApi.Material[]) || []; + } catch { + return []; + } +}); -async function getMaterialPageFun() { - const data = await getMaterialPage({ - ...queryParams, - type: props.type, - }); - list.value = data.list; - total.value = data.total; -} +const imageLoading = computed(() => { + return imageGridApi.grid?.loading || false; +}); -async function getFreePublishPageFun() { - const data = await getFreePublishPage(queryParams); - data.list.forEach((item: any) => { - const articles = item.content.newsItem; - articles.forEach((article: any) => { - article.picUrl = article.thumbUrl; - }); - }); - list.value = data.list; - total.value = data.total; -} +const imageTotal = computed(() => { + try { + const proxyInfo = imageGridApi.grid?.getProxyInfo(); + return proxyInfo?.pager?.total || 0; + } catch { + return 0; + } +}); -async function getDraftPageFun() { - const data = await getDraftPage(queryParams); - data.list.forEach((draft: any) => { - const articles = draft.content.newsItem; - articles.forEach((article: any) => { - article.picUrl = article.thumbUrl; - }); - }); - list.value = data.list; - total.value = data.total; -} +const imageCurrentPage = computed({ + get: () => { + try { + return imageGridApi.grid?.pagerConfig?.currentPage || 1; + } catch { + return 1; + } + }, + set: (value: number) => { + imageGridApi.grid?.commitProxy('page', { currentPage: value }); + }, +}); -async function getPage() { - if (props.type === 'voice') { - await voiceGridApi.reload({ accountId: queryParams.accountId }); - return; - } - if (props.type === 'video') { - await videoGridApi.reload({ accountId: queryParams.accountId }); - return; +const imagePageSize = computed({ + get: () => { + try { + return imageGridApi.grid?.pagerConfig?.pageSize || 10; + } catch { + return 10; + } + }, + set: (value: number) => { + imageGridApi.grid?.commitProxy('page', { pageSize: value, currentPage: 1 }); + }, +}); + +const newsList = computed(() => { + try { + const tableData = newsGridApi.grid?.getTableData(); + return (tableData?.tableData as any[]) || []; + } catch { + return []; } +}); + +const newsLoading = computed(() => { + return newsGridApi.grid?.loading || false; +}); - loading.value = true; +const newsTotal = computed(() => { try { - if (props.type === 'news' && props.newsType === NewsType.Published) { - await getFreePublishPageFun(); - } else if (props.type === 'news' && props.newsType === NewsType.Draft) { - await getDraftPageFun(); - } else { - await getMaterialPageFun(); - } - } finally { - loading.value = false; + const proxyInfo = newsGridApi.grid?.getProxyInfo(); + return proxyInfo?.pager?.total || 0; + } catch { + return 0; } +}); + +const newsCurrentPage = computed({ + get: () => { + try { + return newsGridApi.grid?.pagerConfig?.currentPage || 1; + } catch { + return 1; + } + }, + set: (value: number) => { + newsGridApi.grid?.commitProxy('page', { currentPage: value }); + }, +}); + +const newsPageSize = computed({ + get: () => { + try { + return newsGridApi.grid?.pagerConfig?.pageSize || 10; + } catch { + return 10; + } + }, + set: (value: number) => { + newsGridApi.grid?.commitProxy('page', { pageSize: value, currentPage: 1 }); + }, +}); + +function selectMaterialFun(item: any) { + emit('selectMaterial', item); } +// 监听 accountId 变化 watch( () => props.accountId, (accountId) => { - queryParams.accountId = accountId; - queryParams.pageNo = 1; - getPage(); + switch (props.type) { + case 'image': { + imageGridApi.reload({ accountId }); + break; + } + case 'news': { + newsGridApi.reload({ accountId }); + break; + } + case 'video': { + videoGridApi.reload({ accountId }); + break; + } + case 'voice': { + voiceGridApi.reload({ accountId }); + break; + } + } }, { immediate: true }, ); +// 监听 type 变化 watch( () => props.type, () => { - queryParams.pageNo = 1; - getPage(); + switch (props.type) { + case 'image': { + imageGridApi.reload({ accountId: props.accountId }); + break; + } + case 'news': { + newsGridApi.reload({ accountId: props.accountId }); + break; + } + case 'video': { + videoGridApi.reload({ accountId: props.accountId }); + break; + } + case 'voice': { + voiceGridApi.reload({ accountId: props.accountId }); + break; + } + } }, ); +// 监听 newsType 变化 watch( () => props.newsType, () => { if (props.type === 'news') { - queryParams.pageNo = 1; - getPage(); + newsGridApi.reload({ accountId: props.accountId }); } }, ); @@ -289,42 +445,47 @@ watch( @@ -363,37 +524,52 @@ watch( + + diff --git a/apps/web-antd/src/views/mp/material/index.vue b/apps/web-antd/src/views/mp/material/index.vue index 7f82c79307..94faddf396 100644 --- a/apps/web-antd/src/views/mp/material/index.vue +++ b/apps/web-antd/src/views/mp/material/index.vue @@ -1,79 +1,120 @@ - - diff --git a/apps/web-antd/src/views/mp/material/modules/video-table.vue b/apps/web-antd/src/views/mp/material/modules/video-table.vue deleted file mode 100644 index 22803b3016..0000000000 --- a/apps/web-antd/src/views/mp/material/modules/video-table.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/mp/material/modules/voice-table.vue b/apps/web-antd/src/views/mp/material/modules/voice-table.vue deleted file mode 100644 index 2d114afec4..0000000000 --- a/apps/web-antd/src/views/mp/material/modules/voice-table.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/mp/components/wx-material-select/wx-material-select.vue b/apps/web-ele/src/views/mp/components/wx-material-select/wx-material-select.vue index b73f369432..418341fa6a 100644 --- a/apps/web-ele/src/views/mp/components/wx-material-select/wx-material-select.vue +++ b/apps/web-ele/src/views/mp/components/wx-material-select/wx-material-select.vue @@ -2,7 +2,7 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { MpMaterialApi } from '#/api/mp/material'; -import { reactive, ref, watch } from 'vue'; +import { computed, watch } from 'vue'; import { NewsType } from '@vben/constants'; import { IconifyIcon } from '@vben/icons'; @@ -33,16 +33,6 @@ const emit = defineEmits<{ (e: 'selectMaterial', item: any): void; }>(); -const loading = ref(false); // 遮罩层 -const total = ref(0); // 总条数 -const list = ref([]); // 数据列表 -// TODO @dlyan @AI:这里是不是应该都用 grid; -const queryParams = reactive({ - accountId: props.accountId, - pageNo: 1, - pageSize: 10, -}); // 查询参数 - const voiceGridColumns: VxeTableGridOptions['columns'] = [ { @@ -122,6 +112,99 @@ const videoGridColumns: VxeTableGridOptions['columns'] = }, ]; +// Image Grid +const [ImageGrid, imageGridApi] = useVbenVxeGrid({ + gridOptions: { + columns: [], + height: 'auto', + keepSource: true, + pagerConfig: { + enabled: false, + }, + proxyConfig: { + ajax: { + query: async ({ page }, { accountId }) => { + const finalAccountId = accountId ?? props.accountId; + if (!finalAccountId) { + return { list: [], total: 0 }; + } + return await getMaterialPage({ + pageNo: page.currentPage, + pageSize: page.pageSize, + accountId: finalAccountId, + type: 'image', + }); + }, + }, + autoLoad: false, + }, + rowConfig: { + keyField: 'mediaId', + isHover: true, + }, + toolbarConfig: { + enabled: false, + }, + } as VxeTableGridOptions, +}); + +// News Grid +const [NewsGrid, newsGridApi] = useVbenVxeGrid({ + gridOptions: { + columns: [], + height: 'auto', + keepSource: true, + pagerConfig: { + enabled: false, + }, + proxyConfig: { + ajax: { + query: async ({ page }, { accountId }) => { + const finalAccountId = accountId ?? props.accountId; + if (!finalAccountId) { + return { list: [], total: 0 }; + } + if (props.newsType === NewsType.Published) { + const data = await getFreePublishPage({ + accountId: finalAccountId, + pageNo: page.currentPage, + pageSize: page.pageSize, + }); + data.list.forEach((item: any) => { + const articles = item.content.newsItem; + articles.forEach((article: any) => { + article.picUrl = article.thumbUrl; + }); + }); + return data; + } else { + const data = await getDraftPage({ + accountId: finalAccountId, + pageNo: page.currentPage, + pageSize: page.pageSize, + }); + data.list.forEach((draft: any) => { + const articles = draft.content.newsItem; + articles.forEach((article: any) => { + article.picUrl = article.thumbUrl; + }); + }); + return data; + } + }, + }, + autoLoad: false, + }, + rowConfig: { + keyField: 'mediaId', + isHover: true, + }, + toolbarConfig: { + enabled: false, + }, + } as VxeTableGridOptions, +}); + const [VoiceGrid, voiceGridApi] = useVbenVxeGrid({ gridOptions: { border: true, @@ -135,7 +218,7 @@ const [VoiceGrid, voiceGridApi] = useVbenVxeGrid({ proxyConfig: { ajax: { query: async ({ page }, { accountId }) => { - const finalAccountId = accountId ?? queryParams.accountId; + const finalAccountId = accountId ?? props.accountId; if (!finalAccountId) { return { list: [], total: 0 }; } @@ -171,7 +254,7 @@ const [VideoGrid, videoGridApi] = useVbenVxeGrid({ proxyConfig: { ajax: { query: async ({ page }, { accountId }) => { - const finalAccountId = accountId ?? queryParams.accountId; + const finalAccountId = accountId ?? props.accountId; if (finalAccountId === undefined || finalAccountId === null) { return { list: [], total: 0 }; } @@ -194,91 +277,164 @@ const [VideoGrid, videoGridApi] = useVbenVxeGrid({ } as VxeTableGridOptions, }); -function selectMaterialFun(item: any) { - emit('selectMaterial', item); -} +// 从 Grid 获取数据 +const imageList = computed(() => { + try { + const tableData = imageGridApi.grid?.getTableData(); + return (tableData?.tableData as MpMaterialApi.Material[]) || []; + } catch { + return []; + } +}); -async function getMaterialPageFun() { - const data = await getMaterialPage({ - ...queryParams, - type: props.type, - }); - list.value = data.list; - total.value = data.total; -} +const imageLoading = computed(() => { + return imageGridApi.grid?.loading || false; +}); -async function getFreePublishPageFun() { - const data = await getFreePublishPage(queryParams); - data.list.forEach((item: any) => { - const articles = item.content.newsItem; - articles.forEach((article: any) => { - article.picUrl = article.thumbUrl; - }); - }); - list.value = data.list; - total.value = data.total; -} +const imageTotal = computed(() => { + try { + const proxyInfo = imageGridApi.grid?.getProxyInfo(); + return proxyInfo?.pager?.total || 0; + } catch { + return 0; + } +}); -async function getDraftPageFun() { - const data = await getDraftPage(queryParams); - data.list.forEach((draft: any) => { - const articles = draft.content.newsItem; - articles.forEach((article: any) => { - article.picUrl = article.thumbUrl; - }); - }); - list.value = data.list; - total.value = data.total; -} +const imageCurrentPage = computed({ + get: () => { + try { + return imageGridApi.grid?.pagerConfig?.currentPage || 1; + } catch { + return 1; + } + }, + set: (value: number) => { + imageGridApi.grid?.commitProxy('page', { currentPage: value }); + }, +}); -async function getPage() { - if (props.type === 'voice') { - await voiceGridApi.reload({ accountId: queryParams.accountId }); - return; - } - if (props.type === 'video') { - await videoGridApi.reload({ accountId: queryParams.accountId }); - return; +const imagePageSize = computed({ + get: () => { + try { + return imageGridApi.grid?.pagerConfig?.pageSize || 10; + } catch { + return 10; + } + }, + set: (value: number) => { + imageGridApi.grid?.commitProxy('page', { pageSize: value, currentPage: 1 }); + }, +}); + +const newsList = computed(() => { + try { + const tableData = newsGridApi.grid?.getTableData(); + return (tableData?.tableData as any[]) || []; + } catch { + return []; } +}); - loading.value = true; +const newsLoading = computed(() => { + return newsGridApi.grid?.loading || false; +}); + +const newsTotal = computed(() => { try { - if (props.type === 'news' && props.newsType === NewsType.Published) { - await getFreePublishPageFun(); - } else if (props.type === 'news' && props.newsType === NewsType.Draft) { - await getDraftPageFun(); - } else { - await getMaterialPageFun(); - } - } finally { - loading.value = false; + const proxyInfo = newsGridApi.grid?.getProxyInfo(); + return proxyInfo?.pager?.total || 0; + } catch { + return 0; } +}); + +const newsCurrentPage = computed({ + get: () => { + try { + return newsGridApi.grid?.pagerConfig?.currentPage || 1; + } catch { + return 1; + } + }, + set: (value: number) => { + newsGridApi.grid?.commitProxy('page', { currentPage: value }); + }, +}); + +const newsPageSize = computed({ + get: () => { + try { + return newsGridApi.grid?.pagerConfig?.pageSize || 10; + } catch { + return 10; + } + }, + set: (value: number) => { + newsGridApi.grid?.commitProxy('page', { pageSize: value, currentPage: 1 }); + }, +}); + +function selectMaterialFun(item: any) { + emit('selectMaterial', item); } +// 监听 accountId 变化 watch( () => props.accountId, (accountId) => { - queryParams.accountId = accountId; - queryParams.pageNo = 1; - getPage(); + switch (props.type) { + case 'image': { + imageGridApi.reload({ accountId }); + break; + } + case 'news': { + newsGridApi.reload({ accountId }); + break; + } + case 'video': { + videoGridApi.reload({ accountId }); + break; + } + case 'voice': { + voiceGridApi.reload({ accountId }); + break; + } + } }, { immediate: true }, ); +// 监听 type 变化 watch( () => props.type, () => { - queryParams.pageNo = 1; - getPage(); + switch (props.type) { + case 'image': { + imageGridApi.reload({ accountId: props.accountId }); + break; + } + case 'news': { + newsGridApi.reload({ accountId: props.accountId }); + break; + } + case 'video': { + videoGridApi.reload({ accountId: props.accountId }); + break; + } + case 'voice': { + voiceGridApi.reload({ accountId: props.accountId }); + break; + } + } }, ); +// 监听 newsType 变化 watch( () => props.newsType, () => { if (props.type === 'news') { - queryParams.pageNo = 1; - getPage(); + newsGridApi.reload({ accountId: props.accountId }); } }, ); @@ -287,38 +443,41 @@ watch( + + diff --git a/apps/web-ele/src/views/mp/material/index.vue b/apps/web-ele/src/views/mp/material/index.vue index 7edcfb3967..d7753ca1a2 100644 --- a/apps/web-ele/src/views/mp/material/index.vue +++ b/apps/web-ele/src/views/mp/material/index.vue @@ -1,5 +1,8 @@ - - - - - - - -
- -
- - + + + + + + + + + + + + + + + + + + diff --git a/apps/web-ele/src/views/mp/material/modules/data.ts b/apps/web-ele/src/views/mp/material/modules/data.ts index cab6f251e0..cd3e07ac1b 100644 --- a/apps/web-ele/src/views/mp/material/modules/data.ts +++ b/apps/web-ele/src/views/mp/material/modules/data.ts @@ -1,3 +1,4 @@ +import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { MpMaterialApi } from '#/api/mp/material'; @@ -131,3 +132,14 @@ export function useImageGridColumns(): VxeTableGridOptions -import type { MpMaterialApi } from '#/api/mp/material'; - -import { nextTick, onMounted, watch } from 'vue'; - -import { $t } from '@vben/locales'; - -import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; - -import { useImageGridColumns } from './data'; - -const props = defineProps<{ - list: MpMaterialApi.Material[]; - loading: boolean; -}>(); - -const emit = defineEmits<{ - delete: [v: number]; - refresh: []; -}>(); - -const columns = useImageGridColumns(); - -const [Grid, gridApi] = useVbenVxeGrid({ - gridOptions: { - border: true, - columns, - keepSource: true, - pagerConfig: { - enabled: false, - }, - rowConfig: { - keyField: 'id', - isHover: true, - height: 220, - }, - toolbarConfig: { - refresh: true, - }, - showOverflow: 'tooltip', - proxyConfig: { - ajax: { - query: async () => { - // 数据由父组件管理,触发刷新事件后返回当前数据 - emit('refresh'); - // 返回当前数据,避免覆盖 - return { - list: Array.isArray(props.list) ? props.list : [], - total: props.list?.length || 0, - }; - }, - }, - enabled: true, - autoLoad: false, - }, - }, -}); - -function updateGridData(data: MpMaterialApi.Material[]) { - if (gridApi.grid?.loadData) { - gridApi.grid.loadData(data); - } else { - gridApi.setGridOptions({ data }); - } -} - -watch( - () => props.list, - async (list: MpMaterialApi.Material[]) => { - const data = Array.isArray(list) ? list : []; - await nextTick(); - updateGridData(data); - }, - { immediate: true, flush: 'post' }, -); - -watch( - () => props.loading, - (loading: boolean) => { - gridApi.setLoading(loading); - }, -); - -/** 初始化 */ -onMounted(async () => { - await nextTick(); - updateGridData(Array.isArray(props.list) ? props.list : []); - gridApi.setLoading(props.loading); -}); - - - diff --git a/apps/web-ele/src/views/mp/material/modules/video-table.vue b/apps/web-ele/src/views/mp/material/modules/video-table.vue deleted file mode 100644 index 180c1fcb95..0000000000 --- a/apps/web-ele/src/views/mp/material/modules/video-table.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/mp/material/modules/voice-table.vue b/apps/web-ele/src/views/mp/material/modules/voice-table.vue deleted file mode 100644 index 8d32d5bd85..0000000000 --- a/apps/web-ele/src/views/mp/material/modules/voice-table.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - -- Gitee