feat: implement marketing punch card management page
Some checks failed
Build and Deploy TenantUI / build-and-deploy (push) Failing after 1s

This commit is contained in:
2026-03-02 21:43:47 +08:00
parent 0e043ddd79
commit be0a8e6914
24 changed files with 4450 additions and 0 deletions

View File

@@ -186,4 +186,5 @@ export async function deleteMarketingCouponApi(data: DeleteMarketingCouponDto) {
export * from './flash-sale';
export * from './full-reduction';
export * from './new-customer';
export * from './punch-card';
export * from './seckill';

View File

@@ -0,0 +1,334 @@
/**
* 文件职责:营销中心次卡管理 API 与 DTO 定义。
* 1. 维护次卡列表、详情、保存、状态、删除、使用记录及导出契约。
*/
import { requestClient } from '#/api/request';
/** 次卡状态。 */
export type MarketingPunchCardStatus = 'disabled' | 'enabled';
/** 有效期类型。 */
export type MarketingPunchCardValidityType = 'days' | 'range';
/** 适用范围类型。 */
export type MarketingPunchCardScopeType =
| 'all'
| 'category'
| 'product'
| 'tag';
/** 使用模式。 */
export type MarketingPunchCardUsageMode = 'cap' | 'free';
/** 过期策略。 */
export type MarketingPunchCardExpireStrategy = 'invalidate' | 'refund';
/** 使用记录展示状态。 */
export type MarketingPunchCardUsageDisplayStatus =
| 'almost_used_up'
| 'expired'
| 'normal'
| 'used_up';
/** 使用记录筛选状态。 */
export type MarketingPunchCardUsageFilterStatus =
| 'expired'
| 'normal'
| 'used_up';
/** 次卡范围。 */
export interface MarketingPunchCardScopeDto {
categoryIds: string[];
productIds: string[];
scopeType: MarketingPunchCardScopeType;
tagIds: string[];
}
/** 次卡模板统计。 */
export interface MarketingPunchCardStatsDto {
activeInUseCount: number;
onSaleCount: number;
totalRevenueAmount: number;
totalSoldCount: number;
}
/** 次卡列表项。 */
export interface MarketingPunchCardListItemDto {
activeCount: number;
coverImageUrl?: string;
dailyLimit: null | number;
id: string;
isDimmed: boolean;
name: string;
originalPrice: null | number;
revenueAmount: number;
salePrice: number;
scopeType: MarketingPunchCardScopeType;
soldCount: number;
status: MarketingPunchCardStatus;
totalTimes: number;
updatedAt: string;
usageCapAmount: null | number;
usageMode: MarketingPunchCardUsageMode;
validitySummary: string;
}
/** 次卡列表结果。 */
export interface MarketingPunchCardListResultDto {
items: MarketingPunchCardListItemDto[];
page: number;
pageSize: number;
stats: MarketingPunchCardStatsDto;
totalCount: number;
}
/** 次卡详情。 */
export interface MarketingPunchCardDetailDto {
activeCount: number;
allowTransfer: boolean;
coverImageUrl?: string;
dailyLimit: null | number;
description?: string;
expireStrategy: MarketingPunchCardExpireStrategy;
id: string;
name: string;
notifyChannels: string[];
originalPrice: null | number;
perOrderLimit: null | number;
perUserPurchaseLimit: null | number;
revenueAmount: number;
salePrice: number;
scope: MarketingPunchCardScopeDto;
soldCount: number;
status: MarketingPunchCardStatus;
storeId: string;
totalTimes: number;
updatedAt: string;
usageCapAmount: null | number;
usageMode: MarketingPunchCardUsageMode;
validityDays: null | number;
validityType: MarketingPunchCardValidityType;
validFrom: null | string;
validTo: null | string;
}
/** 保存次卡请求。 */
export interface SaveMarketingPunchCardDto {
allowTransfer: boolean;
coverImageUrl?: string;
dailyLimit: null | number;
description?: string;
expireStrategy: MarketingPunchCardExpireStrategy;
id?: string;
name: string;
notifyChannels: string[];
originalPrice: null | number;
perOrderLimit: null | number;
perUserPurchaseLimit: null | number;
salePrice: number;
scopeCategoryIds: string[];
scopeProductIds: string[];
scopeTagIds: string[];
scopeType: MarketingPunchCardScopeType;
storeId: string;
totalTimes: number;
usageCapAmount: null | number;
usageMode: MarketingPunchCardUsageMode;
validityDays: null | number;
validityType: MarketingPunchCardValidityType;
validFrom: null | string;
validTo: null | string;
}
/** 修改状态请求。 */
export interface ChangeMarketingPunchCardStatusDto {
punchCardId: string;
status: MarketingPunchCardStatus;
storeId: string;
}
/** 删除次卡请求。 */
export interface DeleteMarketingPunchCardDto {
punchCardId: string;
storeId: string;
}
/** 次卡列表查询。 */
export interface MarketingPunchCardListQuery {
keyword?: string;
page: number;
pageSize: number;
status?: '' | MarketingPunchCardStatus;
storeId: string;
}
/** 次卡详情查询。 */
export interface MarketingPunchCardDetailQuery {
punchCardId: string;
storeId: string;
}
/** 使用记录统计。 */
export interface MarketingPunchCardUsageStatsDto {
expiringSoonCount: number;
monthUsedCount: number;
todayUsedCount: number;
}
/** 次卡选项。 */
export interface MarketingPunchCardTemplateOptionDto {
name: string;
templateId: string;
}
/** 使用记录项。 */
export interface MarketingPunchCardUsageRecordDto {
displayStatus: MarketingPunchCardUsageDisplayStatus;
extraPayAmount: null | number;
id: string;
memberName: string;
memberPhoneMasked: string;
productName: string;
punchCardId: string;
punchCardInstanceId: string;
punchCardName: string;
recordNo: string;
remainingTimesAfterUse: number;
totalTimes: number;
usedAt: string;
usedTimes: number;
}
/** 使用记录列表结果。 */
export interface MarketingPunchCardUsageRecordListResultDto {
items: MarketingPunchCardUsageRecordDto[];
page: number;
pageSize: number;
stats: MarketingPunchCardUsageStatsDto;
templateOptions: MarketingPunchCardTemplateOptionDto[];
totalCount: number;
}
/** 使用记录查询参数。 */
export interface MarketingPunchCardUsageRecordListQuery {
keyword?: string;
page: number;
pageSize: number;
punchCardId?: string;
status?: '' | MarketingPunchCardUsageFilterStatus;
storeId: string;
}
/** 使用记录导出参数。 */
export interface ExportMarketingPunchCardUsageRecordQuery {
keyword?: string;
punchCardId?: string;
status?: '' | MarketingPunchCardUsageFilterStatus;
storeId: string;
}
/** 使用记录导出回执。 */
export interface MarketingPunchCardUsageRecordExportDto {
fileContentBase64: string;
fileName: string;
totalCount: number;
}
/** 写入使用记录请求。 */
export interface WriteMarketingPunchCardUsageRecordDto {
extraPayAmount: null | number;
memberName?: string;
memberPhoneMasked?: string;
productName: string;
punchCardId: string;
punchCardInstanceId?: string;
punchCardInstanceNo?: string;
storeId: string;
usedAt?: string;
usedTimes: number;
}
/** 查询次卡列表。 */
export async function getMarketingPunchCardListApi(
params: MarketingPunchCardListQuery,
) {
return requestClient.get<MarketingPunchCardListResultDto>(
'/marketing/punch-card/list',
{
params,
},
);
}
/** 查询次卡详情。 */
export async function getMarketingPunchCardDetailApi(
params: MarketingPunchCardDetailQuery,
) {
return requestClient.get<MarketingPunchCardDetailDto>(
'/marketing/punch-card/detail',
{
params,
},
);
}
/** 保存次卡。 */
export async function saveMarketingPunchCardApi(
data: SaveMarketingPunchCardDto,
) {
return requestClient.post<MarketingPunchCardDetailDto>(
'/marketing/punch-card/save',
data,
);
}
/** 修改次卡状态。 */
export async function changeMarketingPunchCardStatusApi(
data: ChangeMarketingPunchCardStatusDto,
) {
return requestClient.post<MarketingPunchCardDetailDto>(
'/marketing/punch-card/status',
data,
);
}
/** 删除次卡。 */
export async function deleteMarketingPunchCardApi(
data: DeleteMarketingPunchCardDto,
) {
return requestClient.post('/marketing/punch-card/delete', data);
}
/** 查询使用记录。 */
export async function getMarketingPunchCardUsageRecordListApi(
params: MarketingPunchCardUsageRecordListQuery,
) {
return requestClient.get<MarketingPunchCardUsageRecordListResultDto>(
'/marketing/punch-card/usage-record/list',
{
params,
},
);
}
/** 导出使用记录。 */
export async function exportMarketingPunchCardUsageRecordApi(
params: ExportMarketingPunchCardUsageRecordQuery,
) {
return requestClient.get<MarketingPunchCardUsageRecordExportDto>(
'/marketing/punch-card/usage-record/export',
{
params,
},
);
}
/** 写入使用记录。 */
export async function writeMarketingPunchCardUsageRecordApi(
data: WriteMarketingPunchCardUsageRecordDto,
) {
return requestClient.post<MarketingPunchCardUsageRecordDto>(
'/marketing/punch-card/usage-record/write',
data,
);
}