feat: 支持任务监控系统
This commit is contained in:
@@ -53,15 +53,14 @@ describe('范思伯特福中福响应映射', () => {
|
||||
})
|
||||
vi.stubGlobal('fetch', fetchMock)
|
||||
|
||||
await fansiboteFuzhongAdapter.getAvailability(query, {
|
||||
courtId: query.courtId
|
||||
})
|
||||
await fansiboteFuzhongAdapter.getAvailability(query)
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledOnce()
|
||||
const request = fetchMock.mock.calls[0]?.[1] as RequestInit
|
||||
expect(request.headers).toEqual(expect.objectContaining({
|
||||
STOREID: '6038652'
|
||||
}))
|
||||
expect(request.headers).not.toHaveProperty('PSPLVISITORID')
|
||||
expect(JSON.parse(String(request.body))).toEqual({
|
||||
dateTime: '2026-07-16',
|
||||
userId: 6038652,
|
||||
@@ -283,6 +282,13 @@ describe('范思伯特福中福响应映射', () => {
|
||||
},
|
||||
expect.objectContaining({ id: '1784027073124705081' })
|
||||
])
|
||||
expect(result.slots.map(({ status, unavailableLabel }) => ({
|
||||
status,
|
||||
unavailableLabel
|
||||
}))).toEqual([
|
||||
{ status: 'booked', unavailableLabel: '已订' },
|
||||
{ status: 'booked', unavailableLabel: '已订' }
|
||||
])
|
||||
})
|
||||
|
||||
it('接口字段变化时明确失败,不静默丢时段', () => {
|
||||
|
||||
@@ -228,19 +228,21 @@ function parseSlot(value: unknown, enrollments: ParsedEnrollment[]): BookingSlot
|
||||
const slotBeginDatetime = slot.beginDatetime
|
||||
const slotEndDatetime = slot.endDatetime
|
||||
|
||||
const status: BookingSlot['status'] = canBook
|
||||
? 'available'
|
||||
: slot.status === 1
|
||||
? 'booked'
|
||||
: 'blocked'
|
||||
const bookedBy = status === 'booked' && appointment
|
||||
? parseBookingContacts(appointment)
|
||||
: []
|
||||
const enrollment = enrollments.find((candidate) =>
|
||||
candidate.classroomUid === slot.txtClassroomUid &&
|
||||
slotBeginDatetime <= candidate.endDatetime &&
|
||||
slotEndDatetime >= candidate.beginDatetime
|
||||
)?.activity
|
||||
const status: BookingSlot['status'] = enrollment
|
||||
? 'booked'
|
||||
: canBook
|
||||
? 'available'
|
||||
: slot.status === 1
|
||||
? 'booked'
|
||||
: 'blocked'
|
||||
const bookedBy = status === 'booked' && appointment
|
||||
? parseBookingContacts(appointment)
|
||||
: []
|
||||
|
||||
return {
|
||||
id: `${slot.txtClassroomUid}:${slotBeginDatetime}`,
|
||||
@@ -298,13 +300,11 @@ export function buildAvailabilityRequestBody(date: string) {
|
||||
}
|
||||
|
||||
async function getAvailability(
|
||||
query: AvailabilityQuery,
|
||||
settings: CourtRuntimeSettings
|
||||
query: AvailabilityQuery
|
||||
): Promise<AvailabilityDay> {
|
||||
if (query.courtId !== fansiboteFuzhongCourt.id) {
|
||||
throw new Error('球场标识与适配器不匹配')
|
||||
}
|
||||
if (settings.courtId !== query.courtId) throw new Error('球场配置与适配器不匹配')
|
||||
if (!DATE_PATTERN.test(query.date)) throw new Error('预约日期格式错误')
|
||||
|
||||
const response = await fetch(AVAILABILITY_ENDPOINT, {
|
||||
|
||||
@@ -32,11 +32,7 @@ export class AdapterRegistry {
|
||||
|
||||
async getAvailability(query: AvailabilityQuery) {
|
||||
const adapter = this.getAdapter(query.courtId)
|
||||
const settings = await this.settingsStore.get(
|
||||
adapter.court.id,
|
||||
adapter.defaultSettings
|
||||
)
|
||||
return adapter.getAvailability(query, settings)
|
||||
return adapter.getAvailability(query)
|
||||
}
|
||||
|
||||
async getCourtSettings(courtId: string) {
|
||||
@@ -125,7 +121,7 @@ export class AdapterRegistry {
|
||||
const availability = await adapter.getAvailability({
|
||||
courtId: parsedInput.courtId,
|
||||
date: parsedInput.date
|
||||
}, settings)
|
||||
})
|
||||
const slot = availability.slots.find((candidate) => candidate.id === parsedInput.slotId)
|
||||
if (!slot) throw new Error('目标时段已不存在,请刷新后重试')
|
||||
if (slot.status !== 'available' && slot.status !== 'limited') {
|
||||
|
||||
@@ -25,10 +25,7 @@ export class ProviderMutationError extends Error {
|
||||
export interface CourtAdapter {
|
||||
readonly court: CourtSummary
|
||||
readonly defaultSettings: CourtRuntimeSettings
|
||||
getAvailability(
|
||||
query: AvailabilityQuery,
|
||||
settings: CourtRuntimeSettings
|
||||
): Promise<AvailabilityDay>
|
||||
getAvailability(query: AvailabilityQuery): Promise<AvailabilityDay>
|
||||
preflightWriteSettings?(settings: CourtRuntimeSettings): void
|
||||
createBooking?(
|
||||
slot: BookingSlot,
|
||||
|
||||
Reference in New Issue
Block a user