您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
添加可选参数列表、如接口地址为xx/xx/{id},会将接口改为xxx/xx/ + id
// ==UserScript== // @name yapi获取接口脚本 // @namespace http://tampermonkey.net/ // @version 2.1 // @description 添加可选参数列表、如接口地址为xx/xx/{id},会将接口改为xxx/xx/ + id // @description4 修复重命名导致的函数冲突 // @description3 解决鼠标事件冲突,避免拖动后直接打开 // @description2 添加可拖拽功能 // @description1 更新缓存为列表,可以设置更多的模板 // @author wuyuanbo // @match http://yapi.dashuf.com/group/20 // @match http://yapi.dashuf.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=dashuf.com // @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js // @license GPL License // @grant none // ==/UserScript== window.onload = function () { (function () { 'use strict'; const css = ` .layout { position: fixed; display: none; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); left: 0; top: 0; } .model { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 10px; background: #fff; box-shadow: 0 0 5px #ccc; box-sizing: border-box; z-index: 1; } .model .title { font-size: 20px; color: #333; text-align: center; border-bottom: 1px solid #ccc; padding: 10px 0; position: relative; } .model .title .g-right { position: absolute; right: 10px; top: 25px; cursor: pointer; display: inline-block; width: 20px; height: 2px; background: #999; line-height: 0; font-size: 0; vertical-align: middle; transform: rotate(45deg); } .model .title .g-right:after { content: "/"; display: block; width: 20px; height: 2px; background: #999; transform: rotate(-90deg); } .model .title .g-right::before { content: ""; position: absolute; left: 0px; top: -10px; width: 20px; height: 20px; } .model .tips { font-size: 14px; color: #999; padding-left: 20px; } .model ul { padding: 20px; } .model ul li { display: flex; align-items: center; font-size: 14px; color: #333; border: 1px solid #ccc; border-bottom: 0; padding: 0 10px; } .model ul li span { padding: 10px 0; flex: 0 0 100px; font-size: 14px; color: #999; } .model ul li p { width: 100%; padding: 10px; border-left: 1px solid #ccc; } .model ul li p textarea { display: block; width: 100%; margin-bottom: 10px; height: 100px; } .model ul .list:last-child { border-bottom: 1px solid #ccc; } .model ul .list:hover { background: #eee; } .model ul .list.active { background: #eee; } .suspension { position: fixed; right: 10px; bottom: 40%; width: 60px; height: 60px; z-index: 999; border-radius: 100%; font-size: 16px; background: rgba(0,0,0,0.7); color: #fff; box-sizing: border-box; padding: 10px; text-align: center; cursor: move; } /*# sourceMappingURL=index.css.map */ `; var node = document.createElement("style"); node.type = "text/css"; node.appendChild(document.createTextNode(css)); document.documentElement.appendChild(node); let suspension = document.createElement("div"); suspension.className="suspension fixed"; suspension.innerHTML = "复制接口"; document.documentElement.appendChild(suspension); // var drag2=function(obj){ // obj.bind("mousedown",startDrag); // } // drag2($(document).find('.suspension')); let fixed = $(document).find('.suspension.fixed'); var key = false; var firstTime = 0; var lastTime = 0; $(document).mousemove(function(e) { if (!!this.move) { // console.log(e); var posix = !document.move_target ? {'x': 0, 'y': 0} : document.move_target.posix, callback = document.call_down || function(event) { $(this.move_target).css({ 'top': e.pageY - posix.y, 'left': e.pageX - posix.x }); }; callback.call(this, e, posix); } }).mouseup(function(e) { lastTime = new Date().getTime(); if (!!this.move) { var callback = document.call_up || function(event){}; callback.call(this, e); $.extend(this, { 'move': false, 'move_target': null, 'call_down': false, 'call_up': false }); } if ((lastTime - firstTime) < 200) { key = true; } }); var $box = fixed.mousedown(function(e) { var offset = $(this).offset(); firstTime = new Date().getTime(); this.posix = {'x': e.pageX - offset.left, 'y': e.pageY - offset.top}; console.log(this.posix); $.extend(document, {'move': true, 'move_target': this}); }) //fixed.bind("mousedown", startDrag); //fixed.bind("mouseleave", stop); //$(document).on('mousedown', '.suspension', function() { //console.log($(this)); //startDrag($(this)); // $(this).bind("mousedown", startDrag); //}) $(document).on('click', '.suspension', function() { if (!key) { return; } key = false; getData.stringList = ""; // getData.getOne("fn"); chooseTemplate(); }) let templateList = []; try { if (localStorage.getItem("template")) { templateList = JSON.parse(localStorage.getItem("template")) } } catch(err) { console.error("此时缓存内储存的是字符串格式,将更新为数组格式"); localStorage.setItem("template", JSON.stringify([])) templateList = []; } // let templateList = localStorage.getItem("template") ? : []; // 创建model $("body").append(` <div class="layout"> <div class="model"> <div class="title">选择模板 <div class="g-right"></div></div> <div class="tips"> /*<br> * @ urlName 路径拼接名称<br> * @ url 接口地址<br> * @ notes 注释<br> * @ method 请求方式<br> * 请使用以上参数,否则会报错失效<br> */<br> </div> <div><button class="getTableJSON">获取请求参数</button></div> <ul> <li class="list" data-type="str"><span>列表:</span><p>{{urlName}}: host + "{{url}}", // {{notes}}注释</p></li> <li class="list" data-type="fn"><span>函数:</span><p> // {{notes}}<br> export function {{urlName}}(data) {<br> return request({<br> url: host + "{{url}}",<br> method: "{{method}}",<br> {{method.toLowerCase() === "post" ? "data" : "params"}}: data<br> })<br> };<br></p></li> <li class="list" data-type="useSelf"><span>使用模板</span><p><select class="selectTemplateName"> <option>请选择</option> ${ templateList?.map(item => { return `<option value="${item.templateName}">${item.templateName}</option>` }).join("") } <select> <button class="useTemplate" disabled="true">使用</button></p></li> <li class="list" data-type="self"><span><input placeholder="自定义模板:" type="text" class="templateName" style="width: 100px;"/></span><p><textarea col="10" row="10" id="template">// {{notes}} export function {{urlName}}(data) { return MyFetch.{{method}}(host + "{{url}}", data) };</textarea> <button class="confirmBtn" disabled="true">提交</button><button class="deleteTemplate" disabled="true">删除</button></p></li> </ul> </div></div>`); // 获取url路径id function getUrlId(strUrl) { strUrl = strUrl.split("/"); return strUrl[strUrl.length - 1]; }; $(document).on('click', '.list', function () { $(".list").removeClass("active"); $(this).addClass("active"); let type = $(this).attr("data-type"); $(".confirmBtn").attr("disabled", "true"); getData.stringList = ""; if (getUrlId(location.href).indexOf('cat_') === -1) { if (type === "str") { getData.getOne(); } else if (type === "fn") { getData.getOne("fn") } else if (type === "self") { $(".confirmBtn").removeAttr("disabled"); } } else { if (type === "str") { getData.getJson(); } else if (type === "fn") { getData.getFn("fn") } else if (type === "self") { $(".confirmBtn").removeAttr("disabled"); } } }); $(document).on('click', '.g-right', function () { $('.layout').hide(); $(".layout .list").removeClass("active"); }) // 选择模板 function chooseTemplate() { $(".layout").show(); }; $(document).on('click', '.confirmBtn', function () { let str = $("#template").val(); let templateName = $(".templateName").val(); if(str === "") { alert("请输入模板"); return false; } if (templateName === "") { alert("请输入模板名称"); return; } if (templateList.some(item => item.templateName === templateName)) { templateList[templateList.findIndex(item => item.templateName === item.templateName)].template = str } else { templateList.push({templateName, template: str}); } localStorage.setItem("template", JSON.stringify(templateList)); // str = str.replace(/\{\{/g, "'+").replace(/\}\}/g, "+'"); getData.updateTemplateOption(); getData.generate(str); }) // 删除按钮 $(document).on('click', '.deleteTemplate', function() { getData.deleteTemplate(templateNameKey); }); let templateNameKey = ""; $(document).on("change", ".selectTemplateName", function() { let name = $(this).val(); if (name) { templateNameKey = name; $(".deleteTemplate").removeAttr("disabled"); $(".useTemplate").removeAttr("disabled"); let obj = templateList[templateList.findIndex(item => item.templateName === name)]; $("#template").val(obj.template); $(".templateName").val(obj.templateName); } else { $(".deleteTemplate").attr("disabled"); $(".useTemplate").attr("disabled"); $("#template").val(); $(".templateName").val(); } }) $(document).on('click', '.useTemplate', function() { let obj = templateList[templateList.findIndex(item => item.templateName === templateNameKey)]; getData.generate(obj.template); }) $(document).on('click', '.getTableJSON', function() { getData.getRequestParameter() }) let getData = { stringList: "", shearPlate: function (str) { const aux = document.createElement('textarea'); aux.readOnly = 'readonly'; aux.style.position = 'absoult'; aux.style.left = '-9999px'; aux.value = str; // 设置元素内容 // aux.setAttribute('value', str) // 将元素插入页面进行调用 document.body.appendChild(aux) // 复制内容 aux.select() aux.setSelectionRange(0, aux.value.length); // 将内容复制到剪贴板 document.execCommand('copy') // 删除创建元素 document.body.removeChild(aux) alert(str + " 已复制到剪切板") }, firstToUpper1: function (str) { // return str.trim().toLowerCase().replace(str[0], str[0].toUpperCase()); // toLowerCase 会将词组全部转换成小写 str = str.replace(/\{|\}/g, ""); return str.trim().replace(str[0], str[0].toUpperCase()); }, getData: function (callBack) { let data = { id: getUrlId(location.href) }; $.ajax({ type: "get", url: "http://yapi.dashuf.com/api/interface/get", data: data, success: function (res) { console.log(res); if (res.errcode === 0) { callBack(res.data); } } }) }, getTableData: function (callBack) { let data = { catid: getUrlId(location.href).split("_")[1], page: 1, limit: 200 }; $.ajax({ type: "get", url: "http://yapi.dashuf.com/api/interface/list_cat", data: data, success: function (res) { if (res.errcode === 0) { callBack(res.data.list); } } }) }, generate: function (str) { let json = ""; console.log(str); let that = this; let variable = str.match(/\{\{(.+?)\}\}/g); if (getUrlId(location.href).indexOf('cat_') === -1) { this.getData(data => { data.notes = data.title; data.url = data.path; let split = data.url.split("/"); let urlName = split[split.length - 2] + this.firstToUpper1(split[split.length - 1]); data.urlName = urlName; variable.forEach(key => { str = str.replace(key, key.replace(/\{|\}/g, "") === 'method' ? data[key.replace(/\{|\}/g, "")].toLowerCase() : data[key.replace(/\{|\}/g, "")]); }) json += str; that.stringList += str; console.log(json); that.shearPlate(this.stringList); }) } else { this.getTableData(res => { res.forEach(item => { let result = JSON.parse(JSON.stringify(str)); item.url = item.path; let split = item.url.split("/"); item.urlName = split[split.length - 2] + this.firstToUpper1(split[split.length - 1]); item.notes = item.title; item.method = item.method; console.log(item.method); variable.forEach(key => { result = result.replace(key, key.replace(/\{|\}/g, "") === 'method' ? item[key.replace(/\{|\}/g, "")].toLowerCase() : item[key.replace(/\{|\}/g, "")]); }) json += result; that.stringList += result; }); console.log(json); that.shearPlate(that.stringList); }) } }, getJson: function () { let json = ""; // yapi拿到接口地址和拼接注释 this.getTableData(table => { table.forEach(item => { let url, urlName, notes, method, split; url = item.path; split = url.split("/"); urlName = split[split.length - 2] + this.firstToUpper1(split[split.length - 1]); notes = item.title; method = item.method.toLowerCase(); json += `${urlName}: host + ${url}, // ${notes} `; this.stringList += urlName + ': host + "' + url + '", // ' + notes + '\n' }) console.log(json); this.shearPlate(this.stringList); }); }, getFn: function () { let json = ""; // yapi拿到接口地址和拼接注释 this.getTableData(table => { table.forEach(item => { let url, urlName, notes, method, split; url = item.path; let urlId = this.getUrlID(url) split = url.split("/"); urlName = split[split.length - 2] + (urlId ? urlId : this.firstToUpper1(split[split.length - 1])); notes = item.title; method = item.method.toLowerCase(); json += `// ${notes} export function ${urlName}(data) { return request({ url: host + "${urlId ? url.replace(/\{.*\}/g, "") : url}"${ urlId ? "+" + urlId : "" }, method: "${method}", ${urlId ? "" : method.trim().toLowerCase() === "post" ? "data: data" : "params: data"} }) }; ` this.stringList += '// ' + notes + '\r\n' + 'export function ' + urlName + '(data) {\r' + ' return request({\r' + ' url: host + "' + url + '",\r' + ' method: "' + method + '",\r' + (urlId ? "" : ' ' + (method.trim().toLowerCase() === "post" ? 'data' : 'params') + ': data\r') + ' })\r' + '};\r' }) console.log(json); this.shearPlate(this.stringList); }); }, getOne: function (type = 'li') { this.getData(data => { console.log(data); let result = ""; let notes = data.title; let method = data.method.toLowerCase(); let url = data.path; let urlId = this.getUrlID(url) let split = url.split("/"); let urlName = split[split.length - 2] + (urlId ? urlId : this.firstToUpper1(split[split.length - 1])); if (type === "li") { result = `${urlName}: host + '${url}', // ${notes}`; this.stringList = urlName + ': host + "' + (urlId ? url.replace(/\{.*\}/g, "") : url) + '", // ' + notes; } else { result = `// ${notes} export function ${urlName}(${ urlId ? urlId : 'data' }) { return request({ url: host + "${urlId ? url.replace(/\{.*\}/g, "") : url}"${ urlId ? "+" + urlId : "" }, method: "${method}", ${urlId ? "" : method.trim().toLowerCase() === "post" ? "data: data" : "params: data"} }) }; ` this.stringList = '// ' + notes + '\r\n' + 'export function ' + urlName + '('+ (urlId ? urlId : 'data') +') {\r' + ' return request({\r' + ' url: host + "' + (urlId ? url.replace(/\{.*\}/g, "") : url) + '"'+ (urlId ? "+" + urlId : "") +',\r' + ' method: "' + method + '",\r' + (urlId ? "" : ' ' + (method.trim().toLowerCase() === "post" ? 'data' : 'params') + ': data\r') + ' })\r' + '};\r' } console.log(result); this.shearPlate(this.stringList); }); }, deleteTemplate: function(name) { let index = templateList.findIndex(item => item.templateName === name); let con = confirm("是否删除“"+templateList[index].templateName + "”模板?"); if (con) { templateList.splice(index, 1); console.log(templateList); this.updateTemplateOption(); $(".deleteTemplate").attr("disabled"); $(".useTemplate").attr("disabled"); $("#template").val(); $(".templateName").val(); localStorage.setItem("template", JSON.stringify(templateList)); } }, updateTemplateOption() { $(".selectTemplateName").html(`<option>请选择</option>${ templateList.map(item => { return `<option value="${item.templateName}">${item.templateName}</option>` }).join("") }`); }, getRequestParameter() { let text = ""; if (getUrlId(location.href).indexOf("cat_") > -1) { alert("请进入详情页获取接口参数"); return; } this.getData(res => { let properties = ""; if (res.method === "GET") { properties = res.req_query } else { properties = JSON.parse(res.req_body_other).properties; } for(let i in properties){ let item = properties[i]; if (res.method === "GET") { text += '"' + item.name + '": '+ JSON.stringify(this.chooseType(item.type)) +', // ' + properties[i].desc + '\r\n' } else { text += '"' + i + '": '+ JSON.stringify(this.chooseType(properties[i].type)) +', // ' + properties[i].description + '\r\n' } }; this.shearPlate(text); }) }, chooseType(type) { switch(type) { case 'number': return null; case 'boolean': return false; case 'string': return ""; case 'Array': return []; default: return null; } }, getUrlID(str) { let matchLength = str.match(/\{.*\}/g) let id = "" if (matchLength) { id = matchLength[0].replace(/\{|\}/g, "") } return id } } // Your code here... })(); }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址