review:【mall 商城】product 相关代码

pull/209/head
YunaiV 2025-09-02 19:41:18 +08:00
parent 160846b665
commit d0457b4e4b
12 changed files with 49 additions and 20 deletions

View File

@ -1,2 +1,3 @@
// TODO @xingyu【待讨论】是不是把 user select 放到 user 目录的 components 下dept select 放到 dept 目录的 components 下
export { default as DeptSelectModal } from './dept-select-modal.vue'; export { default as DeptSelectModal } from './dept-select-modal.vue';
export { default as UserSelectModal } from './user-select-modal.vue'; export { default as UserSelectModal } from './user-select-modal.vue';

View File

@ -44,6 +44,7 @@ function handleEdit(row: MallCategoryApi.Category) {
/** 查看商品操作 */ /** 查看商品操作 */
const router = useRouter(); // const router = useRouter(); //
const handleViewSpu = (id: number) => { const handleViewSpu = (id: number) => {
// TODO @xingyu
router.push({ router.push({
name: 'ProductSpu', name: 'ProductSpu',
query: { categoryId: id }, query: { categoryId: id },
@ -165,8 +166,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
type: 'link', type: 'link',
icon: ACTION_ICON.VIEW, icon: ACTION_ICON.VIEW,
auth: ['product:category:update'], auth: ['product:category:update'],
ifShow: row.parentId > 0, ifShow: row.parentId !== undefined && row.parentId > 0,
onClick: handleViewSpu.bind(null, row), onClick: handleViewSpu.bind(null, row.id!),
}, },
{ {
label: $t('common.delete'), label: $t('common.delete'),

View File

@ -111,6 +111,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
} }
/** 表格列配置 */ /** 表格列配置 */
// TODO @xingyu列表的宽度需要优化下样式~
export function useGridColumns<T = MallCommentApi.Comment>( export function useGridColumns<T = MallCommentApi.Comment>(
onStatusChange?: ( onStatusChange?: (
newStatus: boolean, newStatus: boolean,

View File

@ -2,8 +2,9 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MallSpuApi } from '#/api/mall/product/spu'; import type { MallSpuApi } from '#/api/mall/product/spu';
// TODO @xingyu mall search xxx
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { confirm, DocAlert, Page } from '@vben/common-ui'; import { confirm, DocAlert, Page } from '@vben/common-ui';
import { import {
@ -30,6 +31,7 @@ import { ProductSpuStatusEnum } from '#/utils';
import { useGridColumns, useGridFormSchema } from './data'; import { useGridColumns, useGridFormSchema } from './data';
const { push } = useRouter(); const { push } = useRouter();
const route = useRoute(); //
const tabType = ref(0); const tabType = ref(0);
const categoryList = ref(); const categoryList = ref();
@ -64,8 +66,9 @@ const tabsData = ref([
]); ]);
/** 刷新表格 */ /** 刷新表格 */
function onRefresh() { async function onRefresh() {
gridApi.query(); await gridApi.query();
await getTabCount();
} }
/** 获得每个 Tab 的数量 */ /** 获得每个 Tab 的数量 */
@ -124,7 +127,7 @@ async function handleStatus02Change(row: MallSpuApi.Spu, newStatus: number) {
.then(async () => { .then(async () => {
await updateStatus({ id: row.id as number, status: newStatus }); await updateStatus({ id: row.id as number, status: newStatus });
message.success(`${text}成功`); message.success(`${text}成功`);
onRefresh(); await onRefresh();
}) })
.catch(() => { .catch(() => {
message.error(`${text}失败`); message.error(`${text}失败`);
@ -209,11 +212,16 @@ function onChangeTab(key: any) {
gridApi.query(); gridApi.query();
} }
onMounted(() => { onMounted(async () => {
getTabCount(); // categoryId
getCategoryList({}).then((res) => { if (route.query.categoryId) {
categoryList.value = handleTree(res, 'id', 'parentId', 'children'); await gridApi.formApi.setValues({
categoryId: Number(route.query.categoryId),
}); });
}
await getTabCount();
const categoryRes = await getCategoryList({});
categoryList.value = handleTree(categoryRes, 'id', 'parentId', 'children');
}); });
</script> </script>
@ -228,6 +236,7 @@ onMounted(() => {
<Grid> <Grid>
<template #top> <template #top>
<!-- TODO @xingyutabs 可以考虑往上以一些和操作按钮在一排 -->
<Tabs class="border-none" @change="onChangeTab"> <Tabs class="border-none" @change="onChangeTab">
<Tabs.TabPane <Tabs.TabPane
v-for="item in tabsData" v-for="item in tabsData"
@ -257,6 +266,7 @@ onMounted(() => {
/> />
</template> </template>
<template #expand_content="{ row }"> <template #expand_content="{ row }">
<!-- TODO @xingyu展开的样子有点丑 -->
<Descriptions <Descriptions
:column="4" :column="4"
class="mt-4" class="mt-4"

View File

@ -1,3 +1,6 @@
<script lang="ts" setup></script> <script lang="ts" setup></script>
<template>detail</template> <template>
detail
<!-- TODO @xingyu待开发 -->
</template>

View File

@ -1,3 +1,6 @@
<script lang="ts" setup></script> <script lang="ts" setup></script>
<template>form</template> <template>
form
<!-- TODO @xingyu待开发 -->
</template>

View File

@ -166,7 +166,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
icon: ACTION_ICON.VIEW, icon: ACTION_ICON.VIEW,
auth: ['product:category:update'], auth: ['product:category:update'],
ifShow: row.parentId !== undefined && row.parentId > 0, ifShow: row.parentId !== undefined && row.parentId > 0,
onClick: handleViewSpu.bind(null, row.id || 0), onClick: handleViewSpu.bind(null, row.id!),
}, },
{ {
label: $t('common.delete'), label: $t('common.delete'),

View File

@ -27,6 +27,7 @@ export function useFormSchema(): VbenFormSchema[] {
}, },
rules: 'required', rules: 'required',
}, },
// TODO @霖:用户头像,有点丑,多了一层
{ {
fieldName: 'userAvatar', fieldName: 'userAvatar',
label: '用户头像', label: '用户头像',
@ -45,6 +46,7 @@ export function useFormSchema(): VbenFormSchema[] {
component: 'Textarea', component: 'Textarea',
rules: 'required', rules: 'required',
}, },
// TODO @霖:星级缺了;
{ {
fieldName: 'descriptionScores', fieldName: 'descriptionScores',
label: '描述星级', label: '描述星级',
@ -57,6 +59,7 @@ export function useFormSchema(): VbenFormSchema[] {
component: 'Rate', component: 'Rate',
rules: 'required', rules: 'required',
}, },
// TODO @霖:评价图片,有点丑,多了一层
{ {
fieldName: 'picUrls', fieldName: 'picUrls',
label: '评论图片', label: '评论图片',
@ -111,6 +114,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
} }
/** 表格列配置 */ /** 表格列配置 */
// TODO @霖:列表的宽度需要优化下,样式~
export function useGridColumns<T = MallCommentApi.Comment>( export function useGridColumns<T = MallCommentApi.Comment>(
onStatusChange?: ( onStatusChange?: (
newStatus: boolean, newStatus: boolean,

View File

@ -59,6 +59,7 @@ function handleReply(row: MallCommentApi.Comment) {
} }
/** 更新状态 */ /** 更新状态 */
// TODO @
async function handleStatusChange( async function handleStatusChange(
newStatus: boolean, newStatus: boolean,
row: MallCommentApi.Comment, row: MallCommentApi.Comment,

View File

@ -7,6 +7,8 @@ import { handleTree } from '@vben/utils';
import { getCategoryList } from '#/api/mall/product/category'; import { getCategoryList } from '#/api/mall/product/category';
import { getRangePickerDefaultProps } from '#/utils'; import { getRangePickerDefaultProps } from '#/utils';
// TODO @霖:所有 mall 的 search 少了,请输入 xxx表单也是类似
/** 列表的搜索表单 */ /** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] { export function useGridFormSchema(): VbenFormSchema[] {
return [ return [

View File

@ -65,7 +65,7 @@ const tabsData = ref([
/** 刷新表格 */ /** 刷新表格 */
async function onRefresh() { async function onRefresh() {
gridApi.query(); await gridApi.query();
await getTabCount(); await getTabCount();
} }
@ -105,7 +105,7 @@ async function handleDelete(row: MallSpuApi.Spu) {
try { try {
await deleteSpu(row.id as number); await deleteSpu(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name])); ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh(); await onRefresh();
} finally { } finally {
hideLoading.close(); hideLoading.close();
} }
@ -121,7 +121,7 @@ async function handleStatus02Change(row: MallSpuApi.Spu, newStatus: number) {
await confirm(`确认要"${row.name}"${text}吗?`); await confirm(`确认要"${row.name}"${text}吗?`);
await updateStatus({ id: row.id as number, status: newStatus }); await updateStatus({ id: row.id as number, status: newStatus });
ElMessage.success(`${text}成功`); ElMessage.success(`${text}成功`);
onRefresh(); await onRefresh();
} }
/** 更新状态 */ /** 更新状态 */
@ -205,13 +205,13 @@ function onChangeTab(key: any) {
onMounted(async () => { onMounted(async () => {
// categoryId // categoryId
if (route.query.categoryId) { if (route.query.categoryId) {
gridApi.formApi.setValues({ await gridApi.formApi.setValues({
categoryId: Number(route.query.categoryId), categoryId: Number(route.query.categoryId),
}); });
} }
await getTabCount(); await getTabCount();
const res = await getCategoryList({}); const categoryRes = await getCategoryList({});
categoryList.value = handleTree(res, 'id', 'parentId', 'children'); categoryList.value = handleTree(categoryRes, 'id', 'parentId', 'children');
}); });
</script> </script>
@ -226,6 +226,7 @@ onMounted(async () => {
<Grid> <Grid>
<template #top> <template #top>
<!-- TODO @xingyutabs 可以考虑往上以一些和操作按钮在一排 -->
<ElTabs class="border-none" @tab-change="onChangeTab"> <ElTabs class="border-none" @tab-change="onChangeTab">
<ElTabs.TabPane <ElTabs.TabPane
v-for="item in tabsData" v-for="item in tabsData"
@ -255,6 +256,7 @@ onMounted(async () => {
]" ]"
/> />
</template> </template>
<!-- TODO @展开的样子不展示信息 -->
<template #expand_content="{ row }"> <template #expand_content="{ row }">
<ElDescriptions <ElDescriptions
:column="4" :column="4"

View File

@ -143,6 +143,7 @@ onMounted(async () => {
</script> </script>
<template> <template>
<!-- TODO @样式有点丑要不照 vue3 + element-plus 在优化下 -->
<Page :auto-content-height="true"> <Page :auto-content-height="true">
<ElTabs v-model="activeTab"> <ElTabs v-model="activeTab">
<ElTabPane label="基础设置" name="info"> <ElTabPane label="基础设置" name="info">