From 1b3e2eef812b6f5e55c40eb2cc8b8fadbc6af4d7 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Sat, 7 Jun 2025 11:53:32 +0800 Subject: [PATCH] feat: mall comment --- apps/web-antd/src/api/mall/product/comment.ts | 10 +- .../src/views/mall/product/comment/data.ts | 205 ++++++++++++++++++ .../src/views/mall/product/comment/index.vue | 173 ++++++++++++--- .../mall/product/comment/modules/form.vue | 83 +++++++ 4 files changed, 445 insertions(+), 26 deletions(-) create mode 100644 apps/web-antd/src/views/mall/product/comment/data.ts create mode 100644 apps/web-antd/src/views/mall/product/comment/modules/form.vue diff --git a/apps/web-antd/src/api/mall/product/comment.ts b/apps/web-antd/src/api/mall/product/comment.ts index 7ca1e45fa..8990c2048 100644 --- a/apps/web-antd/src/api/mall/product/comment.ts +++ b/apps/web-antd/src/api/mall/product/comment.ts @@ -3,6 +3,12 @@ import type { PageParam, PageResult } from '@vben/request'; import { requestClient } from '#/api/request'; export namespace MallCommentApi { + export interface Property { + propertyId: number; + propertyName: string; + valueId: number; + valueName: string; + } /** 商品评论 */ export interface Comment { id: number; @@ -20,11 +26,13 @@ export namespace MallCommentApi { descriptionScores: number; benefitScores: number; content: string; - picUrls: string; + picUrls: string[]; replyStatus: boolean; replyUserId: number; replyContent: string; replyTime: Date; + createTime: Date; + skuProperties: Property[]; } /** 评论可见性更新 */ diff --git a/apps/web-antd/src/views/mall/product/comment/data.ts b/apps/web-antd/src/views/mall/product/comment/data.ts new file mode 100644 index 000000000..f422155d6 --- /dev/null +++ b/apps/web-antd/src/views/mall/product/comment/data.ts @@ -0,0 +1,205 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeGridPropTypes } from '#/adapter/vxe-table'; +import type { MallCommentApi } from '#/api/mall/product/comment'; + +import { getSpuSimpleList } from '#/api/mall/product/spu'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'spuId', + label: '商品', + component: 'ApiSelect', + componentProps: { + api: getSpuSimpleList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'userAvatar', + label: '用户头像', + component: 'ImageUpload', + componentProps: { + maxSize: 1, + }, + rules: 'required', + }, + { + fieldName: 'userNickname', + label: '用户名称', + component: 'Input', + rules: 'required', + }, + { + fieldName: 'content', + label: '评论内容', + component: 'Textarea', + rules: 'required', + }, + { + fieldName: 'descriptionScores', + label: '描述星级', + component: 'Rate', + rules: 'required', + }, + { + fieldName: 'benefitScores', + label: '服务星级', + component: 'Rate', + rules: 'required', + }, + { + fieldName: 'picUrls', + label: '评论图片', + component: 'ImageUpload', + componentProps: { + maxSize: 9, + }, + rules: 'required', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'replyStatus', + label: '回复状态', + component: 'Select', + componentProps: { + options: [ + { label: '已回复', value: true }, + { label: '未回复', value: false }, + ], + }, + }, + { + fieldName: 'spuName', + label: '商品名称', + component: 'Input', + }, + { + fieldName: 'userNickname', + label: '用户名称', + component: 'Input', + }, + { + fieldName: 'orderId', + label: '订单编号', + component: 'Input', + }, + { + fieldName: 'createTime', + label: '评论时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 表格列配置 */ +export function useGridColumns( + onStatusChange?: ( + newStatus: boolean, + row: T, + ) => PromiseLike, +): VxeGridPropTypes.Columns { + return [ + { + field: 'id', + title: '评论编号', + fixed: 'left', + }, + { + field: 'skuPicUrl', + title: '商品图片', + cellRender: { + name: 'CellImage', + }, + }, + { + field: 'spuName', + title: '商品名称', + minWidth: 200, + }, + { + field: 'skuProperties', + title: '商品属性', + minWidth: 200, + formatter: ({ cellValue }) => { + return cellValue && cellValue.length > 0 + ? cellValue + .map((item: any) => `${item.propertyName} : ${item.valueName}`) + .join('\n') + : '-'; + }, + }, + { + field: 'userNickname', + title: '用户名称', + }, + { + field: 'descriptionScores', + title: '商品评分', + }, + { + field: 'benefitScores', + title: '服务评分', + }, + { + field: 'content', + title: '评论内容', + }, + { + field: 'picUrls', + title: '评论图片', + cellRender: { + name: 'CellImages', + }, + }, + { + field: 'replyContent', + title: '回复内容', + }, + { + field: 'createTime', + title: '评论时间', + formatter: 'formatDateTime', + }, + { + field: 'visible', + title: '是否展示', + align: 'center', + cellRender: { + attrs: { beforeChange: onStatusChange }, + name: 'CellSwitch', + props: { + checkedValue: true, + unCheckedValue: false, + }, + }, + }, + { + title: '操作', + width: 80, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mall/product/comment/index.vue b/apps/web-antd/src/views/mall/product/comment/index.vue index 1a59c945a..8511c5a00 100644 --- a/apps/web-antd/src/views/mall/product/comment/index.vue +++ b/apps/web-antd/src/views/mall/product/comment/index.vue @@ -1,34 +1,157 @@ diff --git a/apps/web-antd/src/views/mall/product/comment/modules/form.vue b/apps/web-antd/src/views/mall/product/comment/modules/form.vue new file mode 100644 index 000000000..71352fa82 --- /dev/null +++ b/apps/web-antd/src/views/mall/product/comment/modules/form.vue @@ -0,0 +1,83 @@ + + +