feat: 调整了字段的展示
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
<view class="queue-ticket" :class="`queue-ticket--${ticketTone}`">
|
<view class="queue-ticket" :class="`queue-ticket--${ticketTone}`">
|
||||||
<view class="queue-ticket__topline">
|
<view class="queue-ticket__topline">
|
||||||
<view>
|
<view>
|
||||||
<text class="queue-ticket__project">{{ ticket.project_name }}</text>
|
<text class="queue-ticket__project">{{ ticket.projectName }}</text>
|
||||||
<text class="queue-ticket__title">{{ ticketLabel }}</text>
|
<text class="queue-ticket__title">{{ ticketLabel }}</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="queue-ticket__status-mark" />
|
<text class="queue-ticket__status-mark" />
|
||||||
@@ -11,24 +11,24 @@
|
|||||||
|
|
||||||
<view class="queue-ticket__number">
|
<view class="queue-ticket__number">
|
||||||
<text>我的号码</text>
|
<text>我的号码</text>
|
||||||
<text class="queue-ticket__number-value">{{ ticket.ticket_number }}</text>
|
<text class="queue-ticket__number-value">{{ ticket.ticketNumber }}</text>
|
||||||
<text class="queue-ticket__number-meta">本号 {{ ticket.party_size }} 人</text>
|
<text class="queue-ticket__number-meta">本号 {{ ticket.partySize }} 人</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="queue-ticket__metrics">
|
<view class="queue-ticket__metrics">
|
||||||
<view class="queue-ticket__metric">
|
<view class="queue-ticket__metric">
|
||||||
<text>当前最新到号</text>
|
<text>当前最新到号</text>
|
||||||
<text class="queue-ticket__metric-value">{{ ticket.latest_called_number || "暂无" }}</text>
|
<text class="queue-ticket__metric-value">{{ ticket.latestCalledNumber || "暂无" }}</text>
|
||||||
</view>
|
</view>
|
||||||
<template v-if="ticketStatus === 'WAITING' && !projectPaused">
|
<template v-if="ticketStatus === 'WAITING' && !projectPaused">
|
||||||
<view class="queue-ticket__metric">
|
<view class="queue-ticket__metric">
|
||||||
<text>预计等待时间</text>
|
<text>预计等待时间</text>
|
||||||
<text class="queue-ticket__metric-value">{{ formatEstimatedWait(ticket.estimated_wait) }}</text>
|
<text class="queue-ticket__metric-value">{{ formatEstimatedWait(ticket.estimatedWait) }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="queue-ticket__metric queue-ticket__metric--wide">
|
<view class="queue-ticket__metric queue-ticket__metric--wide">
|
||||||
<text>前方排队</text>
|
<text>前方排队</text>
|
||||||
<text class="queue-ticket__metric-value">{{ ticket.tickets_ahead == null ? "未知" : ticket.tickets_ahead + " 个号码" }}</text>
|
<text class="queue-ticket__metric-value">{{ ticket.ticketsAhead == null ? "未知" : ticket.ticketsAhead + " 个号码" }}</text>
|
||||||
<text class="queue-ticket__metric-meta">{{ ticket.people_ahead == null ? "人数未知" : "共 " + ticket.people_ahead + " 人" }}</text>
|
<text class="queue-ticket__metric-meta">{{ ticket.peopleAhead == null ? "人数未知" : "共 " + ticket.peopleAhead + " 人" }}</text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<view v-if="ticketStatus === 'CALLED'" class="queue-call-action">
|
<view v-if="ticketStatus === 'CALLED'" class="queue-call-action">
|
||||||
<text>现在请前往</text>
|
<text>现在请前往</text>
|
||||||
<text class="queue-call-action__entrance">{{ ticket.entrance || "现场入口" }}</text>
|
<text class="queue-call-action__entrance">{{ ticket.entrance || "现场入口" }}</text>
|
||||||
<text class="queue-call-action__desc">请出示排队号码,叫号时间 {{ formatDateTime(ticket.called_at) }}</text>
|
<text class="queue-call-action__desc">请出示排队号码,叫号时间 {{ formatDateTime(ticket.calledAt) }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<text v-if="ticketStatus !== 'WAITING' && ticketStatus !== 'CALLED'" class="queue-ticket__guidance">
|
<text v-if="ticketStatus !== 'WAITING' && ticketStatus !== 'CALLED'" class="queue-ticket__guidance">
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
<view class="queue-ticket__metadata">
|
<view class="queue-ticket__metadata">
|
||||||
<text>手机号:尾号 {{ phoneLast4 }}</text>
|
<text>手机号:尾号 {{ phoneLast4 }}</text>
|
||||||
<text>更新于 {{ formatDateTime(lastUpdatedAt || ticket.last_updated_at) }}</text>
|
<text>更新于 {{ formatDateTime(lastUpdatedAt || ticket.lastUpdatedAt) }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -78,13 +78,13 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const ticketStatus = computed(() => String(props.ticket?.status || "").toUpperCase());
|
const ticketStatus = computed(() => String(props.ticket?.status || "").toUpperCase());
|
||||||
const statusMeta = computed(() => visitorStatusMeta(props.ticket.status, props.ticket.people_ahead));
|
const statusMeta = computed(() => visitorStatusMeta(props.ticket.status, props.ticket.peopleAhead));
|
||||||
const projectPaused = computed(() => ticketStatus.value === "WAITING" && String(props.ticket?.project?.status || "").toUpperCase() === "PAUSED");
|
const projectPaused = computed(() => ticketStatus.value === "WAITING" && String(props.ticket?.project?.status || "").toUpperCase() === "PAUSED");
|
||||||
const ticketTone = computed(() => projectPaused.value ? "warning" : statusMeta.value.tone);
|
const ticketTone = computed(() => projectPaused.value ? "warning" : statusMeta.value.tone);
|
||||||
const ticketLabel = computed(() => projectPaused.value ? "项目暂时暂停" : statusMeta.value.label);
|
const ticketLabel = computed(() => projectPaused.value ? "项目暂时暂停" : statusMeta.value.label);
|
||||||
const phoneLast4 = computed(() => String(props.ticket?.phone_last4 || "").replace(/\D/g, "").slice(-4) || "未知");
|
const phoneLast4 = computed(() => String(props.ticket?.phoneLast4 || "").replace(/\D/g, "").slice(-4) || "未知");
|
||||||
const visitorNotice = computed(() => {
|
const visitorNotice = computed(() => {
|
||||||
if (props.ticket?.visitor_notice === null) return "";
|
if (props.ticket?.visitorNotice === null) return "";
|
||||||
return props.ticket?.visitor_notice?.trim() || "请您在景区附近等候,注意听从工作人员指引。";
|
return props.ticket?.visitorNotice?.trim() || "请您在景区附近等候,注意听从工作人员指引。";
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -87,18 +87,18 @@
|
|||||||
</picker>
|
</picker>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<text v-if="selectedProject?.visitor_notice" class="queue-notice">{{ selectedProject.visitor_notice }}</text>
|
<text v-if="selectedProject?.visitorNotice" class="queue-notice">{{ selectedProject.visitorNotice }}</text>
|
||||||
|
|
||||||
<label class="queue-field">
|
<label class="queue-field">
|
||||||
<text>同行人数</text>
|
<text>同行人数</text>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
inputmode="numeric"
|
inputmode="numeric"
|
||||||
:value="ticketForm.party_size"
|
:value="ticketForm.partySize"
|
||||||
:disabled="createBusy"
|
:disabled="createBusy"
|
||||||
:min="minPartySize"
|
:min="minPartySize"
|
||||||
:max="maxPartySize"
|
:max="maxPartySize"
|
||||||
@input="handleTicketFormInput('party_size', $event)"
|
@input="handleTicketFormInput('partySize', $event)"
|
||||||
/>
|
/>
|
||||||
<text class="queue-field__hint">本项目每个号码可绑定 {{ minPartySize }} 到 {{ maxPartySize }} 人</text>
|
<text class="queue-field__hint">本项目每个号码可绑定 {{ minPartySize }} 到 {{ maxPartySize }} 人</text>
|
||||||
</label>
|
</label>
|
||||||
@@ -120,9 +120,9 @@
|
|||||||
<label class="queue-field">
|
<label class="queue-field">
|
||||||
<text>姓氏(选填)</text>
|
<text>姓氏(选填)</text>
|
||||||
<input
|
<input
|
||||||
:value="ticketForm.last_name"
|
:value="ticketForm.lastName"
|
||||||
:disabled="createBusy"
|
:disabled="createBusy"
|
||||||
@input="handleTicketFormInput('last_name', $event)"
|
@input="handleTicketFormInput('lastName', $event)"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@
|
|||||||
:show-retry="Boolean(currentStatusResource.error && currentStatusResource.data)"
|
:show-retry="Boolean(currentStatusResource.error && currentStatusResource.data)"
|
||||||
@retry="refreshCurrentStatus"
|
@retry="refreshCurrentStatus"
|
||||||
/>
|
/>
|
||||||
<TicketCard :ticket="tokenResource.data" :last-updated-at="tokenResource.data.last_updated_at || tokenResource.lastSuccessAt" />
|
<TicketCard :ticket="tokenResource.data" :last-updated-at="tokenResource.data.lastUpdatedAt || tokenResource.lastSuccessAt" />
|
||||||
<button class="queue-button queue-button--secondary queue-refresh" :disabled="tokenResource.refreshing" hover-class="none" @click="refreshCurrentStatus">
|
<button class="queue-button queue-button--secondary queue-refresh" :disabled="tokenResource.refreshing" hover-class="none" @click="refreshCurrentStatus">
|
||||||
{{ tokenResource.refreshing ? "正在刷新" : "刷新状态" }}
|
{{ tokenResource.refreshing ? "正在刷新" : "刷新状态" }}
|
||||||
</button>
|
</button>
|
||||||
@@ -284,9 +284,9 @@ const createIntent = ref(null);
|
|||||||
|
|
||||||
const ticketForm = reactive({
|
const ticketForm = reactive({
|
||||||
phone: "",
|
phone: "",
|
||||||
last_name: "",
|
lastName: "",
|
||||||
honorific: "",
|
honorific: "",
|
||||||
party_size: 1,
|
partySize: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectsResource = reactive({
|
const projectsResource = reactive({
|
||||||
@@ -319,11 +319,11 @@ const statusRequestGate = createSingleFlight();
|
|||||||
const selectedProject = computed(() => projectsResource.projects.find((project) => project.id === selectedProjectId.value) || null);
|
const selectedProject = computed(() => projectsResource.projects.find((project) => project.id === selectedProjectId.value) || null);
|
||||||
const projectNames = computed(() => projectsResource.projects.map((project) => project.name));
|
const projectNames = computed(() => projectsResource.projects.map((project) => project.name));
|
||||||
const selectedProjectIndex = computed(() => Math.max(0, projectsResource.projects.findIndex((project) => project.id === selectedProjectId.value)));
|
const selectedProjectIndex = computed(() => Math.max(0, projectsResource.projects.findIndex((project) => project.id === selectedProjectId.value)));
|
||||||
const minPartySize = computed(() => Number(selectedProject.value?.min_party_size) || 1);
|
const minPartySize = computed(() => Number(selectedProject.value?.minPartySize) || 1);
|
||||||
const maxPartySize = computed(() => Number(selectedProject.value?.max_party_size) || minPartySize.value);
|
const maxPartySize = computed(() => Number(selectedProject.value?.maxPartySize) || minPartySize.value);
|
||||||
const canSubmitTicket = computed(() => !createBusy.value && Boolean(selectedProjectId.value) && Boolean(projectsResource.projects.length));
|
const canSubmitTicket = computed(() => !createBusy.value && Boolean(selectedProjectId.value) && Boolean(projectsResource.projects.length));
|
||||||
const createdTicketTarget = computed(() => createdTicket.value ? resolveStatusTarget(createdTicket.value) : null);
|
const createdTicketTarget = computed(() => createdTicket.value ? resolveStatusTarget(createdTicket.value) : null);
|
||||||
const createdTicketProjectName = computed(() => selectedProject.value?.name || createdTicket.value?.ticket?.project_name || "当前项目");
|
const createdTicketProjectName = computed(() => selectedProject.value?.name || createdTicket.value?.ticket?.projectName || "当前项目");
|
||||||
const currentStatusResource = computed(() => tokenResource);
|
const currentStatusResource = computed(() => tokenResource);
|
||||||
const currentStale = computed(() => Boolean(currentStatusResource.value.data) && isTimestampStale(currentStatusResource.value.lastSuccessAt, 30_000));
|
const currentStale = computed(() => Boolean(currentStatusResource.value.data) && isTimestampStale(currentStatusResource.value.lastSuccessAt, 30_000));
|
||||||
const headerTone = computed(() => {
|
const headerTone = computed(() => {
|
||||||
@@ -356,7 +356,7 @@ watch(selectedProject, () => normalizePartySize());
|
|||||||
|
|
||||||
onLoad((options = {}) => {
|
onLoad((options = {}) => {
|
||||||
const sceneToken = extractVisitorToken(parseRouteValue(options.scene));
|
const sceneToken = extractVisitorToken(parseRouteValue(options.scene));
|
||||||
const token = parseRouteValue(options.token || options.public_token) || sceneToken;
|
const token = parseRouteValue(options.token || options.publicToken) || sceneToken;
|
||||||
const phone = parseRouteValue(options.phone);
|
const phone = parseRouteValue(options.phone);
|
||||||
const tab = parseRouteValue(options.tab);
|
const tab = parseRouteValue(options.tab);
|
||||||
|
|
||||||
@@ -504,9 +504,9 @@ const handleProjectChange = (event) => {
|
|||||||
|
|
||||||
const normalizePartySize = () => {
|
const normalizePartySize = () => {
|
||||||
if (!selectedProject.value) return;
|
if (!selectedProject.value) return;
|
||||||
const current = Number(ticketForm.party_size);
|
const current = Number(ticketForm.partySize);
|
||||||
if (!Number.isInteger(current) || current < minPartySize.value || current > maxPartySize.value) {
|
if (!Number.isInteger(current) || current < minPartySize.value || current > maxPartySize.value) {
|
||||||
ticketForm.party_size = minPartySize.value;
|
ticketForm.partySize = minPartySize.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,9 +516,9 @@ const handleTicketFormInput = (field, event) => {
|
|||||||
|
|
||||||
const updateTicketForm = (field, value) => {
|
const updateTicketForm = (field, value) => {
|
||||||
let nextValue = value;
|
let nextValue = value;
|
||||||
if (field === "party_size") {
|
if (field === "partySize") {
|
||||||
const digits = digitsOnly(value);
|
const digits = digitsOnly(value);
|
||||||
ticketForm.party_size = digits === "" ? "" : Number(digits);
|
ticketForm.partySize = digits === "" ? "" : Number(digits);
|
||||||
nextValue = digits;
|
nextValue = digits;
|
||||||
} else if (field === "phone") {
|
} else if (field === "phone") {
|
||||||
const phone = digitsOnly(value);
|
const phone = digitsOnly(value);
|
||||||
@@ -560,7 +560,7 @@ const submitTicket = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const partySize = Number(ticketForm.party_size);
|
const partySize = Number(ticketForm.partySize);
|
||||||
if (!Number.isInteger(partySize) || partySize < minPartySize.value || partySize > maxPartySize.value) {
|
if (!Number.isInteger(partySize) || partySize < minPartySize.value || partySize > maxPartySize.value) {
|
||||||
formError.value = `本项目每个号码可绑定 ${minPartySize.value} 到 ${maxPartySize.value} 人`;
|
formError.value = `本项目每个号码可绑定 ${minPartySize.value} 到 ${maxPartySize.value} 人`;
|
||||||
return;
|
return;
|
||||||
@@ -576,7 +576,7 @@ const submitTicket = async () => {
|
|||||||
const payload = {
|
const payload = {
|
||||||
phone,
|
phone,
|
||||||
party_size: partySize,
|
party_size: partySize,
|
||||||
last_name: ticketForm.last_name.trim(),
|
last_name: ticketForm.lastName.trim(),
|
||||||
honorific: ticketForm.honorific,
|
honorific: ticketForm.honorific,
|
||||||
allow_duplicate: confirmDuplicatePhone.value,
|
allow_duplicate: confirmDuplicatePhone.value,
|
||||||
};
|
};
|
||||||
@@ -612,9 +612,9 @@ const submitTicket = async () => {
|
|||||||
|
|
||||||
const resetTicketForm = () => {
|
const resetTicketForm = () => {
|
||||||
ticketForm.phone = "";
|
ticketForm.phone = "";
|
||||||
ticketForm.last_name = "";
|
ticketForm.lastName = "";
|
||||||
ticketForm.honorific = "";
|
ticketForm.honorific = "";
|
||||||
ticketForm.party_size = minPartySize.value;
|
ticketForm.partySize = minPartySize.value;
|
||||||
phoneError.value = "";
|
phoneError.value = "";
|
||||||
formError.value = "";
|
formError.value = "";
|
||||||
}
|
}
|
||||||
@@ -700,7 +700,7 @@ const refreshTokenStatus = async ({ initial = false } = {}) => {
|
|||||||
try {
|
try {
|
||||||
const data = await getPublicStatus(currentToken.value);
|
const data = await getPublicStatus(currentToken.value);
|
||||||
if (requestId !== statusRequestId || viewMode.value !== VIEW_TOKEN) return;
|
if (requestId !== statusRequestId || viewMode.value !== VIEW_TOKEN) return;
|
||||||
applyStatusSuccess(tokenResource, data);
|
applyStatusSuccess(tokenResource, Array.isArray(data?.tickets) ? data.tickets[0] : data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (requestId !== statusRequestId || viewMode.value !== VIEW_TOKEN) return;
|
if (requestId !== statusRequestId || viewMode.value !== VIEW_TOKEN) return;
|
||||||
applyStatusError(tokenResource, error);
|
applyStatusError(tokenResource, error);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { normalizePublicStatus } from "../../utils/queueUtils.mjs";
|
|
||||||
import request from "../base/request";
|
import request from "../base/request";
|
||||||
|
|
||||||
export class QueueApiError extends Error {
|
export class QueueApiError extends Error {
|
||||||
@@ -74,22 +73,13 @@ export const createPublicTicket = (projectId, payload, idempotencyKey = newQueue
|
|||||||
project_id: projectId,
|
project_id: projectId,
|
||||||
idempotency_key: idempotencyKey,
|
idempotency_key: idempotencyKey,
|
||||||
...payload,
|
...payload,
|
||||||
})).then((response) => ({
|
|
||||||
...response,
|
|
||||||
ticket: normalizePublicStatus(response.ticket),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getPublicStatus = () => {
|
export const getPublicStatus = () => {
|
||||||
return normalizeQueueRequest(request.get("/hotelBiz/visitorQueue/status", {}))
|
return normalizeQueueRequest(request.get("/hotelBiz/visitorQueue/status", {}));
|
||||||
.then((response) => normalizePublicStatus(response));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const searchPublicStatusByPhone = () => {
|
export const searchPublicStatusByPhone = () => {
|
||||||
return normalizeQueueRequest(request.get("/hotelBiz/visitorQueue/status", {})).then((response) => {
|
return getPublicStatus();
|
||||||
if (Array.isArray(response.tickets)) {
|
|
||||||
return { tickets: response.tickets.map(normalizePublicStatus) };
|
|
||||||
}
|
|
||||||
return { tickets: [normalizePublicStatus(response)] };
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ let requestId = 0;
|
|||||||
|
|
||||||
const hasLookupTarget = computed(() => Boolean(phone.value || token.value));
|
const hasLookupTarget = computed(() => Boolean(phone.value || token.value));
|
||||||
const tickets = computed(() => {
|
const tickets = computed(() => {
|
||||||
if (token.value) return resource.data ? [resource.data] : [];
|
|
||||||
return resource.data?.tickets || [];
|
return resource.data?.tickets || [];
|
||||||
});
|
});
|
||||||
const selectedTicket = computed(() => {
|
const selectedTicket = computed(() => {
|
||||||
@@ -153,7 +152,7 @@ watch(tickets, () => syncSelectedTicket(), { deep: true });
|
|||||||
|
|
||||||
onLoad((options = {}) => {
|
onLoad((options = {}) => {
|
||||||
phone.value = parseRouteValue(options.phone);
|
phone.value = parseRouteValue(options.phone);
|
||||||
token.value = parseRouteValue(options.token || options.public_token);
|
token.value = parseRouteValue(options.token || options.publicToken);
|
||||||
});
|
});
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
|
|||||||
@@ -26,11 +26,13 @@ export const formatEstimatedWait = (value) => {
|
|||||||
return Number.isFinite(numeric) ? `约 ${Math.max(0, Math.round(numeric))} 分钟` : value;
|
return Number.isFinite(numeric) ? `约 ${Math.max(0, Math.round(numeric))} 分钟` : value;
|
||||||
}
|
}
|
||||||
if (typeof value === "object") {
|
if (typeof value === "object") {
|
||||||
const estimate = Number(value.estimate_minutes);
|
if (value.available === false && value.reason) return value.reason;
|
||||||
|
|
||||||
|
const estimate = Number(value.estimateMinutes);
|
||||||
if (Number.isFinite(estimate)) return `约 ${Math.max(0, Math.round(estimate))} 分钟`;
|
if (Number.isFinite(estimate)) return `约 ${Math.max(0, Math.round(estimate))} 分钟`;
|
||||||
|
|
||||||
const min = Number(value.min ?? value.min_minutes ?? value.lower ?? value.lower_minutes);
|
const min = Number(value.min ?? value.minMinutes ?? value.lower ?? value.lowerMinutes);
|
||||||
const max = Number(value.max ?? value.max_minutes ?? value.upper ?? value.upper_minutes);
|
const max = Number(value.max ?? value.maxMinutes ?? value.upper ?? value.upperMinutes);
|
||||||
if (Number.isFinite(min) && Number.isFinite(max)) {
|
if (Number.isFinite(min) && Number.isFinite(max)) {
|
||||||
return `预计 ${Math.max(0, Math.round(min))}-${Math.max(0, Math.round(max))} 分钟`;
|
return `预计 ${Math.max(0, Math.round(min))}-${Math.max(0, Math.round(max))} 分钟`;
|
||||||
}
|
}
|
||||||
@@ -78,23 +80,14 @@ export const visitorStatusMeta = (status, peopleAhead) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const normalizePublicStatus = (ticket = {}) => {
|
|
||||||
const partySize = Number(ticket.party_size);
|
|
||||||
return {
|
|
||||||
...ticket,
|
|
||||||
party_size: Number.isFinite(partySize) && partySize > 0 ? partySize : 1,
|
|
||||||
ticket_number: ticket.ticket_number || ticket.display_number || "暂无",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const buildTicketKey = (ticket = {}) => {
|
export const buildTicketKey = (ticket = {}) => {
|
||||||
return `${ticket.project?.id ?? ticket.project_name}:${ticket.ticket_number}`;
|
return `${ticket.project?.id ?? ticket.projectName}:${ticket.ticketNumber}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const resolveStatusTarget = (response = {}) => {
|
export const resolveStatusTarget = (response = {}) => {
|
||||||
if (response.public_token) return { token: response.public_token };
|
if (response.publicToken) return { token: response.publicToken };
|
||||||
|
|
||||||
const url = response.public_url || response.status_path || "";
|
const url = response.publicUrl || response.statusPath || "";
|
||||||
const match = String(url).match(/\/visitor\/([^/?#]+)/);
|
const match = String(url).match(/\/visitor\/([^/?#]+)/);
|
||||||
if (match?.[1]) return { token: decodeURIComponent(match[1]) };
|
if (match?.[1]) return { token: decodeURIComponent(match[1]) };
|
||||||
|
|
||||||
@@ -105,7 +98,7 @@ export const extractVisitorToken = (value) => {
|
|||||||
const text = String(value ?? "").trim();
|
const text = String(value ?? "").trim();
|
||||||
if (!text) return "";
|
if (!text) return "";
|
||||||
|
|
||||||
const tokenMatch = text.match(/(?:^|[?&#])(?:token|public_token)=([^&#]+)/);
|
const tokenMatch = text.match(/(?:^|[?&#])(?:token|publicToken)=([^&#]+)/);
|
||||||
if (tokenMatch?.[1]) return decodeMaybe(tokenMatch[1]);
|
if (tokenMatch?.[1]) return decodeMaybe(tokenMatch[1]);
|
||||||
|
|
||||||
const visitorMatch = text.match(/\/visitor\/([^/?#]+)/);
|
const visitorMatch = text.match(/\/visitor\/([^/?#]+)/);
|
||||||
|
|||||||
Reference in New Issue
Block a user