助手效果图

看完这篇文章,你将免费拥有你自己的Ai助手,全程干货,先到先得
在这里插入图片描述

获取免费的AI大模型接口

访问这个地址 生成key https://openrouter.ai/mistralai/mistral-small-3.2-24b-instruct:free/api
或者调用其他的免费大模型,这个根据自己的需求更改,要先注册这个网站
在这里插入图片描述

修改默认的参数

最主要的就是你申请生成的key
在这里插入图片描述

助手源码

纯HTML的源码,嘎嘎够劲

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title></title><style>body {font-family: 'Arial', sans-serif;margin: 0;padding: 0;height: 100vh;user-select: none;overflow: hidden;}#chat-container {position: fixed;bottom: 20px;right: 20px;width: 300px;height: 400px;background-color: white;border-radius: 10px;box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);display: flex;flex-direction: column;overflow: hidden;z-index: 1000;resize: both;min-width: 300px;min-height: 400px;transition: transform 0.2s ease, opacity 0.2s ease;transform-origin: bottom right;}#chat-container.minimized {transform: scale(0);opacity: 0;pointer-events: none;}#chat-header {background-color: #4a6bdf;color: white;padding: 12px 15px;cursor: move;display: flex;justify-content: space-between;align-items: center;}#chat-title {font-weight: bold;font-size: 16px;}#minimize-btn, #restore-btn {background: none;border: none;color: white;font-size: 18px;cursor: pointer;padding: 0;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;}#minimized-chat {position: fixed;width: 50px;height: 50px;border-radius: 10px;background-color: #4a6bdf;box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);z-index: 1000;display: none;transition: transform 0.1s ease;}#minimized-chat:active {transform: scale(0.95);}#restore-btn {position: absolute;width: 100%;height: 100%;font-size: 24px;display: flex;align-items: center;justify-content: center;cursor: move;pointer-events: auto;}#chat-messages {flex: 1;padding: 15px;overflow-y: auto;background-color: #f9f9f9;}.message {margin-bottom: 12px;max-width: 80%;padding: 8px 12px;border-radius: 12px;line-height: 1.4;word-wrap: break-word;}.user-message {background-color: #e3effd;margin-left: auto;border-bottom-right-radius: 4px;}.ai-message {background-color: white;margin-right: auto;border-bottom-left-radius: 4px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);}#chat-input-area {display: flex;padding: 10px;border-top: 1px solid #eee;background-color: white;}#chat-input {flex: 1;padding: 10px;border: 1px solid #ddd;border-radius: 20px;outline: none;resize: none;height: 40px;max-height: 100px;font-family: inherit;}#send-btn {margin-left: 10px;padding: 0 15px;background-color: #4a6bdf;color: white;border: none;border-radius: 20px;cursor: pointer;transition: background-color 0.2s;}#send-btn.stop {background-color: #ff4d4d;}#send-btn:hover {background-color: #3a5bcf;}#send-btn.stop:hover {background-color: #e63c3c;}.typing-indicator {display: inline-block;margin-left: 5px;}.typing-dot {display: inline-block;width: 6px;height: 6px;border-radius: 50%;background-color: #999;margin-right: 3px;animation: typingAnimation 1.4s infinite ease-in-out;}.typing-dot:nth-child(1) {animation-delay: 0s;}.typing-dot:nth-child(2) {animation-delay: 0.2s;}.typing-dot:nth-child(3) {animation-delay: 0.4s;}@keyframes typingAnimation {0%, 60%, 100% {transform: translateY(0);}30% {transform: translateY(-5px);}}.stopped-message {color: #888;font-style: italic;}</style>
</head><body><div id="chat-container"><div id="chat-header"><div id="chat-title">AI助手</div><button id="minimize-btn"></button></div><div id="chat-messages"></div><div id="chat-input-area"><textarea id="chat-input" placeholder="输入消息..." rows="1"></textarea><button id="send-btn">发送</button></div></div><div id="minimized-chat"><button id="restore-btn">+</button></div><script>// 获取DOM元素const chatContainer = document.getElementById('chat-container');const chatHeader = document.getElementById('chat-header');const minimizedChat = document.getElementById('minimized-chat');const minimizeBtn = document.getElementById('minimize-btn');const restoreBtn = document.getElementById('restore-btn');const chatInput = document.getElementById('chat-input');const sendBtn = document.getElementById('send-btn');const chatMessages = document.getElementById('chat-messages');// 全局变量let isDragging = false;let isMinimizedDragging = false;let offsetX, offsetY;let startX, startY;let restoreBtnClicked = false;let abortController = null; // 用于中止fetch请求let isWaitingForResponse = false; // 是否正在等待响应let isTypingEffectActive = false; // 是否正在打字效果中let typingTimeoutId = null; // 打字效果的timeout ID// 限制元素在窗口范围内function constrainToWindow(element, x, y) {const rect = element.getBoundingClientRect();const windowWidth = window.innerWidth;const windowHeight = window.innerHeight;const maxX = windowWidth - rect.width;const maxY = windowHeight - rect.height;x = Math.max(0, Math.min(x, maxX));y = Math.max(0, Math.min(y, maxY));return { x, y };}// 主窗口拖动功能chatHeader.addEventListener('mousedown', (e) => {if (e.target.id !== 'chat-header' && e.target.id !== 'chat-title') return;isDragging = true;startX = e.clientX;startY = e.clientY;const rect = chatContainer.getBoundingClientRect();offsetX = startX - rect.left;offsetY = startY - rect.top;chatContainer.style.cursor = 'grabbing';chatContainer.style.transition = 'none';e.preventDefault();});// 恢复按钮拖动功能restoreBtn.addEventListener('mousedown', (e) => {isMinimizedDragging = true;restoreBtnClicked = false;startX = e.clientX;startY = e.clientY;const rect = minimizedChat.getBoundingClientRect();offsetX = startX - rect.left;offsetY = startY - rect.top;minimizedChat.style.cursor = 'grabbing';minimizedChat.style.transition = 'none';e.preventDefault();e.stopPropagation();});// 恢复按钮点击功能restoreBtn.addEventListener('dblclick', (e) => {if (!isMinimizedDragging && !restoreBtnClicked) {restoreBtnClicked = true;restoreChatWindow();}e.stopPropagation();});document.addEventListener('mousemove', (e) => {if (isDragging) {let x = e.clientX - offsetX;let y = e.clientY - offsetY;const constrained = constrainToWindow(chatContainer, x, y);x = constrained.x;y = constrained.y;chatContainer.style.left = `${x}px`;chatContainer.style.top = `${y}px`;chatContainer.style.right = 'auto';chatContainer.style.bottom = 'auto';}if (isMinimizedDragging) {let x = e.clientX - offsetX;let y = e.clientY - offsetY;const constrained = constrainToWindow(minimizedChat, x, y);x = constrained.x;y = constrained.y;minimizedChat.style.left = `${x}px`;minimizedChat.style.top = `${y}px`;minimizedChat.style.right = 'auto';minimizedChat.style.bottom = 'auto';}});document.addEventListener('mouseup', () => {if (isDragging) {isDragging = false;chatContainer.style.cursor = 'default';chatContainer.style.transition = 'transform 0.2s ease, opacity 0.2s ease';}if (isMinimizedDragging) {isMinimizedDragging = false;minimizedChat.style.cursor = 'move';minimizedChat.style.transition = 'transform 0.1s ease';}});// 缩小/恢复功能minimizeBtn.addEventListener('click', (e) => {e.stopPropagation();const rect = chatContainer.getBoundingClientRect();minimizedChat.style.left = `${rect.left}px`;minimizedChat.style.top = `${rect.top}px`;minimizedChat.style.right = 'auto';minimizedChat.style.bottom = 'auto';const constrained = constrainToWindow(minimizedChat, parseFloat(minimizedChat.style.left || 0),parseFloat(minimizedChat.style.top || 0));minimizedChat.style.left = `${constrained.x}px`;minimizedChat.style.top = `${constrained.y}px`;chatContainer.classList.add('minimized');setTimeout(() => {minimizedChat.style.display = 'block';}, 200);});function restoreChatWindow() {chatContainer.style.left = 'auto';chatContainer.style.top = 'auto';chatContainer.style.right = '20px';chatContainer.style.bottom = '20px';chatContainer.classList.remove('minimized');minimizedChat.style.display = 'none';}// 聊天功能chatInput.addEventListener('input', function() {this.style.height = 'auto';this.style.height = (this.scrollHeight > 100 ? 100 : this.scrollHeight) + 'px';});function sendMessage() {const message = chatInput.value.trim();if (!message) return;addMessage(message, 'user');chatInput.value = '';chatInput.style.height = '40px';// 改变按钮状态setSendButtonState('stop');const typingId = showTypingIndicator();simulateAIResponse(message, typingId);}function stopRequest() {if (abortController) {abortController.abort();abortController = null;}if (isTypingEffectActive) {clearTimeout(typingTimeoutId);isTypingEffectActive = false;// 添加停止提示const stoppedDiv = document.createElement('div');stoppedDiv.className = 'message ai-message stopped-message';stoppedDiv.textContent = '已停止生成回复';chatMessages.appendChild(stoppedDiv);chatMessages.scrollTop = chatMessages.scrollHeight;}setSendButtonState('send');isWaitingForResponse = false;// 移除正在输入指示器const typingElements = document.querySelectorAll('[id^="typing-"]');typingElements.forEach(el => el.remove());}function setSendButtonState(state) {if (state === 'stop') {sendBtn.textContent = '停止';sendBtn.classList.add('stop');sendBtn.removeEventListener('click', sendMessage);sendBtn.addEventListener('click', stopRequest);isWaitingForResponse = true;} else {sendBtn.textContent = '发送';sendBtn.classList.remove('stop');sendBtn.removeEventListener('click', stopRequest);sendBtn.addEventListener('click', sendMessage);isWaitingForResponse = false;}}chatInput.addEventListener('keydown', (e) => {if (e.key === 'Enter' && !e.shiftKey) {e.preventDefault();if (!isWaitingForResponse) {sendMessage();}}});// 初始化按钮事件sendBtn.addEventListener('click', sendMessage);function addMessage(text, sender) {const messageDiv = document.createElement('div');messageDiv.className = `message ${sender}-message`;messageDiv.textContent = text;chatMessages.appendChild(messageDiv);chatMessages.scrollTop = chatMessages.scrollHeight;}function showTypingIndicator() {const typingDiv = document.createElement('div');typingDiv.className = 'message ai-message';typingDiv.id = 'typing-' + Date.now();const typingText = document.createElement('span');typingText.textContent = 'YiLin:';const typingDots = document.createElement('span');typingDots.className = 'typing-indicator';for (let i = 0; i < 3; i++) {const dot = document.createElement('span');dot.className = 'typing-dot';typingDots.appendChild(dot);}typingDiv.appendChild(typingText);typingDiv.appendChild(typingDots);chatMessages.appendChild(typingDiv);chatMessages.scrollTop = chatMessages.scrollHeight;return typingDiv.id;}function removeTypingIndicator(id) {const typingElement = document.getElementById(id);if (typingElement) {typingElement.remove();}}async function simulateAIResponse(userMessage, typingId) {abortController = new AbortController();try {const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {method: "POST",headers: {"Authorization": "Bearer sk-or-v1-xxxxxxxxxxxx","HTTP-Referer": "https://nanwish.love","X-Title": "沂霖博客","Content-Type": "application/json"},body: JSON.stringify({"model": "mistralai/mistral-small-3.2-24b-instruct:free","messages": [{"role": "user","content": [{"type": "text","text": userMessage}]}]}),signal: abortController.signal});const data = await response.json();removeTypingIndicator(typingId);if (data.choices && data.choices[0].message.content) {typeWriterEffect(data.choices[0].message.content);} else {addMessage("抱歉,未能获取有效回复", 'ai');setSendButtonState('send');}} catch (error) {if (error.name !== 'AbortError') {removeTypingIndicator(typingId);addMessage("抱歉,发生错误: " + error.message, 'ai');setSendButtonState('send');}} finally {abortController = null;}}function typeWriterEffect(text) {const messageDiv = document.createElement('div');messageDiv.className = 'message ai-message';chatMessages.appendChild(messageDiv);let i = 0;const speed = 20;isTypingEffectActive = true;function type() {if (i < text.length) {messageDiv.textContent += text.charAt(i);i++;chatMessages.scrollTop = chatMessages.scrollHeight;typingTimeoutId = setTimeout(type, speed);} else {isTypingEffectActive = false;setSendButtonState('send');}}type();}// 初始化window.addEventListener('DOMContentLoaded', () => {minimizedChat.style.display = 'none';setTimeout(() => {typeWriterEffect("你好!我是沂霖,我可以辅助你使用MarkDown,聊天,查资料!你可以输入问题或指令,我会尽力回答。");}, 500);});// 窗口大小变化时重新限制位置window.addEventListener('resize', () => {if (!chatContainer.classList.contains('minimized')) {const rect = chatContainer.getBoundingClientRect();const constrained = constrainToWindow(chatContainer, rect.left, rect.top);chatContainer.style.left = `${constrained.x}px`;chatContainer.style.top = `${constrained.y}px`;}if (minimizedChat.style.display === 'block') {const rect = minimizedChat.getBoundingClientRect();const constrained = constrainToWindow(minimizedChat, rect.left, rect.top);minimizedChat.style.left = `${constrained.x}px`;minimizedChat.style.top = `${constrained.y}px`;}});</script>
</body></html>

把这个嵌入到你的网站页面 就可以实现站点助手了

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89002.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89002.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/89002.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASProxy64.dll导致jetbrains家的IDE都无法打开。

在Windows11中,无法打开jetbrains的IDE的软件,经过排查,发现与ASProxy64.dll有关。 E:\idea\IntelliJ IDEA 2024.1.7\bin>idea.bat CompileCommand: exclude com/intellij/openapi/vfs/impl/FilePartNodeRoot.trieDescend bool exclude = true # # A fatal error has bee…

springboot+Vue逍遥大药房管理系统

概述 基于springbootVue开发的逍遥大药房管理系统。该系统功能完善&#xff0c;既包含强大的后台管理模块&#xff0c;又具备用户友好的前台展示界面。 主要内容 一、后台管理系统功能 ​​核心管理模块​​&#xff1a; 用户管理&#xff1a;管理员与普通用户权限分级药品分…

探索阿里云智能媒体管理IMM:解锁媒体处理新境界

一、引言&#xff1a;开启智能媒体管理新时代 在数字化浪潮的席卷下&#xff0c;媒体行业正经历着前所未有的变革。从传统媒体到新媒体的转型&#xff0c;从内容生产到传播分发&#xff0c;每一个环节都在寻求更高效、更智能的解决方案。而云计算&#xff0c;作为推动这一变革…

[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+jsp实现的新生报道管理系统,推荐!

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了新生报道管理系统的开发全过程。通过分析高校新生入学报到信息管理的不足&#xff0c;创建了一个计算机管理高校新生入学报到信息的方案。文章介绍了新生报道管…

给定一个整型矩阵map,求最大的矩形区域为1的数量

题目: 给定一个整型矩阵map,其中的值只有0和1两种,求其中全是1的 所有矩形区域中,最大的矩形区域为1的数量。 例如: 1 1 1 0 其中,最大的矩形区域有3个1,所以返回3。 再如: 1 0 1 1 1 1 1 1 1 1 1 0 其中,最大的矩形区域有6个1,所以返回6。 解题思…

第8章-财务数据

get_fund # 查看股票代码000001.XSHE在2022年9月1日的总市值 q query( valuation ).filter( valuation.code 000001.XSHE ) df get_fundamentals(q, 2022-09-01) print(df[market_cap][0]) # 获取第一行的market_cap值 这段代码看起来是用于查询股票在特定日期的总…

SQL关键字三分钟入门:ROW_NUMBER() —— 窗口函数为每一行编号

在进行数据分析时&#xff0c;我们常常需要为查询结果集中的每条记录生成一个唯一的序号或行号。例如&#xff1a; 为每位员工按照入职时间排序并编号&#xff1b;按照订单金额对订单进行排序&#xff0c;并给每个订单分配一个顺序编号&#xff1b;在分组数据内为每条记录编号…

微信小程序如何实现通过邮箱验证修改密码功能

基于腾讯云开发&#xff08;Tencent Cloud Base&#xff09;实现小程序邮箱验证找回密码功能的完整逻辑说明及关键代码实现。结合安全性和开发效率&#xff0c;方案采用 ​​云函数 小程序前端​​ 的架构&#xff0c;使用 ​​Nodemailer​​ 发送邮件。Nodemailer 是一个专为…

C# VB.NET中Tuple轻量级数据结构和固定长度数组

C# VB.NET取字符串中全角字符数量和半角字符数量-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148871910 在VB.NET中&#xff0c;使用Tuple和固定长度数组在性能上有细微差异&#xff0c;以下是详细分析&#xff1a; 性能对比测试 通过测试 100 万次调用&am…

建筑物年代预测与空间异质性分析解决方案

建筑物年代预测与空间异质性分析解决方案 1. 问题分析与创新点设计 核心任务:预测建筑物建造年代,并分析空间异质性对预测的影响 创新点设计: 空间权重矩阵集成:构建空间邻接矩阵量化地理邻近效应多尺度特征提取:融合建筑物微观特征与街区宏观特征异质性分区建模:基于…

FOUPK3system5XOS

Foupk3systemX5OS系统19.60内测版&#xff08;X9&#xff09;2023年4月16日正式发布 1.0Foupk3systemX5OS系统19.60&#xff08;X9&#xff09;2024年10月6日发布 Foupk3systemX5OS系统19.60增强版&#xff08;X9X5&#xff09;2024年10月6日发布Foupk3systemX5OS系统19.60正…

随机生成的乱码域名”常由**域名生成算法(DGA)** 产生

“随机生成的乱码域名”常由**域名生成算法&#xff08;DGA&#xff09;** 产生&#xff0c;是网络攻击&#xff08;尤其是僵尸网络、恶意软件控制场景 &#xff09;中躲避检测的手段&#xff0c;以下是关键解析&#xff1a; ### 一、本质与产生逻辑 乱码域名是攻击者利用 **DG…

Solidity学习 - 继承

文章目录 前言继承的基本概念继承的基本用法单继承实现函数重写&#xff08;overriding&#xff09; 构造函数的继承处理多重继承抽象合约 前言 继承是面向对象编程中的核心概念之一&#xff0c;Solidity作为一种面向对象的智能合约语言&#xff0c;同样支持继承机制。通过继承…

依赖注入(Dependency Injection, DI)的核心概念和解决的核心问题

核心概念&#xff1a; 依赖注入是一种设计模式&#xff0c;也是实现控制反转&#xff08;Inversion of Control, IoC&#xff09; 原则的一种具体技术。其核心思想是&#xff1a; 解耦&#xff1a; 将一个类&#xff08;客户端&#xff09;所依赖的其他类或服务&#xff08;依…

Reactor Schedulers

Reactor 是一个基于响应式编程的库&#xff0c;它提供了丰富的调度器&#xff08;Schedulers&#xff09;机制&#xff0c;用于管理异步操作的执行环境。Schedulers 是 Reactor 中的核心组件之一&#xff0c;它们允许开发者灵活地控制操作符和订阅操作在哪个线程上执行&#xf…

设备树引入

一、设备树的基本知识 1、什么是设备树&#xff1f;为什么会有设备树&#xff1f; 2011年&#xff0c;Linux之父Linus Torvalds发现这个问题后&#xff0c;就通过邮件向ARM-Linux开发社区发了一封邮件&#xff0c;不禁的发出了一句“This whole ARM thing is a f*cking pain i…

【数据标注师】3D标注

目录 一、 **3D标注知识体系框架**二、 **五阶能力培养体系**▶ **阶段1&#xff1a;空间认知筑基&#xff08;2-3周&#xff09;**▶ **阶段2&#xff1a;核心标注技能深化**▶ **阶段3&#xff1a;复杂场景解决方案**▶ **阶段4&#xff1a;领域深度专精▶ **阶段5&#xff1…

华为HN8145V光猫改华为蓝色公版界面,三网通用,xgpon公版光猫

咸鱼只卖20多元一个&#xff0c;还是xgpon的万兆猫&#xff0c;性价比不错哦 除了没有2.5G网口&#xff0c;其他还行。 改成公版光猫后&#xff0c;运营商是无法纳管光猫&#xff0c;无法后台修改光猫数据及超密。 华为 HN8145V 光猫具有以下特点&#xff1a; 性能方面 高速接…

【LeetCode 热题 100】438. 找到字符串中所有字母异位词——(解法二)定长滑动窗口+数组

Problem: 438. 找到字符串中所有字母异位词 题目&#xff1a;给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 【LeetCode 热题 100】438. 找到字符串中所有字母异位词——&#xff08;解法一&…

PAC 学习框架:机器学习的可靠性工程

PAC&#xff08;Probably Approximately Correct&#xff09; 是机器学习理论的核心框架&#xff0c;用于量化学习算法的可靠性。它回答了一个关键问题&#xff1a; “需要多少训练样本&#xff0c;才能以较高概率学到一个近似正确的模型&#xff1f;” 一、PAC 名称拆解 术语…