Files
Genarrative/src/components/common/floatingFeedbackEntryModel.ts
T
wuxiangwanzi fcd9470dcf 加入客服反馈和社区二维码
增加桌面端全站客服反馈悬浮入口。

悬停入口时展示 QQ 和微信社区二维码浮窗。

补充入口拖拽边界、点击跳转和移动端隐藏测试。

同步全站客服悬浮入口接入文档。
2026-06-23 21:02:13 +08:00

82 lines
2.3 KiB
TypeScript

export const FLOATING_FEEDBACK_FORM_URL =
'https://kcnz41bksl1c.feishu.cn/share/base/form/shrcn1p9WpuZMDxrI5ysLLJhw7k';
export const FLOATING_FEEDBACK_DESKTOP_QUERY = '(min-width: 1024px)';
export const FLOATING_FEEDBACK_SIZE = 57.6;
export const FLOATING_FEEDBACK_MARGIN = 20;
export const FLOATING_FEEDBACK_INITIAL_LEFT = 24;
export const FLOATING_FEEDBACK_INITIAL_BOTTOM = 96;
export const FLOATING_FEEDBACK_DRAG_CLICK_THRESHOLD = 4;
export const FLOATING_FEEDBACK_DRAG_CLICK_SUPPRESS_MS = 250;
export const FLOATING_FEEDBACK_CONTACT_PANEL_WIDTH = 348;
export type FloatingFeedbackPosition = {
left: number;
top: number;
};
function roundFloatingFeedbackCoordinate(value: number) {
return Math.round(value * 10) / 10;
}
export function clampFloatingFeedbackPosition(
position: FloatingFeedbackPosition,
viewport: { width: number; height: number },
) {
const minLeft = FLOATING_FEEDBACK_MARGIN;
const minTop = FLOATING_FEEDBACK_MARGIN;
const maxLeft = Math.max(
minLeft,
viewport.width - FLOATING_FEEDBACK_SIZE - FLOATING_FEEDBACK_MARGIN,
);
const maxTop = Math.max(
minTop,
viewport.height - FLOATING_FEEDBACK_SIZE - FLOATING_FEEDBACK_MARGIN,
);
return {
left: roundFloatingFeedbackCoordinate(
Math.min(maxLeft, Math.max(minLeft, position.left)),
),
top: roundFloatingFeedbackCoordinate(
Math.min(maxTop, Math.max(minTop, position.top)),
),
};
}
export function resolveInitialFloatingFeedbackPosition(viewport: {
width: number;
height: number;
}) {
return clampFloatingFeedbackPosition(
{
left: FLOATING_FEEDBACK_INITIAL_LEFT,
top:
viewport.height -
FLOATING_FEEDBACK_SIZE -
FLOATING_FEEDBACK_INITIAL_BOTTOM,
},
viewport,
);
}
export function resolveFloatingFeedbackContactPanelOffset(
position: FloatingFeedbackPosition,
viewport: { width: number },
) {
const entryCenter = position.left + FLOATING_FEEDBACK_SIZE / 2;
const minCenter = FLOATING_FEEDBACK_MARGIN + FLOATING_FEEDBACK_CONTACT_PANEL_WIDTH / 2;
const maxCenter =
viewport.width -
FLOATING_FEEDBACK_MARGIN -
FLOATING_FEEDBACK_CONTACT_PANEL_WIDTH / 2;
if (maxCenter < minCenter) {
return 0;
}
return roundFloatingFeedbackCoordinate(
Math.min(maxCenter, Math.max(minCenter, entryCenter)) - entryCenter,
);
}