// ==UserScript== // @name ChatGPT学习通作业考试助手 // @version 3.0.3 // @description 本脚本【采用ChatGPT,DeepSeek,Gemini等顶尖AI直接生成答案】 【🥇操作简单】ChatGPT学习通助手,安装即可使用;推荐使用作业、考试自动答题【✨版本特性】版本特性:无题库,全采用AI回复答案,原作者:Ne-21 // @match *://*.chaoxing.com/* // @match *://*.edu.cn/* // @tag 免费试用 // @connect 911285.xyz // @connect gptjs.808860.xyz // @connect 127.0.0.1 // @run-at document-end // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_info // @grant GM_getResourceText // @require https://gptjs.808860.xyz/libs/TyprMd5.js // @require https://gptjs.808860.xyz/libs/sweetalert2-11.1.0.all.min.js // @require https://gptjs.808860.xyz/libs/jquery-3.7.1.min.js // @resource Table https://gptjs.808860.xyz/libs/table.json // @icon data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDEiIGhlaWdodD0iNDEiIHZpZXdCb3g9IjAgMCA0MSA0MSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2Utd2lkdGg9IjEuNSIgY2xhc3M9ImgtNiB3LTYiIHJvbGU9ImltZyI+PHRpdGxlPkNoYXRHUFQ8L3RpdGxlPjx0ZXh0IHg9Ii05OTk5IiB5PSItOTk5OSI+Q2hhdEdQVDwvdGV4dD48cGF0aCBkPSJNMzcuNTMyNCAxNi44NzA3QzM3Ljk4MDggMTUuNTI0MSAzOC4xMzYzIDE0LjA5NzQgMzcuOTg4NiAxMi42ODU5QzM3Ljg0MDkgMTEuMjc0NCAzNy4zOTM0IDkuOTEwNzYgMzYuNjc2IDguNjg2MjJDMzUuNjEyNiA2LjgzNDA0IDMzLjk4ODIgNS4zNjc2IDMyLjAzNzMgNC40OTg1QzMwLjA4NjQgMy42Mjk0MSAyNy45MDk4IDMuNDAyNTkgMjUuODIxNSAzLjg1MDc4QzI0Ljg3OTYgMi43ODkzIDIzLjcyMTkgMS45NDEyNSAyMi40MjU3IDEuMzYzNDFDMjEuMTI5NSAwLjc4NTU3NSAxOS43MjQ5IDAuNDkxMjY5IDE4LjMwNTggMC41MDAxOTdDMTYuMTcwOCAwLjQ5NTA0NCAxNC4wODkzIDEuMTY4MDMgMTIuMzYxNCAyLjQyMjE0QzEwLjYzMzUgMy42NzYyNCA5LjM0ODUzIDUuNDQ2NjYgOC42OTE3IDcuNDc4MTVDNy4zMDA4NSA3Ljc2Mjg2IDUuOTg2ODYgOC4zNDE0IDQuODM3NyA5LjE3NTA1QzMuNjg4NTQgMTAuMDA4NyAyLjczMDczIDExLjA3ODIgMi4wMjgzOSAxMi4zMTJDMC45NTY0NjQgMTQuMTU5MSAwLjQ5ODkwNSAxNi4yOTg4IDAuNzIxNjk4IDE4LjQyMjhDMC45NDQ0OTIgMjAuNTQ2NyAxLjgzNjEyIDIyLjU0NDkgMy4yNjggMjQuMTI5M0MyLjgxOTY2IDI1LjQ3NTkgMi42NjQxMyAyNi45MDI2IDIuODExODIgMjguMzE0MUMyLjk1OTUxIDI5LjcyNTYgMy40MDcwMSAzMS4wODkyIDQuMTI0MzcgMzIuMzEzOEM1LjE4NzkxIDM0LjE2NTkgNi44MTIzIDM1LjYzMjIgOC43NjMyMSAzNi41MDEzQzEwLjcxNDEgMzcuMzcwNCAxMi44OTA3IDM3LjU5NzMgMTQuOTc4OSAzNy4xNDkyQzE1LjkyMDggMzguMjEwNyAxNy4wNzg2IDM5LjA1ODcgMTguMzc0NyAzOS42MzY2QzE5LjY3MDkgNDAuMjE0NCAyMS4wNzU1IDQwLjUwODcgMjIuNDk0NiA0MC40OTk4QzI0LjYzMDcgNDAuNTA1NCAyNi43MTMzIDM5LjgzMjEgMjguNDQxOCAzOC41NzcyQzMwLjE3MDQgMzcuMzIyMyAzMS40NTU2IDM1LjU1MDYgMzIuMTExOSAzMy41MTc5QzMzLjUwMjcgMzMuMjMzMiAzNC44MTY3IDMyLjY1NDcgMzUuOTY1OSAzMS44MjFDMzcuMTE1IDMwLjk4NzQgMzguMDcyOCAyOS45MTc4IDM4Ljc3NTIgMjguNjg0QzM5Ljg0NTggMjYuODM3MSA0MC4zMDIzIDI0LjY5NzkgNDAuMDc4OSAyMi41NzQ4QzM5Ljg1NTYgMjAuNDUxNyAzOC45NjM5IDE4LjQ1NDQgMzcuNTMyNCAxNi44NzA3Wk0yMi40OTc4IDM3Ljg4NDlDMjAuNzQ0MyAzNy44ODc0IDE5LjA0NTkgMzcuMjczMyAxNy42OTk0IDM2LjE1MDFDMTcuNzYwMSAzNi4xMTcgMTcuODY2NiAzNi4wNTg2IDE3LjkzNiAzNi4wMTYxTDI1LjkwMDQgMzEuNDE1NkMyNi4xMDAzIDMxLjMwMTkgMjYuMjY2MyAzMS4xMzcgMjYuMzgxMyAzMC45Mzc4QzI2LjQ5NjQgMzAuNzM4NiAyNi41NTYzIDMwLjUxMjQgMjYuNTU0OSAzMC4yODI1VjE5LjA1NDJMMjkuOTIxMyAyMC45OThDMjkuOTM4OSAyMS4wMDY4IDI5Ljk1NDEgMjEuMDE5OCAyOS45NjU2IDIxLjAzNTlDMjkuOTc3IDIxLjA1MiAyOS45ODQyIDIxLjA3MDcgMjkuOTg2NyAyMS4wOTAyVjMwLjM4ODlDMjkuOTg0MiAzMi4zNzUgMjkuMTk0NiAzNC4yNzkxIDI3Ljc5MDkgMzUuNjg0MUMyNi4zODcyIDM3LjA4OTIgMjQuNDgzOCAzNy44ODA2IDIyLjQ5NzggMzcuODg0OVpNNi4zOTIyNyAzMS4wMDY0QzUuNTEzOTcgMjkuNDg4OCA1LjE5NzQyIDI3LjcxMDcgNS40OTgwNCAyNS45ODMyQzUuNTU3MTggMjYuMDE4NyA1LjY2MDQ4IDI2LjA4MTggNS43MzQ2MSAyNi4xMjQ0TDEzLjY5OSAzMC43MjQ4QzEzLjg5NzUgMzAuODQwOCAxNC4xMjMzIDMwLjkwMiAxNC4zNTMyIDMwLjkwMkMxNC41ODMgMzAuOTAyIDE0LjgwODggMzAuODQwOCAxNS4wMDczIDMwLjcyNDhMMjQuNzMxIDI1LjExMDNWMjguOTk3OUMyNC43MzIxIDI5LjAxNzcgMjQuNzI4MyAyOS4wMzc2IDI0LjcxOTkgMjkuMDU1NkMyNC43MTE1IDI5LjA3MzYgMjQuNjk4OCAyOS4wODkzIDI0LjY4MjkgMjkuMTAxMkwxNi42MzE3IDMzLjc0OTdDMTQuOTA5NiAzNC43NDE2IDEyLjg2NDMgMzUuMDA5NyAxMC45NDQ3IDM0LjQ5NTRDOS4wMjUwNiAzMy45ODExIDcuMzg3ODUgMzIuNzI2MyA2LjM5MjI3IDMxLjAwNjRaTTQuMjk3MDcgMTMuNjE5NEM1LjE3MTU2IDEyLjA5OTggNi41NTI3OSAxMC45MzY0IDguMTk4ODUgMTAuMzMyN0M4LjE5ODg1IDEwLjQwMTMgOC4xOTQ5MSAxMC41MjI4IDguMTk0OTEgMTAuNjA3MVYxOS44MDhDOC4xOTM1MSAyMC4wMzc4IDguMjUzMzQgMjAuMjYzOCA4LjM2ODIzIDIwLjQ2MjlDOC40ODMxMiAyMC42NjE5IDguNjQ4OTMgMjAuODI2NyA4Ljg0ODYzIDIwLjk0MDRMMTguNTcyMyAyNi41NTQyTDE1LjIwNiAyOC40OTc5QzE1LjE4OTQgMjguNTA4OSAxNS4xNzAzIDI4LjUxNTUgMTUuMTUwNSAyOC41MTczQzE1LjEzMDcgMjguNTE5MSAxNS4xMTA3IDI4LjUxNiAxNS4wOTI0IDI4LjUwODJMNy4wNDA0NiAyMy44NTU3QzUuMzIxMzUgMjIuODYwMSA0LjA2NzE2IDIxLjIyMzUgMy41NTI4OSAxOS4zMDQ2QzMuMDM4NjIgMTcuMzg1OCAzLjMwNjI0IDE1LjM0MTMgNC4yOTcwNyAxMy42MTk0Wk0zMS45NTUgMjAuMDU1NkwyMi4yMzEyIDE0LjQ0MTFMMjUuNTk3NiAxMi40OTgxQzI1LjYxNDIgMTIuNDg3MiAyNS42MzMzIDEyLjQ4MDUgMjUuNjUzMSAxMi40Nzg3QzI1LjY3MjkgMTIuNDc2OSAyNS42OTI4IDEyLjQ4MDEgMjUuNzExMSAxMi40ODc5TDMzLjc2MzEgMTcuMTM2NEMzNC45OTY3IDE3Ljg0OSAzNi4wMDE3IDE4Ljg5ODIgMzYuNjYwNiAyMC4xNjEzQzM3LjMxOTQgMjEuNDI0NCAzNy42MDQ3IDIyLjg0OSAzNy40ODMyIDI0LjI2ODRDMzcuMzYxNyAyNS42ODc4IDM2LjgzODIgMjcuMDQzMiAzNS45NzQzIDI4LjE3NTlDMzUuMTEwMyAyOS4zMDg2IDMzLjk0MTUgMzAuMTcxNyAzMi42MDQ3IDMwLjY2NDFDMzIuNjA0NyAzMC41OTQ3IDMyLjYwNDcgMzAuNDczMyAzMi42MDQ3IDMwLjM4ODlWMjEuMTg4QzMyLjYwNjYgMjAuOTU4NiAzMi41NDc0IDIwLjczMjggMzIuNDMzMiAyMC41MzM4QzMyLjMxOSAyMC4zMzQ4IDMyLjE1NCAyMC4xNjk4IDMxLjk1NSAyMC4wNTU2Wk0zNS4zMDU1IDE1LjAxMjhDMzUuMjQ2NCAxNC45NzY1IDM1LjE0MzEgMTQuOTE0MiAzNS4wNjkgMTQuODcxN0wyNy4xMDQ1IDEwLjI3MTJDMjYuOTA2IDEwLjE1NTQgMjYuNjgwMyAxMC4wOTQzIDI2LjQ1MDQgMTAuMDk0M0MyNi4yMjA2IDEwLjA5NDMgMjUuOTk0OCAxMC4xNTU0IDI1Ljc5NjMgMTAuMjcxMkwxNi4wNzI2IDE1Ljg4NThWMTEuOTk4MkMxNi4wNzE1IDExLjk3ODMgMTYuMDc1MyAxMS45NTg1IDE2LjA4MzcgMTEuOTQwNUMxNi4wOTIxIDExLjkyMjUgMTYuMTA0OCAxMS45MDY4IDE2LjEyMDcgMTEuODk0OUwyNC4xNzE5IDcuMjUwMjVDMjUuNDA1MyA2LjUzOTAzIDI2LjgxNTggNi4xOTM3NiAyOC4yMzgzIDYuMjU0ODJDMjkuNjYwOCA2LjMxNTg5IDMxLjAzNjQgNi43ODA3NyAzMi4yMDQ0IDcuNTk1MDhDMzMuMzcyMyA4LjQwOTM5IDM0LjI4NDIgOS41Mzk0NSAzNC44MzM0IDEwLjg1MzFDMzUuMzgyNiAxMi4xNjY3IDM1LjU0NjQgMTMuNjA5NSAzNS4zMDU1IDE1LjAxMjhaTTE0LjI0MjQgMjEuOTQxOUwxMC44NzUyIDE5Ljk5ODFDMTAuODU3NiAxOS45ODkzIDEwLjg0MjMgMTkuOTc2MyAxMC44MzA5IDE5Ljk2MDJDMTAuODE5NSAxOS45NDQxIDEwLjgxMjIgMTkuOTI1NCAxMC44MDk4IDE5LjkwNThWMTAuNjA3MUMxMC44MTA3IDkuMTgyOTUgMTEuMjE3MyA3Ljc4ODQ4IDExLjk4MTkgNi41ODY5NkMxMi43NDY2IDUuMzg1NDQgMTMuODM3NyA0LjQyNjU5IDE1LjEyNzUgMy44MjI2NEMxNi40MTczIDMuMjE4NjkgMTcuODUyNCAyLjk5NDY0IDE5LjI2NDkgMy4xNzY3QzIwLjY3NzUgMy4zNTg3NiAyMi4wMDg5IDMuOTM5NDEgMjMuMTAzNCA0Ljg1MDY3QzIzLjA0MjcgNC44ODM3OSAyMi45MzcgNC45NDIxNSAyMi44NjY4IDQuOTg0NzNMMTQuOTAyNCA5LjU4NTE3QzE0LjcwMjUgOS42OTg3OCAxNC41MzY2IDkuODYzNTYgMTQuNDIxNSAxMC4wNjI2QzE0LjMwNjUgMTAuMjYxNiAxNC4yNDY2IDEwLjQ4NzcgMTQuMjQ3OSAxMC43MTc1TDE0LjI0MjQgMjEuOTQxOVpNMTYuMDcxIDE3Ljk5OTFMMjAuNDAxOCAxNS40OTc4TDI0LjczMjUgMTcuOTk3NVYyMi45OTg1TDIwLjQwMTggMjUuNDk4M0wxNi4wNzEgMjIuOTk4NVYxNy45OTkxWiIgZmlsbD0iY3VycmVudENvbG9yIj48L3BhdGg+PC9zdmc+ // @homepage https://scriptcat.org/script-show-page/1027 // ==/UserScript== /*********************************自定义配置区******************************************************** */ var setting = { showBox: 1, // 显示脚本浮窗,0为关闭,1为开启,不建议关闭 maskImg: 1, // 显示皮卡丘,0为关闭,1为开启,默认开启,无实质作用,只是为了减少睿智问题 task: 0, // 只处理任务点任务,0为关闭,1为开启 video: 1, // 处理视频,0为关闭,1为开启 audio: 1, // 处理音频,0为关闭,1为开启 rate: 1, // 视频/音频倍速,默认 1(正常),可在浮窗设置中调整(1/1.25/1.5/2) review: 0, // 复习模式,0为关闭,1为开启可以补挂视频时长 work: 1, // 测验自动处理,0为关闭,1为开启,开启将会处理测验,关闭会跳过测验 time: 2500, // 答题时间间隔,默认5s=5000 sub: 0, // 测验自动提交,0为关闭,1为开启,当没答案时测验将不会提交,如需提交请设置force:1 force: 0, // 测验强制提交,0为关闭,1为开启,开启此功能将会强制提交测验(无论作答与否) decrypt: 1, // 字体解密,0为关闭,1为开启,推荐开启,方法来自wyn665817大佬 redo: 0, // 重做模式,0为关闭,1为开启,开启后不跳过已答题,重新AI作答覆盖旧答案 fuzzyMatch: 1, // 相似度匹配,0为关闭,1为开启,开启后当精确匹配失败时使用相似度匹配选择最接近的选项 examTurn: 0, // 考试自动跳转下一题,0为关闭,1为开启 examTurnTime: 0, // 考试自动跳转下一题随机间隔时间(3-7s)之间,0为关闭,1为开启 goodStudent: 1, // 好学生模式,不自动选择答案,仅将单选题和多选题的ABCD加粗 alterTitle: 1, //修改题目,将AI回复的答案插入题目中,不建议关闭,AI回复不能完全匹配答案,题目显示答案供手动选择 autoLogin: 0, // 自动登录,0为关闭,1为开启,开启此功能请配置登陆配置项 phone: '', // 登录配置项:登录手机号/超星号 password: '' // 登录配置项:登录密码 } /************************************************************************************************** */ /* _ _ _ _ ___ __ /\ | | | | | \ | | |__ \/_ | / \ _ _ | |_ | |__ ___ _ __ | \| | ___ ______ ) || | / /\ \ | | | || __|| '_ \ / _ \ | '__| | . ` | / _ \|______|/ / | | / ____ \| |_| || |_ | | | || (_) || | | |\ || __/ / /_ | | /_/ \_\\__,_| \__||_| |_| \___/ |_| |_| \_| \___| |____||_| TG:https://t.me/+REKHQoWVJh45MDg1 Date:20240914 */ /************************************************************************************************** */ var _w = unsafeWindow, _l = location, _d = _w.document, $ = _w.jQuery || top.jQuery, md5 = md5 || window.md5, UE = _w.UE, Swal = Swal || window.Swal; // 多域名候选及自动测速选择 var HOST_CANDIDATES = [ "https://911285.xyz", "https://gptjs.808860.xyz" ]; // 读取缓存的域名与时间戳 var _cachedHost = localStorage.getItem('GPTJsSetting.hostSelected'); var _cachedAt = parseInt(localStorage.getItem('GPTJsSetting.hostSelectedAt') || '0'); // 初始 _host:优先使用缓存,否则使用第一个候选 var _host = _cachedHost || HOST_CANDIDATES[0]; function requestAuth(host) { return new Promise(function (resolve, reject) { var startAt = Date.now(); var _u = getCk('_uid') || getCk('UID'); try { GM_xmlhttpRequest({ method: 'GET', url: host + '/api/v1/auth?uid=' + _u + '&v=' + GM_info['script']['version'], timeout: 5000, onload: function (xhr) { if (xhr.status == 200) { resolve({ host: host, ms: Date.now() - startAt, response: xhr.responseText }); } else { reject(new Error('status error')); } }, onerror: function () { reject(new Error('error')); }, ontimeout: function () { reject(new Error('timeout')); } }); } catch (e) { reject(e); } }); } function findFastest() { return new Promise(function (resolve, reject) { var hasResolved = false; var errCount = 0; HOST_CANDIDATES.forEach(function (h) { requestAuth(h).then(function (res) { if (!hasResolved) { hasResolved = true; _host = res.host; localStorage.setItem('GPTJsSetting.hostSelected', _host); localStorage.setItem('GPTJsSetting.hostSelectedAt', String(Date.now())); try { console.log('[GPTJs] 切换到更快域名:', _host, '延迟', res.ms + 'ms'); } catch (_) { /* empty */ } resolve(res); } }).catch(function () { errCount++; if (errCount == HOST_CANDIDATES.length && !hasResolved) reject(); }); }); }); } function initFastestHost() { var twoHours = 2 * 60 * 60 * 1000; if (_cachedAt && (Date.now() - _cachedAt) < twoHours) { return requestAuth(_host).catch(function () { return findFastest(); }); } else { return findFastest(); } } var _authPromise = initFastestHost(); var _mlist, _defaults, _domList, $subBtn, $saveBtn, $frame_c, $okBtn; $('.navshow').find('a:contains(体验新版)')[0] ? $('.navshow').find('a:contains(体验新版)')[0].click() : ''; setting.decrypt ? decryptFont() : ''; function waitForJQueryElement(selector) { return new Promise(function (resolve) { var interval = setInterval(function () { if ($(selector).length > 0) { clearInterval(interval); resolve(); } }, 500); }); } if (_l.hostname == 'i.mooc.chaoxing.com' || _l.hostname == "i.chaoxing.com") { // } else if (_l.pathname == '/login' && setting.autoLogin) { showBox() waitForJQueryElement('#phone').then(function () { autoLogin() }); } else if (_l.pathname.includes('/mycourse/studentstudy')) { showBox() $('#ne-21log', window.parent.document).html('初始化完毕!') } else if (_l.pathname.includes('/knowledge/cards')) { var params = getTaskParams() var parsedParams = null; if (params && params !== '$mArg') { try { parsedParams = $.parseJSON(params); } catch (e) { parsedParams = null; } } if (!parsedParams || !parsedParams['attachments'] || parsedParams['attachments'].length <= 0) { logger('无任务点可处理,即将跳转页面', 'red') toNext() } else { waitForJQueryElement('.wrap .ans-cc .ans-attach-ct').then(function () { top.checkJob ? top.checkJob = () => false : true _domList = [] _mlist = parsedParams['attachments'] _defaults = parsedParams['defaults'] $.each($('.wrap .ans-cc .ans-attach-ct'), (i, t) => { _domList.push($(t).find('iframe')) }) missonStart() }); } } else if (_l.pathname.includes('/exam/test/reVersionTestStartNew')) { showBox() waitForJQueryElement('.mark_table .whiteDiv').then(function () { missonExam() }); } else if (_l.pathname.includes('/mooc2/exam/preview')) { showBox() waitForJQueryElement('.mark_table .questionLi').then(function () { missonExamPreview() }); } else if (_l.pathname.includes('/mooc2/work/dowork')) { showBox() waitForJQueryElement('.mark_table form').then(function () { missonHomeWork() }); } else if (_l.pathname.includes('/work/phone/doHomeWork')) { var _oldal = _w.alert _w.alert = function (msg) { if (msg == '保存成功') { return; } return _oldal(msg) } var _oldcf = _w.confirm _w.confirm = function (msg) { if (msg.includes('确认提交') || msg.includes('未做完')) { return true } return _oldcf(msg) } } else if (_l.pathname.includes('/mooc2/exam/exam-list')) { // Swal.fire('ChatGPT学习通助手提示', '注意:请谨慎使用脚本考试,开始考试之前请确保该账号已激活脚本。', 'info') } else if (_l.pathname == '/mycourse/stu') { checkBrowser() } else { // console.log(_l.pathname) } function checkBrowser() { var userAgent = navigator.userAgent if (userAgent.indexOf('Chrome') == -1 || GM_info.scriptHandler != 'ScriptCat') { // 非推荐环境,但不弹出警告 // Swal.fire('您使用的不是推荐运行环境(edge、谷歌浏览器+ScriptCat),脚本运行可能会发生问题.') } } function parseUrlParams() { let query = window.location.search.substring(1); let vars = query.split("&"); let _p = {} for (let i = 0; i < vars.length; i++) { let pair = vars[i].split("="); _p[pair[0]] = pair[1] } return _p } function updateLocalStorage(event) { var checkbox = event.target; localStorage.setItem(checkbox.id, checkbox.checked); } // 判断是否开启重做模式(不跳过已答题) function isRedoMode() { var stored = localStorage.getItem('GPTJsSetting.redo'); if (stored !== null) return stored === 'true'; return !!setting.redo; } // 判断是否开启相似度匹配 function isFuzzyMatchEnabled() { var stored = localStorage.getItem('GPTJsSetting.fuzzyMatch'); if (stored !== null) return stored === 'true'; return !!setting.fuzzyMatch; } // 计算两个字符串的相似度(基于Levenshtein距离),返回 0~1 之间的值,1表示完全相同 function stringSimilarity(s1, s2) { if (!s1 && !s2) return 1; if (!s1 || !s2) return 0; // 统一小写、去除首尾空白 s1 = s1.toLowerCase().trim(); s2 = s2.toLowerCase().trim(); if (s1 === s2) return 1; var len1 = s1.length, len2 = s2.length; if (len1 === 0 || len2 === 0) return 0; // Levenshtein距离 - 空间优化版 var prev = [], curr = []; for (var j = 0; j <= len2; j++) prev[j] = j; for (var i = 1; i <= len1; i++) { curr[0] = i; for (var j = 1; j <= len2; j++) { if (s1[i - 1] === s2[j - 1]) { curr[j] = prev[j - 1]; } else { curr[j] = 1 + Math.min(prev[j], curr[j - 1], prev[j - 1]); } } var tmp = prev; prev = curr; curr = tmp; } var maxLen = Math.max(len1, len2); return 1 - prev[len2] / maxLen; } // 在选项数组中查找与AI回答最相似的选项,返回索引;相似度低于阈值时返回-1 // threshold 默认 0.5(50%相似度) function findBestFuzzyMatch(optionTexts, aiAnswer, threshold) { if (!isFuzzyMatchEnabled()) return -1; if (!aiAnswer || !optionTexts || optionTexts.length === 0) return -1; threshold = (threshold !== undefined) ? threshold : 0.5; var bestIndex = -1, bestScore = 0; for (var i = 0; i < optionTexts.length; i++) { var score = stringSimilarity(optionTexts[i], aiAnswer); if (score > bestScore) { bestScore = score; bestIndex = i; } } if (bestScore >= threshold) { logger('相似度匹配: 最佳匹配项[' + bestIndex + '] 相似度=' + (bestScore * 100).toFixed(1) + '%', 'blue'); return bestIndex; } logger('相似度匹配: 所有选项相似度均低于阈值(' + (threshold * 100) + '%),最高=' + (bestScore * 100).toFixed(1) + '%', 'orange'); return -1; } // 多选题模糊匹配:AI返回的答案用'|'分割后,对每个答案片段在选项中找最佳匹配 // 返回匹配到的选项索引数组 function findFuzzyMatchMultiple(optionTexts, aiAnswer, threshold) { if (!isFuzzyMatchEnabled()) return []; if (!aiAnswer || !optionTexts || optionTexts.length === 0) return []; threshold = (threshold !== undefined) ? threshold : 0.5; var parts = aiAnswer.split('|'); var matched = []; for (var p = 0; p < parts.length; p++) { var part = parts[p].trim(); if (!part) continue; var bestIndex = -1, bestScore = 0; for (var i = 0; i < optionTexts.length; i++) { var score = stringSimilarity(optionTexts[i], part); if (score > bestScore) { bestScore = score; bestIndex = i; } } if (bestScore >= threshold && matched.indexOf(bestIndex) === -1) { matched.push(bestIndex); logger('相似度匹配(多选): "' + part + '" → 选项[' + bestIndex + '] 相似度=' + (bestScore * 100).toFixed(1) + '%', 'blue'); } } return matched; } // 读取播放倍速:优先 localStorage(UI 设置),否则回退 setting.rate;范围 (0, 16] function getRate() { var stored = localStorage.getItem('GPTJsSetting.rate'); var n = stored !== null ? parseFloat(stored) : (setting.rate || 1); if (!isFinite(n) || n <= 0) n = 1; if (n > 16) n = 16; return n; } // 统一判断题答案解析:将AI回答归一为 'true' / 'false' / null // 解决旧版 string.indexOf 子串匹配导致 "正确的"、"True"、"对的" 等变体匹配失败的问题 function parseJudgeAnswer(agrs) { if (!agrs) return null; var s = agrs.replace(/[。,.,!!\s]/g, '').toLowerCase(); var trueWords = ['正确', '是', '对', '√', 't', 'true', 'ri', 'right', 'yes']; var falseWords = ['错误', '否', '错', '×', 'f', 'false', 'wr', 'wrong', 'no']; // 精确匹配 for (var i = 0; i < trueWords.length; i++) { if (s === trueWords[i]) return 'true'; } for (var i = 0; i < falseWords.length; i++) { if (s === falseWords[i]) return 'false'; } // 包含匹配(优先判断"错"避免"正确的"误判——先检查否定词) for (var i = 0; i < falseWords.length; i++) { if (s.indexOf(falseWords[i]) !== -1) return 'false'; } for (var i = 0; i < trueWords.length; i++) { if (s.indexOf(trueWords[i]) !== -1) return 'true'; } return null; } // 在选项列表中查找"正确/对"或"错误/错"对应的索引 function findJudgeOptionIndex(optionTexts, isTrue) { var trueWords = ['正确', '是', '对', '√', 'T', 'ri']; var falseWords = ['错误', '否', '错', '×', 'F', 'wr']; var words = isTrue ? trueWords : falseWords; for (var i = 0; i < optionTexts.length; i++) { var t = optionTexts[i]; for (var j = 0; j < words.length; j++) { if (t.indexOf(words[j]) !== -1) return i; } } return -1; } // 查找文本作答类题目(简答/写作/翻译/名词解释/论述题/计算题/材料题等)的 textarea。 // 按特异性优先级尝试多个选择器,最后兜底为任意 textarea。 function findAnswerTextareas($container) { if (!$container || $container.length === 0) return $(); // 1) 标准 UEditor 下层 textarea,name="answerEditor{questionId}{i}" var $eles = $container.find('textarea[name^="answerEditor"]'); if ($eles.length > 0) return $eles; // 2) 旧版/兼容路径 $eles = $container.find('.subEditor textarea, .Answer .divText textarea, .stem_answer textarea, .edui-editor textarea'); if ($eles.length > 0) return $eles; // 3) 兜底:容器内任意 textarea return $container.find('textarea'); } function showBox() { //公告&充值 if (setting.showBox && top.document.querySelector('#ne-21notice') == undefined) { // 注入样式(仅一次) if (!top.document.getElementById('ne-21style')) { var styleEl = top.document.createElement('style'); styleEl.id = 'ne-21style'; styleEl.textContent = ` /* === Liquid Glass UI (iOS 26 style, neutral light glass) === */ #ne-21box{position:fixed;top:5%;right:16%;width:340px;z-index:99999;font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;font-size:13px;color:rgba(15,23,42,.86);background:linear-gradient(180deg,rgba(255,255,255,.62) 0%,rgba(241,245,249,.55) 100%);backdrop-filter:blur(22px) saturate(180%) brightness(1.04);-webkit-backdrop-filter:blur(22px) saturate(180%) brightness(1.04);border:1px solid rgba(255,255,255,.65);border-radius:22px;box-shadow:0 0 0 1px rgba(15,23,42,.09),0 24px 48px -12px rgba(15,23,42,.45),0 10px 26px -8px rgba(15,23,42,.3),inset 0 1px 0 rgba(255,255,255,.9),inset 0 -1px 0 rgba(15,23,42,.06);overflow:hidden;transition:opacity .25s ease,transform .25s ease;animation:ne21-in .4s cubic-bezier(.2,.9,.3,1) both;} @keyframes ne21-in{from{opacity:0;transform:translateY(-8px) scale(.98)}to{opacity:1;transform:none}} #ne-21box .ne21-header{position:relative;display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:linear-gradient(180deg,rgba(255,255,255,.72) 0%,rgba(248,250,252,.35) 100%);color:rgba(15,23,42,.92);border-bottom:1px solid rgba(15,23,42,.07);cursor:move;user-select:none;} #ne-21box .ne21-header::after{content:'';position:absolute;left:14px;right:14px;bottom:-1px;height:1px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.85),transparent);pointer-events:none;} #ne-21box.ne21-collapsed .ne21-body{display:none;} #ne-21box.ne21-collapsed .ne21-header{border-bottom:none;} #ne-21box.ne21-collapsed .ne21-header::after{display:none;} #ne-21box .ne21-title{display:flex;align-items:center;gap:9px;font-weight:600;font-size:14px;letter-spacing:.3px;margin:0;color:inherit;} #ne-21box .ne21-dot{width:9px;height:9px;border-radius:50%;background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.98),rgba(255,255,255,.5) 55%,rgba(15,23,42,.18) 100%);box-shadow:0 0 0 0 rgba(255,255,255,.7),inset 0 1px 1px rgba(255,255,255,.95);animation:ne21-pulse 2s infinite;flex-shrink:0;} @keyframes ne21-pulse{0%{box-shadow:0 0 0 0 rgba(255,255,255,.7),inset 0 1px 1px rgba(255,255,255,.95)}70%{box-shadow:0 0 0 8px rgba(255,255,255,0),inset 0 1px 1px rgba(255,255,255,.95)}100%{box-shadow:0 0 0 0 rgba(255,255,255,0),inset 0 1px 1px rgba(255,255,255,.95)}} #ne-21box #ne-21close{margin:0;width:24px;height:24px;padding:0;display:inline-flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;line-height:1;color:rgba(15,23,42,.7);cursor:pointer;border:1px solid rgba(255,255,255,.65);border-radius:50%;background:rgba(255,255,255,.55);box-shadow:0 0 0 1px rgba(15,23,42,.06),inset 0 1px 0 rgba(255,255,255,.8),0 1px 2px rgba(15,23,42,.08);transition:background .2s,color .2s,transform .15s;user-select:none;font-family:inherit;} #ne-21box #ne-21close:hover{background:rgba(255,255,255,.78);color:rgba(15,23,42,.92);box-shadow:0 0 0 1px rgba(15,23,42,.08),inset 0 1px 0 rgba(255,255,255,.9),0 1px 2px rgba(15,23,42,.1);} #ne-21box #ne-21close:active{transform:scale(.92);} #ne-21box .ne21-body{padding:14px 16px 16px;} #ne-21box #ne-21notice{border-top:none!important;margin:0 0 6px!important;overflow:visible;} #ne-21box .ne21-uid{display:flex;align-items:center;gap:6px;color:rgba(15,23,42,.62);font-size:12px;margin-bottom:10px;padding:8px 12px;background:rgba(255,255,255,.5);border:1px solid rgba(255,255,255,.7);border-radius:12px;box-shadow:0 0 0 1px rgba(15,23,42,.05),inset 0 1px 0 rgba(255,255,255,.75),0 1px 2px rgba(15,23,42,.05);} #ne-21box .ne21-uid b{color:rgba(15,23,42,.92);font-weight:600;} #ne-21box .ne21-row{display:flex;gap:8px;align-items:center;} #ne-21box .ne21-btn{display:inline-flex;align-items:center;justify-content:center;padding:7px 14px;font-size:12px;font-weight:500;border-radius:14px;cursor:pointer;border:1px solid rgba(255,255,255,.7);transition:transform .15s,box-shadow .2s,background .2s,color .2s;white-space:nowrap;} #ne-21box .ne21-btn-primary{color:rgba(15,23,42,.92);background:rgba(255,255,255,.72);box-shadow:0 0 0 1px rgba(15,23,42,.07),inset 0 1px 0 rgba(255,255,255,.95),inset 0 -6px 12px -6px rgba(15,23,42,.08),0 4px 10px -2px rgba(15,23,42,.22);} #ne-21box .ne21-btn-primary:hover{transform:translateY(-1px);background:rgba(255,255,255,.88);box-shadow:0 0 0 1px rgba(15,23,42,.09),inset 0 1px 0 rgba(255,255,255,1),inset 0 -6px 12px -6px rgba(15,23,42,.1),0 6px 14px -2px rgba(15,23,42,.28);} #ne-21box .ne21-btn-secondary{color:rgba(15,23,42,.78);background:rgba(255,255,255,.45);box-shadow:0 0 0 1px rgba(15,23,42,.06),inset 0 1px 0 rgba(255,255,255,.75),0 1px 2px rgba(15,23,42,.06);} #ne-21box .ne21-btn-secondary:hover{background:rgba(255,255,255,.65);color:rgba(15,23,42,.92);box-shadow:0 0 0 1px rgba(15,23,42,.08),inset 0 1px 0 rgba(255,255,255,.85),0 2px 4px rgba(15,23,42,.08);} #ne-21box .ne21-btn:active{transform:translateY(0) scale(.98);} #ne-21box #modelSelect{flex:1;min-width:0;padding:7px 10px;font-size:12px;border-radius:14px;border:1px solid rgba(255,255,255,.7);background:rgba(255,255,255,.55);color:rgba(15,23,42,.86);cursor:pointer;outline:none;box-shadow:0 0 0 1px rgba(15,23,42,.06),inset 0 1px 0 rgba(255,255,255,.8);transition:background .2s,box-shadow .2s;} #ne-21box #modelSelect:hover{background:rgba(255,255,255,.7);} #ne-21box #modelSelect:focus{background:rgba(255,255,255,.75);box-shadow:0 0 0 1px rgba(15,23,42,.08),inset 0 1px 0 rgba(255,255,255,.85),0 0 0 4px rgba(15,23,42,.1);} #ne-21box .ne21-select{padding:5px 8px;font-size:12px;border-radius:10px;border:1px solid rgba(255,255,255,.65);background:rgba(255,255,255,.5);color:rgba(15,23,42,.86);cursor:pointer;outline:none;min-width:80px;flex-shrink:0;box-shadow:0 0 0 1px rgba(15,23,42,.05),inset 0 1px 0 rgba(255,255,255,.75);transition:background .2s,box-shadow .2s;} #ne-21box .ne21-select:hover{background:rgba(255,255,255,.7);} #ne-21box .ne21-select:focus{background:rgba(255,255,255,.72);box-shadow:0 0 0 1px rgba(15,23,42,.08),inset 0 1px 0 rgba(255,255,255,.82),0 0 0 3px rgba(15,23,42,.06);} #ne-21box #userInfo{margin:10px 0 0;padding:10px 12px;background:rgba(255,255,255,.5);border:1px solid rgba(255,255,255,.7);border-radius:12px;box-shadow:0 0 0 1px rgba(15,23,42,.05),inset 0 1px 0 rgba(255,255,255,.75);font-size:12px;color:rgba(15,23,42,.66);line-height:1.6;overflow:hidden;} #ne-21box #userInfo:empty{display:none;} #ne-21box #userInfo b{color:rgba(15,23,42,.9);font-weight:600;} #ne-21box #moreSettings{padding:4px 14px;background:rgba(255,255,255,.42);border:1px solid rgba(255,255,255,.65);border-radius:14px;box-shadow:0 0 0 1px rgba(15,23,42,.05),inset 0 1px 0 rgba(255,255,255,.7);margin:10px 0 0;} #ne-21box #moreSettings label{display:flex;flex-direction:row-reverse;align-items:center;justify-content:space-between;margin:0;padding:8px 2px;font-size:12px;color:rgba(15,23,42,.78);cursor:pointer;user-select:none;line-height:1.4;} #ne-21box #moreSettings label + label{border-top:1px dashed rgba(15,23,42,.1);} #ne-21box #moreSettings input[type=checkbox]{appearance:none;-webkit-appearance:none;width:34px;height:20px;border:1px solid rgba(15,23,42,.08);border-radius:20px;cursor:pointer;position:relative;transition:background .25s,box-shadow .25s;background:rgba(15,23,42,.16);box-shadow:inset 0 1px 2px rgba(15,23,42,.12);margin:0 0 0 10px;flex-shrink:0;} #ne-21box #moreSettings input[type=checkbox]::before{content:'';position:absolute;top:1px;left:1px;width:16px;height:16px;border-radius:50%;background:linear-gradient(180deg,rgba(255,255,255,1),rgba(255,255,255,.85));box-shadow:0 1px 3px rgba(15,23,42,.25),inset 0 1px 0 rgba(255,255,255,1);transition:transform .25s cubic-bezier(.2,.9,.3,1);} #ne-21box #moreSettings input[type=checkbox]:hover{background:rgba(15,23,42,.24);} #ne-21box #moreSettings input[type=checkbox]:checked{background:rgba(255,255,255,.78);border-color:rgba(15,23,42,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.95),inset 0 -2px 4px rgba(15,23,42,.08),0 0 0 1px rgba(15,23,42,.06);} #ne-21box #moreSettings input[type=checkbox]:checked:hover{background:rgba(255,255,255,.92);} #ne-21box #moreSettings input[type=checkbox]:checked::before{transform:translateX(14px);} #ne-21box #moreSettings p{display:none;} #ne-21box #ne-21thinking{display:none!important;} @keyframes ne21-spin{to{transform:rotate(360deg)}} @keyframes ne21-dot{0%,80%,100%{transform:scale(.5);opacity:.4}40%{transform:scale(1);opacity:1}} #ne-21box #ne-21log .ne21-log-spinner{display:inline-block;width:9px;height:9px;margin-right:5px;border:1.5px solid rgba(15,23,42,.18);border-top-color:rgba(15,23,42,.7);border-radius:50%;vertical-align:-1px;animation:ne21-spin .8s linear infinite;} #ne-21box #ne-21log .ne21-log-dots{display:inline-flex;gap:2px;margin-left:3px;vertical-align:1px;} #ne-21box #ne-21log .ne21-log-dots i{width:3px;height:3px;border-radius:50%;background:currentColor;opacity:.65;animation:ne21-dot 1.2s infinite ease-in-out both;} #ne-21box #ne-21log .ne21-log-dots i:nth-child(2){animation-delay:.16s;} #ne-21box #ne-21log .ne21-log-dots i:nth-child(3){animation-delay:.32s;} #ne-21box #ne-21log{max-height:140px;overflow-y:auto;margin:12px 0 0;padding:10px 12px;background:rgba(15,23,42,.06);border:1px solid rgba(255,255,255,.55);border-radius:14px;box-shadow:0 0 0 1px rgba(15,23,42,.06),inset 0 1px 0 rgba(255,255,255,.6),inset 0 0 16px rgba(15,23,42,.06);font-family:"SF Mono","Cascadia Code",Consolas,Menlo,monospace;font-size:11px;line-height:1.6;color:rgba(15,23,42,.78);} #ne-21box #ne-21log:empty{display:none;} #ne-21box #ne-21log::-webkit-scrollbar{width:5px;} #ne-21box #ne-21log::-webkit-scrollbar-thumb{background:rgba(15,23,42,.2);border-radius:4px;} #ne-21box #ne-21log::-webkit-scrollbar-thumb:hover{background:rgba(15,23,42,.32);} #ne-21box #ne-21log p{margin:0;padding:2px 0;word-break:break-all;} #ne-21box #ne-21log hr{display:none;} #ne-21box #ne-21log .ne21-time{color:rgba(15,23,42,.4);margin-right:6px;} `; top.document.head.appendChild(styleEl); } var box_html = `

ChatGPT 学习通助手

AI 思考中
`; $(box_html).appendTo('body'); // 恢复保存的位置与收起/展开状态 (function () { var $box = $('#ne-21box'); // 恢复位置 try { var savedPos = localStorage.getItem('GPTJsSetting.boxPosition'); if (savedPos) { var pos = JSON.parse(savedPos); if (pos && typeof pos.left === 'number' && typeof pos.top === 'number') { var vw = window.innerWidth, vh = window.innerHeight; var w = $box.outerWidth() || 340; // 约束:避免恢复后跑到视窗外不可见 var nx = Math.max(40 - w, Math.min(pos.left, vw - 40)); var ny = Math.max(0, Math.min(pos.top, vh - 40)); $box.css({ left: nx + 'px', top: ny + 'px', right: 'auto' }); } } } catch (_) { /* empty */ } // 恢复收起/展开状态 if (localStorage.getItem('GPTJsSetting.boxCollapsed') === 'true') { $box.addClass('ne21-collapsed'); $('#ne-21close').text('+').attr('aria-label', '展开'); } })(); // 收起/展开按钮:切换 .ne21-collapsed,按钮文本在 − / + 之间切换 $('#ne-21close').on('mousedown', function (e) { e.stopPropagation(); // 避免触发标题栏拖动 }).on('click', function (e) { e.stopPropagation(); var collapsed = $('#ne-21box').toggleClass('ne21-collapsed').hasClass('ne21-collapsed'); $(this).text(collapsed ? '+' : '−'); $(this).attr('aria-label', collapsed ? '展开' : '收起'); // 持久化收起/展开状态 try { localStorage.setItem('GPTJsSetting.boxCollapsed', collapsed ? 'true' : 'false'); } catch (_) { /* empty */ } }); // 标题栏拖动:拖动结束后写入 localStorage,刷新后保持上次位置 (function () { var $box = $('#ne-21box'); var $header = $box.find('.ne21-header'); var dragging = false, startX = 0, startY = 0, startLeft = 0, startTop = 0; $header.on('mousedown', function (e) { if (e.which !== 1) return; // 仅响应鼠标左键 if ($(e.target).closest('#ne-21close').length) return; // 点在按钮上不拖动 dragging = true; var rect = $box[0].getBoundingClientRect(); startX = e.clientX; startY = e.clientY; startLeft = rect.left; startTop = rect.top; // 清空 right,把 left/top 改为像素值,避免与默认 left:66% 计算冲突 $box.css({ left: startLeft + 'px', top: startTop + 'px', right: 'auto' }); $('body').css('user-select', 'none'); e.preventDefault(); }); $(document).on('mousemove.ne21drag', function (e) { if (!dragging) return; var nx = startLeft + (e.clientX - startX); var ny = startTop + (e.clientY - startY); var w = $box.outerWidth(); var vw = window.innerWidth; var vh = window.innerHeight; // 约束:保留至少 40px 标题栏在视窗内,便于回拉 nx = Math.max(40 - w, Math.min(nx, vw - 40)); ny = Math.max(0, Math.min(ny, vh - 40)); $box.css({ left: nx + 'px', top: ny + 'px' }); }).on('mouseup.ne21drag', function () { if (!dragging) return; dragging = false; $('body').css('user-select', ''); // 持久化位置 try { var rect = $box[0].getBoundingClientRect(); localStorage.setItem('GPTJsSetting.boxPosition', JSON.stringify({ left: rect.left, top: rect.top })); } catch (_) { /* empty */ } }); })(); // 设置面板切换 + 复选框监听器 (function () { var moreSettings = document.getElementById('moreSettings'); var userInfo = document.getElementById('userInfo'); if (!moreSettings || !userInfo) return; // #moreSettingsBtn 由 $('#ne-21notice').html(...) 在后面动态注入, // 此时还不存在,且每次 showBox() 都会被重建,因此使用事件委托。 var isSettingsVisible = false; $('#ne-21box').on('click', '#moreSettingsBtn', function () { userInfo.style.display = isSettingsVisible ? 'block' : 'none'; moreSettings.style.display = isSettingsVisible ? 'none' : 'block'; this.textContent = isSettingsVisible ? '设置' : '返回'; isSettingsVisible = !isSettingsVisible; }); // 修改题目默认开启(仅初始化一次,避免 forEach 内重复执行) if (localStorage.getItem('GPTJsSetting.alterTitle') === null) { localStorage.setItem('GPTJsSetting.alterTitle', 'true'); } // 相似度匹配默认开启 if (localStorage.getItem('GPTJsSetting.fuzzyMatch') === null) { localStorage.setItem('GPTJsSetting.fuzzyMatch', 'true'); } ['sub', 'force', 'examTurn', 'goodStudent', 'alterTitle', 'redo', 'fuzzyMatch'].forEach(function (settingId) { var checkbox = document.getElementById('GPTJsSetting.' + settingId); if (!checkbox) return; checkbox.addEventListener('change', updateLocalStorage); checkbox.checked = localStorage.getItem('GPTJsSetting.' + settingId) === 'true'; }); // 倍速下拉:恢复上次选择并持久化 var rateSelect = document.getElementById('GPTJsSetting.rate'); if (rateSelect) { rateSelect.value = localStorage.getItem('GPTJsSetting.rate') || '1'; rateSelect.addEventListener('change', function () { localStorage.setItem('GPTJsSetting.rate', rateSelect.value); }); } })(); } else { $('#ne-21log', window.parent.document).html('') } let _u = getCk('_uid') || getCk('UID') $('#ne-21notice').html(`
学习通账号 UID:${_u || '-'}
`); // 模型列表缓存:先从缓存加载避免闪烁 var CACHE_KEY_MODELS = 'GPTJsSetting.cachedModels'; var cachedModels = localStorage.getItem(CACHE_KEY_MODELS); if (cachedModels) { $('#modelSelect').html(cachedModels); } // 同步恢复上次选中的模型,避免等 window.onload 造成的闪烁 var lastSelectedModel = localStorage.getItem('GPTJsSetting.model'); if (lastSelectedModel) { $('#modelSelect').val(lastSelectedModel); } // 同步绑定 change 监听(命名空间避免 showBox 重入时重复绑定) $('#modelSelect').off('change.gptjsModel').on('change.gptjsModel', function () { localStorage.setItem('GPTJsSetting.model', $(this).val()); }); //公告&积分 if (_authPromise) { _authPromise.then(function (res) { var obj = {}; try { obj = $.parseJSON(res.response) || {}; } catch (e) { /* empty */ } var data = obj.data || {}; var notice = data.notice || ''; var score = (data.score !== undefined && data.score !== null) ? data.score : '-'; $('#userInfo').html(notice + "积分余额:" + score); // 模型列表:只有内容变化时才更新DOM和缓存,避免闪烁 if (data.models && data.models !== cachedModels) { localStorage.setItem(CACHE_KEY_MODELS, data.models); // 优先使用 localStorage 中保存的模型;否则保留当前