feat:【antd】【mall】spu 优化
This commit is contained in:
@@ -62,13 +62,6 @@ export namespace MallSpuApi {
|
||||
valueName?: string; // 属性值名称
|
||||
}
|
||||
|
||||
// TODO @puhui999:这个还要么?
|
||||
/** 优惠券模板 */
|
||||
export interface GiveCouponTemplate {
|
||||
id?: number; // 优惠券编号
|
||||
name?: string; // 优惠券名称
|
||||
}
|
||||
|
||||
/** 商品状态更新请求 */
|
||||
export interface SpuStatusUpdateReqVO {
|
||||
id: number; // 商品编号
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace MallBargainActivityApi {
|
||||
@@ -32,17 +30,6 @@ export namespace MallBargainActivityApi {
|
||||
bargainMinPrice: number; // 砍价底价
|
||||
stock: number; // 活动库存
|
||||
}
|
||||
|
||||
// TODO @puhui999:要不要删除?
|
||||
/** 扩展 SKU 配置 */
|
||||
export type SkuExtension = {
|
||||
productConfig: BargainProduct; // 砍价活动配置
|
||||
} & MallSpuApi.Sku;
|
||||
|
||||
/** 扩展 SPU 配置 */
|
||||
export interface SpuExtension extends MallSpuApi.Spu {
|
||||
skus: SkuExtension[]; // SKU 列表
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询砍价活动列表 */
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace MallCombinationActivityApi {
|
||||
@@ -25,23 +23,12 @@ export namespace MallCombinationActivityApi {
|
||||
products: CombinationProduct[]; // 商品列表
|
||||
}
|
||||
|
||||
// TODO @puhui999:要不要删除?
|
||||
/** 拼团活动所需属性 */
|
||||
export interface CombinationProduct {
|
||||
spuId: number; // 商品 SPU 编号
|
||||
skuId: number; // 商品 SKU 编号
|
||||
combinationPrice: number; // 拼团价格
|
||||
}
|
||||
|
||||
/** 扩展 SKU 配置 */
|
||||
export type SkuExtension = {
|
||||
productConfig: CombinationProduct; // 拼团活动配置
|
||||
} & MallSpuApi.Sku;
|
||||
|
||||
/** 扩展 SPU 配置 */
|
||||
export interface SpuExtension extends MallSpuApi.Spu {
|
||||
skus: SkuExtension[]; // SKU 列表
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询拼团活动列表 */
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace MallDiscountActivityApi {
|
||||
@@ -25,17 +23,6 @@ export namespace MallDiscountActivityApi {
|
||||
endTime?: Date; // 结束时间
|
||||
products?: DiscountProduct[]; // 商品列表
|
||||
}
|
||||
|
||||
// TODO @puhui999:要不要删除?
|
||||
/** 扩展 SKU 配置 */
|
||||
export type SkuExtension = {
|
||||
productConfig: DiscountProduct; // 限时折扣配置
|
||||
} & MallSpuApi.Sku;
|
||||
|
||||
/** 扩展 SPU 配置 */
|
||||
export interface SpuExtension extends MallSpuApi.Spu {
|
||||
skus: SkuExtension[]; // SKU 列表
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询限时折扣活动列表 */
|
||||
|
||||
@@ -36,17 +36,6 @@ export namespace MallPointActivityApi {
|
||||
price: number; // 兑换金额,单位:分
|
||||
}
|
||||
|
||||
// TODO @puhui999:这些还需要么?
|
||||
/** 扩展 SKU 配置 */
|
||||
export type SkuExtension = {
|
||||
productConfig: PointProduct; // 积分商城商品配置
|
||||
} & MallSpuApi.Sku;
|
||||
|
||||
/** 扩展 SPU 配置 */
|
||||
export interface SpuExtension extends MallSpuApi.Spu {
|
||||
skus: SkuExtension[]; // SKU 列表
|
||||
}
|
||||
|
||||
/** 扩展 SPU 配置(带积分信息) */
|
||||
export interface SpuExtensionWithPoint extends MallSpuApi.Spu {
|
||||
pointStock: number; // 积分商城活动库存
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace MallSeckillActivityApi {
|
||||
@@ -34,17 +32,6 @@ export namespace MallSeckillActivityApi {
|
||||
seckillPrice?: number; // 秒杀价格
|
||||
products?: SeckillProduct[]; // 秒杀商品列表
|
||||
}
|
||||
|
||||
// TODO @puhui999:这些还需要么?
|
||||
/** 扩展 SKU 配置 */
|
||||
export type SkuExtension = {
|
||||
productConfig: SeckillProduct; // 秒杀商品配置
|
||||
} & MallSpuApi.Sku;
|
||||
|
||||
/** 扩展 SPU 配置 */
|
||||
export interface SpuExtension extends MallSpuApi.Spu {
|
||||
skus: SkuExtension[]; // SKU 列表
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询秒杀活动列表 */
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
export * from './property-util';
|
||||
export { default as SkuList } from './sku-list.vue';
|
||||
export { default as SkuTableSelect } from './sku-table-select.vue';
|
||||
export { default as SpuShowcase } from './spu-showcase.vue';
|
||||
export { default as SpuTableSelect } from './spu-table-select.vue';
|
||||
export * from './type';
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
import type { PropertyAndValues } from '#/views/mall/product/spu/components/type';
|
||||
|
||||
/** 获得商品的规格列表 - 商品相关的公共函数(被其他模块如 promotion 使用) */
|
||||
const getPropertyList = (spu: MallSpuApi.Spu): PropertyAndValues[] => {
|
||||
// 直接拿返回的 skus 属性逆向生成出 propertyList
|
||||
const properties: PropertyAndValues[] = [];
|
||||
// 只有是多规格才处理
|
||||
if (spu.specType) {
|
||||
spu.skus?.forEach((sku) => {
|
||||
sku.properties?.forEach(
|
||||
({ propertyId, propertyName, valueId, valueName }) => {
|
||||
// 添加属性
|
||||
if (!properties?.some((item) => item.id === propertyId)) {
|
||||
properties.push({
|
||||
id: propertyId!,
|
||||
name: propertyName!,
|
||||
values: [],
|
||||
});
|
||||
}
|
||||
// 添加属性值
|
||||
const index = properties?.findIndex((item) => item.id === propertyId);
|
||||
if (
|
||||
!properties[index]?.values?.some((value) => value.id === valueId)
|
||||
) {
|
||||
properties[index]?.values?.push({ id: valueId!, name: valueName! });
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
return properties;
|
||||
};
|
||||
|
||||
export { getPropertyList };
|
||||
@@ -1,9 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import type { PropertyAndValues, RuleConfig } from '../index';
|
||||
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
import type {
|
||||
PropertyAndValues,
|
||||
RuleConfig,
|
||||
} from '#/views/mall/product/spu/components';
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
22
apps/web-antd/src/views/mall/product/spu/components/type.ts
Normal file
22
apps/web-antd/src/views/mall/product/spu/components/type.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/** 商品属性及其值的树形结构(用于前端展示和操作) */
|
||||
export interface PropertyAndValues {
|
||||
id: number;
|
||||
name: string;
|
||||
values?: PropertyAndValues[];
|
||||
}
|
||||
|
||||
export interface RuleConfig {
|
||||
// 需要校验的字段
|
||||
// 例:name: 'name' 则表示校验 sku.name 的值
|
||||
// 例:name: 'productConfig.stock' 则表示校验 sku.productConfig.name 的值,此处 productConfig 表示我在 Sku 上扩展的属性
|
||||
name: string;
|
||||
// 校验规格为一个毁掉函数,其中 arg 为需要校验的字段的值。
|
||||
// 例:需要校验价格必须大于0.01
|
||||
// {
|
||||
// name:'price',
|
||||
// rule:(arg: number) => arg > 0.01
|
||||
// }
|
||||
rule: (arg: any) => boolean;
|
||||
// 校验不通过时的消息提示
|
||||
message: string;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
|
||||
// TODO @puhui999:这个是不是 api 后端有定义类似的?如果是,是不是放到 api 哈?
|
||||
export interface PropertyAndValues {
|
||||
id: number;
|
||||
name: string;
|
||||
values?: PropertyAndValues[];
|
||||
}
|
||||
|
||||
export interface RuleConfig {
|
||||
// 需要校验的字段
|
||||
// 例:name: 'name' 则表示校验 sku.name 的值
|
||||
// 例:name: 'productConfig.stock' 则表示校验 sku.productConfig.name 的值,此处 productConfig 表示我在 Sku 上扩展的属性
|
||||
name: string;
|
||||
// 校验规格为一个毁掉函数,其中 arg 为需要校验的字段的值。
|
||||
// 例:需要校验价格必须大于0.01
|
||||
// {
|
||||
// name:'price',
|
||||
// rule:(arg: number) => arg > 0.01
|
||||
// }
|
||||
rule: (arg: any) => boolean;
|
||||
// 校验不通过时的消息提示
|
||||
message: string;
|
||||
}
|
||||
|
||||
// TODO @puhui999:这个是只有 index.ts 在用么?还是别的模块也会用
|
||||
/** 获得商品的规格列表 - 商品相关的公共函数 */
|
||||
const getPropertyList = (spu: MallSpuApi.Spu): PropertyAndValues[] => {
|
||||
// 直接拿返回的 skus 属性逆向生成出 propertyList
|
||||
const properties: PropertyAndValues[] = [];
|
||||
// 只有是多规格才处理
|
||||
if (spu.specType) {
|
||||
spu.skus?.forEach((sku) => {
|
||||
sku.properties?.forEach(
|
||||
({ propertyId, propertyName, valueId, valueName }) => {
|
||||
// 添加属性
|
||||
if (!properties?.some((item) => item.id === propertyId)) {
|
||||
properties.push({
|
||||
id: propertyId!,
|
||||
name: propertyName!,
|
||||
values: [],
|
||||
});
|
||||
}
|
||||
// 添加属性值
|
||||
const index = properties?.findIndex((item) => item.id === propertyId);
|
||||
if (
|
||||
!properties[index]?.values?.some((value) => value.id === valueId)
|
||||
) {
|
||||
properties[index]?.values?.push({ id: valueId!, name: valueName! });
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
return properties;
|
||||
};
|
||||
|
||||
export { getPropertyList };
|
||||
|
||||
// 导出组件
|
||||
// TODO @puhui999:如果 sku-list.vue 要对外,可以考虑在 spu 下面,搞个 components 模块;(目前看,别的模块应该会用到哈。);modules 是当前模块用到的,components 是跨模块要用到的。
|
||||
export { default as SkuList } from './modules/sku-list.vue';
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { PropertyAndValues, RuleConfig } from './index';
|
||||
|
||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||
import type {
|
||||
PropertyAndValues,
|
||||
RuleConfig,
|
||||
} from '#/views/mall/product/spu/components';
|
||||
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
@@ -14,6 +16,7 @@ import { Button, Card, message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { createSpu, getSpu, updateSpu } from '#/api/mall/product/spu';
|
||||
import { getPropertyList, SkuList } from '#/views/mall/product/spu/components';
|
||||
|
||||
import {
|
||||
useDeliveryFormSchema,
|
||||
@@ -22,10 +25,8 @@ import {
|
||||
useOtherFormSchema,
|
||||
useSkuFormSchema,
|
||||
} from './data';
|
||||
import { getPropertyList } from './index';
|
||||
import ProductAttributes from './modules/product-attributes.vue';
|
||||
import ProductPropertyAddForm from './modules/product-property-add-form.vue';
|
||||
import SkuList from './modules/sku-list.vue';
|
||||
|
||||
const spuId = ref<number>();
|
||||
const { params, name } = useRoute();
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 商品发布 - 库存价格 - 属性列表 -->
|
||||
<script lang="ts" setup>
|
||||
import type { PropertyAndValues } from '../index';
|
||||
|
||||
import type { MallPropertyApi } from '#/api/mall/product/property';
|
||||
import type { PropertyAndValues } from '#/views/mall/product/spu/components';
|
||||
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import type { MallPointActivityApi } from '#/api/mall/promotion/point';
|
||||
import type { RuleConfig } from '#/views/mall/product/spu/form';
|
||||
import type { RuleConfig } from '#/views/mall/product/spu/components';
|
||||
// TODO @puhui999:有问题
|
||||
// import type { SpuProperty } from '#/views/mall/promotion/components/types';
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
updatePointActivity,
|
||||
} from '#/api/mall/promotion/point';
|
||||
import { $t } from '#/locales';
|
||||
import { getPropertyList } from '#/views/mall/product/spu/form';
|
||||
import { getPropertyList } from '#/views/mall/product/spu/components';
|
||||
|
||||
// TODO @puhui999:有问题
|
||||
// import { SpuAndSkuList, SpuSkuSelect } from '../../../components';
|
||||
|
||||
Reference in New Issue
Block a user