generated from root/feiqiu-ETL
feat:引入 TDesign 以及前端初稿
This commit is contained in:
119
Prototype/js/ai-float-btn.js
Normal file
119
Prototype/js/ai-float-btn.js
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* AI 浮动对话按钮组件
|
||||
* 统一在所有需要的页面使用
|
||||
*/
|
||||
(function() {
|
||||
// 创建样式
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.ai-float-btn-container {
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: 96px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.ai-float-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
/* 渐变动画背景 */
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #f5576c 75%, #667eea 100%);
|
||||
background-size: 400% 400%;
|
||||
animation: gradientShift 8s ease infinite;
|
||||
box-shadow: 0 4px 20px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.ai-float-btn:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.ai-float-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(145deg, rgba(255,255,255,0.2) 0%, transparent 50%, rgba(0,0,0,0.1) 100%);
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 背景渐变动画 */
|
||||
@keyframes gradientShift {
|
||||
0% { background-position: 0% 50%; }
|
||||
25% { background-position: 50% 100%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
75% { background-position: 50% 0%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
|
||||
.ai-float-btn svg {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// 创建按钮DOM
|
||||
function createAIFloatBtn() {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'ai-float-btn-container';
|
||||
|
||||
const btn = document.createElement('div');
|
||||
btn.className = 'ai-float-btn';
|
||||
|
||||
// 可爱风格的AI图标 - 小机器人助手
|
||||
btn.innerHTML = `
|
||||
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- 机器人头部 -->
|
||||
<rect x="5" y="7" width="14" height="12" rx="4" fill="white"/>
|
||||
|
||||
<!-- 天线 -->
|
||||
<path d="M12 7V4" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="12" cy="3" r="1.5" fill="white"/>
|
||||
|
||||
<!-- 眼睛 - 可爱的大眼睛 -->
|
||||
<circle cx="9" cy="11.5" r="2" fill="#667eea"/>
|
||||
<circle cx="15" cy="11.5" r="2" fill="#667eea"/>
|
||||
|
||||
<!-- 眼睛高光 -->
|
||||
<circle cx="9.5" cy="11" r="0.7" fill="white"/>
|
||||
<circle cx="15.5" cy="11" r="0.7" fill="white"/>
|
||||
|
||||
<!-- 微笑嘴巴 -->
|
||||
<path d="M9.5 15C10 16 14 16 14.5 15" stroke="#667eea" stroke-width="1.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- 腮红 -->
|
||||
<circle cx="7" cy="13.5" r="1" fill="#f5a0c0" opacity="0.6"/>
|
||||
<circle cx="17" cy="13.5" r="1" fill="#f5a0c0" opacity="0.6"/>
|
||||
|
||||
<!-- 耳朵/装饰 -->
|
||||
<rect x="3" y="10" width="2" height="4" rx="1" fill="white"/>
|
||||
<rect x="19" y="10" width="2" height="4" rx="1" fill="white"/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
// 点击跳转到聊天页面
|
||||
btn.addEventListener('click', () => {
|
||||
// 可以根据需要修改跳转逻辑
|
||||
window.location.href = 'chat.html';
|
||||
});
|
||||
|
||||
container.appendChild(btn);
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
|
||||
// 页面加载完成后创建按钮
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', createAIFloatBtn);
|
||||
} else {
|
||||
createAIFloatBtn();
|
||||
}
|
||||
})();
|
||||
|
||||
91
Prototype/js/bottom-nav.js
Normal file
91
Prototype/js/bottom-nav.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* 通用底部导航组件
|
||||
* 在所有需要底部导航的页面引入此脚本即可自动生成底部导航栏
|
||||
*/
|
||||
(function() {
|
||||
// 获取当前页面路径
|
||||
const currentPath = window.location.pathname;
|
||||
const currentPage = currentPath.substring(currentPath.lastIndexOf('/') + 1);
|
||||
|
||||
// 判断当前激活的tab
|
||||
const isTaskActive = currentPage === 'task-list.html';
|
||||
const isBoardActive = currentPage.startsWith('board-');
|
||||
const isMyActive = currentPage === 'my-profile.html';
|
||||
|
||||
// 统一的图标定义 - 激活态用fill+stroke,未激活态用stroke
|
||||
const icons = {
|
||||
// 任务图标 - 剪贴板带勾选
|
||||
task: {
|
||||
active: `<svg class="w-6 h-6 text-primary" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="5" y="4" width="14" height="17" rx="2" fill="currentColor" stroke="currentColor" stroke-width="1"/>
|
||||
<rect x="8" y="2" width="8" height="4" rx="1" fill="currentColor" stroke="currentColor" stroke-width="1"/>
|
||||
<path d="M9 12l2 2 4-4" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>`,
|
||||
inactive: `<svg class="w-6 h-6 text-gray-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<rect x="5" y="4" width="14" height="17" rx="2"/>
|
||||
<rect x="8" y="2" width="8" height="4" rx="1"/>
|
||||
<path d="M9 12l2 2 4-4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>`
|
||||
},
|
||||
// 看板图标 - 三个柱状图
|
||||
board: {
|
||||
active: `<svg class="w-6 h-6 text-primary" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1">
|
||||
<rect x="4" y="13" width="4" height="8" rx="1"/>
|
||||
<rect x="10" y="8" width="4" height="13" rx="1"/>
|
||||
<rect x="16" y="3" width="4" height="18" rx="1"/>
|
||||
</svg>`,
|
||||
inactive: `<svg class="w-6 h-6 text-gray-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<rect x="4" y="13" width="4" height="8" rx="1"/>
|
||||
<rect x="10" y="8" width="4" height="13" rx="1"/>
|
||||
<rect x="16" y="3" width="4" height="18" rx="1"/>
|
||||
</svg>`
|
||||
},
|
||||
// 我的图标 - 人物头像
|
||||
my: {
|
||||
active: `<svg class="w-6 h-6 text-primary" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1">
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
<path d="M5.5 21a6.5 6.5 0 0113 0h-13z"/>
|
||||
</svg>`,
|
||||
inactive: `<svg class="w-6 h-6 text-gray-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
<path d="M5.5 21a6.5 6.5 0 0113 0h-13z"/>
|
||||
</svg>`
|
||||
}
|
||||
};
|
||||
|
||||
// 创建底部导航HTML
|
||||
const navHTML = `
|
||||
<div id="bottomNav" class="fixed bottom-0 left-0 right-0 h-16 bg-white/95 backdrop-blur-lg border-t border-gray-2 flex items-center justify-around px-4 z-50">
|
||||
<a href="task-list.html" class="flex flex-col items-center gap-1">
|
||||
${isTaskActive ? icons.task.active : icons.task.inactive}
|
||||
<span class="text-xs ${isTaskActive ? 'text-primary font-medium' : 'text-gray-6'}">任务</span>
|
||||
</a>
|
||||
<a href="board-finance.html" class="flex flex-col items-center gap-1">
|
||||
${isBoardActive ? icons.board.active : icons.board.inactive}
|
||||
<span class="text-xs ${isBoardActive ? 'text-primary font-medium' : 'text-gray-6'}">看板</span>
|
||||
</a>
|
||||
<a href="my-profile.html" class="flex flex-col items-center gap-1">
|
||||
${isMyActive ? icons.my.active : icons.my.inactive}
|
||||
<span class="text-xs ${isMyActive ? 'text-primary font-medium' : 'text-gray-6'}">我的</span>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// 等待DOM加载完成后插入导航
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', insertNav);
|
||||
} else {
|
||||
insertNav();
|
||||
}
|
||||
|
||||
function insertNav() {
|
||||
// 移除页面中已有的底部导航(如果有的话)
|
||||
const existingNav = document.querySelector('nav.fixed.bottom-0, div.fixed.bottom-0[class*="h-16"]');
|
||||
if (existingNav && (existingNav.querySelector('a[href*="task-list"]') || existingNav.querySelector('a[href*="board-"]') || existingNav.querySelector('a[href*="my-profile"]'))) {
|
||||
existingNav.remove();
|
||||
}
|
||||
|
||||
// 插入新导航到body末尾
|
||||
document.body.insertAdjacentHTML('beforeend', navHTML);
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user