理杏仁助手

雪球、理性仁等网站之间跳转

目前為 2024-01-10 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name 理杏仁助手
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.7
  5. // @description 雪球、理性仁等网站之间跳转
  6. // @author chen
  7. // @include /^https:\/\/(xueqiu|www\.lixinger)+\.com.*/
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. /*eslint-disable*/
  13. ;
  14. (function() {
  15. 'use strict'
  16.  
  17. const hkStockTemplateUrl = 'https://www.lixinger.com/analytics/company/detail/hk/{stockCode}/{tickerId}/fundamental/valuation/primary'
  18. const szStockTemplateUrl = 'https://www.lixinger.com/analytics/company/detail/sz/{stockCode}/{tickerId}/fundamental/valuation/primary'
  19. const shStockTemplateUrl = 'https://www.lixinger.com/analytics/company/detail/sh/{stockCode}/{tickerId}/fundamental/valuation/primary'
  20. const bjStockTemplateUrl = 'https://www.lixinger.com/analytics/company/detail/bj/{stockCode}/{tickerId}/fundamental/valuation/primary'
  21.  
  22. const szFundTemplateUrl = 'https://www.lixinger.com/analytics/fund/detail/sz/{stockCode}/{tickerId}/valuation/fitting'
  23. const shFundTemplateUrl = 'https://www.lixinger.com/analytics/fund/detail/sh/{stockCode}/{tickerId}/valuation/fitting'
  24.  
  25. const szIndexTemplateUrl = 'https://www.lixinger.com/analytics/index/detail/sz/{stockCode}/{tickerId}/fundamental/valuation/primary'
  26. const shIndexTemplateUrl = 'https://www.lixinger.com/analytics/index/detail/sh/{stockCode}/{tickerId}/fundamental/valuation/primary'
  27. const csiIndexTemplateUrl = 'https://www.lixinger.com/analytics/index/detail/csi/{stockCode}/{tickerId}/fundamental/valuation/primary'
  28.  
  29. const regList = [
  30. // 港股
  31. /^\d{5}$/,
  32. // 深市股票
  33. /^SZ(00|01|02|20|30)\d{4}$/,
  34. // 沪市股票
  35. /^SH(600|601|603|605|688|689|900)\d{3}$/,
  36. // 北交所
  37. /^BJ(8|4)\d{5}$/,
  38. // 深市基金
  39. /^SZ(15|16)\d{4}$/,
  40. // 沪市基金
  41. /^SH5\d{5}$/,
  42. // 深证指数
  43. /^SZ39\d{4}$/,
  44. // 沪市指数
  45. /^SH000\d{3}$/,
  46. // 中证指数
  47. /^CSI(\d|H)\d{5}$/
  48. ];
  49.  
  50. const urlList = [
  51. hkStockTemplateUrl,
  52. szStockTemplateUrl,
  53. shStockTemplateUrl,
  54. bjStockTemplateUrl,
  55. szFundTemplateUrl,
  56. shFundTemplateUrl,
  57. szIndexTemplateUrl,
  58. shIndexTemplateUrl,
  59. csiIndexTemplateUrl,
  60. ];
  61.  
  62. function normalizeCode(code) {
  63. return code && code.replace(/^(sz|sh|bj|csi)/i, '')
  64. }
  65.  
  66. function getLixingrenStockPageUrl(code) {
  67. const stockCode = normalizeCode(code)
  68. // 美股不支持
  69. if (!stockCode) return ''
  70.  
  71. for (let i = 0; i < regList.length; i++) {
  72. if (regList[i].test(code)) {
  73. return urlList[i].replace(/\{stockCode\}/g, stockCode).replace(/\{tickerId\}/g, stockCode.replace(/[a-z]+/gi, ''))
  74. }
  75. }
  76.  
  77. return ''
  78. }
  79.  
  80. function setHrefAttribute(el, code) {
  81. const url = getLixingrenStockPageUrl(code)
  82. if (!url) {
  83. console.log('不支持的证券代码:' + code)
  84. return
  85. }
  86. el.attr('href', url)
  87. }
  88.  
  89. function insertAfterLxrIcon(el, code) {
  90. const url = getLixingrenStockPageUrl(code)
  91. if (!url) {
  92. console.log('不支持的证券代码:' + code)
  93. return
  94. };
  95.  
  96. el.after(`<div style="float: left;margin: 0 20px">
  97. <a class="lxr-icon" target="_blank">
  98. <img style="width: 20px;height: 20px;vertical-align: middle"
  99. src="https://www.lixinger.com/static/img/logo50x50.png"
  100. style="vertical-align: middle;" />
  101. </a>
  102. </div>`)
  103. }
  104.  
  105. if (location.host === 'xueqiu.com') {
  106. /**
  107. * 主页自选股跳转到理性仁
  108. */
  109. const linkSelector = '#optional tr.sortable a.code'
  110. $(document.body).on('click', linkSelector, function(e) {
  111. var href = $(this).attr('href')
  112. if (href.indexOf('www.lixinger.com') > -1) {
  113. return
  114. }
  115.  
  116. const code = href.replace('/S/', '')
  117. setHrefAttribute($(this), code)
  118. })
  119.  
  120. /**
  121. * 股票页跳转到理性仁
  122. */
  123. const titleSelector = '#app .stock-name'
  124.  
  125. insertAfterLxrIcon($(titleSelector).eq(0), location.pathname.replace('/S/', ''));
  126.  
  127. $('.lxr-icon').on('mouseenter', function() {
  128. const code = location.pathname.replace('/S/', '')
  129. setHrefAttribute($(this), code)
  130. })
  131.  
  132. return
  133. }
  134.  
  135. /*
  136. * 理性仁相关功能
  137. */
  138. if (location.host === 'www.lixinger.com') {
  139. setInterval(function() {
  140. const regex = /\/analytics\/(company|fund|index)\/detail\/(sh|sz|bj|csi|hk|nasdaq|nyse)\/(\w+)\/(\d+)\/.+/;
  141. const result = location.pathname.match(regex);
  142. const linkNode = document.querySelector('.xueqiu-link');
  143.  
  144. if (!result) {
  145. linkNode?.remove();
  146. return;
  147. }
  148. if (linkNode) {
  149. if (linkNode.getAttribute("stock-code") === result[3]) {
  150. return;
  151. } else {
  152. linkNode.remove();
  153. }
  154. }
  155. const nameNode = document.querySelector('div.action-group.d-flex');
  156. if (!nameNode) {
  157. return
  158. }
  159. let market = (['hk', 'nasdaq'].includes(result[2]) ? '' : result[2]).toUpperCase();
  160. if(result[1] === 'index' && result[2] === 'hk'){
  161. market = result[2].toUpperCase();
  162. }
  163. const code = result[3].toUpperCase();
  164. const xueqiuUrl = 'https://xueqiu.com/S/' + market + code
  165. const a = document.createElement('a')
  166. a.innerHTML = `<img
  167. src="https://assets.imedao.com/images/favicon.png"
  168. style="width: 1.32rem;"
  169. />`;
  170. a.setAttribute('href', xueqiuUrl)
  171. a.setAttribute('target', '_blank')
  172. a.style.cssText = 'margin-left: 0.5rem;'
  173. a.setAttribute("class", "xueqiu-link");
  174. a.setAttribute("stock-code", result[3]);
  175. nameNode.append(a)
  176. }, 3000)
  177. }
  178. })()