1
This commit is contained in:
64
src/apis/mall-app/address.ts
Normal file
64
src/apis/mall-app/address.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import {
|
||||||
|
APP_API_PATHS,
|
||||||
|
normalizeAppAddressDefaultSetResponse,
|
||||||
|
normalizeAppAddressListResponse,
|
||||||
|
normalizeAppAddressSaveResponse,
|
||||||
|
normalizeMallAppPayload,
|
||||||
|
postMallApp,
|
||||||
|
} from './shared'
|
||||||
|
import type {
|
||||||
|
AppAddressDefaultSetRequest,
|
||||||
|
AppAddressDefaultSetResponse,
|
||||||
|
AppAddressDeleteRequest,
|
||||||
|
AppAddressDeleteResponse,
|
||||||
|
AppAddressListRequest,
|
||||||
|
AppAddressListResponse,
|
||||||
|
AppAddressSaveRequest,
|
||||||
|
AppAddressSaveResponse,
|
||||||
|
} from '@/types/mall'
|
||||||
|
|
||||||
|
export const apiAppAddressList = async (payload: AppAddressListRequest, signal?: AbortSignal) => {
|
||||||
|
const response = await postMallApp<AppAddressListResponse, AppAddressListRequest>(
|
||||||
|
APP_API_PATHS.addressList,
|
||||||
|
normalizeMallAppPayload(payload),
|
||||||
|
signal
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data: normalizeAppAddressListResponse(response.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const apiAppAddressSave = async (payload: AppAddressSaveRequest, signal?: AbortSignal) => {
|
||||||
|
const response = await postMallApp<AppAddressSaveResponse, AppAddressSaveRequest>(
|
||||||
|
APP_API_PATHS.addressSave,
|
||||||
|
normalizeMallAppPayload(payload),
|
||||||
|
signal
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data: normalizeAppAddressSaveResponse(response.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const apiAppAddressDelete = (payload: AppAddressDeleteRequest, signal?: AbortSignal) =>
|
||||||
|
postMallApp<AppAddressDeleteResponse, AppAddressDeleteRequest>(
|
||||||
|
APP_API_PATHS.addressDelete,
|
||||||
|
normalizeMallAppPayload(payload),
|
||||||
|
signal
|
||||||
|
)
|
||||||
|
|
||||||
|
export const apiAppAddressDefaultSet = async (payload: AppAddressDefaultSetRequest, signal?: AbortSignal) => {
|
||||||
|
const response = await postMallApp<AppAddressDefaultSetResponse, AppAddressDefaultSetRequest>(
|
||||||
|
APP_API_PATHS.addressDefaultSet,
|
||||||
|
normalizeMallAppPayload(payload),
|
||||||
|
signal
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data: normalizeAppAddressDefaultSetResponse(response.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,26 @@
|
|||||||
import { APP_API_PATHS, normalizeMallAppPayload, postMallApp } from './shared'
|
import {
|
||||||
|
APP_API_PATHS,
|
||||||
|
normalizeAppAfterSaleApplyResponse,
|
||||||
|
normalizeMallAppPayload,
|
||||||
|
postMallApp,
|
||||||
|
} from './shared'
|
||||||
import type {
|
import type {
|
||||||
AppAfterSaleApplyRequest,
|
AppAfterSaleApplyRequest,
|
||||||
AppAfterSaleApplyResponse,
|
AppAfterSaleApplyResponse,
|
||||||
} from '@/types/mall'
|
} from '@/types/mall'
|
||||||
|
|
||||||
export const apiAppAfterSaleApply = (
|
export const apiAppAfterSaleApply = async (
|
||||||
payload: AppAfterSaleApplyRequest,
|
payload: AppAfterSaleApplyRequest,
|
||||||
signal?: AbortSignal
|
signal?: AbortSignal
|
||||||
) =>
|
) => {
|
||||||
postMallApp<AppAfterSaleApplyResponse, AppAfterSaleApplyRequest>(
|
const response = await postMallApp<AppAfterSaleApplyResponse, AppAfterSaleApplyRequest>(
|
||||||
APP_API_PATHS.afterSaleApply,
|
APP_API_PATHS.afterSaleApply,
|
||||||
normalizeMallAppPayload(payload),
|
normalizeMallAppPayload(payload),
|
||||||
signal
|
signal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data: normalizeAppAfterSaleApplyResponse(response.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import { APP_API_PATHS, normalizeAppCartListResponse, normalizeMallAppPayload, postMallApp } from './shared'
|
import {
|
||||||
|
APP_API_PATHS,
|
||||||
|
normalizeAppCartListResponse,
|
||||||
|
normalizeAppCartSaveResponse,
|
||||||
|
normalizeMallAppPayload,
|
||||||
|
postMallApp,
|
||||||
|
} from './shared'
|
||||||
import type {
|
import type {
|
||||||
AppCartListRequest,
|
AppCartListRequest,
|
||||||
AppCartListResponse,
|
AppCartListResponse,
|
||||||
@@ -21,13 +27,19 @@ export const apiAppCartList = async (payload: AppCartListRequest, signal?: Abort
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const apiAppCartSave = (payload: AppCartSaveRequest, signal?: AbortSignal) =>
|
export const apiAppCartSave = async (payload: AppCartSaveRequest, signal?: AbortSignal) => {
|
||||||
postMallApp<AppCartSaveResponse, AppCartSaveRequest>(
|
const response = await postMallApp<AppCartSaveResponse, AppCartSaveRequest>(
|
||||||
APP_API_PATHS.cartSave,
|
APP_API_PATHS.cartSave,
|
||||||
normalizeMallAppPayload(payload),
|
normalizeMallAppPayload(payload),
|
||||||
signal
|
signal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data: normalizeAppCartSaveResponse(response.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const apiAppCartRemove = (payload: AppCartRemoveRequest, signal?: AbortSignal) =>
|
export const apiAppCartRemove = (payload: AppCartRemoveRequest, signal?: AbortSignal) =>
|
||||||
postMallApp<AppCartRemoveResponse, AppCartRemoveRequest>(
|
postMallApp<AppCartRemoveResponse, AppCartRemoveRequest>(
|
||||||
APP_API_PATHS.cartRemove,
|
APP_API_PATHS.cartRemove,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ export * from './shared'
|
|||||||
export * from './home'
|
export * from './home'
|
||||||
export * from './goods'
|
export * from './goods'
|
||||||
export * from './cart'
|
export * from './cart'
|
||||||
|
export * from './address'
|
||||||
export * from './trade'
|
export * from './trade'
|
||||||
export * from './order'
|
export * from './order'
|
||||||
export * from './afterSale'
|
export * from './afterSale'
|
||||||
|
|||||||
@@ -1,31 +1,43 @@
|
|||||||
import type {
|
import type {
|
||||||
|
AppAddressDefaultSetResponse,
|
||||||
|
AppAddressListResponse,
|
||||||
|
AppAddressSaveResponse,
|
||||||
|
AppAfterSaleApplyResponse,
|
||||||
AppCartListResponse,
|
AppCartListResponse,
|
||||||
|
AppCartSaveResponse,
|
||||||
AppGoodsDetailResponse,
|
AppGoodsDetailResponse,
|
||||||
AppGoodsPageResponse,
|
AppGoodsPageResponse,
|
||||||
AppHomeMerchantGoodsResponse,
|
AppHomeMerchantGoodsResponse,
|
||||||
AppHomeResponse,
|
AppHomeResponse,
|
||||||
AppRecentNewGoodsResponse,
|
AppRecentNewGoodsResponse,
|
||||||
AppOrderDetailResponse,
|
AppOrderDetailResponse,
|
||||||
|
AppOrderConfirmResponse,
|
||||||
AppOrderPageResponse,
|
AppOrderPageResponse,
|
||||||
|
AppTradeCreateResponse,
|
||||||
CartItemInfo,
|
CartItemInfo,
|
||||||
|
CartGoodsGroupInfo,
|
||||||
|
CartMerchantGroupInfo,
|
||||||
GoodsDetailInfo,
|
GoodsDetailInfo,
|
||||||
GoodsSkuInfo,
|
GoodsSkuInfo,
|
||||||
GoodsSummary,
|
GoodsSummary,
|
||||||
AppTradePreviewResponse,
|
AppTradePreviewResponse,
|
||||||
HomeMerchantGoodsBlock,
|
HomeMerchantGoodsBlock,
|
||||||
|
MerchantDeliveryOptionInfo,
|
||||||
MerchantId,
|
MerchantId,
|
||||||
MerchantInfo,
|
MerchantInfo,
|
||||||
|
MerchantPackageOptionInfo,
|
||||||
OrderDetailInfo,
|
OrderDetailInfo,
|
||||||
OrderSummary,
|
OrderSummary,
|
||||||
RecommendMerchantInfo,
|
RecommendMerchantInfo,
|
||||||
RecentNewGoodsItem,
|
RecentNewGoodsItem,
|
||||||
TradePreviewInfo,
|
TradePreviewInfo,
|
||||||
|
TradePreviewItemInfo,
|
||||||
TradePreviewStoreInfo,
|
TradePreviewStoreInfo,
|
||||||
} from '@/types/mall'
|
} from '@/types/mall'
|
||||||
|
|
||||||
type MaybeMallUidPayload = {
|
type MaybeMallIdentityPayload = {
|
||||||
uid?: number
|
uid?: number
|
||||||
memberId?: number
|
memberId?: MerchantId | number
|
||||||
}
|
}
|
||||||
|
|
||||||
type MaybeMallMerchantPayload = {
|
type MaybeMallMerchantPayload = {
|
||||||
@@ -33,6 +45,22 @@ type MaybeMallMerchantPayload = {
|
|||||||
storeId?: number | string
|
storeId?: number | string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MaybeMallIdPayload = {
|
||||||
|
id?: string | number
|
||||||
|
skuId?: string | number
|
||||||
|
skuIds?: Array<string | number>
|
||||||
|
addressId?: string | number
|
||||||
|
orderId?: string | number
|
||||||
|
orderItemId?: string | number
|
||||||
|
categoryId?: string | number
|
||||||
|
buyItems?: Array<{ skuId?: string | number; buyNum?: number }>
|
||||||
|
merchantOptions?: Array<{
|
||||||
|
merchantId?: MerchantId | number
|
||||||
|
deliveryOptionId?: string | number
|
||||||
|
packageOptionId?: string | number
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
type RawRecommendMerchantPayload = Partial<RecommendMerchantInfo> & {
|
type RawRecommendMerchantPayload = Partial<RecommendMerchantInfo> & {
|
||||||
id?: RecommendMerchantInfo['id']
|
id?: RecommendMerchantInfo['id']
|
||||||
merchantId?: MerchantId | number | string
|
merchantId?: MerchantId | number | string
|
||||||
@@ -56,6 +84,8 @@ type RawMerchantEntityPayload = Partial<MerchantInfo> & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RawGoodsSummaryPayload = Partial<GoodsSummary> & {
|
type RawGoodsSummaryPayload = Partial<GoodsSummary> & {
|
||||||
|
id?: GoodsSummary['id'] | number
|
||||||
|
spuId?: GoodsSummary['id'] | number
|
||||||
merchantId?: MerchantId | number | string
|
merchantId?: MerchantId | number | string
|
||||||
createdAt?: GoodsSummary['createdAt'] | string | null
|
createdAt?: GoodsSummary['createdAt'] | string | null
|
||||||
updatedAt?: GoodsSummary['updatedAt'] | string | null
|
updatedAt?: GoodsSummary['updatedAt'] | string | null
|
||||||
@@ -69,14 +99,29 @@ type RawGoodsSummaryPayload = Partial<GoodsSummary> & {
|
|||||||
update_time?: number | string | null
|
update_time?: number | string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
const toMerchantId = (value: MerchantId | number | string | null | undefined): MerchantId =>
|
const toId = (value: string | number | null | undefined): string => (value == null ? '' : String(value))
|
||||||
value == null ? '' : String(value)
|
|
||||||
|
const toMerchantId = (value: MerchantId | number | string | null | undefined): MerchantId => toId(value)
|
||||||
|
|
||||||
const toNumber = (value: number | string | null | undefined): number => {
|
const toNumber = (value: number | string | null | undefined): number => {
|
||||||
const parsed = Number(value)
|
const parsed = Number(value)
|
||||||
return Number.isFinite(parsed) ? parsed : 0
|
return Number.isFinite(parsed) ? parsed : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toBoolean = (value: boolean | number | string | null | undefined): boolean => {
|
||||||
|
if (typeof value === 'boolean') {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
return value !== 0
|
||||||
|
}
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return ['1', 'true', 'yes'].includes(value.trim().toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const pickText = (...values: Array<string | null | undefined>): string => {
|
const pickText = (...values: Array<string | null | undefined>): string => {
|
||||||
for (const value of values) {
|
for (const value of values) {
|
||||||
if (typeof value === 'string' && value.trim()) {
|
if (typeof value === 'string' && value.trim()) {
|
||||||
@@ -111,12 +156,52 @@ const toUnixTime = (value: number | string | null | undefined): number => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const normalizeMallAppPayload = <TPayload extends object>(payload: TPayload): TPayload => {
|
export const normalizeMallAppPayload = <TPayload extends object>(payload: TPayload): TPayload => {
|
||||||
const normalized = { ...payload } as TPayload & MaybeMallUidPayload & MaybeMallMerchantPayload
|
const normalized = { ...payload } as TPayload &
|
||||||
|
MaybeMallIdentityPayload &
|
||||||
|
MaybeMallMerchantPayload &
|
||||||
|
MaybeMallIdPayload
|
||||||
|
|
||||||
if (normalized.uid == null && normalized.memberId != null) {
|
delete normalized.uid
|
||||||
normalized.uid = normalized.memberId
|
if (normalized.memberId != null) {
|
||||||
|
normalized.memberId = toMerchantId(normalized.memberId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalized.id != null) {
|
||||||
|
normalized.id = toId(normalized.id)
|
||||||
|
}
|
||||||
|
if (normalized.skuId != null) {
|
||||||
|
normalized.skuId = toId(normalized.skuId)
|
||||||
|
}
|
||||||
|
if (normalized.skuIds != null) {
|
||||||
|
normalized.skuIds = normalized.skuIds.map(toId)
|
||||||
|
}
|
||||||
|
if (normalized.addressId != null) {
|
||||||
|
normalized.addressId = toId(normalized.addressId)
|
||||||
|
}
|
||||||
|
if (normalized.orderId != null) {
|
||||||
|
normalized.orderId = toId(normalized.orderId)
|
||||||
|
}
|
||||||
|
if (normalized.orderItemId != null) {
|
||||||
|
normalized.orderItemId = toId(normalized.orderItemId)
|
||||||
|
}
|
||||||
|
if (normalized.categoryId != null) {
|
||||||
|
normalized.categoryId = toId(normalized.categoryId)
|
||||||
|
}
|
||||||
|
if (normalized.buyItems != null) {
|
||||||
|
normalized.buyItems = normalized.buyItems.map(item => ({
|
||||||
|
...item,
|
||||||
|
skuId: item.skuId == null ? item.skuId : toId(item.skuId),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
if (normalized.merchantOptions != null) {
|
||||||
|
normalized.merchantOptions = normalized.merchantOptions.map(option => ({
|
||||||
|
...option,
|
||||||
|
merchantId: option.merchantId == null ? option.merchantId : toMerchantId(option.merchantId),
|
||||||
|
deliveryOptionId:
|
||||||
|
option.deliveryOptionId == null ? option.deliveryOptionId : toId(option.deliveryOptionId),
|
||||||
|
packageOptionId: option.packageOptionId == null ? option.packageOptionId : toId(option.packageOptionId),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
delete normalized.memberId
|
|
||||||
|
|
||||||
if (normalized.merchantId != null) {
|
if (normalized.merchantId != null) {
|
||||||
normalized.merchantId = toMerchantId(normalized.merchantId)
|
normalized.merchantId = toMerchantId(normalized.merchantId)
|
||||||
@@ -131,7 +216,10 @@ export const normalizeMallAppPayload = <TPayload extends object>(payload: TPaylo
|
|||||||
|
|
||||||
const normalizeGoodsSku = (sku: GoodsSkuInfo): GoodsSkuInfo => ({
|
const normalizeGoodsSku = (sku: GoodsSkuInfo): GoodsSkuInfo => ({
|
||||||
...sku,
|
...sku,
|
||||||
|
id: toId(sku.id),
|
||||||
|
spuId: String(sku.spuId),
|
||||||
merchantId: toMerchantId(sku.merchantId),
|
merchantId: toMerchantId(sku.merchantId),
|
||||||
|
storeId: toId(sku.storeId),
|
||||||
})
|
})
|
||||||
|
|
||||||
const normalizeGoodsSummary = (goods: RawGoodsSummaryPayload): GoodsSummary => {
|
const normalizeGoodsSummary = (goods: RawGoodsSummaryPayload): GoodsSummary => {
|
||||||
@@ -139,9 +227,12 @@ const normalizeGoodsSummary = (goods: RawGoodsSummaryPayload): GoodsSummary => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...normalized,
|
...normalized,
|
||||||
|
id: String(goods.spuId ?? goods.id ?? ''),
|
||||||
merchantId: toMerchantId(goods.merchantId),
|
merchantId: toMerchantId(goods.merchantId),
|
||||||
merchantName: pickText(goods.merchantName),
|
merchantName: pickText(goods.merchantName),
|
||||||
merchantLogo: pickText(goods.merchantLogo),
|
merchantLogo: pickText(goods.merchantLogo),
|
||||||
|
storeId: toId(goods.storeId),
|
||||||
|
categoryId: toId(goods.categoryId),
|
||||||
createdAt: toUnixTime(goods.createdAt ?? goods.createAt ?? goods.created_at ?? goods.createTime ?? goods.create_time),
|
createdAt: toUnixTime(goods.createdAt ?? goods.createAt ?? goods.created_at ?? goods.createTime ?? goods.create_time),
|
||||||
updatedAt: toUnixTime(goods.updatedAt ?? goods.updateAt ?? goods.updated_at ?? goods.updateTime ?? goods.update_time),
|
updatedAt: toUnixTime(goods.updatedAt ?? goods.updateAt ?? goods.updated_at ?? goods.updateTime ?? goods.update_time),
|
||||||
}
|
}
|
||||||
@@ -159,7 +250,10 @@ const normalizeRecentNewGoodsItem = (goods: RecentNewGoodsItem): RecentNewGoodsI
|
|||||||
|
|
||||||
const normalizeGoodsDetailInfo = (detail: GoodsDetailInfo): GoodsDetailInfo => ({
|
const normalizeGoodsDetailInfo = (detail: GoodsDetailInfo): GoodsDetailInfo => ({
|
||||||
...detail,
|
...detail,
|
||||||
|
id: toId(detail.id),
|
||||||
merchantId: toMerchantId(detail.merchantId),
|
merchantId: toMerchantId(detail.merchantId),
|
||||||
|
storeId: toId(detail.storeId),
|
||||||
|
categoryId: toId(detail.categoryId),
|
||||||
createdAt: toUnixTime(detail.createdAt),
|
createdAt: toUnixTime(detail.createdAt),
|
||||||
updatedAt: toUnixTime(detail.updatedAt),
|
updatedAt: toUnixTime(detail.updatedAt),
|
||||||
skus: (detail.skus ?? []).map(normalizeGoodsSku),
|
skus: (detail.skus ?? []).map(normalizeGoodsSku),
|
||||||
@@ -167,22 +261,104 @@ const normalizeGoodsDetailInfo = (detail: GoodsDetailInfo): GoodsDetailInfo => (
|
|||||||
|
|
||||||
const normalizeCartItem = (item: CartItemInfo): CartItemInfo => ({
|
const normalizeCartItem = (item: CartItemInfo): CartItemInfo => ({
|
||||||
...item,
|
...item,
|
||||||
|
id: toId(item.id),
|
||||||
|
memberId: item.memberId == null ? undefined : toMerchantId(item.memberId),
|
||||||
merchantId: toMerchantId(item.merchantId),
|
merchantId: toMerchantId(item.merchantId),
|
||||||
|
merchantName: pickText(item.merchantName),
|
||||||
|
merchantLogo: pickText(item.merchantLogo),
|
||||||
|
storeId: toId(item.storeId),
|
||||||
|
spuId: String(item.spuId),
|
||||||
|
skuId: toId(item.skuId),
|
||||||
|
itemAmount:
|
||||||
|
item.itemAmount ??
|
||||||
|
(Number.isFinite(Number(item.salePrice)) && Number.isFinite(Number(item.buyNum))
|
||||||
|
? (Number(item.salePrice) * Number(item.buyNum)).toFixed(2)
|
||||||
|
: '0'),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeCartGoodsGroup = (goods: CartGoodsGroupInfo): CartGoodsGroupInfo => ({
|
||||||
|
...goods,
|
||||||
|
spuId: String(goods.spuId),
|
||||||
|
spuName: pickText(goods.spuName),
|
||||||
|
coverUrl: pickText(goods.coverUrl),
|
||||||
|
checked: Boolean(goods.checked),
|
||||||
|
goodsAmount: goods.goodsAmount ?? '0',
|
||||||
|
checkedAmount: goods.checkedAmount ?? '0',
|
||||||
|
items: (goods.items ?? []).map(normalizeCartItem),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeCartMerchantGroup = (group: CartMerchantGroupInfo): CartMerchantGroupInfo => ({
|
||||||
|
...group,
|
||||||
|
merchantId: toMerchantId(group.merchantId),
|
||||||
|
merchantName: pickText(group.merchantName) || '未命名商家',
|
||||||
|
merchantLogo: pickText(group.merchantLogo),
|
||||||
|
checked: Boolean(group.checked),
|
||||||
|
itemCount: toNumber(group.itemCount),
|
||||||
|
goodsCount: toNumber(group.goodsCount),
|
||||||
|
goodsAmount: group.goodsAmount ?? '0',
|
||||||
|
checkedAmount: group.checkedAmount ?? '0',
|
||||||
|
goods: (group.goods ?? []).map(normalizeCartGoodsGroup),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeTradePreviewItem = (item: TradePreviewItemInfo): TradePreviewItemInfo => ({
|
||||||
|
...item,
|
||||||
|
spuId: String(item.spuId),
|
||||||
|
skuId: toId(item.skuId),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeDeliveryOption = (option: MerchantDeliveryOptionInfo): MerchantDeliveryOptionInfo => ({
|
||||||
|
...option,
|
||||||
|
id: toId(option.id),
|
||||||
|
merchantId: toMerchantId(option.merchantId),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizePackageOption = (option: MerchantPackageOptionInfo): MerchantPackageOptionInfo => ({
|
||||||
|
...option,
|
||||||
|
id: toId(option.id),
|
||||||
|
merchantId: toMerchantId(option.merchantId),
|
||||||
})
|
})
|
||||||
|
|
||||||
const normalizeTradePreviewGroup = (group: TradePreviewStoreInfo): TradePreviewStoreInfo => ({
|
const normalizeTradePreviewGroup = (group: TradePreviewStoreInfo): TradePreviewStoreInfo => ({
|
||||||
...group,
|
...group,
|
||||||
merchantId: toMerchantId(group.merchantId),
|
merchantId: toMerchantId(group.merchantId),
|
||||||
|
storeId: group.storeId == null ? undefined : toId(group.storeId),
|
||||||
|
deliveryOptions: (group.deliveryOptions ?? []).map(normalizeDeliveryOption),
|
||||||
|
packageOptions: (group.packageOptions ?? []).map(normalizePackageOption),
|
||||||
|
selectedDeliveryOption: group.selectedDeliveryOption
|
||||||
|
? normalizeDeliveryOption(group.selectedDeliveryOption)
|
||||||
|
: undefined,
|
||||||
|
selectedPackageOption: group.selectedPackageOption ? normalizePackageOption(group.selectedPackageOption) : undefined,
|
||||||
|
items: (group.items ?? []).map(normalizeTradePreviewItem),
|
||||||
})
|
})
|
||||||
|
|
||||||
const normalizeOrderSummary = (order: OrderSummary): OrderSummary => ({
|
const normalizeOrderSummary = (order: OrderSummary): OrderSummary => ({
|
||||||
...order,
|
...order,
|
||||||
|
id: toId(order.id),
|
||||||
|
tradeId: toId(order.tradeId),
|
||||||
|
memberId: order.memberId == null ? undefined : toMerchantId(order.memberId),
|
||||||
merchantId: toMerchantId(order.merchantId),
|
merchantId: toMerchantId(order.merchantId),
|
||||||
|
storeId: toId(order.storeId),
|
||||||
})
|
})
|
||||||
|
|
||||||
const normalizeOrderDetailInfo = (order: OrderDetailInfo): OrderDetailInfo => ({
|
const normalizeOrderDetailInfo = (order: OrderDetailInfo): OrderDetailInfo => ({
|
||||||
...order,
|
...order,
|
||||||
|
id: toId(order.id),
|
||||||
|
tradeId: toId(order.tradeId),
|
||||||
|
memberId: order.memberId == null ? undefined : toMerchantId(order.memberId),
|
||||||
merchantId: toMerchantId(order.merchantId),
|
merchantId: toMerchantId(order.merchantId),
|
||||||
|
storeId: toId(order.storeId),
|
||||||
|
selectedDeliveryOption: order.selectedDeliveryOption
|
||||||
|
? normalizeDeliveryOption(order.selectedDeliveryOption)
|
||||||
|
: undefined,
|
||||||
|
selectedPackageOption: order.selectedPackageOption ? normalizePackageOption(order.selectedPackageOption) : undefined,
|
||||||
|
items: (order.items ?? []).map(item => ({
|
||||||
|
...item,
|
||||||
|
id: toId(item.id),
|
||||||
|
orderId: toId(item.orderId),
|
||||||
|
tradeId: toId(item.tradeId),
|
||||||
|
spuId: String(item.spuId),
|
||||||
|
skuId: toId(item.skuId),
|
||||||
|
})),
|
||||||
})
|
})
|
||||||
|
|
||||||
const normalizeRecommendMerchant = (
|
const normalizeRecommendMerchant = (
|
||||||
@@ -194,6 +370,7 @@ const normalizeRecommendMerchant = (
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...(merchant as RecommendMerchantInfo),
|
...(merchant as RecommendMerchantInfo),
|
||||||
|
id: toId(merchant.id ?? merchant.merchantId),
|
||||||
merchantId: toMerchantId(merchant.merchantId ?? merchant.id),
|
merchantId: toMerchantId(merchant.merchantId ?? merchant.id),
|
||||||
storeName: pickText(merchant.storeName, merchant.merchantName),
|
storeName: pickText(merchant.storeName, merchant.merchantName),
|
||||||
storeLogo: pickText(merchant.storeLogo, merchant.logo),
|
storeLogo: pickText(merchant.storeLogo, merchant.logo),
|
||||||
@@ -215,6 +392,7 @@ const normalizeMerchantEntity = (
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...(merchant as MerchantInfo),
|
...(merchant as MerchantInfo),
|
||||||
|
id: toId(merchant.id ?? merchant.merchantId),
|
||||||
merchantId: toMerchantId(merchant.merchantId ?? merchant.id),
|
merchantId: toMerchantId(merchant.merchantId ?? merchant.id),
|
||||||
storeName: pickText(merchant.storeName, merchant.merchantName),
|
storeName: pickText(merchant.storeName, merchant.merchantName),
|
||||||
storeLogo: pickText(merchant.storeLogo, merchant.logo),
|
storeLogo: pickText(merchant.storeLogo, merchant.logo),
|
||||||
@@ -223,6 +401,26 @@ const normalizeMerchantEntity = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const normalizeAddressInfo = (address: AppAddressListResponse['list'][number]) => ({
|
||||||
|
...address,
|
||||||
|
id: toId(address.id),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeBanner = (banner: AppHomeResponse['banners'][number]) => ({
|
||||||
|
...banner,
|
||||||
|
id: toId(banner.id),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeCategoryNav = (category: AppHomeResponse['categoryNavs'][number]) => ({
|
||||||
|
...category,
|
||||||
|
categoryId: toId(category.categoryId),
|
||||||
|
})
|
||||||
|
|
||||||
|
const normalizeChannel = (channel: AppHomeResponse['channels'][number]) => ({
|
||||||
|
...channel,
|
||||||
|
id: toId(channel.id),
|
||||||
|
})
|
||||||
|
|
||||||
const normalizeHomeMerchantGoodsBlock = (
|
const normalizeHomeMerchantGoodsBlock = (
|
||||||
block: HomeMerchantGoodsBlock | undefined
|
block: HomeMerchantGoodsBlock | undefined
|
||||||
): HomeMerchantGoodsBlock | undefined => {
|
): HomeMerchantGoodsBlock | undefined => {
|
||||||
@@ -262,7 +460,40 @@ export const normalizeAppCartListResponse = (
|
|||||||
payload: AppCartListResponse
|
payload: AppCartListResponse
|
||||||
): AppCartListResponse => ({
|
): AppCartListResponse => ({
|
||||||
...payload,
|
...payload,
|
||||||
list: payload.list.map(normalizeCartItem),
|
merchantGroups: (payload.merchantGroups ?? []).map(normalizeCartMerchantGroup),
|
||||||
|
itemCount: toNumber(payload.itemCount),
|
||||||
|
goodsCount: toNumber(payload.goodsCount),
|
||||||
|
goodsAmount: payload.goodsAmount ?? '0',
|
||||||
|
checkedCount: toNumber(payload.checkedCount),
|
||||||
|
checkedAmount: payload.checkedAmount ?? '0',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const normalizeAppCartSaveResponse = (
|
||||||
|
payload: AppCartSaveResponse
|
||||||
|
): AppCartSaveResponse => ({
|
||||||
|
...payload,
|
||||||
|
cartId: toId(payload.cartId),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const normalizeAppAddressListResponse = (
|
||||||
|
payload: AppAddressListResponse
|
||||||
|
): AppAddressListResponse => ({
|
||||||
|
...payload,
|
||||||
|
list: (payload.list ?? []).map(normalizeAddressInfo),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const normalizeAppAddressSaveResponse = (
|
||||||
|
payload: AppAddressSaveResponse
|
||||||
|
): AppAddressSaveResponse => ({
|
||||||
|
...payload,
|
||||||
|
addressId: toId(payload.addressId),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const normalizeAppAddressDefaultSetResponse = (
|
||||||
|
payload: AppAddressDefaultSetResponse
|
||||||
|
): AppAddressDefaultSetResponse => ({
|
||||||
|
...payload,
|
||||||
|
addressId: toId(payload.addressId),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const normalizeAppOrderPageResponse = (
|
export const normalizeAppOrderPageResponse = (
|
||||||
@@ -279,6 +510,20 @@ export const normalizeAppOrderDetailResponse = (
|
|||||||
data: normalizeOrderDetailInfo(payload.data),
|
data: normalizeOrderDetailInfo(payload.data),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const normalizeAppOrderConfirmResponse = (
|
||||||
|
payload: AppOrderConfirmResponse
|
||||||
|
): AppOrderConfirmResponse => ({
|
||||||
|
...payload,
|
||||||
|
orderId: toId(payload.orderId),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const normalizeAppAfterSaleApplyResponse = (
|
||||||
|
payload: AppAfterSaleApplyResponse
|
||||||
|
): AppAfterSaleApplyResponse => ({
|
||||||
|
...payload,
|
||||||
|
afterSaleId: toId(payload.afterSaleId),
|
||||||
|
})
|
||||||
|
|
||||||
export const normalizeAppHomeResponse = (payload: AppHomeResponse): AppHomeResponse => {
|
export const normalizeAppHomeResponse = (payload: AppHomeResponse): AppHomeResponse => {
|
||||||
const recommendMerchants = (payload.recommendMerchants ?? payload.recommendStores ?? [])
|
const recommendMerchants = (payload.recommendMerchants ?? payload.recommendStores ?? [])
|
||||||
.map(normalizeRecommendMerchant)
|
.map(normalizeRecommendMerchant)
|
||||||
@@ -289,6 +534,9 @@ export const normalizeAppHomeResponse = (payload: AppHomeResponse): AppHomeRespo
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...payload,
|
...payload,
|
||||||
|
banners: (payload.banners ?? []).map(normalizeBanner),
|
||||||
|
categoryNavs: (payload.categoryNavs ?? []).map(normalizeCategoryNav),
|
||||||
|
channels: (payload.channels ?? []).map(normalizeChannel),
|
||||||
recommendGoods: payload.recommendGoods.map(normalizeGoodsSummary),
|
recommendGoods: payload.recommendGoods.map(normalizeGoodsSummary),
|
||||||
recommendMerchants,
|
recommendMerchants,
|
||||||
featuredMerchants,
|
featuredMerchants,
|
||||||
@@ -305,7 +553,7 @@ export const normalizeAppHomeMerchantGoodsResponse = (
|
|||||||
normalizeHomeMerchantGoodsBlock(payload.data) ??
|
normalizeHomeMerchantGoodsBlock(payload.data) ??
|
||||||
({
|
({
|
||||||
merchant: {
|
merchant: {
|
||||||
id: 0,
|
id: '0',
|
||||||
merchantId: '0',
|
merchantId: '0',
|
||||||
storeName: '',
|
storeName: '',
|
||||||
storeLogo: '',
|
storeLogo: '',
|
||||||
@@ -319,7 +567,7 @@ export const normalizeAppHomeMerchantGoodsResponse = (
|
|||||||
orderCount: 0,
|
orderCount: 0,
|
||||||
},
|
},
|
||||||
store: {
|
store: {
|
||||||
id: 0,
|
id: '0',
|
||||||
merchantId: '0',
|
merchantId: '0',
|
||||||
storeName: '',
|
storeName: '',
|
||||||
storeLogo: '',
|
storeLogo: '',
|
||||||
@@ -354,7 +602,7 @@ export const normalizeAppTradePreviewResponse = (
|
|||||||
): AppTradePreviewResponse => {
|
): AppTradePreviewResponse => {
|
||||||
const data = payload.data as TradePreviewInfo & {
|
const data = payload.data as TradePreviewInfo & {
|
||||||
uid?: number
|
uid?: number
|
||||||
memberId?: number
|
memberId?: MerchantId | number
|
||||||
merchantGroups?: TradePreviewInfo['merchantGroups']
|
merchantGroups?: TradePreviewInfo['merchantGroups']
|
||||||
storeGroups?: TradePreviewInfo['merchantGroups']
|
storeGroups?: TradePreviewInfo['merchantGroups']
|
||||||
}
|
}
|
||||||
@@ -364,10 +612,24 @@ export const normalizeAppTradePreviewResponse = (
|
|||||||
...payload,
|
...payload,
|
||||||
data: {
|
data: {
|
||||||
...data,
|
...data,
|
||||||
uid: data.uid ?? data.memberId ?? 0,
|
addressId: toId(data.addressId),
|
||||||
memberId: data.memberId ?? data.uid,
|
uid: data.uid ?? 0,
|
||||||
|
memberId: data.memberId == null ? undefined : toMerchantId(data.memberId),
|
||||||
merchantGroups: merchantGroups.map(normalizeTradePreviewGroup),
|
merchantGroups: merchantGroups.map(normalizeTradePreviewGroup),
|
||||||
storeGroups: merchantGroups.map(normalizeTradePreviewGroup),
|
storeGroups: merchantGroups.map(normalizeTradePreviewGroup),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const normalizeAppTradeCreateResponse = (
|
||||||
|
payload: AppTradeCreateResponse
|
||||||
|
): AppTradeCreateResponse => ({
|
||||||
|
...payload,
|
||||||
|
tradeId: toId(payload.tradeId),
|
||||||
|
payUrl: pickText(payload.payUrl),
|
||||||
|
payExternal: toBoolean(payload.payExternal),
|
||||||
|
payExpiredAt: toUnixTime(payload.payExpiredAt),
|
||||||
|
payChannel: pickText(payload.payChannel),
|
||||||
|
paySubject: pickText(payload.paySubject),
|
||||||
|
orderIds: (payload.orderIds ?? []).map(toId),
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
APP_API_PATHS,
|
APP_API_PATHS,
|
||||||
normalizeAppOrderDetailResponse,
|
normalizeAppOrderDetailResponse,
|
||||||
|
normalizeAppOrderConfirmResponse,
|
||||||
normalizeAppOrderPageResponse,
|
normalizeAppOrderPageResponse,
|
||||||
normalizeMallAppPayload,
|
normalizeMallAppPayload,
|
||||||
postMallApp,
|
postMallApp,
|
||||||
@@ -40,9 +41,15 @@ export const apiAppOrderDetail = async (payload: AppOrderDetailRequest, signal?:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const apiAppOrderConfirm = (payload: AppOrderConfirmRequest, signal?: AbortSignal) =>
|
export const apiAppOrderConfirm = async (payload: AppOrderConfirmRequest, signal?: AbortSignal) => {
|
||||||
postMallApp<AppOrderConfirmResponse, AppOrderConfirmRequest>(
|
const response = await postMallApp<AppOrderConfirmResponse, AppOrderConfirmRequest>(
|
||||||
APP_API_PATHS.orderConfirm,
|
APP_API_PATHS.orderConfirm,
|
||||||
normalizeMallAppPayload(payload),
|
normalizeMallAppPayload(payload),
|
||||||
signal
|
signal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data: normalizeAppOrderConfirmResponse(response.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ export const APP_API_PATHS = {
|
|||||||
cartList: '/api/v1/mall/app/cart_list',
|
cartList: '/api/v1/mall/app/cart_list',
|
||||||
cartSave: '/api/v1/mall/app/cart_save',
|
cartSave: '/api/v1/mall/app/cart_save',
|
||||||
cartRemove: '/api/v1/mall/app/cart_remove',
|
cartRemove: '/api/v1/mall/app/cart_remove',
|
||||||
|
addressList: '/api/v1/mall/app/address_list',
|
||||||
|
addressSave: '/api/v1/mall/app/address_save',
|
||||||
|
addressDelete: '/api/v1/mall/app/address_delete',
|
||||||
|
addressDefaultSet: '/api/v1/mall/app/address_default_set',
|
||||||
tradePreview: '/api/v1/mall/app/trade_preview',
|
tradePreview: '/api/v1/mall/app/trade_preview',
|
||||||
tradeCreate: '/api/v1/mall/app/trade_create',
|
tradeCreate: '/api/v1/mall/app/trade_create',
|
||||||
orderPage: '/api/v1/mall/app/order_page',
|
orderPage: '/api/v1/mall/app/order_page',
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
APP_API_PATHS,
|
APP_API_PATHS,
|
||||||
|
normalizeAppTradeCreateResponse,
|
||||||
normalizeAppTradePreviewResponse,
|
normalizeAppTradePreviewResponse,
|
||||||
normalizeMallAppPayload,
|
normalizeMallAppPayload,
|
||||||
postMallApp,
|
postMallApp,
|
||||||
@@ -24,9 +25,15 @@ export const apiAppTradePreview = async (payload: AppTradePreviewRequest, signal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const apiAppTradeCreate = (payload: AppTradeCreateRequest, signal?: AbortSignal) =>
|
export const apiAppTradeCreate = async (payload: AppTradeCreateRequest, signal?: AbortSignal) => {
|
||||||
postMallApp<AppTradeCreateResponse, AppTradeCreateRequest>(
|
const response = await postMallApp<AppTradeCreateResponse, AppTradeCreateRequest>(
|
||||||
APP_API_PATHS.tradeCreate,
|
APP_API_PATHS.tradeCreate,
|
||||||
normalizeMallAppPayload(payload),
|
normalizeMallAppPayload(payload),
|
||||||
signal
|
signal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
data: normalizeAppTradeCreateResponse(response.data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
1591
src/index.css
1591
src/index.css
File diff suppressed because it is too large
Load Diff
@@ -152,10 +152,10 @@ const buildGoods = (seed: string[], index: number): GoodsSummary => {
|
|||||||
const price = 29 + index * 7
|
const price = 29 + index * 7
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: 10001 + index,
|
id: String(10001 + index),
|
||||||
merchantId: String(5001 + (index % 4)),
|
merchantId: String(5001 + (index % 4)),
|
||||||
storeId: 6001 + (index % 5),
|
storeId: String(6001 + (index % 5)),
|
||||||
categoryId: index + 1,
|
categoryId: String(index + 1),
|
||||||
categoryName: category.label,
|
categoryName: category.label,
|
||||||
spuNo: `YTSPU${String(index + 1).padStart(4, '0')}`,
|
spuNo: `YTSPU${String(index + 1).padStart(4, '0')}`,
|
||||||
spuName: seed[0],
|
spuName: seed[0],
|
||||||
@@ -181,7 +181,7 @@ const buildStore = (seed: string[], index: number): RecommendMerchantInfo => {
|
|||||||
const category = MARKET_CATEGORIES[(index % (MARKET_CATEGORIES.length - 1)) + 1]
|
const category = MARKET_CATEGORIES[(index % (MARKET_CATEGORIES.length - 1)) + 1]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: 9001 + index,
|
id: String(9001 + index),
|
||||||
merchantId: String(5001 + index),
|
merchantId: String(5001 + index),
|
||||||
storeName: seed[0],
|
storeName: seed[0],
|
||||||
storeLogo: createArtwork(seed[0], seed[1], category.accent, category.accentSoft),
|
storeLogo: createArtwork(seed[0], seed[1], category.accent, category.accentSoft),
|
||||||
@@ -206,14 +206,14 @@ export const FALLBACK_GOODS_PAGE: AppGoodsPageResponse = {
|
|||||||
|
|
||||||
export const FALLBACK_HOME: AppHomeResponse = {
|
export const FALLBACK_HOME: AppHomeResponse = {
|
||||||
categoryNavs: MARKET_CATEGORIES.map((item, index) => ({
|
categoryNavs: MARKET_CATEGORIES.map((item, index) => ({
|
||||||
categoryId: index + 1,
|
categoryId: String(index + 1),
|
||||||
categoryName: item.label,
|
categoryName: item.label,
|
||||||
goodsCount: Math.max(0, goodsList.length - index),
|
goodsCount: Math.max(0, goodsList.length - index),
|
||||||
sort: index,
|
sort: index,
|
||||||
})),
|
})),
|
||||||
banners: [
|
banners: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: '1',
|
||||||
title: '精准搜款 · 一件代发',
|
title: '精准搜款 · 一件代发',
|
||||||
subTitle: '多平台供给与商家资源聚合',
|
subTitle: '多平台供给与商家资源聚合',
|
||||||
description: '首页主视觉广告栏',
|
description: '首页主视觉广告栏',
|
||||||
@@ -228,7 +228,7 @@ export const FALLBACK_HOME: AppHomeResponse = {
|
|||||||
endTime: 1730000000,
|
endTime: 1730000000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: '2',
|
||||||
title: '热卖数码专场',
|
title: '热卖数码专场',
|
||||||
subTitle: '快充、支架、耳机同步起量',
|
subTitle: '快充、支架、耳机同步起量',
|
||||||
description: '首页活动广告栏',
|
description: '首页活动广告栏',
|
||||||
@@ -245,7 +245,7 @@ export const FALLBACK_HOME: AppHomeResponse = {
|
|||||||
],
|
],
|
||||||
searchKeywords: HOT_KEYWORDS,
|
searchKeywords: HOT_KEYWORDS,
|
||||||
channels: PLATFORM_CHANNELS.map((item, index) => ({
|
channels: PLATFORM_CHANNELS.map((item, index) => ({
|
||||||
id: index + 1,
|
id: String(index + 1),
|
||||||
title: item.label,
|
title: item.label,
|
||||||
subTitle: item.subtitle,
|
subTitle: item.subtitle,
|
||||||
iconUrl: '',
|
iconUrl: '',
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { useNavigate, useParams } from 'react-router-dom'
|
import { useNavigate, useParams } from 'react-router-dom'
|
||||||
import { apiAppGoodsDetail } from '@/apis'
|
import { toast } from 'sonner'
|
||||||
|
import { apiAppCartSave, apiAppGoodsDetail } from '@/apis'
|
||||||
import MarketPageHeader from '@/components/MarketPageHeader'
|
import MarketPageHeader from '@/components/MarketPageHeader'
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
import type {
|
import type {
|
||||||
@@ -58,12 +59,12 @@ const WHITE_IMAGE_KEYWORDS = ['white', 'wash', 'clean', 'plain', 'background', '
|
|||||||
|
|
||||||
const getSpecValue = (sku: ResolvedGoodsSkuInfo, patterns: string[]) => {
|
const getSpecValue = (sku: ResolvedGoodsSkuInfo, patterns: string[]) => {
|
||||||
const matched = sku.specs.find(spec => {
|
const matched = sku.specs.find(spec => {
|
||||||
const name = typeof spec.name === 'string' ? spec.name : ''
|
const name = typeof spec.attributeName === 'string' ? spec.attributeName : ''
|
||||||
|
|
||||||
return patterns.some(pattern => name.toLowerCase().includes(pattern.toLowerCase()))
|
return patterns.some(pattern => name.toLowerCase().includes(pattern.toLowerCase()))
|
||||||
})
|
})
|
||||||
|
|
||||||
return typeof matched?.value === 'string' ? matched.value.trim() : ''
|
return typeof matched?.attributeValue === 'string' ? matched.attributeValue.trim() : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const splitSkuName = (skuName: string) =>
|
const splitSkuName = (skuName: string) =>
|
||||||
@@ -175,14 +176,18 @@ const getProductParams = (detail: ResolvedGoodsDetailInfo): ParamItem[] => {
|
|||||||
].filter(item => item.value)
|
].filter(item => item.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getSelectedCartItems = (skus: ResolvedGoodsSkuInfo[], quantities: Record<string, number>) =>
|
||||||
|
skus
|
||||||
|
.map(sku => ({
|
||||||
|
sku,
|
||||||
|
buyNum: Math.min(Math.max(0, quantities[sku.id] ?? 0), sku.stock),
|
||||||
|
}))
|
||||||
|
.filter(item => item.buyNum > 0)
|
||||||
|
|
||||||
function GoodsDetailPage() {
|
function GoodsDetailPage() {
|
||||||
const { spuId = '' } = useParams()
|
const { spuId = '' } = useParams()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const token = useUserStore(state => state.token)
|
const token = useUserStore(state => state.token)
|
||||||
const userInfo = useUserStore(state => state.userInfo)
|
|
||||||
const storedMemberId = useUserStore(state => state.memberId)
|
|
||||||
|
|
||||||
const currentUid = userInfo?.uid ?? storedMemberId ?? token?.memberId ?? token?.uid ?? 0
|
|
||||||
|
|
||||||
const [payload, setPayload] = useState<AppGoodsDetailResponse | null>(null)
|
const [payload, setPayload] = useState<AppGoodsDetailResponse | null>(null)
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
@@ -191,7 +196,8 @@ function GoodsDetailPage() {
|
|||||||
const [keyword, setKeyword] = useState('')
|
const [keyword, setKeyword] = useState('')
|
||||||
const [selectedColor, setSelectedColor] = useState('')
|
const [selectedColor, setSelectedColor] = useState('')
|
||||||
const [activeDetailTab, setActiveDetailTab] = useState<DetailTabKey>('detail')
|
const [activeDetailTab, setActiveDetailTab] = useState<DetailTabKey>('detail')
|
||||||
const [quantities, setQuantities] = useState<Record<number, number>>({})
|
const [quantities, setQuantities] = useState<Record<string, number>>({})
|
||||||
|
const [cartSaving, setCartSaving] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!spuId) {
|
if (!spuId) {
|
||||||
@@ -204,7 +210,7 @@ function GoodsDetailPage() {
|
|||||||
setLoading(true)
|
setLoading(true)
|
||||||
setError(null)
|
setError(null)
|
||||||
|
|
||||||
apiAppGoodsDetail({ uid: currentUid, spuId }, controller.signal)
|
apiAppGoodsDetail({ spuId }, controller.signal)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
setPayload(response.data)
|
setPayload(response.data)
|
||||||
})
|
})
|
||||||
@@ -220,7 +226,7 @@ function GoodsDetailPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return () => controller.abort()
|
return () => controller.abort()
|
||||||
}, [currentUid, spuId])
|
}, [spuId])
|
||||||
|
|
||||||
const detail = useMemo(() => (payload?.data ? resolveGoodsDetailInfo(payload.data) : null), [payload])
|
const detail = useMemo(() => (payload?.data ? resolveGoodsDetailInfo(payload.data) : null), [payload])
|
||||||
const merchant = payload?.merchant ?? payload?.store ?? null
|
const merchant = payload?.merchant ?? payload?.store ?? null
|
||||||
@@ -273,6 +279,14 @@ function GoodsDetailPage() {
|
|||||||
return galleryImages
|
return galleryImages
|
||||||
}, [detailImages, galleryImages])
|
}, [detailImages, galleryImages])
|
||||||
const whiteImages = useMemo(() => (detail ? getWhiteImageList(detail) : []), [detail])
|
const whiteImages = useMemo(() => (detail ? getWhiteImageList(detail) : []), [detail])
|
||||||
|
const selectedCartItems = useMemo(
|
||||||
|
() => getSelectedCartItems(detail?.skus ?? [], quantities),
|
||||||
|
[detail, quantities]
|
||||||
|
)
|
||||||
|
const selectedCartTotal = useMemo(
|
||||||
|
() => selectedCartItems.reduce((total, item) => total + item.buyNum, 0),
|
||||||
|
[selectedCartItems]
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setActiveImage(galleryImages[0] ?? '')
|
setActiveImage(galleryImages[0] ?? '')
|
||||||
@@ -282,9 +296,9 @@ function GoodsDetailPage() {
|
|||||||
setSelectedColor(colorOptions[0]?.color ?? '')
|
setSelectedColor(colorOptions[0]?.color ?? '')
|
||||||
}, [colorOptions])
|
}, [colorOptions])
|
||||||
|
|
||||||
const updateQuantity = (skuId: number, delta: number) => {
|
const updateQuantity = (skuId: string, delta: number, stock: number) => {
|
||||||
setQuantities(current => {
|
setQuantities(current => {
|
||||||
const nextValue = Math.max(0, (current[skuId] ?? 0) + delta)
|
const nextValue = Math.min(stock, Math.max(0, (current[skuId] ?? 0) + delta))
|
||||||
return {
|
return {
|
||||||
...current,
|
...current,
|
||||||
[skuId]: nextValue,
|
[skuId]: nextValue,
|
||||||
@@ -292,6 +306,36 @@ function GoodsDetailPage() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleAddCart = async () => {
|
||||||
|
if (!token?.accessToken) {
|
||||||
|
navigate('/login')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedCartItems.length === 0) {
|
||||||
|
toast.warning('请先选择要加入购物车的商品数量')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setCartSaving(true)
|
||||||
|
await Promise.all(
|
||||||
|
selectedCartItems.map(item =>
|
||||||
|
apiAppCartSave({
|
||||||
|
skuId: item.sku.id,
|
||||||
|
buyNum: item.buyNum,
|
||||||
|
checked: true,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
toast.success(`已加入购物车 ${selectedCartTotal} 件商品`)
|
||||||
|
} catch (nextError) {
|
||||||
|
toast.error(nextError instanceof Error ? nextError.message : '加入购物车失败')
|
||||||
|
} finally {
|
||||||
|
setCartSaving(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleHeaderSearch = (nextKeyword: string) => {
|
const handleHeaderSearch = (nextKeyword: string) => {
|
||||||
const trimmedKeyword = nextKeyword.trim()
|
const trimmedKeyword = nextKeyword.trim()
|
||||||
navigate(trimmedKeyword ? `/list/new?key=${encodeURIComponent(trimmedKeyword)}` : '/list/new')
|
navigate(trimmedKeyword ? `/list/new?key=${encodeURIComponent(trimmedKeyword)}` : '/list/new')
|
||||||
@@ -425,11 +469,15 @@ function GoodsDetailPage() {
|
|||||||
<strong>{formatMoney(option.sku.salePrice || detail.minPrice)}</strong>
|
<strong>{formatMoney(option.sku.salePrice || detail.minPrice)}</strong>
|
||||||
<small>库存 {option.sku.stock}</small>
|
<small>库存 {option.sku.stock}</small>
|
||||||
<div>
|
<div>
|
||||||
<button type="button" onClick={() => updateQuantity(option.sku.id, -1)}>
|
<button type="button" onClick={() => updateQuantity(option.sku.id, -1, option.sku.stock)}>
|
||||||
-
|
-
|
||||||
</button>
|
</button>
|
||||||
<b>{quantities[option.sku.id] ?? 0}</b>
|
<b>{quantities[option.sku.id] ?? 0}</b>
|
||||||
<button type="button" onClick={() => updateQuantity(option.sku.id, 1)}>
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={option.sku.stock <= 0 || (quantities[option.sku.id] ?? 0) >= option.sku.stock}
|
||||||
|
onClick={() => updateQuantity(option.sku.id, 1, option.sku.stock)}
|
||||||
|
>
|
||||||
+
|
+
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -440,6 +488,27 @@ function GoodsDetailPage() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="market-empty-state">暂无 SKU 信息</div>
|
<div className="market-empty-state">暂无 SKU 信息</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{detail.skus.length > 0 ? (
|
||||||
|
<div className="market-detail-cart-actions">
|
||||||
|
<button
|
||||||
|
className="market-detail-cart-actions__primary"
|
||||||
|
type="button"
|
||||||
|
disabled={cartSaving}
|
||||||
|
onClick={() => void handleAddCart()}
|
||||||
|
>
|
||||||
|
{cartSaving ? '加入中...' : '加入购物车'}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="market-detail-cart-actions__ghost"
|
||||||
|
type="button"
|
||||||
|
onClick={() => navigate('/member?tab=cart')}
|
||||||
|
>
|
||||||
|
查看购物车
|
||||||
|
</button>
|
||||||
|
{selectedCartTotal > 0 ? <span>已选 {selectedCartTotal} 件</span> : null}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<aside
|
<aside
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { toast } from 'sonner'
|
|||||||
import { apiAppGoodsPage, apiAppHome, apiAppRecentNewGoods } from '@/apis'
|
import { apiAppGoodsPage, apiAppHome, apiAppRecentNewGoods } from '@/apis'
|
||||||
import MarketPageHeader from '@/components/MarketPageHeader'
|
import MarketPageHeader from '@/components/MarketPageHeader'
|
||||||
import type { MarketNavKey } from '@/components/MarketNav'
|
import type { MarketNavKey } from '@/components/MarketNav'
|
||||||
import { useUserStore } from '@/store/user'
|
|
||||||
import type {
|
import type {
|
||||||
AppGoodsPageResponse,
|
AppGoodsPageResponse,
|
||||||
AppHomeResponse,
|
AppHomeResponse,
|
||||||
@@ -150,11 +149,7 @@ function HomePage() {
|
|||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
const token = useUserStore(state => state.token)
|
|
||||||
const userInfo = useUserStore(state => state.userInfo)
|
|
||||||
const storedMemberId = useUserStore(state => state.memberId)
|
|
||||||
|
|
||||||
const currentUid = userInfo?.uid ?? storedMemberId ?? token?.memberId ?? token?.uid ?? 0
|
|
||||||
const initialSearchKeyword = searchParams.get('key')?.trim() ?? ''
|
const initialSearchKeyword = searchParams.get('key')?.trim() ?? ''
|
||||||
const isInitialSearchPage = location.pathname === '/list/new' || Boolean(initialSearchKeyword)
|
const isInitialSearchPage = location.pathname === '/list/new' || Boolean(initialSearchKeyword)
|
||||||
|
|
||||||
@@ -193,7 +188,7 @@ function HomePage() {
|
|||||||
setHomeLoading(true)
|
setHomeLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiAppHome({ uid: currentUid })
|
const response = await apiAppHome()
|
||||||
|
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
return
|
return
|
||||||
@@ -221,7 +216,7 @@ function HomePage() {
|
|||||||
return () => {
|
return () => {
|
||||||
canceled = true
|
canceled = true
|
||||||
}
|
}
|
||||||
}, [currentUid])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let canceled = false
|
let canceled = false
|
||||||
@@ -231,7 +226,6 @@ function HomePage() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiAppRecentNewGoods({
|
const response = await apiAppRecentNewGoods({
|
||||||
uid: currentUid,
|
|
||||||
page: 1,
|
page: 1,
|
||||||
size: RECENT_GOODS_PAGE_SIZE,
|
size: RECENT_GOODS_PAGE_SIZE,
|
||||||
})
|
})
|
||||||
@@ -262,7 +256,7 @@ function HomePage() {
|
|||||||
return () => {
|
return () => {
|
||||||
canceled = true
|
canceled = true
|
||||||
}
|
}
|
||||||
}, [currentUid, recentNewGoodsRefreshKey])
|
}, [recentNewGoodsRefreshKey])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let canceled = false
|
let canceled = false
|
||||||
@@ -272,7 +266,6 @@ function HomePage() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiAppGoodsPage({
|
const response = await apiAppGoodsPage({
|
||||||
uid: currentUid,
|
|
||||||
keyword: submittedKeyword || undefined,
|
keyword: submittedKeyword || undefined,
|
||||||
sortType,
|
sortType,
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -305,7 +298,7 @@ function HomePage() {
|
|||||||
return () => {
|
return () => {
|
||||||
canceled = true
|
canceled = true
|
||||||
}
|
}
|
||||||
}, [currentUid, sortType, submittedKeyword])
|
}, [sortType, submittedKeyword])
|
||||||
|
|
||||||
const banners = useMemo(() => resolveHomeTopBanners(homePayload), [homePayload])
|
const banners = useMemo(() => resolveHomeTopBanners(homePayload), [homePayload])
|
||||||
const recommendStores = useMemo(() => resolveHomeRankStores(homePayload), [homePayload])
|
const recommendStores = useMemo(() => resolveHomeRankStores(homePayload), [homePayload])
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@ import { useEffect, useMemo, useState } from 'react'
|
|||||||
import { Link, useNavigate, useParams } from 'react-router-dom'
|
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||||
import { apiAppGoodsPage, apiAppHomeMerchantGoods } from '@/apis'
|
import { apiAppGoodsPage, apiAppHomeMerchantGoods } from '@/apis'
|
||||||
import MarketPageHeader from '@/components/MarketPageHeader'
|
import MarketPageHeader from '@/components/MarketPageHeader'
|
||||||
import { useUserStore } from '@/store/user'
|
|
||||||
import type { AppGoodsPageResponse, HomeMerchantGoodsBlock, GoodsSortType, GoodsSummary } from '@/types/mall'
|
import type { AppGoodsPageResponse, HomeMerchantGoodsBlock, GoodsSortType, GoodsSummary } from '@/types/mall'
|
||||||
|
|
||||||
const GOODS_SORT_OPTIONS: Array<{ key: GoodsSortType; label: string }> = [
|
const GOODS_SORT_OPTIONS: Array<{ key: GoodsSortType; label: string }> = [
|
||||||
@@ -36,11 +35,6 @@ const formatPrice = (item: GoodsSummary) => {
|
|||||||
function ShopPage() {
|
function ShopPage() {
|
||||||
const { merchantId = '' } = useParams()
|
const { merchantId = '' } = useParams()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const token = useUserStore(state => state.token)
|
|
||||||
const userInfo = useUserStore(state => state.userInfo)
|
|
||||||
const storedMemberId = useUserStore(state => state.memberId)
|
|
||||||
|
|
||||||
const currentUid = userInfo?.uid ?? storedMemberId ?? token?.memberId ?? token?.uid ?? 0
|
|
||||||
|
|
||||||
const [headerKeyword, setHeaderKeyword] = useState('')
|
const [headerKeyword, setHeaderKeyword] = useState('')
|
||||||
const [keyword, setKeyword] = useState('')
|
const [keyword, setKeyword] = useState('')
|
||||||
@@ -61,14 +55,14 @@ function ShopPage() {
|
|||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
setError(null)
|
setError(null)
|
||||||
|
|
||||||
apiAppHomeMerchantGoods({ uid: currentUid, merchantId, limit: 12 }, controller.signal)
|
apiAppHomeMerchantGoods({ merchantId, limit: 12 }, controller.signal)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
setMerchantBlock(response.data.data)
|
setMerchantBlock(response.data.data)
|
||||||
})
|
})
|
||||||
.catch(() => undefined)
|
.catch(() => undefined)
|
||||||
|
|
||||||
return () => controller.abort()
|
return () => controller.abort()
|
||||||
}, [currentUid, merchantId])
|
}, [merchantId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!merchantId) {
|
if (!merchantId) {
|
||||||
@@ -81,7 +75,6 @@ function ShopPage() {
|
|||||||
|
|
||||||
apiAppGoodsPage(
|
apiAppGoodsPage(
|
||||||
{
|
{
|
||||||
uid: currentUid,
|
|
||||||
merchantId,
|
merchantId,
|
||||||
keyword: searchKeyword || undefined,
|
keyword: searchKeyword || undefined,
|
||||||
sortType,
|
sortType,
|
||||||
@@ -105,7 +98,7 @@ function ShopPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return () => controller.abort()
|
return () => controller.abort()
|
||||||
}, [currentUid, merchantId, searchKeyword, sortType])
|
}, [merchantId, searchKeyword, sortType])
|
||||||
|
|
||||||
const goodsList = useMemo(() => goodsPayload?.list ?? merchantBlock?.goods ?? [], [goodsPayload, merchantBlock])
|
const goodsList = useMemo(() => goodsPayload?.list ?? merchantBlock?.goods ?? [], [goodsPayload, merchantBlock])
|
||||||
const merchant = merchantBlock?.merchant ?? merchantBlock?.store ?? null
|
const merchant = merchantBlock?.merchant ?? merchantBlock?.store ?? null
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ export interface DetailJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SpecItem {
|
export interface SpecItem {
|
||||||
name: string
|
attributeName: string
|
||||||
value: string
|
attributeValue: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ParamItem {
|
export interface ParamItem {
|
||||||
@@ -74,7 +74,7 @@ export interface ExtraInfoJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface StoreInfo {
|
export interface StoreInfo {
|
||||||
id: number
|
id: string
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
merchantName?: string
|
merchantName?: string
|
||||||
logo?: string
|
logo?: string
|
||||||
@@ -102,10 +102,10 @@ export interface StoreInfo {
|
|||||||
export type MerchantInfo = StoreInfo
|
export type MerchantInfo = StoreInfo
|
||||||
|
|
||||||
export interface GoodsSkuInfo {
|
export interface GoodsSkuInfo {
|
||||||
id: number
|
id: string
|
||||||
spuId: number
|
spuId: string
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
storeId: number
|
storeId: string
|
||||||
skuNo: string
|
skuNo: string
|
||||||
skuName: string
|
skuName: string
|
||||||
barcode: string
|
barcode: string
|
||||||
@@ -124,12 +124,12 @@ export interface GoodsSkuInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GoodsSummary {
|
export interface GoodsSummary {
|
||||||
id: number
|
id: string
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
merchantName?: string
|
merchantName?: string
|
||||||
merchantLogo?: string
|
merchantLogo?: string
|
||||||
storeId: number
|
storeId: string
|
||||||
categoryId: number
|
categoryId: string
|
||||||
categoryName: string
|
categoryName: string
|
||||||
spuNo: string
|
spuNo: string
|
||||||
spuName: string
|
spuName: string
|
||||||
@@ -151,10 +151,10 @@ export interface GoodsSummary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GoodsDetailInfo {
|
export interface GoodsDetailInfo {
|
||||||
id: number
|
id: string
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
storeId: number
|
storeId: string
|
||||||
categoryId: number
|
categoryId: string
|
||||||
categoryName?: string
|
categoryName?: string
|
||||||
spuNo: string
|
spuNo: string
|
||||||
spuName: string
|
spuName: string
|
||||||
@@ -182,13 +182,15 @@ export interface GoodsDetailInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CartItemInfo {
|
export interface CartItemInfo {
|
||||||
id: number
|
id: string
|
||||||
uid: number
|
uid: number
|
||||||
memberId?: number
|
memberId?: MerchantId
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
storeId: number
|
merchantName?: string
|
||||||
spuId: number
|
merchantLogo?: string
|
||||||
skuId: number
|
storeId: string
|
||||||
|
spuId: string
|
||||||
|
skuId: string
|
||||||
spuName: string
|
spuName: string
|
||||||
skuName: string
|
skuName: string
|
||||||
coverUrl: string
|
coverUrl: string
|
||||||
@@ -196,19 +198,91 @@ export interface CartItemInfo {
|
|||||||
buyNum: number
|
buyNum: number
|
||||||
checked: boolean
|
checked: boolean
|
||||||
salePrice: string
|
salePrice: string
|
||||||
|
itemAmount: string
|
||||||
status: CartItemStatus
|
status: CartItemStatus
|
||||||
createdAt: number
|
createdAt: number
|
||||||
updatedAt: number
|
updatedAt: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CartGoodsGroupInfo {
|
||||||
|
spuId: string
|
||||||
|
spuName: string
|
||||||
|
coverUrl: string
|
||||||
|
checked: boolean
|
||||||
|
goodsAmount?: string
|
||||||
|
checkedAmount?: string
|
||||||
|
items: CartItemInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CartMerchantGroupInfo {
|
||||||
|
merchantId: MerchantId
|
||||||
|
merchantName: string
|
||||||
|
merchantLogo: string
|
||||||
|
checked: boolean
|
||||||
|
itemCount?: number
|
||||||
|
goodsCount?: number
|
||||||
|
goodsAmount?: string
|
||||||
|
checkedAmount?: string
|
||||||
|
goods: CartGoodsGroupInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserAddressInfo {
|
||||||
|
id: string
|
||||||
|
uid: number
|
||||||
|
receiverName: string
|
||||||
|
receiverMobile: string
|
||||||
|
countryCode: string
|
||||||
|
province: string
|
||||||
|
city: string
|
||||||
|
district: string
|
||||||
|
addressDetail: string
|
||||||
|
zipCode: string
|
||||||
|
tag: string
|
||||||
|
isDefault: boolean
|
||||||
|
createdAt: number
|
||||||
|
updatedAt: number
|
||||||
|
}
|
||||||
|
|
||||||
export interface TradeBuyItem {
|
export interface TradeBuyItem {
|
||||||
skuId: number
|
skuId: string
|
||||||
buyNum: number
|
buyNum: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TradeMerchantOptionInput {
|
||||||
|
merchantId: MerchantId
|
||||||
|
deliveryOptionId?: string
|
||||||
|
packageOptionId?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MerchantDeliveryOptionInfo {
|
||||||
|
id: string
|
||||||
|
merchantId: MerchantId
|
||||||
|
optionName: string
|
||||||
|
deliveryCode: string
|
||||||
|
feeAmount: string
|
||||||
|
description: string
|
||||||
|
sort: number
|
||||||
|
status: EnabledStatus
|
||||||
|
createdAt: number
|
||||||
|
updatedAt: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MerchantPackageOptionInfo {
|
||||||
|
id: string
|
||||||
|
merchantId: MerchantId
|
||||||
|
optionName: string
|
||||||
|
packageCode: string
|
||||||
|
feeAmount: string
|
||||||
|
description: string
|
||||||
|
sort: number
|
||||||
|
status: EnabledStatus
|
||||||
|
createdAt: number
|
||||||
|
updatedAt: number
|
||||||
|
}
|
||||||
|
|
||||||
export interface TradePreviewItemInfo {
|
export interface TradePreviewItemInfo {
|
||||||
spuId: number
|
spuId: string
|
||||||
skuId: number
|
skuId: string
|
||||||
spuName: string
|
spuName: string
|
||||||
skuName: string
|
skuName: string
|
||||||
coverUrl: string
|
coverUrl: string
|
||||||
@@ -220,19 +294,25 @@ export interface TradePreviewItemInfo {
|
|||||||
|
|
||||||
export interface TradePreviewStoreInfo {
|
export interface TradePreviewStoreInfo {
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
storeId: number
|
merchantName: string
|
||||||
storeName: string
|
storeId?: string
|
||||||
|
storeName?: string
|
||||||
goodsAmount: string
|
goodsAmount: string
|
||||||
freightAmount: string
|
freightAmount: string
|
||||||
|
packageAmount: string
|
||||||
discountAmount: string
|
discountAmount: string
|
||||||
payAmount: string
|
payAmount: string
|
||||||
|
deliveryOptions: MerchantDeliveryOptionInfo[]
|
||||||
|
packageOptions: MerchantPackageOptionInfo[]
|
||||||
|
selectedDeliveryOption?: MerchantDeliveryOptionInfo
|
||||||
|
selectedPackageOption?: MerchantPackageOptionInfo
|
||||||
items: TradePreviewItemInfo[]
|
items: TradePreviewItemInfo[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TradePreviewInfo {
|
export interface TradePreviewInfo {
|
||||||
uid: number
|
uid: number
|
||||||
memberId?: number
|
memberId?: MerchantId
|
||||||
addressId: number
|
addressId: string
|
||||||
receiverName: string
|
receiverName: string
|
||||||
receiverMobile: string
|
receiverMobile: string
|
||||||
receiverCountryCode: string
|
receiverCountryCode: string
|
||||||
@@ -245,6 +325,7 @@ export interface TradePreviewInfo {
|
|||||||
currency: string
|
currency: string
|
||||||
goodsAmount: string
|
goodsAmount: string
|
||||||
freightAmount: string
|
freightAmount: string
|
||||||
|
packageAmount: string
|
||||||
discountAmount: string
|
discountAmount: string
|
||||||
payAmount: string
|
payAmount: string
|
||||||
orderCount: number
|
orderCount: number
|
||||||
@@ -253,12 +334,12 @@ export interface TradePreviewInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderItemInfo {
|
export interface OrderItemInfo {
|
||||||
id: number
|
id: string
|
||||||
orderId: number
|
orderId: string
|
||||||
tradeId: number
|
tradeId: string
|
||||||
orderNo: string
|
orderNo: string
|
||||||
spuId: number
|
spuId: string
|
||||||
skuId: number
|
skuId: string
|
||||||
spuName: string
|
spuName: string
|
||||||
skuName: string
|
skuName: string
|
||||||
coverUrl: string
|
coverUrl: string
|
||||||
@@ -273,20 +354,21 @@ export interface OrderItemInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderSummary {
|
export interface OrderSummary {
|
||||||
id: number
|
id: string
|
||||||
tradeId: number
|
tradeId: string
|
||||||
tradeNo: string
|
tradeNo: string
|
||||||
orderNo: string
|
orderNo: string
|
||||||
uid: number
|
uid: number
|
||||||
memberId?: number
|
memberId?: MerchantId
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
storeId: number
|
storeId: string
|
||||||
storeName: string
|
storeName: string
|
||||||
orderStatus: OrderStatus
|
orderStatus: OrderStatus
|
||||||
afterSaleStatus: AfterSaleStatus
|
afterSaleStatus: AfterSaleStatus
|
||||||
currency: string
|
currency: string
|
||||||
goodsAmount: string
|
goodsAmount: string
|
||||||
freightAmount: string
|
freightAmount: string
|
||||||
|
packageAmount: string
|
||||||
discountAmount: string
|
discountAmount: string
|
||||||
payAmount: string
|
payAmount: string
|
||||||
payTime: number
|
payTime: number
|
||||||
@@ -298,20 +380,21 @@ export interface OrderSummary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderDetailInfo {
|
export interface OrderDetailInfo {
|
||||||
id: number
|
id: string
|
||||||
tradeId: number
|
tradeId: string
|
||||||
tradeNo: string
|
tradeNo: string
|
||||||
orderNo: string
|
orderNo: string
|
||||||
uid: number
|
uid: number
|
||||||
memberId?: number
|
memberId?: MerchantId
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
storeId: number
|
storeId: string
|
||||||
storeName: string
|
storeName: string
|
||||||
orderStatus: OrderStatus
|
orderStatus: OrderStatus
|
||||||
afterSaleStatus: AfterSaleStatus
|
afterSaleStatus: AfterSaleStatus
|
||||||
currency: string
|
currency: string
|
||||||
goodsAmount: string
|
goodsAmount: string
|
||||||
freightAmount: string
|
freightAmount: string
|
||||||
|
packageAmount: string
|
||||||
discountAmount: string
|
discountAmount: string
|
||||||
payAmount: string
|
payAmount: string
|
||||||
buyerRemark: string
|
buyerRemark: string
|
||||||
@@ -327,6 +410,8 @@ export interface OrderDetailInfo {
|
|||||||
deliveryCompany: string
|
deliveryCompany: string
|
||||||
deliveryNo: string
|
deliveryNo: string
|
||||||
payChannel: string
|
payChannel: string
|
||||||
|
selectedDeliveryOption?: MerchantDeliveryOptionInfo
|
||||||
|
selectedPackageOption?: MerchantPackageOptionInfo
|
||||||
extraInfoJson: string
|
extraInfoJson: string
|
||||||
payTime: number
|
payTime: number
|
||||||
shipTime: number
|
shipTime: number
|
||||||
@@ -339,7 +424,7 @@ export interface OrderDetailInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface BannerInfo {
|
export interface BannerInfo {
|
||||||
id: number
|
id: string
|
||||||
title: string
|
title: string
|
||||||
subTitle: string
|
subTitle: string
|
||||||
description: string
|
description: string
|
||||||
@@ -355,14 +440,14 @@ export interface BannerInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface HomeCategoryNav {
|
export interface HomeCategoryNav {
|
||||||
categoryId: number
|
categoryId: string
|
||||||
categoryName: string
|
categoryName: string
|
||||||
goodsCount: number
|
goodsCount: number
|
||||||
sort: number
|
sort: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HomeChannelCard {
|
export interface HomeChannelCard {
|
||||||
id: number
|
id: string
|
||||||
title: string
|
title: string
|
||||||
subTitle: string
|
subTitle: string
|
||||||
iconUrl: string
|
iconUrl: string
|
||||||
@@ -373,7 +458,7 @@ export interface HomeChannelCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RecommendStoreInfo {
|
export interface RecommendStoreInfo {
|
||||||
id: string | number
|
id: string
|
||||||
merchantId: MerchantId
|
merchantId: MerchantId
|
||||||
storeName: string
|
storeName: string
|
||||||
storeLogo: string
|
storeLogo: string
|
||||||
@@ -439,9 +524,7 @@ export interface ResolvedOrderDetailInfo extends OrderDetailInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppHomeRequest {
|
export interface AppHomeRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppHomeResponse {
|
export interface AppHomeResponse {
|
||||||
@@ -470,9 +553,7 @@ export interface RecentNewGoodsItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppRecentNewGoodsRequest {
|
export interface AppRecentNewGoodsRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
page?: number
|
page?: number
|
||||||
size?: number
|
size?: number
|
||||||
}
|
}
|
||||||
@@ -483,12 +564,10 @@ export interface AppRecentNewGoodsResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppHomeMerchantGoodsRequest {
|
export interface AppHomeMerchantGoodsRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
merchantId?: MerchantId
|
merchantId?: MerchantId
|
||||||
/** @deprecated use merchantId */
|
/** @deprecated use merchantId */
|
||||||
storeId?: number
|
storeId?: string
|
||||||
limit?: number
|
limit?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,13 +576,11 @@ export interface AppHomeMerchantGoodsResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppGoodsPageRequest extends IPageParams {
|
export interface AppGoodsPageRequest extends IPageParams {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
merchantId?: MerchantId
|
merchantId?: MerchantId
|
||||||
/** @deprecated use merchantId */
|
/** @deprecated use merchantId */
|
||||||
storeId?: number
|
storeId?: string
|
||||||
categoryId?: number
|
categoryId?: string
|
||||||
keyword?: string
|
keyword?: string
|
||||||
sortType?: GoodsSortType
|
sortType?: GoodsSortType
|
||||||
}
|
}
|
||||||
@@ -514,10 +591,8 @@ export interface AppGoodsPageResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppGoodsDetailRequest {
|
export interface AppGoodsDetailRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
spuId: string
|
||||||
memberId?: number
|
|
||||||
spuId: number | string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppGoodsDetailResponse {
|
export interface AppGoodsDetailResponse {
|
||||||
@@ -528,50 +603,86 @@ export interface AppGoodsDetailResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppCartListRequest {
|
export interface AppCartListRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppCartListResponse {
|
export interface AppCartListResponse {
|
||||||
list: CartItemInfo[]
|
merchantGroups: CartMerchantGroupInfo[]
|
||||||
|
itemCount: number
|
||||||
|
goodsCount: number
|
||||||
|
goodsAmount: string
|
||||||
checkedCount: number
|
checkedCount: number
|
||||||
checkedAmount: string
|
checkedAmount: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppCartSaveRequest {
|
export interface AppCartSaveRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
skuId: string
|
||||||
memberId?: number
|
|
||||||
skuId: number
|
|
||||||
buyNum: number
|
buyNum: number
|
||||||
checked: boolean
|
checked: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppCartSaveResponse {
|
export interface AppCartSaveResponse {
|
||||||
cartId: number
|
cartId: string
|
||||||
buyNum: number
|
buyNum: number
|
||||||
checked: boolean
|
checked: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppCartRemoveRequest {
|
export interface AppCartRemoveRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
skuIds: string[]
|
||||||
memberId?: number
|
|
||||||
skuIds: number[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppCartRemoveResponse {
|
export interface AppCartRemoveResponse {
|
||||||
removedCount: number
|
removedCount: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AppAddressListRequest = Record<string, never>
|
||||||
|
|
||||||
|
export interface AppAddressListResponse {
|
||||||
|
list: UserAddressInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppAddressSaveRequest {
|
||||||
|
id?: string
|
||||||
|
receiverName: string
|
||||||
|
receiverMobile: string
|
||||||
|
countryCode?: string
|
||||||
|
province?: string
|
||||||
|
city?: string
|
||||||
|
district?: string
|
||||||
|
addressDetail: string
|
||||||
|
zipCode?: string
|
||||||
|
tag?: string
|
||||||
|
isDefault?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppAddressSaveResponse {
|
||||||
|
addressId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppAddressDeleteRequest {
|
||||||
|
addressId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppAddressDeleteResponse {
|
||||||
|
removedCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppAddressDefaultSetRequest {
|
||||||
|
addressId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppAddressDefaultSetResponse {
|
||||||
|
addressId: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface AppTradePreviewRequest {
|
export interface AppTradePreviewRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
buyItems?: TradeBuyItem[]
|
buyItems?: TradeBuyItem[]
|
||||||
addressId: number
|
addressId: string
|
||||||
buyerRemark?: string
|
buyerRemark?: string
|
||||||
|
merchantOptions?: TradeMerchantOptionInput[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppTradePreviewResponse {
|
export interface AppTradePreviewResponse {
|
||||||
@@ -579,30 +690,32 @@ export interface AppTradePreviewResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppTradeCreateRequest {
|
export interface AppTradeCreateRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
buyItems?: TradeBuyItem[]
|
buyItems?: TradeBuyItem[]
|
||||||
addressId: number
|
addressId: string
|
||||||
buyerRemark?: string
|
buyerRemark?: string
|
||||||
payChannel: string
|
payChannel: string
|
||||||
|
merchantOptions?: TradeMerchantOptionInput[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppTradeCreateResponse {
|
export interface AppTradeCreateResponse {
|
||||||
tradeId: number
|
tradeId: string
|
||||||
tradeNo: string
|
tradeNo: string
|
||||||
payStatus: PayStatus
|
payStatus: PayStatus
|
||||||
tradeStatus: TradeStatus
|
tradeStatus: TradeStatus
|
||||||
payAmount: string
|
payAmount: string
|
||||||
expiredAt: number
|
expiredAt: number
|
||||||
orderIds: number[]
|
payUrl?: string
|
||||||
|
payExternal?: boolean
|
||||||
|
payExpiredAt?: number
|
||||||
|
payChannel?: string
|
||||||
|
paySubject?: string
|
||||||
|
orderIds: string[]
|
||||||
orderNos: string[]
|
orderNos: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppOrderPageRequest extends IPageParams {
|
export interface AppOrderPageRequest extends IPageParams {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
|
||||||
memberId?: number
|
|
||||||
orderStatus?: OrderStatus
|
orderStatus?: OrderStatus
|
||||||
afterSaleStatus?: AfterSaleStatus
|
afterSaleStatus?: AfterSaleStatus
|
||||||
}
|
}
|
||||||
@@ -613,10 +726,8 @@ export interface AppOrderPageResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppOrderDetailRequest {
|
export interface AppOrderDetailRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
orderId: string
|
||||||
memberId?: number
|
|
||||||
orderId: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppOrderDetailResponse {
|
export interface AppOrderDetailResponse {
|
||||||
@@ -624,24 +735,20 @@ export interface AppOrderDetailResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppOrderConfirmRequest {
|
export interface AppOrderConfirmRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
orderId: string
|
||||||
memberId?: number
|
|
||||||
orderId: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppOrderConfirmResponse {
|
export interface AppOrderConfirmResponse {
|
||||||
orderId: number
|
orderId: string
|
||||||
orderStatus: OrderStatus
|
orderStatus: OrderStatus
|
||||||
finishTime: number
|
finishTime: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppAfterSaleApplyRequest {
|
export interface AppAfterSaleApplyRequest {
|
||||||
uid?: number
|
memberId?: MerchantId
|
||||||
/** @deprecated use uid */
|
orderId: string
|
||||||
memberId?: number
|
orderItemId: string
|
||||||
orderId: number
|
|
||||||
orderItemId: number
|
|
||||||
afterSaleType: AfterSaleType
|
afterSaleType: AfterSaleType
|
||||||
reason: string
|
reason: string
|
||||||
description?: string
|
description?: string
|
||||||
@@ -650,7 +757,7 @@ export interface AppAfterSaleApplyRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AppAfterSaleApplyResponse {
|
export interface AppAfterSaleApplyResponse {
|
||||||
afterSaleId: number
|
afterSaleId: string
|
||||||
afterSaleNo: string
|
afterSaleNo: string
|
||||||
afterSaleStatus: Exclude<AfterSaleStatus, 'none'>
|
afterSaleStatus: Exclude<AfterSaleStatus, 'none'>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user