立创商城自动领券

立创商城自动领券~~~

  1. // ==UserScript==
  2. // @name 立创商城自动领券
  3. // @version 0.15
  4. // @license MIT
  5. // @namespace http://tampermonkey.net/
  6. // @description 立创商城自动领券~~~
  7. // @author Clistery
  8. // @match https://www.szlcsc.com/huodong.html*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=szlcsc.com
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. ;(function () {
  14. 'use strict'
  15.  
  16. const numberRegx = /\d+/
  17.  
  18. // 添加通知样式
  19. const style = document.createElement('style')
  20. style.textContent = `
  21. .notification {
  22. position: fixed;
  23. top: 50px;
  24. right: 20px;
  25. padding: 15px;
  26. background-color: #444;
  27. color: white;
  28. border-radius: 5px;
  29. box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  30. opacity: 0;
  31. transition: opacity 0.5s ease, right 0.5s ease;
  32. z-index: 9999;
  33. transform: translate(0%, -50%);
  34. }
  35. .notification.show {
  36. opacity: 1;
  37. top: 50%;
  38. right: 50px;
  39. }
  40. .notification.hide {
  41. opacity: 0;
  42. top: 50%;
  43. right: 20px;
  44. }
  45. #get-tickets-btn {
  46. background-image: linear-gradient(0deg, #558b2f, #7cb342);
  47. cursor: pointer;
  48. position: fixed;
  49. width: 2.4375rem;
  50. line-height: 0.8125rem;
  51. font-size: 0.8125rem;
  52. white-space: pre-line;
  53. display: flex;
  54. top: 50%;
  55. right: 0px;
  56. writing-mode: vertical-lr;
  57. text-orientation: upright;
  58. padding: 10px 0;
  59. z-index: 100001;
  60. border-radius: 10px;
  61. opacity: 0.7;
  62. box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),
  63. 0 3px 1px -2px rgba(0, 0, 0, 0.2);
  64. overflow: hidden;
  65. transform: translate(0%, -50%);
  66. user-select: none;
  67. }
  68. #lc-www > main > aside > section {
  69. position: fixed;
  70. align-items: start;
  71. width: 56px;
  72. }
  73. #lc-www > main > aside > section.right-\\[-56px\\] {
  74. left: -56px;
  75. }
  76. #lc-www > main > aside > section.\\!right-0 {
  77. left: 0 !important;
  78. }
  79. #lc-www > main > aside > button {
  80. }
  81. #lc-www > main > aside > button.right-\\[-46px\\] {
  82. left: -46px;
  83. }
  84. #lc-www > main > aside > button.\\!right-0 {
  85. left: 0 !important;
  86. }
  87. `
  88. document.head.appendChild(style)
  89.  
  90. // 显示通知函数
  91. function showNotification(message, duration = 3000) {
  92. const notification = document.createElement('div')
  93. notification.className = 'notification'
  94. notification.textContent = message
  95. document.body.appendChild(notification)
  96.  
  97. // 显示通知
  98. setTimeout(() => {
  99. notification.classList.add('show')
  100. }, 100)
  101.  
  102. // 隐藏通知
  103. setTimeout(() => {
  104. notification.classList.remove('show')
  105. notification.classList.add('hide')
  106. setTimeout(() => {
  107. document.body.removeChild(notification)
  108. }, 500)
  109. }, duration)
  110. }
  111.  
  112. const run = () => {
  113. showNotification('等待页面数据加载完毕...')
  114. setTimeout(() => {
  115. loadTickets()
  116. }, 3000)
  117. }
  118.  
  119. if (document.readyState === 'loading') {
  120. document.addEventListener('DOMContentLoaded', (event) => {
  121. run()
  122. })
  123. } else {
  124. run()
  125. }
  126.  
  127. function is满减券(e) {
  128. const money = [1, 16, 21, 26]
  129. for (const m of money) {
  130. if (e.textContent.includes(`满${m}可用`)) {
  131. return true
  132. }
  133. }
  134. }
  135.  
  136. /**
  137. * @param {Element} e
  138. */
  139. function isPlus(e) {
  140. return e.textContent.includes('PLUS')
  141. }
  142.  
  143. /**
  144. * @param {Element} e
  145. * @param {Element} btn
  146. */
  147. function is可领取(e, btn) {
  148. return !e.textContent.includes('新人专享') && btn.textContent.includes('立即抢券')
  149. }
  150.  
  151. /**
  152. * @param {Element} e
  153. */
  154. function isMRO(e) {
  155. if (e.parentElement) {
  156. if (e.parentElement.textContent.includes('工业品')) {
  157. if (e.hasChildNodes() && e.childElementCount > 1) {
  158. if (
  159. numberRegx.test(e.firstChild.textContent) &&
  160. numberRegx.test(e.lastChild.textContent)
  161. ) {
  162. let ticketPrice = parseInt(e.firstChild.textContent.match(numberRegx)[0])
  163. let thresholdPrice = parseInt(e.lastChild.textContent.match(numberRegx)[0])
  164. if (Math.abs(ticketPrice - thresholdPrice) < 10) {
  165. return true
  166. }
  167. }
  168. }
  169. }
  170. }
  171. return false
  172. }
  173.  
  174. /**
  175. * @param {Element} e
  176. */
  177. function is包邮券(e) {
  178. return (
  179. (e.textContent.includes('免邮') || e.textContent.includes('包邮')) &&
  180. !e.textContent.includes('工业品')
  181. )
  182. }
  183.  
  184. function loadTickets() {
  185. if (window.getTicketElements) {
  186. console.warn('ticket elements loaded!')
  187. }
  188. console.log('load ticket elements')
  189.  
  190. let allTicketContainer = document.querySelectorAll(
  191. `.m-auto > div > div.flex.flex-wrap > div > div > div:nth-last-child(1)`
  192. )
  193.  
  194. if (allTicketContainer.length <= 0) {
  195. console.warn('优惠券元素查询失败')
  196. return
  197. }
  198.  
  199. window.getTicketElements = []
  200.  
  201. for (let e of allTicketContainer) {
  202. let ellipsisE = e.querySelector('div:first-child')
  203. if (isPlus(e)) {
  204. continue
  205. }
  206. let btn = e.querySelector('button')
  207. if (btn) {
  208. if (is可领取(e, btn)) {
  209. if (isMRO(e) || is满减券(e) || is包邮券(e)) {
  210. console.log(ellipsisE.textContent)
  211. window.getTicketElements.push({
  212. title: ellipsisE.textContent,
  213. ele: btn,
  214. })
  215. }
  216. } else if (btn.textContent.includes('立即使用')) {
  217. let dataset = btn.dataset
  218. if (dataset.spm) {
  219. let couponsGroupE = e.parentElement.parentElement.parentElement.parentElement
  220. if (couponsGroupE && couponsGroupE.dataset) {
  221. let groupId = couponsGroupE.dataset.spm
  222.  
  223. let couponsData =
  224. __NEXT_DATA__.props.pageProps.couponsDataList.couponModelVOListMap[groupId][
  225. parseInt(dataset.spm) - 1
  226. ]
  227. // console.log('couponsData:', couponsData)
  228.  
  229. let aE = document.createElement('a')
  230. aE.innerText = btn.innerText
  231. aE.target = '_blank'
  232. aE.href = couponsData.targetUrl
  233. aE.classList = btn.classList
  234.  
  235. btn.parentNode.replaceChild(aE, btn)
  236. }
  237. }
  238. }
  239. }
  240. }
  241.  
  242. if (window.getTicketElements.length > 0) {
  243. showNotification(`可领 ${window.getTicketElements.length} 张券`)
  244. }
  245. }
  246.  
  247. let getTicketBtn = document.createElement('div')
  248. getTicketBtn.innerHTML = `
  249. <div id="get-tickets-btn">
  250. 自动领取优惠券
  251. </div>
  252. `
  253. document.body.appendChild(getTicketBtn)
  254.  
  255. let realGetTicketsBtnE = getTicketBtn.querySelector('#get-tickets-btn')
  256. realGetTicketsBtnE.onmouseenter = () => {
  257. realGetTicketsBtnE.style.opacity = 1
  258. }
  259. realGetTicketsBtnE.onmouseleave = () => {
  260. realGetTicketsBtnE.style.opacity = 0.7
  261. }
  262.  
  263. let isDragging = false
  264. let startX, startY, offsetX, offsetY
  265.  
  266. const onMouseMove = (event) => {
  267. console.log('onMouseMove')
  268. const currentX = event.clientX
  269. const currentY = event.clientY
  270. const dx = currentX - startX
  271. const dy = currentY - startY
  272.  
  273. if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
  274. isDragging = true
  275. realGetTicketsBtnE.style.cursor = 'grabbing'
  276. realGetTicketsBtnE.style.left = `${currentX - offsetX}px`
  277. realGetTicketsBtnE.style.top = `${currentY - offsetY}px`
  278. realGetTicketsBtnE.removeEventListener('click', window.getTickets)
  279. }
  280. }
  281.  
  282. const onMouseDown = (event) => {
  283. console.log('onMouseDown')
  284. startX = event.clientX
  285. startY = event.clientY
  286. let btnRect = realGetTicketsBtnE.getBoundingClientRect()
  287. offsetX = startX - btnRect.left
  288. offsetY = startY - btnRect.top - btnRect.height / 2
  289. document.addEventListener('mousemove', onMouseMove)
  290. document.addEventListener('mouseup', onMouseUp)
  291. }
  292.  
  293. const onMouseUp = (event) => {
  294. console.log('onMouseUp: ' + isDragging)
  295. realGetTicketsBtnE.style.cursor = 'pointer'
  296. if (isDragging) {
  297. isDragging = false
  298. setTimeout(() => {
  299. realGetTicketsBtnE.addEventListener('click', window.getTickets)
  300. }, 0)
  301. } else {
  302. setTimeout(() => {
  303. window.getTickets()
  304. }, 0)
  305. }
  306. document.removeEventListener('mousemove', onMouseMove)
  307. document.removeEventListener('mouseup', onMouseUp)
  308. }
  309.  
  310. realGetTicketsBtnE.addEventListener('mousedown', onMouseDown)
  311. realGetTicketsBtnE.addEventListener('click', window.getTickets)
  312.  
  313. window.getTickets = async () => {
  314. if (window.getTicketElements) {
  315. console.log('领券咯~~~')
  316. for (const item of window.getTicketElements) {
  317. await new Promise((succ, _) => {
  318. showNotification(`正在领取 ${item.title}`)
  319. item.ele.click()
  320. setTimeout(() => {
  321. succ()
  322. }, 1000)
  323. })
  324. }
  325. clearInterval(hideAlert)
  326.  
  327. showNotification(`共领取 ${window.getTicketElements.length} 张优惠券`)
  328. }
  329. }
  330.  
  331. // 客服
  332. // document.querySelector('#lc-www > main > aside > button').style.left = 0
  333. })()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址