Browse Source

修改入口图标并修复拖拽相关问题

master
wanghanlin 1 week ago
parent
commit
ae52cd8949
  1. BIN
      client/assets/launcher-logo.png
  2. 193
      client/dist/chatbot-sdk.js
  3. 2
      client/dist/chatbot-sdk.js.map
  4. 2
      client/dist/chatbot-sdk.min.js
  5. 2
      client/dist/chatbot-sdk.min.js.map
  6. 31
      client/package-lock.json
  7. 1
      client/package.json
  8. 2
      client/rollup.config.js
  9. 5
      client/src/config.ts
  10. 5
      client/src/images.d.ts
  11. 7
      client/src/index.ts
  12. 180
      client/src/styles.ts
  13. 193
      src/main/resources/static/sdk/chatbot-sdk.js
  14. 2
      src/main/resources/static/sdk/chatbot-sdk.js.map
  15. 2
      src/main/resources/static/sdk/chatbot-sdk.min.js
  16. 2
      src/main/resources/static/sdk/chatbot-sdk.min.js.map

BIN
client/assets/launcher-logo.png

After

Width: 1024  |  Height: 1024  |  Size: 1.3 MiB

193
client/dist/chatbot-sdk.js
File diff suppressed because it is too large
View File

2
client/dist/chatbot-sdk.js.map
File diff suppressed because it is too large
View File

2
client/dist/chatbot-sdk.min.js
File diff suppressed because it is too large
View File

2
client/dist/chatbot-sdk.min.js.map
File diff suppressed because it is too large
View File

31
client/package-lock.json

@ -8,6 +8,7 @@
"name": "chatbot-sdk", "name": "chatbot-sdk",
"version": "1.0.0", "version": "1.0.0",
"devDependencies": { "devDependencies": {
"@rollup/plugin-image": "^3.0.3",
"@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.0", "@rollup/plugin-typescript": "^12.1.0",
"rollup": "^4.30.0", "rollup": "^4.30.0",
@ -508,6 +509,27 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@rollup/plugin-image": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/@rollup/plugin-image/-/plugin-image-3.0.3.tgz",
"integrity": "sha512-qXWQwsXpvD4trSb8PeFPFajp8JLpRtqqOeNYRUKnEQNHm7e5UP7fuSRcbjQAJ7wDZBbnJvSdY5ujNBQd9B1iFg==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"mini-svg-data-uri": "^1.4.4"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-terser": { "node_modules/@rollup/plugin-terser": {
"version": "0.4.4", "version": "0.4.4",
"resolved": "https://registry.npmmirror.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", "resolved": "https://registry.npmmirror.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
@ -1355,6 +1377,15 @@
"@jridgewell/sourcemap-codec": "^1.5.5" "@jridgewell/sourcemap-codec": "^1.5.5"
} }
}, },
"node_modules/mini-svg-data-uri": {
"version": "1.4.4",
"resolved": "https://registry.npmmirror.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
"integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
"dev": true,
"bin": {
"mini-svg-data-uri": "cli.js"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",

1
client/package.json

@ -13,6 +13,7 @@
"test:watch": "vitest" "test:watch": "vitest"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-image": "^3.0.3",
"@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.0", "@rollup/plugin-typescript": "^12.1.0",
"rollup": "^4.30.0", "rollup": "^4.30.0",

2
client/rollup.config.js

@ -1,5 +1,6 @@
import typescript from '@rollup/plugin-typescript'; import typescript from '@rollup/plugin-typescript';
import terser from '@rollup/plugin-terser'; import terser from '@rollup/plugin-terser';
import image from '@rollup/plugin-image';
export default { export default {
input: 'src/index.ts', input: 'src/index.ts',
@ -19,6 +20,7 @@ export default {
}, },
], ],
plugins: [ plugins: [
image(),
typescript({ typescript({
tsconfig: './tsconfig.json', tsconfig: './tsconfig.json',
// Rollup 构建不生成 .d.ts,由独立的 tsc --emitDeclarationOnly 负责 // Rollup 构建不生成 .d.ts,由独立的 tsc --emitDeclarationOnly 负责

5
client/src/config.ts

@ -8,9 +8,10 @@
*/ */
import { SDKConfig, ResolvedConfig } from './types'; import { SDKConfig, ResolvedConfig } from './types';
import { logger } from './logger'; import { logger } from './logger';
import launcherLogo from '../assets/launcher-logo.png';
/** 默认悬浮按钮图标 — E5 梦幻拖尾·全粒子:极光旋转渐变底 + 20 颗粒子系统 */
const DEFAULT_LAUNCHER_ICON = `<span class="csk-pt csk-pt-burst" style="--dx:-16px;--dy:-12px"></span><span class="csk-pt csk-pt-burst" style="--dx:16px;--dy:-10px"></span><span class="csk-pt csk-pt-burst" style="--dx:-14px;--dy:14px"></span><span class="csk-pt csk-pt-burst" style="--dx:13px;--dy:13px"></span><span class="csk-pt csk-pt-burst" style="--dx:0px;--dy:-18px"></span><span class="csk-pt csk-pt-burst" style="--dx:18px;--dy:3px"></span><span class="csk-pt csk-pt-burst" style="--dx:-18px;--dy:-3px"></span><span class="csk-pt csk-pt-burst" style="--dx:0px;--dy:16px"></span><span class="csk-pt csk-pt-float"></span><span class="csk-pt csk-pt-float"></span><span class="csk-pt csk-pt-float"></span><span class="csk-pt csk-pt-float"></span><span class="csk-pt csk-pt-pulse"></span><span class="csk-pt csk-pt-pulse"></span><span class="csk-pt csk-pt-elliptic"></span><span class="csk-pt csk-pt-elliptic"></span><span class="csk-pt csk-pt-ring"></span><span class="csk-pt csk-pt-ring"></span><span class="csk-pt csk-pt-ring"></span><span class="csk-pt csk-pt-ring"></span><span class="csk-sheen"></span><span class="csk-dual"></span>`;
/** 默认悬浮按钮图标 — 使用 assets/launcher-logo.png 的内联 base64 */
const DEFAULT_LAUNCHER_ICON = `<img src="${launcherLogo}" alt="" draggable="false" />`;
/** /**
* *

5
client/src/images.d.ts

@ -0,0 +1,5 @@
/** 图片导入类型声明(Rollup @rollup/plugin-image 会将 PNG 转为 base64 data URL) */
declare module '*.png' {
const src: string;
export default src;
}

7
client/src/index.ts

@ -102,10 +102,13 @@ function init(rawConfig: SDKConfig): void {
// 6.2 启用 Launcher 拖拽(边缘吸附式,支持触摸 + 鼠标) // 6.2 启用 Launcher 拖拽(边缘吸附式,支持触摸 + 鼠标)
launcherDragCleanup = enableLauncherDrag(launcherEl, config, (pos) => { launcherDragCleanup = enableLauncherDrag(launcherEl, config, (pos) => {
const prevSide = launcherPos?.side;
launcherPos = pos; launcherPos = pos;
saveLauncherPosition(config!.integrateId, pos); saveLauncherPosition(config!.integrateId, pos);
// 同步聊天弹窗对齐侧(若弹窗已被用户拖拽过,清除内联定位让 CSS 类接管)
resetWindowPosition();
// 仅在换边时同步弹窗位置,同侧拖动不影响弹窗
if (prevSide && prevSide !== pos.side) {
resetWindowPosition();
}
syncWindowAlignment(pos.side); syncWindowAlignment(pos.side);
// 重新定位 teaser 气泡(若正在显示) // 重新定位 teaser 气泡(若正在显示)
if (teaserEl && !teaserEl.classList.contains('csk-teaser--hidden')) { if (teaserEl && !teaserEl.classList.contains('csk-teaser--hidden')) {

180
client/src/styles.ts

@ -77,29 +77,26 @@ function getStyles(config: ResolvedConfig): string {
width: 60px; width: 60px;
height: 60px; height: 60px;
border-radius: 50%; border-radius: 50%;
/* E5 梦幻拖尾 — 四段极光渐变慢旋 */
background: conic-gradient(from 0deg, #ec4899 0deg, #8b5cf6 90deg, #3b82f6 180deg, #06b6d4 270deg, #ec4899 360deg);
/* 白色背景,简洁克制 */
background: #ffffff;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
color: #fff; color: #fff;
user-select: none; user-select: none;
overflow: visible;
/* 半透明白色光环边框,在白色页面上清晰分离按钮与背景 */
border: 2.5px solid rgba(255, 255, 255, 0.55);
/* 三层投影:接地阴影 + 彩色光晕,把按钮从白底「托」出来 */
overflow: hidden;
/* 浅灰边框 */
border: 2px solid #E5E7EB;
/* 简洁柔和阴影 */
box-shadow: box-shadow:
0 1px 2px rgba(0, 0, 0, 0.06),
0 4px 16px rgba(0, 0, 0, 0.10),
0 6px 24px rgba(236, 72, 153, 0.28),
0 0 48px rgba(236, 72, 153, 0.12);
0 2px 8px rgba(0, 0, 0, 0.08),
0 4px 16px rgba(0, 0, 0, 0.06);
transition: transition:
transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
box-shadow 0.25s ease, box-shadow 0.25s ease,
border-color 0.25s ease; border-color 0.25s ease;
animation: animation:
csk-aurora-spin 5s linear infinite,
csk-launcher-in 0.55s cubic-bezier(0.22, 1, 0.36, 1) both; csk-launcher-in 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
} }
.csk-launcher--right { right: 24px; } .csk-launcher--right { right: 24px; }
@ -107,12 +104,10 @@ function getStyles(config: ResolvedConfig): string {
.csk-launcher:hover { .csk-launcher:hover {
transform: translateY(-3px) scale(1.08); transform: translateY(-3px) scale(1.08);
border-color: rgba(255, 255, 255, 0.75);
border-color: #D1D5DB;
box-shadow: box-shadow:
0 2px 6px rgba(0, 0, 0, 0.10),
0 8px 24px rgba(0, 0, 0, 0.14),
0 10px 36px rgba(236, 72, 153, 0.32),
0 0 56px rgba(236, 72, 153, 0.14);
0 4px 12px rgba(0, 0, 0, 0.10),
0 8px 24px rgba(0, 0, 0, 0.08);
} }
.csk-launcher:active { transform: scale(0.93); } .csk-launcher:active { transform: scale(0.93); }
.csk-launcher svg { .csk-launcher svg {
@ -122,6 +117,15 @@ function getStyles(config: ResolvedConfig): string {
z-index: 1; z-index: 1;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15)); filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
} }
.csk-launcher img {
width: 36px;
height: 36px;
object-fit: contain;
position: relative;
z-index: 1;
-webkit-user-drag: none;
user-select: none;
}
@keyframes csk-launcher-in { @keyframes csk-launcher-in {
0% { opacity: 0; transform: scale(0.5) translateY(16px); } 0% { opacity: 0; transform: scale(0.5) translateY(16px); }
@ -129,150 +133,6 @@ function getStyles(config: ResolvedConfig): string {
100% { opacity: 1; transform: scale(1) translateY(0); } 100% { opacity: 1; transform: scale(1) translateY(0); }
} }
/* ========== E5 梦幻拖尾·全粒子动画系统 ========== */
/* 极光旋转 */
@keyframes csk-aurora-spin {
to { transform: rotate(360deg); }
}
/* 粒子通用 */
.csk-pt {
position: absolute;
border-radius: 50%;
background: #fff;
z-index: 4;
top: 50%;
left: 50%;
pointer-events: none;
}
/* ── 爆散粒子(8颗,不同方向/距离/大小/延迟)── */
.csk-pt-burst { animation: csk-burst 2.8s ease-in-out infinite; }
.csk-pt-burst:nth-child(1) { width:5px; height:5px; animation-delay:0s; }
.csk-pt-burst:nth-child(2) { width:4px; height:4px; animation-delay:0.35s; }
.csk-pt-burst:nth-child(3) { width:5px; height:5px; animation-delay:0.7s; }
.csk-pt-burst:nth-child(4) { width:3px; height:3px; animation-delay:1.05s; }
.csk-pt-burst:nth-child(5) { width:5px; height:5px; animation-delay:1.4s; }
.csk-pt-burst:nth-child(6) { width:4px; height:4px; animation-delay:1.75s; }
.csk-pt-burst:nth-child(7) { width:3px; height:3px; animation-delay:2.1s; }
.csk-pt-burst:nth-child(8) { width:5px; height:5px; animation-delay:2.45s; }
@keyframes csk-burst {
0% { transform: translate(-50%,-50%) scale(0); opacity: 0; }
12% { transform: translate(-50%,-50%) scale(0); opacity: 0; }
32% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.5); opacity: 1; }
48% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(0.5); opacity: .55; }
62% { transform: translate(-50%,-50%) scale(0); opacity: 0; }
100% { transform: translate(-50%,-50%) scale(0); opacity: 0; }
}
/* ── 浮游粒子(持续轨道运动,永不停歇)── */
.csk-pt-float {
animation: csk-float-orbit 3s linear infinite;
box-shadow: 0 0 4px 1px rgba(255,255,255,.5);
}
.csk-pt-float:nth-child(9) { width:3px; height:3px; animation-duration:2.4s; animation-delay:0s; }
.csk-pt-float:nth-child(10) { width:4px; height:4px; animation-duration:3.2s; animation-delay:-0.6s; }
.csk-pt-float:nth-child(11) { width:3px; height:3px; animation-duration:2.8s; animation-delay:-1.2s; }
.csk-pt-float:nth-child(12) { width:4px; height:4px; animation-duration:3.6s; animation-delay:-1.8s; }
@keyframes csk-float-orbit {
0% { transform: translate(-50%,-50%) rotate(0deg) translateX(20px) rotate(0deg); }
100% { transform: translate(-50%,-50%) rotate(360deg) translateX(20px) rotate(-360deg); }
}
/* ── 心跳粒子(中心脉冲 + 呼吸缩放)── */
.csk-pt-pulse {
animation: csk-heart-pulse 1.4s ease-in-out infinite;
}
.csk-pt-pulse:nth-child(13) {
width: 8px; height: 8px;
box-shadow: 0 0 14px 4px rgba(255,255,255,.8), 0 0 28px 8px rgba(255,255,255,.3);
animation-delay: 0s;
}
.csk-pt-pulse:nth-child(14) {
width: 4px; height: 4px;
box-shadow: 0 0 8px 2px rgba(255,255,255,.6);
animation-delay: 0.7s;
}
@keyframes csk-heart-pulse {
0%, 100% { transform: translate(-50%,-50%) scale(0.4); opacity: .3; }
25% { transform: translate(-50%,-50%) scale(1.6); opacity: 1; }
50% { transform: translate(-50%,-50%) scale(0.4); opacity: .3; }
75% { transform: translate(-50%,-50%) scale(0.9); opacity: .6; }
}
/* ── 甩尾粒子(椭圆轨道 + 变速,近大远小)── */
.csk-pt-elliptic {
animation: csk-elliptic-orbit 2.6s ease-in-out infinite;
box-shadow: 0 0 5px 1px rgba(255,255,255,.6);
}
.csk-pt-elliptic:nth-child(15) { width:4px; height:4px; animation-delay:0s; }
.csk-pt-elliptic:nth-child(16) { width:4px; height:4px; animation-delay:-1.3s; }
@keyframes csk-elliptic-orbit {
0% { transform: translate(-50%,-50%) rotate(0deg) translateX(18px) rotate(0deg) scaleY(1); }
25% { transform: translate(-50%,-50%) rotate(90deg) translateX(18px) rotate(-90deg) scaleY(0.45); }
50% { transform: translate(-50%,-50%) rotate(180deg) translateX(18px) rotate(-180deg) scaleY(1); }
75% { transform: translate(-50%,-50%) rotate(270deg) translateX(18px) rotate(-270deg) scaleY(0.45); }
100% { transform: translate(-50%,-50%) rotate(360deg) translateX(18px) rotate(-360deg) scaleY(1); }
}
/* ── 环绕流光(外层慢速光环拖尾)── */
.csk-pt-ring {
width: 3px; height: 3px;
background: rgba(255,255,255,.9);
box-shadow: 0 0 6px 2px rgba(255,255,255,.7);
animation: csk-ring-orbit 5s linear infinite;
}
.csk-pt-ring:nth-child(17) { animation-delay: 0s; }
.csk-pt-ring:nth-child(18) { animation-delay: -1.25s; }
.csk-pt-ring:nth-child(19) { animation-delay: -2.5s; }
.csk-pt-ring:nth-child(20) { animation-delay: -3.75s; }
@keyframes csk-ring-orbit {
0% { transform: translate(-50%,-50%) rotate(0deg) translateX(23px) rotate(0deg) scale(1); opacity: .8; }
50% { transform: translate(-50%,-50%) rotate(180deg) translateX(23px) rotate(-180deg) scale(1.8); opacity: 1; }
100% { transform: translate(-50%,-50%) rotate(360deg) translateX(23px) rotate(-360deg) scale(1); opacity: .8; }
}
/* ── 极光扫光叠加层 ── */
.csk-sheen {
position: absolute;
inset: 0;
border-radius: 50%;
pointer-events: none;
z-index: 3;
overflow: hidden;
}
.csk-sheen::after {
content: '';
position: absolute;
top: -60%; left: -60%;
width: 35%; height: 220%;
background: rgba(255,255,255,.15);
transform: rotate(22deg);
animation: csk-shimmer-sweep 2.8s ease-in-out infinite;
}
@keyframes csk-shimmer-sweep {
0% { left: -60%; }
40% { left: 50%; }
60% { left: 50%; }
100% { left: 130%; }
}
/* ── 双层极光圈(反向旋转,增加层次)── */
.csk-dual {
position: absolute;
inset: 0;
border-radius: 50%;
pointer-events: none;
z-index: 2;
background: conic-gradient(from 180deg, transparent 0%, rgba(255,255,255,.08) 35%, transparent 65%);
animation: csk-aurora-spin 2s linear infinite reverse;
}
/* ========== 聊天弹窗 ========== */ /* ========== 聊天弹窗 ========== */
.csk-window { .csk-window {
position: fixed; position: fixed;

193
src/main/resources/static/sdk/chatbot-sdk.js
File diff suppressed because it is too large
View File

2
src/main/resources/static/sdk/chatbot-sdk.js.map
File diff suppressed because it is too large
View File

2
src/main/resources/static/sdk/chatbot-sdk.min.js
File diff suppressed because it is too large
View File

2
src/main/resources/static/sdk/chatbot-sdk.min.js.map
File diff suppressed because it is too large
View File

Loading…
Cancel
Save