2023/12/31 13:10:52 通过GPT辅助查询,已适配:百度、必应
当前为
// ==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.3
// @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 divE = document.createElement('div');
//divE.classList.add("markdown-body");
divE.innerHTML = `
<div class="searchC">
<textarea class="text" id="story" name="story" rows="1" 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">请稍等一会...</article>
</div>
<style>
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:600px;
overflow: hidden;
overflow-y: scroll;
}
/*搜索框*/
.searchC{
position: relative;
}
.text {
margin: 10px;
max-height:600px;
border-radius: 5px;
color: #9E9C9C;
resize: vertical;
overflow-y:scroll;
}
.btn {
height:50rpx;
background: #7BA7AB;
border-radius: 0 5px 5px 0;
margin: 10px;
position: absolute;
}
</style>
`;
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("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);
}
});
// 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 PostData(query) {
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;
}
}
//document.getElementById('gptAnswer').innerHTML = "请稍等一会儿...";
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);
}
}
function write() {
console.log('已经成功实现节流');
document.getElementById('gptAnswer').innerHTML = "请稍等一会儿...";
var query = document.getElementById("story").value;
if (query.length === 0) {
toastr.warning("请输入自定义关键字/句!")
return;
}
// 执行你的搜索操作或其他逻辑
//console.log("自定义搜索词:" + query);
creatBox();
//执行获取
PostData(query);
}