Files
hotel-biz-h5/src/api/mock.ts

317 lines
9.9 KiB
TypeScript

import dayjs from 'dayjs'
import type { PageResponse, TokenResponse } from '@/types/api'
import type {
CommodityOrder,
CommodityOrderSearch,
UserOrderDetail,
WriteOffPayload,
WriteOffResult
} from '@/types/order'
import type { CreateEventPayload, EventData, EventSearch } from '@/types/event'
import { addDays, formatDateTime, today } from '@/utils/date'
const wait = (ms = 260) => new Promise((resolve) => window.setTimeout(resolve, ms))
const coverImages = [
'https://images.unsplash.com/photo-1566073771259-6a8506099945?auto=format&fit=crop&w=900&q=80',
'https://images.unsplash.com/photo-1542314831-068cd1dbfeeb?auto=format&fit=crop&w=900&q=80',
'https://images.unsplash.com/photo-1551882547-ff40c63fe5fa?auto=format&fit=crop&w=900&q=80'
]
let orders: CommodityOrder[] = [
{
id: '202606160001',
orderAmt: '699.00',
visitorName: '林清',
contactPhone: '13800000001',
checkInData: today(),
checkOutData: addDays(1),
orderStatus: '2',
payStatus: '1',
payAmt: '659.00',
discountAmt: '40.00',
payTime: formatDateTime(dayjs().subtract(2, 'hour').toDate()),
orderType: '0',
createTime: formatDateTime(dayjs().subtract(3, 'hour').toDate()),
roomId: '1208',
commodityName: '湖景大床房含双早',
commodityCoverPhoto: coverImages[0],
commodityAmount: 1,
reservationDate: today()
},
{
id: '202606150108',
orderAmt: '238.00',
visitorName: '王予安',
contactPhone: '13800000002',
orderStatus: '6',
payStatus: '1',
payAmt: '238.00',
orderType: '2',
createTime: formatDateTime(dayjs().subtract(1, 'day').toDate()),
commodityName: '云端餐厅双人套餐',
commodityCoverPhoto: coverImages[1],
commodityAmount: 1,
writeOffTime: formatDateTime(dayjs().subtract(4, 'hour').toDate())
},
{
id: '202606140072',
orderAmt: '158.00',
visitorName: '赵一鸣',
contactPhone: '13800000003',
orderStatus: '4',
payStatus: '1',
payAmt: '158.00',
orderType: '1',
createTime: formatDateTime(dayjs().subtract(2, 'day').toDate()),
commodityName: '温泉中心成人票',
commodityCoverPhoto: coverImages[2],
commodityAmount: 2
},
{
id: '202606130045',
orderAmt: '899.00',
visitorName: '许知夏',
contactPhone: '13800000004',
checkInData: addDays(2),
checkOutData: addDays(3),
orderStatus: '1',
payStatus: '1',
payAmt: '899.00',
orderType: '0',
createTime: formatDateTime(dayjs().subtract(3, 'day').toDate()),
commodityName: '亲子套房一晚',
commodityCoverPhoto: coverImages[0],
commodityAmount: 1,
reservationDate: addDays(2)
}
]
let events: EventData[] = [
{
id: 'EVT20260616001',
entityName: '前台',
eventDescription: '端午假期入住高峰,前台增开一组接待人员并优先处理已预付订单。',
eventStatus: 0,
effectiveStartTime: formatDateTime(dayjs().subtract(1, 'hour').toDate()),
effectiveEndTime: formatDateTime(dayjs().add(8, 'hour').toDate()),
createByName: '值班经理',
popUpReminder: 1,
publicTime: formatDateTime(dayjs().subtract(2, 'hour').toDate()),
imgUrl: coverImages[0],
showStatusDesc: '生效中'
},
{
id: 'EVT20260615002',
entityName: '餐饮部',
eventDescription: '晚餐第二时段预约已满,建议推荐客人选择 19:45 后到店。',
eventStatus: 0,
effectiveStartTime: formatDateTime(dayjs().add(1, 'hour').toDate()),
effectiveEndTime: formatDateTime(dayjs().add(10, 'hour').toDate()),
createByName: '餐饮主管',
popUpReminder: 0,
publicTime: formatDateTime(dayjs().subtract(1, 'day').toDate()),
imgUrl: coverImages[1],
showStatusDesc: '待生效'
}
]
const page = <T>(records: T[], pageNum: number, pageSize: number): PageResponse<T> => {
const start = (pageNum - 1) * pageSize
const current = records.slice(start, start + pageSize)
return {
records: current,
total: records.length,
size: pageSize,
current: pageNum,
pages: Math.ceil(records.length / pageSize)
}
}
export const mockApi = {
async sendMobileCode(payload: { phone: string; imageRandomStr?: string; imageCode?: string }) {
await wait()
if (!payload.phone) return { data: false, msg: '请输入手机号' }
if (!payload.imageRandomStr || !payload.imageCode) return { data: false, msg: '请输入图形验证码' }
return { data: true, msg: '5678nianxx' }
},
async loginByMobile(phone: string): Promise<TokenResponse> {
await wait()
return {
access_token: `mock-token-${Date.now()}`,
refresh_token: 'mock-refresh-token',
token_type: 'Bearer',
expires_in: 43200,
scope: 'server',
client_id: 'custom',
clientId: 'custom',
user_id: '10001',
username: phone,
tenant_id: 1
}
},
async checkBindPhone() {
await wait(120)
return true
},
async bindOrganization(phone: string) {
await wait(180)
if (!phone) {
throw new Error('未绑定组织,请联系管理员')
}
return {
memberId: 'MEMBER10001',
organizationId: 'ORG10001',
memberName: '当前员工',
userPhone: phone,
memberRoleId: 'ROLE_STAFF'
}
},
async getBindStaffInfo() {
await wait(180)
return {
userId: 'USER10001',
memberId: 'MEMBER10001',
organizationId: 'ORG10001',
memberName: '当前员工',
memberRoleId: 'ROLE_STAFF'
}
},
async orderList(query: CommodityOrderSearch) {
await wait()
const keyword = query.orderId || query.contactPhone || ''
const filtered = orders.filter((item) => {
const matchStatus = query.orderStatus ? item.orderStatus === query.orderStatus : true
const matchType = query.commodityTypeCode ? item.orderType === query.commodityTypeCode : true
const matchKeyword = keyword
? item.id.includes(keyword) || item.contactPhone.includes(keyword) || item.visitorName.includes(keyword)
: true
return matchStatus && matchType && matchKeyword
})
return page(filtered, query.pageNum, query.pageSize)
},
async orderDetail(orderId: string): Promise<UserOrderDetail> {
await wait()
const order = orders.find((item) => item.id === orderId) || orders[0]
const totalCount = Number(order.commodityAmount) || 1
const writeOffCount = order.writeOffTime ? totalCount : 0
return {
orderId: order.id,
orderAmt: order.orderAmt,
consumerInfoList: [
{
id: '1',
visitorName: order.visitorName,
contactPhone: order.contactPhone,
idCard: '430***********2218'
}
],
checkInData: order.checkInData,
checkOutData: order.checkOutData,
reservationDate: order.reservationDate,
orderStatus: order.orderStatus,
userId: order.userId,
organizationId: order.organizationId,
payStatus: order.payStatus,
payAmt: order.payAmt,
discountAmt: order.discountAmt,
payTime: order.payTime,
createTime: order.createTime,
commodityCoverPhoto: order.commodityCoverPhoto,
commodityName: order.commodityName,
commodityAddress: '星河湾酒店一层前台',
commodityServiceList: [{ serviceName: '到店核销' }, { serviceName: '不可拆分使用' }],
commodityTip: '请在预约日期到店使用,核销后不支持退款。',
payWay: '0',
paySerialNumber: `WX${order.id}`,
paySource: '2',
orderType: order.orderType,
commodityAmount: String(order.commodityAmount),
storeName: '星河湾酒店',
complaintHotline: '18285123187',
refundable: order.orderStatus !== '6',
commodityId: `COM${order.id.slice(-4)}`,
commodityTypeCode: order.orderType,
commodityFacilityList: ['含早餐', '免费停车', '可预约'],
commodityDescription: '面向到店客人的酒店权益商品,需由员工确认后核销。',
commodityPackageConfig: [
{
packageName: order.commodityName,
packageContent: `${order.commodityName} x ${order.commodityAmount}`,
name: order.commodityName,
count: totalCount,
unit: '份',
packageStatus: writeOffCount >= totalCount ? 1 : 0,
writeOffCount
}
],
reservationEnabled: order.reservationDate ? 1 : 0,
reservationRuleDesc: '预约订单请核对预约日期和联系人信息。',
writeOffRecordList: order.writeOffTime
? [
{
id: `WO${order.id}`,
orderId: order.id,
commodityName: order.commodityName,
packageName: order.commodityName,
userName: '当前员工',
createTime: order.writeOffTime
}
]
: []
}
},
async writeOff(payload: WriteOffPayload): Promise<WriteOffResult> {
await wait()
orders = orders.map((item) =>
item.id === payload.orderId
? { ...item, orderStatus: '6', writeOffTime: formatDateTime(new Date()) }
: item
)
return {
success: true,
orderId: payload.orderId,
packageName: payload.packageName,
message: '核销成功',
operatedAt: formatDateTime(new Date())
}
},
async eventList(query: EventSearch) {
await wait()
const filtered = events.filter((item) => {
const matchName = query.entityName ? item.entityName.includes(query.entityName) : true
const matchStatus = query.eventStatus === undefined ? true : item.eventStatus === query.eventStatus
return matchName && matchStatus
})
return page(filtered, query.pageNum, query.pageSize)
},
async createEvent(payload: CreateEventPayload) {
await wait()
events = [
{
id: `EVT${Date.now()}`,
...payload,
eventStatus: 0,
createByName: '当前员工',
showStatusDesc: '待生效'
},
...events
]
return true
},
async uploadFile(file: File) {
await wait()
return URL.createObjectURL(file)
}
}