接入V4房型信息展示模型

This commit is contained in:
andy
2026-07-21 09:04:13 +07:00
parent 1d593f05fd
commit 8d181ee8ad
21 changed files with 1390 additions and 77 deletions

View File

@@ -15,6 +15,7 @@
<select
v-if="isEditable(field) && isSelectField(field)"
class="v4-field__control"
:name="fieldKey(field)"
:aria-invalid="fieldError(field) ? 'true' : 'false'"
:disabled="selectDisabled(field)"
:value="fieldValue(field)"
@@ -34,15 +35,27 @@
v-else-if="isEditable(field) && isDateField(field)"
class="v4-field__control"
type="date"
:name="fieldKey(field)"
:aria-invalid="fieldError(field) ? 'true' : 'false'"
:value="fieldValue(field)"
@input="updateField(field, $event)"
>
<input
v-else-if="isEditable(field) && isCheckboxField(field)"
class="v4-field__control v4-field__control--checkbox"
type="checkbox"
:name="fieldKey(field)"
:aria-invalid="fieldError(field) ? 'true' : 'false'"
:checked="checkboxValue(field)"
@change="updateCheckboxField(field, $event)"
>
<input
v-else-if="isEditable(field) && isNumberField(field)"
class="v4-field__control"
type="number"
:name="fieldKey(field)"
:aria-invalid="fieldError(field) ? 'true' : 'false'"
:value="fieldValue(field)"
@input="updateField(field, $event)"
@@ -51,6 +64,7 @@
<textarea
v-else-if="isEditable(field) && isTextAreaField(field)"
class="v4-field__control v4-field__control--textarea"
:name="fieldKey(field)"
:aria-invalid="fieldError(field) ? 'true' : 'false'"
:value="fieldValue(field)"
rows="3"
@@ -61,16 +75,26 @@
v-else-if="isEditable(field)"
class="v4-field__control"
type="text"
:name="fieldKey(field)"
:aria-invalid="fieldError(field) ? 'true' : 'false'"
:value="fieldValue(field)"
@input="updateField(field, $event)"
>
<input
v-else-if="isCheckboxField(field)"
class="v4-field__control v4-field__control--checkbox"
type="checkbox"
:name="fieldKey(field)"
:checked="checkboxValue(field)"
disabled
>
<span
v-else
class="v4-field__static"
>
{{ stringifyV4Value(fieldValue(field)) }}
{{ staticFieldValue(field) }}
</span>
<small
@@ -209,13 +233,18 @@ function isEditable(field: ReservationV4TaskCardFieldResult): boolean {
}
function isSelectField(field: ReservationV4TaskCardFieldResult): boolean {
return isSelectControl(field) && Boolean(reservationV4LookupKindForOptionsSource(field.options_source))
return isSelectControl(field) &&
(Boolean(reservationV4LookupKindForOptionsSource(field.options_source)) || fixedFieldOptions(field).length > 0)
}
function isDateField(field: ReservationV4TaskCardFieldResult): boolean {
return normalizeControlType(field.control_type) === 'DATE'
}
function isCheckboxField(field: ReservationV4TaskCardFieldResult): boolean {
return ['CHECKBOX', 'BOOLEAN'].includes(normalizeControlType(field.control_type))
}
function isNumberField(field: ReservationV4TaskCardFieldResult): boolean {
return normalizeControlType(field.control_type) === 'NUMBER'
}
@@ -232,7 +261,7 @@ function fieldOptions(field: ReservationV4TaskCardFieldResult): FieldOption[] {
label: lookupItemLabel(item),
item,
}))
: []
: fixedFieldOptions(field)
const exactItem = exactLookupItemForField(field)
if (exactItem && !options.some((option) => option.value === exactItem.code)) {
options.push({
@@ -267,6 +296,17 @@ function fieldValue(field: ReservationV4TaskCardFieldResult): string | number {
return stringifyV4Value(value)
}
function staticFieldValue(field: ReservationV4TaskCardFieldResult): string {
const value = fieldValue(field)
const matchedOption = fieldOptions(field).find((option) => option.value === value)
return matchedOption?.label ?? stringifyV4Value(value)
}
function checkboxValue(field: ReservationV4TaskCardFieldResult): boolean {
const value = readV4FieldValue(field, props.modelValue)
return value === true || value === 'true' || value === 1 || value === '1'
}
function updateField(field: ReservationV4TaskCardFieldResult, event: Event): void {
const target = event.target as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
delete invalidLookupValues[reservationV4FieldKey(field)]
@@ -276,6 +316,15 @@ function updateField(field: ReservationV4TaskCardFieldResult, event: Event): voi
})
}
function updateCheckboxField(field: ReservationV4TaskCardFieldResult, event: Event): void {
const target = event.target as HTMLInputElement
delete invalidLookupValues[reservationV4FieldKey(field)]
emit('update:modelValue', {
...props.modelValue,
[reservationV4FieldKey(field)]: target.checked,
})
}
function lookupHints(field: ReservationV4TaskCardFieldResult): LookupHint[] {
const kind = reservationV4LookupKindForOptionsSource(field.options_source)
if (!kind) {
@@ -389,6 +438,27 @@ function isSelectControl(field: ReservationV4TaskCardFieldResult): boolean {
return ['SELECT', 'LOOKUP'].includes(normalizeControlType(field.control_type))
}
function fixedFieldOptions(field: ReservationV4TaskCardFieldResult): FieldOption[] {
const optionsSource = normalizeControlType(field.options_source)
if (optionsSource !== 'RESERVATION_V4_GROUP_BOOKING_STATUS_FIXED') {
return []
}
return [
{
value: 'TEN',
label: 'TEN-Tentative',
},
{
value: 'DEF',
label: 'DEF-Definite',
},
{
value: 'INQ',
label: 'INQ-Inquiry',
},
]
}
function lookupItemLabel(item: ReservationV4CatalogLookupItem): string {
if (item.display_name && item.display_name !== item.code) {
return `${item.code} - ${item.display_name}`
@@ -629,6 +699,14 @@ function exactLookupKey(kind: ReservationV4LookupKind, code: string): string {
resize: vertical;
}
.v4-field__control--checkbox {
min-height: 18px;
width: 18px;
accent-color: var(--th-color-blue-600);
box-shadow: none;
padding: 0;
}
.v4-field__control[aria-invalid='true'] {
border-color: var(--th-color-danger);
box-shadow: 0 0 0 3px var(--th-color-danger-bg);