629 lines
14 KiB
TypeScript
629 lines
14 KiB
TypeScript
export type TaskStatus =
|
|
| 'WAITING'
|
|
| 'CLAIMED'
|
|
| 'STARTED'
|
|
| 'SUBMITTED'
|
|
| 'COMPLETED'
|
|
| 'REJECTED'
|
|
| 'EXEMPT'
|
|
| 'SETTLED'
|
|
| 'CANCELLED';
|
|
|
|
export type SettlementStatus = 'DRAFT' | 'CONFIRMED' | 'PAID' | 'CANCELLED';
|
|
export type PayoutStateFilter = 'NONE' | 'SUCCESS' | 'FAIL' | 'PROCESSING' | 'WAIT_USER_CONFIRM';
|
|
export type TransferMode = 'API' | 'MOCK';
|
|
export type UserStatus = 'ACTIVE' | 'DISABLED';
|
|
export type StaffRole = 'CLEANER' | 'STAFF' | 'STORE_ADMIN' | 'TENANT_ADMIN';
|
|
|
|
export interface PageResult<T> {
|
|
items: T[];
|
|
total: number;
|
|
page: number;
|
|
pageSize: number;
|
|
}
|
|
|
|
export interface ManagedStore {
|
|
id: string;
|
|
name: string;
|
|
address: string;
|
|
city: string;
|
|
district: string;
|
|
longitude: number | null;
|
|
latitude: number | null;
|
|
contactPhone: string;
|
|
businessStatus: 'OPEN' | 'CLOSED' | 'SUSPENDED';
|
|
timezone: string;
|
|
wifiSsid: string;
|
|
wifiConfigured: boolean;
|
|
notificationUrl: string;
|
|
sortOrder: number;
|
|
businessHours: StoreBusinessHour[];
|
|
}
|
|
|
|
export interface StoreBusinessHour {
|
|
weekday: number;
|
|
openMinute: number;
|
|
closeMinute: number;
|
|
isClosed: boolean;
|
|
}
|
|
|
|
export interface StoreInput {
|
|
name: string;
|
|
address: string;
|
|
city: string;
|
|
district: string;
|
|
longitude?: number | null;
|
|
latitude?: number | null;
|
|
contactPhone: string;
|
|
timezone: string;
|
|
businessStatus: ManagedStore['businessStatus'];
|
|
wifiSsid: string;
|
|
wifiPassword?: string;
|
|
notificationUrl: string;
|
|
sortOrder: number;
|
|
businessHours: StoreBusinessHour[];
|
|
}
|
|
|
|
export type RoomConfigurationStatus = 'ENABLED' | 'DISABLED';
|
|
export type RoomOperationalStatus =
|
|
| 'AVAILABLE'
|
|
| 'MAINTENANCE'
|
|
| 'RESERVED'
|
|
| 'IN_USE'
|
|
| 'CLEANING_REQUIRED';
|
|
|
|
export interface ManagedRoom {
|
|
id: string;
|
|
storeId: string;
|
|
categoryName: string;
|
|
name: string;
|
|
roomNo: string;
|
|
capacity: number;
|
|
basePriceCents: number;
|
|
weekdayPriceCents: number;
|
|
holidayPriceCents: number;
|
|
overnightPriceCents: number;
|
|
fullDayPriceCents: number;
|
|
minimumSpendCents: number;
|
|
depositCents: number;
|
|
minimumMinutes: number;
|
|
maxAdvanceStartMinutes: number;
|
|
maxAdvanceDays: number;
|
|
configurationStatus: RoomConfigurationStatus;
|
|
operationalStatus: RoomOperationalStatus;
|
|
tags: string[];
|
|
images: string[];
|
|
sortOrder: number;
|
|
}
|
|
|
|
export type RoomInput = Omit<ManagedRoom, 'id'>;
|
|
|
|
export type OrderStatus =
|
|
| 'DRAFT'
|
|
| 'PENDING_PAYMENT'
|
|
| 'PAID'
|
|
| 'RESERVED'
|
|
| 'IN_PROGRESS'
|
|
| 'FINISHED'
|
|
| 'CANCELLED'
|
|
| 'REFUNDING'
|
|
| 'REFUNDED'
|
|
| 'CLOSED';
|
|
|
|
export type OrderAction =
|
|
| 'SUBMIT'
|
|
| 'CONFIRM_PAYMENT'
|
|
| 'RESERVE'
|
|
| 'START'
|
|
| 'FINISH'
|
|
| 'CANCEL'
|
|
| 'BEGIN_REFUND'
|
|
| 'COMPLETE_REFUND'
|
|
| 'CLOSE';
|
|
|
|
export interface ManagedOrder {
|
|
id: string;
|
|
orderNo: string;
|
|
storeId: string;
|
|
storeName: string;
|
|
roomId: string;
|
|
roomName: string;
|
|
roomNo: string;
|
|
status: OrderStatus;
|
|
startAt: string;
|
|
endAt: string;
|
|
totalAmountCents: number;
|
|
paidAmountCents: number;
|
|
latestPayment: null | { id: string; provider: string; status: string };
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface OrderHistoryItem {
|
|
id: string;
|
|
fromStatus: OrderStatus | null;
|
|
toStatus: OrderStatus;
|
|
action: OrderAction | 'CREATED' | 'EXPIRED' | 'MIGRATED';
|
|
actorType: string;
|
|
actorId: string | null;
|
|
source: string;
|
|
reason: string;
|
|
traceId: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export type PaymentAuthorizationStatus = 'UNAUTHORIZED' | 'PENDING' | 'AUTHORIZED' | 'REVOKED';
|
|
|
|
export interface CollectionAccount {
|
|
id: string;
|
|
platformAppId: string;
|
|
storeId: string | null;
|
|
provider: string;
|
|
merchantId: string;
|
|
authorizationStatus: PaymentAuthorizationStatus;
|
|
profitSharingEnabled: boolean | number;
|
|
enabled: boolean | number;
|
|
}
|
|
|
|
export interface ProfitShareReceiver {
|
|
id: string;
|
|
collectionAccountId: string;
|
|
receiverType: 'MERCHANT_ID' | 'PERSONAL_OPENID';
|
|
receiverMasked: string;
|
|
relationType: string;
|
|
name: string;
|
|
authorizationStatus: PaymentAuthorizationStatus;
|
|
enabled: boolean | number;
|
|
}
|
|
|
|
export interface ProfitSharePolicy {
|
|
id: string;
|
|
collectionAccountId: string;
|
|
storeId: string | null;
|
|
receiverId: string;
|
|
percentageBps: number;
|
|
enabled: boolean | number;
|
|
}
|
|
|
|
export interface ProfitShareRecord {
|
|
id: string;
|
|
paymentId: string;
|
|
orderId: string;
|
|
storeId: string;
|
|
shareNo: string;
|
|
receiverType: string;
|
|
receiverMasked: string;
|
|
percentageBps: number;
|
|
amountCents: number;
|
|
status: string;
|
|
failureCode: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface ProfitSharingSnapshot {
|
|
accounts: CollectionAccount[];
|
|
receivers: ProfitShareReceiver[];
|
|
policies: ProfitSharePolicy[];
|
|
shares: ProfitShareRecord[];
|
|
}
|
|
|
|
export type ThirdPartyProvider = 'MEITUAN' | 'DIANPING' | 'DOUYIN' | 'KUAISHOU';
|
|
export type ThirdPartyMode = 'MANUAL' | 'MOCK' | 'API';
|
|
|
|
export interface DirectBookingRecord {
|
|
id: string;
|
|
provider: ThirdPartyProvider;
|
|
externalBookingNo: string;
|
|
storeId: string | null;
|
|
roomId: string | null;
|
|
startsAt: string;
|
|
endsAt: string;
|
|
amountCents: number;
|
|
status: string;
|
|
orderId: string | null;
|
|
failureCode: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface GroupRedemptionRecord {
|
|
id: string;
|
|
provider: ThirdPartyProvider;
|
|
voucherMasked: string;
|
|
orderId: string;
|
|
storeId: string;
|
|
mode: ThirdPartyMode;
|
|
actorId: string | null;
|
|
status: string;
|
|
failureCode: string;
|
|
createdAt: string;
|
|
completedAt: string | null;
|
|
}
|
|
|
|
export interface ThirdPartyRecords {
|
|
bookings: DirectBookingRecord[];
|
|
redemptions: GroupRedemptionRecord[];
|
|
}
|
|
|
|
export interface ThirdPartyConfigSummary {
|
|
id: string;
|
|
provider: ThirdPartyProvider;
|
|
storeId: string | null;
|
|
mode: ThirdPartyMode;
|
|
enabled: boolean;
|
|
credentialRef: string;
|
|
credentialConfigured: boolean;
|
|
settings: Record<string, unknown>;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface ThirdPartyMappingSummary {
|
|
id: string;
|
|
provider: ThirdPartyProvider;
|
|
resourceType: 'STORE' | 'ROOM';
|
|
externalRef: string;
|
|
localResourceId: string;
|
|
}
|
|
|
|
export interface ThirdPartySetup {
|
|
configs: ThirdPartyConfigSummary[];
|
|
mappings: ThirdPartyMappingSummary[];
|
|
}
|
|
|
|
export interface BusinessStatistics {
|
|
storeId: string;
|
|
from: string;
|
|
to: string;
|
|
summary: {
|
|
orderTotal: number;
|
|
activeOrderTotal: number;
|
|
finishedOrderTotal: number;
|
|
bookedAmountCents: number;
|
|
collectedAmountCents: number;
|
|
payingMemberTotal: number;
|
|
voucherTotal: number;
|
|
voucherSucceeded: number;
|
|
voucherFailed: number;
|
|
roomTotal: number;
|
|
availableRoomTotal: number;
|
|
attentionRoomTotal: number;
|
|
};
|
|
orderStatuses: Array<{ status: string; total: number; amountCents: number }>;
|
|
paymentChannels: Array<{ channel: string; total: number; amountCents: number }>;
|
|
dailyRevenue: Array<{ date: string; total: number; amountCents: number }>;
|
|
}
|
|
|
|
export interface ManagedUser {
|
|
id: string;
|
|
userType: string;
|
|
status: UserStatus;
|
|
nickname: string;
|
|
avatarUrl: string;
|
|
maskedPhone: string;
|
|
maskedLastIp: string;
|
|
note: string;
|
|
roles: StaffRole[];
|
|
storeIds: string[];
|
|
wechatMiniappBound: boolean;
|
|
registeredAt: string;
|
|
lastLoginAt: string | null;
|
|
}
|
|
|
|
export interface MemberWalletSummary {
|
|
accountCount: number;
|
|
cashBalanceCents: number;
|
|
giftBalanceCents: number;
|
|
totalBalanceCents: number;
|
|
}
|
|
|
|
export interface MemberBenefitSummary {
|
|
availableCoupons: number;
|
|
frozenCoupons: number;
|
|
activePackages: number;
|
|
frozenPackages: number;
|
|
packageMinutes: number;
|
|
packageAmountCents: number;
|
|
}
|
|
|
|
export interface MemberCard {
|
|
memberId: string;
|
|
status: UserStatus;
|
|
nickname: string;
|
|
maskedPhone: string;
|
|
registeredAt: string;
|
|
lastLoginAt: string | null;
|
|
wallet: MemberWalletSummary;
|
|
benefits: MemberBenefitSummary;
|
|
recharge: {
|
|
rechargeOrderCount: number;
|
|
creditedRechargeCount: number;
|
|
creditedRechargeCents: number;
|
|
giftedRechargeCents: number;
|
|
lastRechargeAt: string | null;
|
|
};
|
|
orders: {
|
|
orderCount: number;
|
|
paidOrderCount: number;
|
|
paidAmountCents: number;
|
|
lastOrderAt: string | null;
|
|
};
|
|
}
|
|
|
|
export interface MemberLedgerEntry {
|
|
ledgerId: string;
|
|
storeId: string | null;
|
|
businessType: string;
|
|
businessId: string;
|
|
entryType: string;
|
|
cashDeltaCents: number;
|
|
giftDeltaCents: number;
|
|
cashBalanceAfterCents: number;
|
|
giftBalanceAfterCents: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface MemberDetail extends MemberCard {
|
|
recentLedger: MemberLedgerEntry[];
|
|
}
|
|
|
|
export type DeviceType = 'CONTROL_BOX' | 'SUB_LOCK' | 'SMART_SOCKET';
|
|
|
|
export interface DeviceAsset {
|
|
id: string;
|
|
storeId: string;
|
|
roomId: string | null;
|
|
deviceId: string;
|
|
imei: string;
|
|
iccid: string | null;
|
|
deviceType: DeviceType;
|
|
model: string;
|
|
firmwareVersion: string;
|
|
status: 'ONLINE' | 'OFFLINE' | 'FAULT';
|
|
signalStrength: number | null;
|
|
capabilities: string[];
|
|
stateSnapshot: Record<string, unknown>;
|
|
lastSeenAt: string | null;
|
|
lastHeartbeatAt: string | null;
|
|
maintenanceStatus: string;
|
|
}
|
|
|
|
export interface DeviceChannel {
|
|
id: string;
|
|
assetId: string;
|
|
roomId: string;
|
|
channelCode: string;
|
|
purpose: string;
|
|
targetKey: string;
|
|
enabled: boolean;
|
|
}
|
|
|
|
export interface DeviceLink {
|
|
id: string;
|
|
parentAssetId: string;
|
|
childAssetId: string;
|
|
roomId: string;
|
|
linkType: string;
|
|
subId: string;
|
|
subtype: string;
|
|
status: string;
|
|
}
|
|
|
|
export interface DeviceAlert {
|
|
id: string;
|
|
assetId: string;
|
|
roomId: string | null;
|
|
alertType: string;
|
|
severity: string;
|
|
status: string;
|
|
summary: string;
|
|
firstSeenAt: string;
|
|
lastSeenAt: string;
|
|
}
|
|
|
|
export interface DeviceMaintenance {
|
|
id: string;
|
|
assetId: string;
|
|
roomId: string | null;
|
|
recordType: 'INSPECTION' | 'REPAIR' | 'REPLACEMENT';
|
|
status: 'OPEN' | 'RESOLVED';
|
|
description: string;
|
|
createdAt: string;
|
|
resolvedAt: string | null;
|
|
}
|
|
|
|
export interface DeviceTopology {
|
|
assets: DeviceAsset[];
|
|
channels: DeviceChannel[];
|
|
links: DeviceLink[];
|
|
openAlerts: DeviceAlert[];
|
|
maintenance: DeviceMaintenance[];
|
|
}
|
|
|
|
export interface CleaningTask {
|
|
id: string;
|
|
taskNo: string;
|
|
storeId: string;
|
|
storeName: string;
|
|
roomId: string;
|
|
roomName: string;
|
|
roomNo: string;
|
|
orderId: string | null;
|
|
orderNo: string | null;
|
|
status: TaskStatus;
|
|
cleanerUserId: string | null;
|
|
priority: number;
|
|
rewardCents: number;
|
|
requirement: string;
|
|
photoUrls: string[];
|
|
rejectReason: string;
|
|
claimedAt?: string;
|
|
startedAt?: string;
|
|
submittedAt?: string;
|
|
completedAt?: string;
|
|
memberCount: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
}
|
|
|
|
export interface CleaningTaskMember {
|
|
id: string;
|
|
taskId: string;
|
|
userId: string;
|
|
nickname: string;
|
|
memberRole: 'LEAD' | 'ASSIST';
|
|
rewardCents: number;
|
|
joinedAt?: string;
|
|
removedAt?: string | null;
|
|
settledAt?: string | null;
|
|
}
|
|
|
|
export interface CleaningTaskEvent {
|
|
id: string;
|
|
taskId: string;
|
|
fromStatus: TaskStatus | null;
|
|
toStatus: TaskStatus;
|
|
action: string;
|
|
actorId: string;
|
|
traceId: string;
|
|
note: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface CleaningSettlement {
|
|
id: string;
|
|
settlementNo: string;
|
|
cleanerUserId: string;
|
|
cleanerName: string;
|
|
storeId: string | null;
|
|
storeName: string | null;
|
|
status: SettlementStatus;
|
|
taskCount: number;
|
|
totalRewardCents: number;
|
|
periodStart: string | null;
|
|
periodEnd: string | null;
|
|
paidBy: string | null;
|
|
confirmedAt: string | null;
|
|
paidAt: string | null;
|
|
payoutChannel: string;
|
|
payoutReference: string;
|
|
payoutState: string;
|
|
payoutPackageInfo: string;
|
|
payoutError: string;
|
|
note: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface CleaningSettlementItem {
|
|
id: string;
|
|
settlementId: string;
|
|
taskId: string;
|
|
taskNo: string;
|
|
orderNo: string | null;
|
|
storeName: string;
|
|
roomName: string;
|
|
roomNo: string;
|
|
cleanerUserId: string;
|
|
cleanerName: string;
|
|
rewardCents: number;
|
|
completedAt: string | null;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface CleaningSettlementDetail {
|
|
settlement: CleaningSettlement;
|
|
items: CleaningSettlementItem[];
|
|
}
|
|
|
|
export interface CleaningStatistics {
|
|
summary: {
|
|
taskTotal: number;
|
|
pendingReview: number;
|
|
active: number;
|
|
rejected: number;
|
|
exempted: number;
|
|
completed: number;
|
|
rewardCents: number;
|
|
pendingSettlementCents: number;
|
|
confirmedSettlementCents: number;
|
|
paidSettlementCents: number;
|
|
};
|
|
byStatus: Array<{
|
|
status: TaskStatus;
|
|
total: number;
|
|
rewardCents: number;
|
|
}>;
|
|
byStore: Array<{
|
|
storeId: string;
|
|
storeName: string;
|
|
taskTotal: number;
|
|
pendingReview: number;
|
|
completed: number;
|
|
rejected: number;
|
|
exempted: number;
|
|
rewardCents: number;
|
|
}>;
|
|
settlements: Array<{
|
|
status: SettlementStatus;
|
|
total: number;
|
|
rewardCents: number;
|
|
}>;
|
|
members: Array<{
|
|
cleanerUserId: string;
|
|
cleanerName: string;
|
|
taskCount: number;
|
|
completedTaskCount: number;
|
|
rejectedTaskCount: number;
|
|
pendingSettlementCents: number;
|
|
settledRewardCents: number;
|
|
}>;
|
|
trend: Array<{
|
|
date: string;
|
|
taskTotal: number;
|
|
pendingReview: number;
|
|
completed: number;
|
|
rejected: number;
|
|
exempted: number;
|
|
rewardCents: number;
|
|
paidSettlementCents: number;
|
|
}>;
|
|
}
|
|
|
|
export type WechatTransferPreflightStatus = 'PASS' | 'WARN' | 'FAIL';
|
|
|
|
export interface WechatTransferPreflightCheck {
|
|
key: string;
|
|
status: WechatTransferPreflightStatus;
|
|
message: string;
|
|
}
|
|
|
|
export interface WechatTransferPreflight {
|
|
ready: boolean;
|
|
settlement: {
|
|
id: string;
|
|
settlementNo: string;
|
|
status: SettlementStatus;
|
|
totalRewardCents: number;
|
|
cleanerUserId: string;
|
|
storeId: string | null;
|
|
};
|
|
account: {
|
|
configured: boolean;
|
|
id?: string;
|
|
storeScoped?: boolean;
|
|
merchantIdMasked?: string;
|
|
credentialRefMasked?: string;
|
|
authorizationStatus?: string;
|
|
};
|
|
credential: {
|
|
configured: boolean;
|
|
appIdPresent?: boolean;
|
|
serialNoPresent?: boolean;
|
|
transferSceneId?: string;
|
|
reportInfoCount?: number;
|
|
transferNotifyUrlConfigured?: boolean;
|
|
platformCertificateCount?: number;
|
|
};
|
|
cleaner: {
|
|
openidConfigured: boolean;
|
|
};
|
|
checks: WechatTransferPreflightCheck[];
|
|
}
|