review:【antd/ele】【mall】营销模块的迁移
This commit is contained in:
@@ -7,6 +7,31 @@ import { getDictOptions } from '@vben/hooks';
|
||||
import { z } from '#/adapter/form';
|
||||
import { getSimpleSeckillConfigList } from '#/api/mall/promotion/seckill/seckillConfig';
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
export function useGridFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
fieldName: 'name',
|
||||
label: '活动名称',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
placeholder: '请输入活动名称',
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'status',
|
||||
label: '活动状态',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
placeholder: '请选择活动状态',
|
||||
clearable: true,
|
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 新增/编辑的表单 */
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
@@ -115,31 +140,6 @@ export function useFormSchema(): VbenFormSchema[] {
|
||||
];
|
||||
}
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
export function useGridFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
fieldName: 'name',
|
||||
label: '活动名称',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
placeholder: '请输入活动名称',
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'status',
|
||||
label: '活动状态',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
placeholder: '请选择活动状态',
|
||||
clearable: true,
|
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 列表的字段 */
|
||||
export function useGridColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
|
||||
@@ -9,7 +9,7 @@ export function setConfigList(list: any[]) {
|
||||
}
|
||||
|
||||
/** 格式化配置名称 */
|
||||
export function formatConfigNames(configId: number): string {
|
||||
export function formatConfigNames(configId: number | string): string {
|
||||
const config = configList.find((item) => item.id === configId);
|
||||
return config === null || config === undefined
|
||||
? ''
|
||||
@@ -27,8 +27,11 @@ export function formatSeckillPrice(products: any[]): string {
|
||||
|
||||
/** 格式化活动时间范围 */
|
||||
export function formatTimeRange(
|
||||
startTime: Date | string,
|
||||
endTime: Date | string,
|
||||
startTime: Date | string | undefined,
|
||||
endTime: Date | string | undefined,
|
||||
): string {
|
||||
return `${formatDate(startTime, 'YYYY-MM-DD')} ~ ${formatDate(endTime, 'YYYY-MM-DD')}`;
|
||||
if (startTime && endTime) {
|
||||
return `${formatDate(startTime, 'YYYY-MM-DD')} ~ ${formatDate(endTime, 'YYYY-MM-DD')}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
},
|
||||
},
|
||||
},
|
||||
// TODO @puhui999:antd 没有,是不是要统一哈。
|
||||
cellConfig: {
|
||||
height: 250,
|
||||
},
|
||||
@@ -164,6 +165,7 @@ onMounted(async () => {
|
||||
link: true,
|
||||
auth: ['promotion:seckill-activity:close'],
|
||||
ifShow: row.status === 0,
|
||||
// TODO @puhui999:antd 这里是 popConfirm,看看要不要统一
|
||||
onClick: handleClose.bind(null, row),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -27,15 +27,19 @@ const getTitle = computed(() => {
|
||||
: $t('ui.actionTitle.create', ['秒杀活动']);
|
||||
});
|
||||
|
||||
// ================= 商品选择相关 =================
|
||||
const spuId = ref<number>();
|
||||
const spuName = ref<string>('');
|
||||
const skuTableData = ref<any[]>([]);
|
||||
const spuSkuSelectRef = ref();
|
||||
|
||||
const spuSkuSelectRef = ref(); // 商品选择弹窗 Ref
|
||||
|
||||
/** 打开商品选择弹窗 */
|
||||
const handleSelectProduct = () => {
|
||||
spuSkuSelectRef.value?.open();
|
||||
};
|
||||
|
||||
/** 选择商品后的回调 */
|
||||
async function handleSpuSelected(selectedSpuId: number, skuIds?: number[]) {
|
||||
const spu = await getSpu(selectedSpuId);
|
||||
if (!spu) return;
|
||||
@@ -43,6 +47,7 @@ async function handleSpuSelected(selectedSpuId: number, skuIds?: number[]) {
|
||||
spuId.value = spu.id;
|
||||
spuName.value = spu.name || '';
|
||||
|
||||
// 筛选指定的 SKU
|
||||
const selectedSkus = skuIds
|
||||
? spu.skus?.filter((sku) => skuIds.includes(sku.id!))
|
||||
: spu.skus;
|
||||
@@ -58,6 +63,8 @@ async function handleSpuSelected(selectedSpuId: number, skuIds?: number[]) {
|
||||
})) || [];
|
||||
}
|
||||
|
||||
// ================= end =================
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
commonConfig: {
|
||||
componentProps: {
|
||||
@@ -77,6 +84,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证商品和 SKU 配置
|
||||
if (!spuId.value) {
|
||||
ElMessage.error('请选择秒杀商品');
|
||||
return;
|
||||
@@ -85,6 +93,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
ElMessage.error('请至少配置一个 SKU');
|
||||
return;
|
||||
}
|
||||
// 验证 SKU 配置
|
||||
const hasInvalidSku = skuTableData.value.some(
|
||||
(sku) => sku.stock < 1 || sku.seckillPrice < 0.01,
|
||||
);
|
||||
@@ -93,6 +102,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
return;
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
modalApi.lock();
|
||||
try {
|
||||
const values = await formApi.getValues();
|
||||
@@ -102,12 +112,13 @@ const [Modal, modalApi] = useVbenModal({
|
||||
products: skuTableData.value.map((sku) => ({
|
||||
skuId: sku.skuId,
|
||||
stock: sku.stock,
|
||||
seckillPrice: Math.round(sku.seckillPrice * 100),
|
||||
seckillPrice: Math.round(sku.seckillPrice * 100), // 转换为分
|
||||
})),
|
||||
};
|
||||
await (formData.value?.id
|
||||
? updateSeckillActivity(data)
|
||||
: createSeckillActivity(data));
|
||||
// 关闭并提示
|
||||
await modalApi.close();
|
||||
emit('success');
|
||||
ElMessage.success($t('ui.actionMessage.operationSuccess'));
|
||||
@@ -123,6 +134,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
skuTableData.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
const data = modalApi.getData<MallSeckillActivityApi.SeckillActivity>();
|
||||
if (!data || !data.id) {
|
||||
return;
|
||||
@@ -130,12 +143,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
modalApi.lock();
|
||||
try {
|
||||
formData.value = await getSeckillActivity(data.id);
|
||||
// TODO @puhui999:这里需要 nextTick 么?因为 antd 有
|
||||
await formApi.setValues(formData.value);
|
||||
// 加载商品和 SKU 信息
|
||||
// TODO @puhui999:if return 简化括号层级
|
||||
if (formData.value.spuId) {
|
||||
const spu = await getSpu(formData.value.spuId);
|
||||
if (spu) {
|
||||
spuId.value = spu.id;
|
||||
spuName.value = spu.name || '';
|
||||
// 回填 SKU 配置
|
||||
const products = formData.value.products || [];
|
||||
skuTableData.value =
|
||||
spu.skus
|
||||
@@ -148,7 +165,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
picUrl: sku.picUrl || spu.picUrl || '',
|
||||
price: sku.price || 0,
|
||||
stock: product?.stock || 0,
|
||||
seckillPrice: (product?.seckillPrice || 0) / 100,
|
||||
seckillPrice: (product?.seckillPrice || 0) / 100, // 分转元
|
||||
};
|
||||
}) || [];
|
||||
}
|
||||
@@ -164,9 +181,12 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<Modal class="w-4/5" :title="getTitle">
|
||||
<div class="mx-4">
|
||||
<Form />
|
||||
|
||||
<!-- 商品选择区域 -->
|
||||
<div class="mt-4">
|
||||
<div class="mb-2 flex items-center">
|
||||
<span class="text-sm font-medium">秒杀活动商品:</span>
|
||||
<!-- TODO @puhui999:使用 ElButton 这种哈 -->
|
||||
<el-button class="ml-2" type="primary" @click="handleSelectProduct">
|
||||
选择商品
|
||||
</el-button>
|
||||
@@ -174,7 +194,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||
已选择: {{ spuName }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- SKU 配置表格 -->
|
||||
<div v-if="skuTableData.length > 0" class="mt-4">
|
||||
<!-- TODO @puhui999:Grid?或者 VXETable 哇? -->
|
||||
<table class="w-full border-collapse border border-gray-300">
|
||||
<thead>
|
||||
<tr class="bg-gray-100">
|
||||
@@ -225,6 +248,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- 商品选择器弹窗 -->
|
||||
<SpuSkuSelect
|
||||
ref="spuSkuSelectRef"
|
||||
:is-select-sku="true"
|
||||
|
||||
@@ -110,7 +110,6 @@ function emitActivityChange() {
|
||||
>
|
||||
<ElTooltip :content="activity.name">
|
||||
<div class="relative h-full w-full">
|
||||
<!-- TODO @芋艿 -->
|
||||
<ElImage
|
||||
:src="activity.picUrl"
|
||||
class="h-full w-full rounded-lg object-cover"
|
||||
|
||||
Reference in New Issue
Block a user