LockArticle.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <template>
  2. <div class="read-more-wrap"
  3. style="display: none; position: absolute; bottom: 0px; z-index: 9999; width: 100%; margin-top: -100px; font-family: PingFangSC-Regular, sans-serif;">
  4. <div id="read-more-mask"
  5. style="position: relative; height: 200px; background: -webkit-gradient(linear, 0 0%, 0 100%, from(rgba(255, 255, 255, 0)), to(rgb(255, 255, 255)));"></div>
  6. <a id="read-more-btn" target="_self"
  7. style="position: absolute; left: 50%; top: 70%; bottom: 30px; transform: translate(-50%, -50%); width: 160px; height: 36px; line-height: 36px; font-size: 15px; text-align: center; border: 1px solid rgb(222, 104, 109); color: rgb(222, 104, 109); background: rgb(255, 255, 255); cursor: pointer; border-radius: 6px;">阅读全文</a>
  8. <div id="btw-modal-wrap" style="display: none;">
  9. <div id="btw-mask"
  10. style="position: fixed; top: 0px; right: 0px; bottom: 0px; left: 0px; opacity: 0.7; z-index: 999; background: rgb(0, 0, 0);"></div>
  11. <div id="btw-modal"
  12. style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 300px; text-align: center; font-size: 13px; background: rgb(255, 255, 255); border-radius: 10px; z-index: 9999; font-family: PingFangSC-Regular, sans-serif;">
  13. <span id="btw-modal-close-btn"
  14. style="position: absolute; top: 5px; right: 15px; line-height: 34px; font-size: 34px; cursor: pointer; opacity: 0.2; z-index: 9999; color: rgb(0, 0, 0); background: none; border: none; outline: none;">×</span>
  15. <p id="btw-modal-header"
  16. style="margin-top: 40px; line-height: 1.8; font-size: 13px;">
  17. 扫码或搜索:<span style="color: #E9405A; font-weight: bold;">微观技术</span>
  18. <br>发送:<span id="fustack-token" class="token"
  19. style="color: #e9415a; font-weight: bold; font-size: 17px; margin-bottom: 45px;">290992</span>
  20. <br>即可<span style="color: #e9415a; font-weight: bold;">立即永久</span>解锁本站全部文章</p>
  21. <img src="/images/personal/qrcode.jpg"
  22. style="width: 180px; margin-top: 10px; margin-bottom: 30px; border: 8px solid rgb(230, 230, 230);">
  23. </div>
  24. </div>
  25. </div>
  26. </template>
  27. <script>
  28. export default {
  29. name: 'LockArticle',
  30. data() {
  31. return {}
  32. },
  33. mounted: function () {
  34. // 定时任务
  35. setInterval(() => {
  36. if (this.isLock()) {
  37. let $article = this.articleObj();
  38. this._detect($article, this);
  39. }
  40. }, 1500);
  41. // 判断是否锁定文章
  42. // if (this.isLock()) {
  43. // setTimeout(() => {
  44. // let $article = this.articleObj();
  45. // this._detect($article, this);
  46. //
  47. // // 定时任务
  48. // setInterval(() => {
  49. // this._detect($article, this);
  50. // }, 5000);
  51. //
  52. // }, 2000);
  53. // }
  54. },
  55. methods: {
  56. isLock() {
  57. return "need" === this.$page.frontmatter.lock;
  58. },
  59. articleObj: function () {
  60. let $article = $('.theme-default-content');
  61. if ($article.length <= 0) return null;
  62. // 文章的实际高度
  63. let height = $article[0].clientHeight;
  64. return {
  65. article: $article,
  66. height: height
  67. }
  68. },
  69. _detect: function (articleObj, t) {
  70. if (null == articleObj) return;
  71. let res = this.getCookie("_unlock");
  72. if ('success' === res) {
  73. return;
  74. }
  75. t.getToken().then(function (token) {
  76. $.ajax({
  77. url: 'https://api.offercome.cn/interfaces/BlogApi.php',
  78. type: "GET",
  79. dataType: "text",
  80. data: {
  81. token: token
  82. },
  83. success: function (data) {
  84. if (data === 'refuse') {
  85. t._lock(articleObj);
  86. } else {
  87. t._unlock(articleObj);
  88. t.setCookie("_unlock", "success", 7);
  89. }
  90. },
  91. error: function (data) {
  92. t._unlock(articleObj);
  93. }
  94. })
  95. });
  96. },
  97. _lock: function (articleObj) {
  98. let $article = articleObj.article;
  99. let height = articleObj.height;
  100. if ($article.length <= 0) return;
  101. // 文章隐藏后的高度
  102. let halfHeight = height * 0.3;
  103. // 篇幅短一点的文章就不需要解锁了
  104. if (this.os().isPc && halfHeight > 800) {
  105. // 获取口令
  106. this.getToken().then(function (token) {
  107. $('#fustack-token').text(token);
  108. // 判断是否已加锁
  109. if ($article.hasClass("lock")) {
  110. return;
  111. }
  112. // 设置文章可显示高度
  113. $article.css({"height": halfHeight + 'px'});
  114. $article.addClass('lock');
  115. // 添加引导解锁标签
  116. $article.remove("#read-more-wrap");
  117. let clone = $('.read-more-wrap').clone();
  118. clone.attr('id', 'read-more-wrap');
  119. clone.css('display', 'block');
  120. clone.find("#read-more-btn").click(function () {
  121. clone.find("#btw-modal-wrap").css('display', 'block');
  122. });
  123. clone.find("#btw-modal-close-btn").click(function () {
  124. clone.find("#btw-modal-wrap").css('display', 'none');
  125. });
  126. $article.append(clone);
  127. });
  128. }
  129. },
  130. _unlock: function (articleObj) {
  131. let $article = articleObj.article;
  132. // 判断是否已加锁
  133. if (!$article.hasClass("lock")) {
  134. return;
  135. }
  136. $article.css('height', 'initial');
  137. $article.removeClass('lock');
  138. $('#read-more-wrap').remove();
  139. },
  140. getToken: async function () {
  141. // 浏览器 Cookie true 不限制
  142. if(navigator.cookieEnabled){
  143. let value = this.getCookie('BAEID');
  144. if (!value) {
  145. return await this.getFingerprintId();
  146. }
  147. return value.substring(value.length - 6).toUpperCase();
  148. } else{
  149. return await this.getFingerprintId();
  150. }
  151. // return await this.getFingerprintId();
  152. },
  153. getFingerprintId: function () {
  154. // https://github.com/fingerprintjs/fingerprintjs
  155. /* new Fingerprint2().get(function(result, components){
  156. let value = result.toUpperCase();
  157. let token = value.substring(value.length - 6).toUpperCase();
  158. // 设置token
  159. $('#fustack-token').text(token);
  160. });
  161. return $('#fustack-token').text();*/
  162. return new Promise( resolve => {
  163. new Fingerprint2().get(function(result, components){
  164. let value = result.toUpperCase();
  165. let token = value.substring(value.length - 6).toUpperCase();
  166. resolve(token);
  167. });
  168. })
  169. },
  170. getUUID: function () {
  171. return 'xxxxxx'.replace(/[xy]/g, function (c) {
  172. let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
  173. return v.toString(16);
  174. });
  175. },
  176. getCookie: function (name) {
  177. let value = "; " + document.cookie;
  178. let parts = value.split("; " + name + "=");
  179. if (parts.length === 2)
  180. return parts.pop().split(";").shift();
  181. },
  182. setCookie: function (name, value, hours){
  183. let exp = new Date();
  184. exp.setTime(exp.getTime() + hours*60*60*1000);
  185. // ;path=/ cookie全站有效
  186. document.cookie = name + "="+ escape (value) + ";path=/;expires=" + exp.toGMTString();
  187. },
  188. os: function () {
  189. let ua = navigator.userAgent,
  190. isWindowsPhone = /(?:Windows Phone)/.test(ua),
  191. isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
  192. isAndroid = /(?:Android)/.test(ua),
  193. isFireFox = /(?:Firefox)/.test(ua),
  194. isChrome = /(?:Chrome|CriOS)/.test(ua),
  195. isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),
  196. isPhone = /(?:iPhone)/.test(ua) && !isTablet,
  197. isPc = !isPhone && !isAndroid && !isSymbian;
  198. return {
  199. isTablet: isTablet,
  200. isPhone: isPhone,
  201. isAndroid: isAndroid,
  202. isPc: isPc
  203. }
  204. }
  205. }
  206. }
  207. </script>
  208. <style lang="stylus">
  209. #read-more-btn {
  210. border: none !important;
  211. text-decoration: none;
  212. background: #3eaf7c !important;
  213. }
  214. #read-more-btn {
  215. color: #fff !important;
  216. transition: all .5s ease;
  217. }
  218. #read-more-btn:hover {
  219. background: #de3636 !important;
  220. }
  221. .lock {
  222. position: relative;
  223. overflow: hidden;
  224. padding-bottom: 30px;
  225. }
  226. </style>