feat: TTLock encoder per workstation (Option A)
- Migration 051: add ttlock_com_port to workstations, drop com_port/workstation_id from hotel_ttlock_config - Backend workstations PATCH: accepts ttlock_com_port alongside name - Backend ttlock: test/issue-card use per-workstation com_port; auto-select online encoder if workstationId not specified - TTLockPage Step 2: per-workstation table with COM port input, Save, Test buttons per row - BookingDetailPanel: auto-issue if 1 encoder online, picker modal if multiple - api.ts: TTLockConfig/Update cleaned up, Workstation gets ttlockComPort, issueCard/testEncoder updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -345,8 +345,11 @@ export const api = {
|
||||
req<Workstation[]>('GET', `/api/hotels/${slug}/workstations`),
|
||||
create: (slug: string, name: string) =>
|
||||
req<Workstation>('POST', `/api/hotels/${slug}/workstations`, { name }),
|
||||
update: (slug: string, id: string, name: string) =>
|
||||
req<Workstation>('PATCH', `/api/hotels/${slug}/workstations/${id}`, { name }),
|
||||
update: (slug: string, id: string, data: { name?: string; ttlockComPort?: string | null }) =>
|
||||
req<Workstation>('PATCH', `/api/hotels/${slug}/workstations/${id}`, {
|
||||
name: data.name,
|
||||
ttlock_com_port: data.ttlockComPort,
|
||||
}),
|
||||
remove: (slug: string, id: string) =>
|
||||
req<void>('DELETE', `/api/hotels/${slug}/workstations/${id}`),
|
||||
pairCode: (slug: string, id: string) =>
|
||||
@@ -610,8 +613,8 @@ export const api = {
|
||||
updateConfig: (slug: string, data: TTLockConfigUpdate) =>
|
||||
req<{ ok: boolean }>('PATCH', `/api/hotels/${slug}/ttlock/config`, data),
|
||||
|
||||
testEncoder: (slug: string) =>
|
||||
req<{ ok: boolean }>('POST', `/api/hotels/${slug}/ttlock/test`),
|
||||
testEncoder: (slug: string, workstationId: string) =>
|
||||
req<{ ok: boolean }>('POST', `/api/hotels/${slug}/ttlock/test`, { workstationId }),
|
||||
|
||||
getRoomLocks: (slug: string) =>
|
||||
req<RoomLockMapping[]>('GET', `/api/hotels/${slug}/ttlock/room-locks`),
|
||||
@@ -622,8 +625,8 @@ export const api = {
|
||||
unmapRoom: (slug: string, roomId: string) =>
|
||||
req<{ ok: boolean }>('DELETE', `/api/hotels/${slug}/ttlock/room-locks/${roomId}`),
|
||||
|
||||
issueCard: (slug: string, bookingId: string) =>
|
||||
req<CardIssuanceResult>('POST', `/api/hotels/${slug}/bookings/${bookingId}/issue-card`),
|
||||
issueCard: (slug: string, bookingId: string, workstationId?: string) =>
|
||||
req<CardIssuanceResult>('POST', `/api/hotels/${slug}/bookings/${bookingId}/issue-card`, workstationId ? { workstationId } : undefined),
|
||||
|
||||
getCards: (slug: string, bookingId: string) =>
|
||||
req<CardIssuance[]>('GET', `/api/hotels/${slug}/bookings/${bookingId}/cards`),
|
||||
@@ -1076,25 +1079,22 @@ export interface Workstation {
|
||||
isOnline: boolean
|
||||
lastSeen: string | null
|
||||
agentVersion?: string
|
||||
ttlockComPort?: string | null
|
||||
createdAt: string
|
||||
devices: WorkstationDevice[] | null
|
||||
}
|
||||
|
||||
export interface TTLockConfig {
|
||||
isEnabled: boolean
|
||||
clientId: string
|
||||
cardSectors: string
|
||||
comPort: string
|
||||
workstationId: string | null
|
||||
isEnabled: boolean
|
||||
clientId: string
|
||||
cardSectors: string
|
||||
}
|
||||
|
||||
export interface TTLockConfigUpdate {
|
||||
isEnabled?: boolean
|
||||
clientId?: string
|
||||
clientSecret?: string
|
||||
cardSectors?: string
|
||||
comPort?: string
|
||||
workstationId?: string | null
|
||||
isEnabled?: boolean
|
||||
clientId?: string
|
||||
clientSecret?: string
|
||||
cardSectors?: string
|
||||
}
|
||||
|
||||
export interface RoomLockMapping {
|
||||
|
||||
Reference in New Issue
Block a user