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 = (records: T[], pageNum: number, pageSize: number): PageResponse => { 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 { 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 { 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 { 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) } }