91APP 後台快速編輯選單

在 91APP 商店前台新增快速編輯功能,可快速跳轉至後台編輯頁面

  1. // ==UserScript==
  2. // @name 91APP 後台快速編輯選單
  3. // @name:zh-TW 91APP 後台快速編輯選單
  4. // @version 1.0
  5. // @description 在 91APP 商店前台新增快速編輯功能,可快速跳轉至後台編輯頁面
  6. // @description:zh-TW 在 91APP 商店前台新增快速編輯功能,可快速跳轉至後台編輯頁面
  7. // @author 元魁魁
  8. // @match https://www.example.com/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=91app.com
  10. // @grant GM_addStyle
  11. // @license MIT
  12. // @namespace https://gf.qytechs.cn/users/1211943
  13. // ==/UserScript==
  14.  
  15.  
  16. // 注入 CSS 樣式
  17. GM_addStyle(`
  18. .admin-quick-menu {
  19. position: fixed !important;
  20. top: 1rem !important;
  21. right: 1rem !important;
  22. z-index: 999999 !important;
  23. font-family: system-ui, -apple-system, sans-serif !important;
  24. user-select: none !important;
  25. }
  26.  
  27. .menu-container {
  28. display: flex !important;
  29. align-items: stretch !important;
  30. background: linear-gradient(135deg, #6366f1, #4f46e5) !important;
  31. border-radius: 0.5rem !important;
  32. box-shadow: 0 4px 12px rgba(79, 70, 229, 0.2) !important;
  33. cursor: move !important;
  34. transition: transform 0.2s, box-shadow 0.2s !important;
  35. }
  36.  
  37. .drag-handle {
  38. padding: 0 0.5rem !important;
  39. display: flex !important;
  40. align-items: center !important;
  41. color: rgba(255, 255, 255, 0.6) !important;
  42. cursor: move !important;
  43. }
  44.  
  45. .menu-container:hover {
  46. transform: translateY(-1px) !important;
  47. box-shadow: 0 6px 16px rgba(79, 70, 229, 0.3) !important;
  48. }
  49.  
  50. .edit-button {
  51. background: none !important;
  52. color: white !important;
  53. padding: 0.625rem 1rem !important;
  54. border: none !important;
  55. cursor: pointer !important;
  56. font-size: 0.875rem !important;
  57. white-space: nowrap !important;
  58. font-weight: 500 !important;
  59. position: relative !important;
  60. overflow: hidden !important;
  61. }
  62.  
  63. .toggle-button {
  64. background: none !important;
  65. color: white !important;
  66. padding: 0.625rem 0.75rem !important;
  67. border: none !important;
  68. border-left: 1px solid rgba(255, 255, 255, 0.2) !important;
  69. cursor: pointer !important;
  70. display: flex !important;
  71. align-items: center !important;
  72. }
  73.  
  74. .menu-content {
  75. display: none !important;
  76. position: absolute !important;
  77. right: 0 !important;
  78. top: calc(100% + 0.5rem) !important;
  79. width: 16rem !important;
  80. background-color: white !important;
  81. border-radius: 0.5rem !important;
  82. box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1) !important;
  83. border: 1px solid #e5e7eb !important;
  84. padding: 0.5rem !important;
  85. }
  86.  
  87. .menu-content.show {
  88. display: block !important;
  89. }
  90.  
  91. .menu-item {
  92. width: 100% !important;
  93. text-align: left !important;
  94. padding: 0.625rem 1rem !important;
  95. color: #374151 !important;
  96. border-radius: 0.375rem !important;
  97. border: none !important;
  98. cursor: pointer !important;
  99. font-size: 0.875rem !important;
  100. background: none !important;
  101. display: block !important;
  102. margin: 0.25rem 0 !important;
  103. transition: all 0.2s !important;
  104. }
  105.  
  106. .menu-item:hover {
  107. background-color: #f3f4f6 !important;
  108. color: #4f46e5 !important;
  109. padding-left: 1.25rem !important;
  110. }
  111. `);
  112.  
  113. // 主要程式碼
  114. (function() {
  115. 'use strict';
  116. function getCurrentPageType() {
  117. const url = window.location.href;
  118. if (url.includes('/Article/Detail/')) {
  119. return 'article';
  120. } else if (url.includes('/SalePage/Index/')) {
  121. return 'product';
  122. }
  123. return null;
  124. }
  125.  
  126. function getIdFromUrl() {
  127. const url = window.location.href;
  128. const matches = url.match(/\/(\d+)$/);
  129. return matches ? matches[1] : null;
  130. }
  131.  
  132. function createAdminMenu() {
  133. const menuDiv = document.createElement('div');
  134. menuDiv.className = 'admin-quick-menu';
  135. menuDiv.id = 'adminQuickMenu';
  136.  
  137. const pageType = getCurrentPageType();
  138. const buttonText = pageType ? '編輯此頁' : '管理選單';
  139.  
  140. menuDiv.innerHTML = `
  141. <div class="menu-container" id="menuHeader">
  142. <div class="drag-handle">
  143. <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
  144. <path d="M4 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm0-3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm0 6a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm6-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm0 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm0 6a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
  145. </svg>
  146. </div>
  147. <button class="edit-button" id="edit-button">${buttonText}</button>
  148. <button class="toggle-button" id="menu-toggle">
  149. <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  150. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
  151. </svg>
  152. </button>
  153. <div class="menu-content" id="menu-content">
  154. <button class="menu-item" id="goto-article-list">部落格後台</button>
  155. <button class="menu-item" id="goto-channel-list">頻道頁後台</button>
  156. </div>
  157. </div>
  158. `;
  159. document.body.appendChild(menuDiv);
  160. }
  161.  
  162.  
  163. function initializeDrag() {
  164. const menuDiv = document.getElementById('adminQuickMenu');
  165. const menuHeader = document.getElementById('menuHeader');
  166. let isDragging = false;
  167. let currentX;
  168. let currentY;
  169. let initialX;
  170. let initialY;
  171. let xOffset = 0;
  172. let yOffset = 0;
  173.  
  174. function dragStart(e) {
  175. if (e.target.tagName.toLowerCase() === 'button') return;
  176.  
  177. if (e.type === "touchstart") {
  178. initialX = e.touches[0].clientX - xOffset;
  179. initialY = e.touches[0].clientY - yOffset;
  180. } else {
  181. initialX = e.clientX - xOffset;
  182. initialY = e.clientY - yOffset;
  183. }
  184.  
  185. isDragging = true;
  186. }
  187.  
  188. function dragEnd() {
  189. initialX = currentX;
  190. initialY = currentY;
  191. isDragging = false;
  192. }
  193.  
  194. function drag(e) {
  195. if (!isDragging) return;
  196.  
  197. e.preventDefault();
  198.  
  199. if (e.type === "touchmove") {
  200. currentX = e.touches[0].clientX - initialX;
  201. currentY = e.touches[0].clientY - initialY;
  202. } else {
  203. currentX = e.clientX - initialX;
  204. currentY = e.clientY - initialY;
  205. }
  206.  
  207. xOffset = currentX;
  208. yOffset = currentY;
  209.  
  210. setTranslate(currentX, currentY, menuDiv);
  211. }
  212.  
  213. function setTranslate(xPos, yPos, el) {
  214. el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
  215. }
  216.  
  217. menuHeader.addEventListener('mousedown', dragStart);
  218. document.addEventListener('mousemove', drag);
  219. document.addEventListener('mouseup', dragEnd);
  220.  
  221. menuHeader.addEventListener('touchstart', dragStart);
  222. document.addEventListener('touchmove', drag);
  223. document.addEventListener('touchend', dragEnd);
  224. }
  225.  
  226. function initializeMenu() {
  227. const menuToggle = document.getElementById('menu-toggle');
  228. const menuContent = document.getElementById('menu-content');
  229. const editButton = document.getElementById('edit-button');
  230.  
  231. menuToggle.addEventListener('click', (e) => {
  232. e.stopPropagation();
  233. menuContent.classList.toggle('show');
  234. });
  235.  
  236. editButton.addEventListener('click', () => {
  237. handleEditClick();
  238. });
  239.  
  240. document.addEventListener('click', (e) => {
  241. if (!menuContent.contains(e.target) && e.target !== menuToggle) {
  242. menuContent.classList.remove('show');
  243. }
  244. });
  245. }
  246.  
  247. function handleEditClick() {
  248. const pageType = getCurrentPageType();
  249. const id = getIdFromUrl();
  250. const shopId = '2351';
  251.  
  252. if (pageType === 'article' && id) {
  253. window.location.href = `https://store.91app.com/InfoModule/ArticleEdit?shopId=${shopId}&id=${id}`;
  254. } else if (pageType === 'product' && id) {
  255. window.location.href = `https://store.91app.com/SalePage/Edit?type=edit&shopId=${shopId}&salepageId=${id}`;
  256. }
  257. }
  258.  
  259. function initializeButtons() {
  260. document.getElementById('goto-article-list').addEventListener('click', () => {
  261. window.location.href = 'https://store.91app.com/InfoModule/List?shopId=2351';
  262. });
  263.  
  264. document.getElementById('goto-channel-list').addEventListener('click', () => {
  265. window.location.href = 'https://store.91app.com/ShopCategory/List?shopId=2351';
  266. });
  267. }
  268.  
  269. function init() {
  270. createAdminMenu();
  271. initializeDrag();
  272. initializeMenu();
  273. initializeButtons();
  274. }
  275.  
  276. if (document.readyState === 'loading') {
  277. document.addEventListener('DOMContentLoaded', init);
  278. } else {
  279. init();
  280. }
  281.  
  282. })();

QingJ © 2025

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