期刊论文查询助手

集成期刊查询和论文跳转功能的助手

  1. // ==UserScript==
  2. // @name 期刊论文查询助手
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description 集成期刊查询和论文跳转功能的助手
  6. // @author Your name
  7. // @match *://*/*
  8. // @match https://www.ablesci.com/assist/create
  9. // @grant GM_xmlhttpRequest
  10. // @grant GM_addStyle
  11. // @grant GM_setValue
  12. // @grant GM_getValue
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // 添加样式
  19. GM_addStyle(`
  20. #paper-helper-ball {
  21. position: fixed;
  22. right: 20px;
  23. bottom: 20px;
  24. width: 50px;
  25. height: 50px;
  26. background: #4CAF50;
  27. border-radius: 50%;
  28. color: white;
  29. display: flex;
  30. align-items: center;
  31. justify-content: center;
  32. cursor: pointer;
  33. box-shadow: 0 2px 5px rgba(0,0,0,0.2);
  34. z-index: 10000;
  35. transition: transform 0.3s;
  36. }
  37. #paper-helper-ball:hover {
  38. transform: scale(1.1);
  39. }
  40. #paper-helper-modal {
  41. display: none;
  42. position: fixed;
  43. right: 80px;
  44. bottom: 80px;
  45. width: 300px;
  46. background: white;
  47. border-radius: 8px;
  48. padding: 15px;
  49. box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  50. z-index: 10000;
  51. }
  52. .tab-buttons {
  53. display: flex;
  54. margin-bottom: 10px;
  55. gap: 5px;
  56. }
  57. .tab-button {
  58. flex: 1;
  59. padding: 8px;
  60. border: none;
  61. border-radius: 4px;
  62. cursor: pointer;
  63. background: #f0f0f0;
  64. }
  65. .tab-button.active {
  66. background: #4CAF50;
  67. color: white;
  68. }
  69. .tab-content {
  70. display: none;
  71. }
  72. .tab-content.active {
  73. display: block;
  74. }
  75. #paper-helper-modal input {
  76. width: 100%;
  77. padding: 8px;
  78. margin-bottom: 10px;
  79. border: 1px solid #ddd;
  80. border-radius: 4px;
  81. }
  82. #paper-helper-modal button {
  83. background: #4CAF50;
  84. color: white;
  85. border: none;
  86. padding: 8px 15px;
  87. border-radius: 4px;
  88. cursor: pointer;
  89. width: 100%;
  90. }
  91. #paper-helper-modal button:hover {
  92. background: #45a049;
  93. }
  94. #query-results {
  95. margin-top: 10px;
  96. padding: 10px;
  97. background: #f5f5f5;
  98. border-radius: 4px;
  99. display: none;
  100. }
  101. .loading {
  102. text-align: center;
  103. margin: 10px 0;
  104. display: none;
  105. }
  106. .error-message {
  107. color: red;
  108. margin-top: 10px;
  109. display: none;
  110. }
  111. `);
  112.  
  113. // 检查当前是否在目标网站
  114. const isTargetSite = window.location.href.includes('ablesci.com/assist/create');
  115.  
  116. if (isTargetSite) {
  117. // 在目标网站自动填充
  118. const paperTitle = GM_getValue('paperTitle', '');
  119. if (paperTitle) {
  120. // 等待页面加载完成
  121. window.addEventListener('load', () => {
  122. setTimeout(() => {
  123. const input = document.getElementById('onekey');
  124. if (input) {
  125. input.value = paperTitle;
  126. // 触发事件
  127. input.dispatchEvent(new Event('input', { bubbles: true }));
  128. input.dispatchEvent(new Event('change', { bubbles: true }));
  129. // 清除存储的标题
  130. GM_setValue('paperTitle', '');
  131. // 点击搜索按钮
  132. const searchButton = document.querySelector('.onekey-search');
  133. if (searchButton) {
  134. searchButton.click();
  135. }
  136. }
  137. }, 500); // 稍微延迟以确保元素已加载
  138. });
  139. }
  140. } else {
  141. // 在其他网站显示浮动球和模态框
  142. const ball = document.createElement('div');
  143. ball.id = 'paper-helper-ball';
  144. ball.innerHTML = '📚';
  145. document.body.appendChild(ball);
  146.  
  147. const modal = document.createElement('div');
  148. modal.id = 'paper-helper-modal';
  149. modal.innerHTML = `
  150. <div class="tab-buttons">
  151. <button class="tab-button active" data-tab="journal">期刊查询</button>
  152. <button class="tab-button" data-tab="paper">论文跳转</button>
  153. </div>
  154. <div class="tab-content active" id="journal-tab">
  155. <input type="text" id="journal-name" placeholder="请输入期刊名称">
  156. <button id="query-button">查询期刊</button>
  157. <div class="loading">查询中...</div>
  158. <div class="error-message"></div>
  159. <div id="query-results"></div>
  160. </div>
  161. <div class="tab-content" id="paper-tab">
  162. <input type="text" id="paper-title" placeholder="请输入论文标题">
  163. <button id="search-button">跳转查询</button>
  164. </div>
  165. `;
  166. document.body.appendChild(modal);
  167.  
  168. // 点击球显示/隐藏模态框
  169. let isModalVisible = false;
  170. ball.addEventListener('click', () => {
  171. isModalVisible = !isModalVisible;
  172. modal.style.display = isModalVisible ? 'block' : 'none';
  173. });
  174.  
  175. // 标签切换功能
  176. const tabButtons = document.querySelectorAll('.tab-button');
  177. tabButtons.forEach(button => {
  178. button.addEventListener('click', () => {
  179. tabButtons.forEach(btn => btn.classList.remove('active'));
  180. document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
  181. button.classList.add('active');
  182. const tabId = button.getAttribute('data-tab') + '-tab';
  183. document.getElementById(tabId).classList.add('active');
  184. });
  185. });
  186.  
  187. // 期刊查询函数
  188. async function queryJournalRank(journalName) {
  189. const apiKey = '69e5dfcf9f6b45b7947e6c8606ef4509';
  190. const baseUrl = 'https://www.easyscholar.cc/open/getPublicationRank';
  191. const encodedName = encodeURIComponent(journalName);
  192. const url = `${baseUrl}?secretKey=${apiKey}&publicationName={encodedName}`;
  193.  
  194. return new Promise((resolve, reject) => {
  195. GM_xmlhttpRequest({
  196. method: 'GET',
  197. url: url,
  198. onload: function(response) {
  199. try {
  200. const data = JSON.parse(response.responseText);
  201. if (data.code === 200) {
  202. const officialRank = data.data.officialRank;
  203. const rankData = officialRank.select || officialRank.all || {};
  204. const result = {};
  205. const indicators = {
  206. "CCF\text{等级}": "ccf",
  207. "SCI\text{五年影响因子}": "sciif5",
  208. "SCI\text{分区}": "sci",
  209. "SCI\text{影响因子}": "sciif"
  210. };
  211.  
  212. let foundAny = false;
  213. for (const [displayName, key] of Object.entries(indicators)) {
  214. if (rankData[key]) {
  215. result[displayName] = rankData[key];
  216. foundAny = true;
  217. }
  218. }
  219.  
  220. if (!foundAny) {
  221. reject('\text{未找到指定的期刊等级信息}');
  222. } else {
  223. resolve(result);
  224. }
  225. } else {
  226. reject(data.msg || '\text{查询失败}');
  227. }
  228. } catch (error) {
  229. reject('\text{数据解析错误}');
  230. }
  231. },
  232. onerror: function(error) {
  233. reject('\text{网络请求失败}');
  234. }
  235. });
  236. });
  237. }
  238.  
  239. // \text{期刊查询按钮点击事件}
  240. document.getElementById('query-button').addEventListener('click', async () => {
  241. const journalName = document.getElementById('journal-name').value.trim();
  242. if (!journalName) {
  243. showError('\text{请输入期刊名称}');
  244. return;
  245. }
  246.  
  247. const loading = document.querySelector('.loading');
  248. const results = document.getElementById('query-results');
  249. const errorMessage = document.querySelector('.error-message');
  250.  
  251. loading.style.display = 'block';
  252. results.style.display = 'none';
  253. errorMessage.style.display = 'none';
  254.  
  255. try {
  256. const data = await queryJournalRank(journalName);
  257. let resultHtml = '<h4>\text{查询结果}:</h4>';
  258. for (const [indicator, value] of Object.entries(data)) {
  259. resultHtml += `<p><strong>{indicator}:</strong> ${value}</p>`;
  260. }
  261. results.innerHTML = resultHtml;
  262. results.style.display = 'block';
  263. } catch (error) {
  264. showError(error);
  265. } finally {
  266. loading.style.display = 'none';
  267. }
  268. });
  269.  
  270. // 论文跳转按钮点击事件
  271. document.getElementById('search-button').addEventListener('click', () => {
  272. const paperTitle = document.getElementById('paper-title').value.trim();
  273. if (paperTitle) {
  274. // 保存标题到存储
  275. GM_setValue('paperTitle', paperTitle);
  276. // 打开新窗口
  277. window.open('https://www.ablesci.com/assist/create', '_blank');
  278. }
  279. });
  280.  
  281. // 点击其他地方关闭模态框
  282. document.addEventListener('click', (event) => {
  283. if (isModalVisible &&
  284. !modal.contains(event.target) &&
  285. !ball.contains(event.target)) {
  286. isModalVisible = false;
  287. modal.style.display = 'none';
  288. }
  289. });
  290. }
  291. })();
  292.  
  293. function showError(message) {
  294. const errorMessage = document.querySelector('.error-message');
  295. errorMessage.textContent = message;
  296. errorMessage.style.display = 'block';
  297. }