// ==UserScript==
// @name Next API
// @namespace Violentmonkey Scripts
// @match *://www.baidu.com/s*
// @match *://www.baidu.com/*
// @match http://www.baidu.com/*
// @match https://www.baidu.com/*
// @match *://*.bing.com/*
// @grant GM_setClipboard
// @grant GM_addStyle
// @grant GM_getResourceText
// @require https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js
// @require https://cdn.bootcdn.net/ajax/libs/showdown/2.1.0/showdown.min.js
// @require https://cdn.bootcdn.net/ajax/libs/highlight.js/11.7.0/highlight.min.js
// @require https://cdn.bootcss.com/toastr.js/latest/js/toastr.min.js
// @resource toastCss https://cdn.bootcss.com/toastr.js/latest/css/toastr.min.css
// @grant none
// @version 1.1.5.1
// @author yang
// @description 2023/12/31 13:10:52 通过GPT辅助查询
// @license MIT
// ==/UserScript==
console.log("加载脚本:" + GetNowDate());
window.onload = function (e) {
creatBox();
GM_addStyle(GM_getResourceText("toastCss"));
// //存储访问密钥到缓存
// let SNKey = localStorage.getItem("SNKey");
// if (SNKey === null) {
// let result = window.prompt("请输入访问密钥!");
// if (result === null) {
// document.getElementById('gptAnswer').innerHTML = "取消访问...";
// return;
// } else {
// localStorage.setItem("SNKey", result);
// }
// }
}
//全局变量 存储搜索关键字
var keyWord = "";
// if (window.location.href.indexOf("baidu.com\/s") > -1) {
// var query = document.getElementById("kw").value;
// console.log("用户输入的搜索词:" + query);
// PostData(query);
// }
//绘画输出框
function creatBox() {
let local = `
<div id="panelTop" class="panelP panelS slide-out">
<div class="searchC">
<textarea class="text" id="story" name="story" rows="3" cols="33"
placeholder="It was a dark and stormy night..."></textarea>
<button class="btn" id='CusomBtn' onclick="">查询</button>
</div>
<div class="card">
<article id="gptAnswer" class="markdown-body" style="height:350px;overflow-y: scroll;">请稍等一会...</article>
</div>
</div>
<div class="footer">
<button id="showHtml" class="showBtn"></button>
</div>
<style>
.panelP {
position: fixed;
right: 20px;
width: 300px;
background-color: #f5f5f5;
padding: 10px;
/* height: 500px; */
position: fixed;
bottom: 40px;
overflow-y: overflow;
z-index: 999;
}
.panelS {
/* width: 200px;
height: 200px; */
background-color: gray;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.slide-out {
transform: translateX(200px);
opacity: 0;
/*pacity: 1;*/
}
.slide-in {
transform: translateX(0);
opacity: 1;
}
.footer {
position: fixed;
bottom: 20px;
/* 根据需求调整到合适的位置 */
right: 20px;
/* 根据需求调整到合适的位置 */
/* width: 300px; */
/* 根据需求调整大小 */
/* background-color: #f5f5f5; */
padding: 10px;
/* border: 1px solid #ccc; */
}
pre .btn-pre-copy {
text-align: right;
display: block;
}
pre .btn-pre-copy:hover {
cursor: pointer;
}
.card {
border: 0.5px solid #ccc;
/* 设置边框 */
background-color: #fff;
/* 设置背景颜色 */
padding: 5px;
/* 设置内部间距 */
margin: 10px;
/* 设置外部间距 */
border-radius: 5px;
/* 添加圆角效果 */
max-height: 350px;
overflow: hidden;
overflow-y: scroll;
}
/*搜索框*/
.searchC {
position: relative;
}
.text {
margin: 10px;
max-height: 200px;
width: 280px;
border-radius: 5px;
color: #9E9C9C;
resize: vertical;
overflow-y: scroll;
}
.btn {
height: 50rpx;
background: #7BA7AB;
border-radius: 0 5px 5px 0;
margin: 0px 10px;
width: 280px;
/* position: absolute; */
}
.showBtn {
width: 50px;
height: 50px;
border-radius: 50%;
background-image: url('https://pic.imgdb.cn/item/6314920616f2c2beb162b42a.gif');
background-size: cover;
background-size: cover;
background-position: center;
}
</style>
`;
let divE = document.createElement('div');
//divE.classList.add("markdown-body");
divE.innerHTML = local;
let NewDom = document.getElementById("gptAnswer");
// let content_right = "";
// if (window.location.href.indexOf("baidu.com\/s") > -1) {
// content_right = document.getElementById('content_right');
// }
// if ((window.location.href.indexOf("bing.com") > -1)) {
// content_right = document.getElementById('b_context');
// }
if (NewDom === null && content_right !== null) {
content_right.prepend(divE);
//监听自定义事件
document.getElementById("CusomBtn").addEventListener("click", jl(write, 1500));
document.getElementById("showHtml").addEventListener("click", function (event) {
// 执行你的搜索操作或其他逻辑
//console.log("用户输入的搜索词:" + query);
var panel = document.getElementById('panelTop'); // 选取id为panel的元素
//panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
if (isSlidedIn) {
panel.classList.remove('slide-in');
panel.classList.add('slide-out');
} else {
panel.classList.remove('slide-out');
panel.classList.add('slide-in');
write();
}
isSlidedIn = !isSlidedIn;
})
}
}
var isSlidedIn = false;
// //监听回车搜索事件
// document.getElementById("kw").addEventListener("keydown", function(event) {
// if (event.keyCode === 13) {
// // 回车键被按下
// //event.preventDefault(); // 阻止默认的提交行为
// var query = document.getElementById("kw").value;
// // 执行你的搜索操作或其他逻辑
// console.log("用户输入的搜索词:" + query);
// creatBox();
// //执行获取
// PostData(query);
// }
// });
// if (window.location.href.indexOf("baidu.com\/s") > -1) {
// // //监听回车搜索事件
// document.getElementById("su").addEventListener("click", function (event) {
// // var query = document.getElementById("kw").value;
// // // 执行你的搜索操作或其他逻辑
// // console.log("用户输入的搜索词:" + query);
// // creatBox();
// // //执行获取
// // PostData(query);
// PostData(keyWord);
// });
// }
//定时任务
setInterval(() => {
creatBox();
let key = "";
if (window.location.href.indexOf("baidu.com\/s") > -1) {
key = getUrlParam(window.location.href, 'wd');
}
if ((window.location.href.indexOf("bing.com") > -1)) {
key = getUrlParam(window.location.href, 'q');
}
if (key !== keyWord) {
keyWord = key;
//执行获取
//PostData(keyWord);
document.getElementById("story").value = keyWord;
}
});
// function CusomBtn() {
// document.getElementById('gptAnswer').innerHTML = "请稍等一会儿...";
// let key = document.getElementById("story").value;
// PostData(key);
// }
//获取地址栏参数
function getUrlParam(url, param) {
const reg = new RegExp("(^|&)" + param + "=([^&]*)(&|$)");
const result = url.substring(url.indexOf('?') + 1).match(reg);
if (result != null) {
return decodeURIComponent(result[2]);
}
return null;
}
function containsProgrammingLanguage(str) {
const programmingLanguages = ['C#', 'c#', 'Java', 'java', 'Python', 'JavaScript', 'js']; // 编程语言列表
for (let i = 0; i < programmingLanguages.length; i++) {
const language = programmingLanguages[i];
if (str.includes(language)) {
return true;
}
}
return false;
}
// // 示例用法
// const string1 = '我喜欢编程,特别是C#和JavaScript';
// console.log(containsProgrammingLanguage(string1)); // 输出: true
// const string2 = '这个字符串没有编程语言的名称';
// console.log(containsProgrammingLanguage(string2)); // 输出: false
function PostData(query, isCheck = true) {
let SNKey = localStorage.getItem("SNKey")
if (SNKey === null) {
let result = window.prompt("请输入访问密钥!");
if (result === null) {
document.getElementById('gptAnswer').innerHTML = "取消访问...";
toastr.error("用户取消访问!");
return;
} else {
localStorage.setItem("SNKey", result);
SNKey = result;
}
}
//isCheck && !containsProgrammingLanguage(query)
if (isCheck) {
console.log("过滤。。。。");
document.getElementById('gptAnswer').innerHTML = "搜索无效。。。";
return;
}
var obj = {
"messages": [{
"role": "system",
"content": "\nYou are ChatGPT, a large language model trained by OpenAI.\nKnowledge cutoff: 2021-09\nCurrent model: gpt-3.5-turbo\nCurrent time: 2023/12/31 12:13:57\nLatex inline: $x^2$ \nLatex block: $$e=mc^2$$\n\n"
},
{
"role": "user",
"content": query
}
],
"stream": false,//是否使用流输出
"model": "gpt-3.5-turbo",
"temperature": 0.5,
"presence_penalty": 0,
"frequency_penalty": 0,
"top_p": 1
};
var httpRequest = new XMLHttpRequest();
var url = "https://api.nextapi.fun/v1/chat/completions";
httpRequest.open("POST", url, true);
httpRequest.setRequestHeader("Content-type", "application/json");
httpRequest.setRequestHeader("Authorization", "Bearer " + SNKey);
httpRequest.send(JSON.stringify(obj)); //发送请求 将json写入send中
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
//处理响应结果
var result = httpRequest.responseText;
//console.log(new Date());
result = JSON.parse(result);
//console.log(result)
//console.log(result.choices[0].message.content);
var message = result.choices[0].message.content;
// var renderedHTML = marked.parse(message);
// // console.log(renderedHTML);
// creatBox();
// var NewDom = document.getElementById("outputStory");
// NewDom.innerHTML = renderedHTML;
creatBox();
showAnserAndHighlightCodeStr(message);
toastr.success("插件辅助查询到相关信息!", "成功");
} else {
//处理请求失败
//alert('请求失败');
toastr.error("请求失败。")
}
}
};
}
//显示答案并高亮代码函数
function showAnserAndHighlightCodeStr(codeStr) {
if (!codeStr) return
rawAns = codeStr; //记录原文
try {
document.getElementById('gptAnswer').innerHTML = mdConverter(codeStr)
} catch (ex) {
console.error(ex)
}
highlightCodeStr() //高亮
//添加代码复制按钮 start
let preList = document.querySelectorAll("#gptAnswer pre")
preList.forEach((pre) => {
try {
if (!pre.querySelector(".btn-pre-copy")) {
//<span class=\"btn-pre-copy\" onclick='preCopy(this)'>复制代码</span>
let copyBtn = document.createElement("span");
copyBtn.setAttribute("class", "btn-pre-copy");
copyBtn.addEventListener("click", (event) => {
let _this = event.target
//console.log(_this)
let pre = _this.parentNode;
//console.log(pre.innerText)
_this.innerText = '';
GM_setClipboard(pre.innerText, "text");
_this.innerText = '复制成功'
toastr.success("恭喜,操作成功了!", "成功")
setTimeout(() => {
_this.innerText = '复制代码'
}, 2000)
})
copyBtn.innerText = '复制代码'
pre.insertBefore(copyBtn, pre.firstChild)
}
} catch (e) {
console.log(e)
}
})
//添加代码复制按钮 end
}
//高亮代码函数
function highlightCodeStr() {
let gptAnswerDiv = document.querySelector("#gptAnswer");
gptAnswerDiv.querySelectorAll('pre code').forEach((el) => {
hljs.highlightElement(el);
});
}
//转换Md格式为Html
function mdConverter(rawData) {
let converter = new showdown.Converter();
converter.setOption('tables',
true); //启用表格选项。从showdown 1.2.0版开始,表支持已作为可选功能移入核心拓展,showdown.table.min.js扩展已被弃用
converter.setOption('openLinksInNewWindow', true) //链接在新窗口打开
converter.setOption('strikethrough', true) //删除线
converter.setOption('emoji', true) //开启emoji
/***
* original: John Gruber 规范中的原始 Markdown 风格
* vanilla:对决基础风味(v1.3.1 起)
* github: GitHub 风格的 Markdown,或 GFM
*/
showdown.setFlavor('github');
try {
return converter.makeHtml(rawData);
} catch (ex) {
console.error(ex)
}
return rawData;
}
//获取当前时间
function GetNowDate() {
// 创建一个 Date 对象来表示当前时间
var now = new Date();
// 获取年份、月份、日期、小时、分钟和秒数
var year = now.getFullYear();
var month = ('0' + (now.getMonth() + 1)).slice(-2); // 月份从 0 开始,需要加 1
var day = ('0' + now.getDate()).slice(-2);
var hours = ('0' + now.getHours()).slice(-2);
var minutes = ('0' + now.getMinutes()).slice(-2);
var seconds = ('0' + now.getSeconds()).slice(-2);
// 构建年月日时分秒的字符串格式
var formattedDateTime = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
// 输出结果
return formattedDateTime;
}
//节流函数
function jl(fn, deplay) {
let timer;
return function () {
let content = this;
let ar = arguments;
if (timer) {
toastr.warning("手速过快!")
return;
}
timer = setTimeout(function () {
fn.apply(content, arguments);
timer = null;
}, deplay);
}
}
var query = "";
function write() {
console.log('已经成功实现节流');
if (query === document.getElementById("story").value) {
return;
}
query = document.getElementById("story").value;
document.getElementById('gptAnswer').innerHTML = "请稍等一会儿...";
if (query.length === 0) {
toastr.warning("请输入自定义关键字/句!")
return;
}
// 执行你的搜索操作或其他逻辑
//console.log("自定义搜索词:" + query);
creatBox();
//执行获取
PostData(query, false);
}