lcap_tools

提供一些网页小工具,低代码开发专用

目前为 2024-08-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name lcap_tools
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2.2
  5. // @description 提供一些网页小工具,低代码开发专用
  6. // @author yuan longhui
  7. // @match *://*/*lcap*
  8. // @match *://*/*frontendcli*
  9. // @match *://*/*frontendrenderdemo*
  10. // @match *://*/*uac*
  11. // @match *://*/*ucs*
  12. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAbCAYAAACJISRoAAAABHNCSVQICAgIfAhkiAAAAQtJREFUSInt1c1Kw0AUhuFTF8kFTJnAFFwKYrHQUjE0Fq2iOxG8Bn/vQ8SbEMX+oLhQ9+raXom9g0lI8roQBDdmFi0q5FsOfOdZDIdTAZAZZ27WQImUyC8ju3v7Ug1q0tva+fZ+dn4h1aAmYacreZ7/PISCPL+8orRBacPbeAyAtZaFxTpKG27v7otGUIgAbGxuo7Th4OgEgMFwhNKGVjskTdPpIA+PTyhtCMw875MJ671PtD8YudTdkCzLWFmNUNpweHyK0oZGs02SJNNDAG76w6+/UdpweXXtWnVH4jim3mihtGFpuYm11hlx3hPP86S7FomISNQJxfd91+ofWcZ/g1SgPL8lUiIF+QCIeCJE+P0wYgAAAABJRU5ErkJggg==
  13. // @grant GM_cookie
  14. // @grant GM_addStyle
  15. // @grant GM_setValue
  16. // @grant GM_getValue
  17. // @grant GM_deleteValue
  18. // @grant GM_listValues
  19. // ==/UserScript==
  20.  
  21. (function () {
  22. 'use strict';
  23. GM_addStyle(
  24. `.y-panel {
  25. width: 150px;
  26. display: flex;
  27. flex-direction: column;
  28. position: fixed;
  29. top: 32px;
  30. right: -150px;
  31. background-color: #a1d4e2;
  32. border-radius: 3px;
  33. transition: all 0.3s;
  34. cursor: pointer;
  35. z-index: 9999999999;
  36. }
  37. .y-panel:before {
  38. width: 40px;
  39. height: 40px;
  40. position: absolute;
  41. top: calc(50% - 24px);
  42. left: -20px;
  43. background-color: #a1d4e2;
  44. border-radius: 40px 0px 0px 40px;
  45. border: 1px solid #5ac6aa;
  46. border-right: none;
  47. content: \"\";
  48. opacity: 0.8;
  49. cursor: pointer;
  50. z-index: 9999999999;
  51. }
  52. .y-panel:hover {
  53. right: 0;
  54. }
  55. .y-panel > .y-panel-btn {
  56. position: relative;
  57. border: 1px solid #fff;
  58. border-radius: 3px;
  59. cursor: pointer;
  60. font-size: 12px;
  61. font-weight: bold;
  62. margin: 4px 5px;
  63. padding: 2px 5px;
  64. text-align: center;
  65. user-select: none;
  66. background-color: #f0f0f0;
  67. z-index: 9999999999;
  68. }
  69. .y-panel-btn:hover {
  70. box-shadow: 0 0 5px rgba(0, 0, 0, 0.8);
  71. }
  72. .y-panel-input {
  73. height: 24px;
  74. margin: 5px 4px;
  75. border-radius: 3px;
  76. }
  77. .y-panel ::-webkit-input-placeholder {
  78. color: rgba(0, 0, 0, 0.5);
  79. padding-left: 5px;
  80. font-size: 12px;
  81. }
  82. .y-panel-btn_delete {
  83. padding: 0px 3px;
  84. color: #000;
  85. font-size: 10px;
  86. position: absolute;
  87. right: 3px;
  88. top: 1px;
  89. background-color: #88befc;
  90. }
  91. .y-panel-btn_delete:hover {
  92. color: #fff;
  93. background-color: #F3629C;
  94. }`
  95. );
  96.  
  97. /**
  98. * type BUTTON_TYPE = {
  99. * text: string
  100. * onclick: () => void
  101. * type?: 'function' | 'normal'
  102. * password?: string
  103. * isStored?: boolean
  104. * }
  105. */
  106.  
  107. // 可以在这里配置常用工号,例如:
  108. const name_map = ['袁龙辉10331290', '孟香君00268638', '郭绍云10286708']
  109. //const name_map = []
  110. // 本地存储的工号
  111. const stored_name_map = GM_listValues().map(item => GM_getValue(item))
  112.  
  113. function register(btns) {
  114. const yPanel = document.querySelector('.y-panel')
  115. if (yPanel) {
  116. yPanel.parentNode.removeChild(yPanel)
  117. }
  118. const container = document.createElement("div");
  119. container.className = "y-panel";
  120. container.setAttribute('draggable', 'true');
  121. container.addEventListener('dragstart', (event) => {
  122. event.dataTransfer.setData('text/plain', null); // 必须设置以启用拖动
  123. });
  124. container.addEventListener('dragend', (event) => {
  125. container.style.top = `${event.clientY}px`;
  126. });
  127. document.body.appendChild(container);
  128. // 生成基本功能的按钮
  129. generateBasicBtn(btns, container)
  130. // 添加跳转按钮
  131. addJumpBtn(container)
  132. // 添加创建员工信息输入框
  133. generateEmpInfoInput(container)
  134. };
  135.  
  136. // 功能1 点击按钮清空cookie并刷新页面
  137. function func_clearCookies() {
  138. const cookies = document.cookie.split(';').map(cookie => cookie.trim().split('=')[0]);
  139. cookies.forEach(item => {
  140. GM_cookie.delete({ name: item });
  141. })
  142. location.reload();
  143. }
  144.  
  145. // 功能2 切换cookie的语言
  146. function func_changeLang() {
  147. const currentUrl = new URL(window.location.href)
  148. const params = currentUrl.searchParams
  149. if (params.get('lang')) {
  150. params.set('lang', params.get('lang') === 'zh' ? 'en' : 'zh')
  151. window.history.replaceState({}, '', currentUrl)
  152. }
  153. const cookies = document.cookie.split(';').map(cookie => cookie.trim());
  154. cookies.forEach(cookie => {
  155. const [name, value] = cookie.trim().split('=')
  156. if (name.includes('Language')) {
  157. GM_cookie.delete({ name });
  158. GM.cookie.set({
  159. name,
  160. value: value === 'zh_CN' ? 'en_US' : 'zh_CN'
  161. })
  162. }
  163. })
  164. location.reload();
  165. }
  166.  
  167. // 功能3 登录
  168. function func_login(empInfo, password = '1') {
  169. const empNo = empInfo.match(/\d+/)[0] // 取出工号
  170. const empNoInput = document.getElementById('input-loginname')
  171. if (!empNoInput) return
  172. const passwordInput = document.getElementById('input-password')
  173. const login_btn = document.getElementsByClassName("el-button login-btn el-button--primary")[0]
  174. var event = new Event('input', {
  175. bubbles: true,
  176. cancelable: true,
  177. });
  178. empNoInput.value = empNo
  179. empNoInput.dispatchEvent(event);
  180. passwordInput.value = password
  181. passwordInput.dispatchEvent(event);
  182. login_btn.click()
  183. }
  184.  
  185. // 在name新增删除后刷新面板
  186. function util_refreshPanel() {
  187. const current_stored_name_map = GM_listValues().map(item => GM_getValue(item))
  188. const current_btn_map = getBasicBtnMap(current_stored_name_map)
  189. register(current_btn_map)
  190. }
  191.  
  192. // 添加跳转按钮
  193. function addJumpBtn(container) {
  194. // 主机名、端口号、路径、查询参数、hash
  195. const { hostname, port, pathname, searchParams, hash } = new URL(window.location.href);
  196. // 获取url中#之后的内容
  197. const hashParts = hash.slice(2).split('/')
  198. // 获取url中的app、bizObject、page
  199. const hashObject = {
  200. app: hashParts.indexOf('app') !== -1 ? hashParts[hashParts.indexOf('app') + 1] : null,
  201. bizObject: hashParts.indexOf('bizObject') !== -1 ? hashParts[hashParts.indexOf('bizObject') + 1] : null,
  202. page: hashParts.indexOf('page') !== -1 ? hashParts[hashParts.indexOf('page') + 1] : null
  203. }
  204. const host = port ? `${hostname}:${port}` : hostname
  205. // 微服务信息 如:zte-paas-lcap-frontendcli
  206. const microServiceInfo = pathname.slice(1).split('/')[0]
  207. // 设计态的微服务路径
  208. const design_path = microServiceInfo.includes('frontendrenderdemo')
  209. ? microServiceInfo.replace('frontendrenderdemo', 'frontendcli')
  210. : microServiceInfo
  211. // 布局、实体、应用主页url
  212. const layoutUrl = `https://${host}/${design_path}/layout-designer.html?lang=zh`
  213. const entityUrl = `https://${host}/${design_path}/entity-designer.html?lang=zh`
  214. const mainPageUrl = `https://${host}/${design_path}/index.html#/platform/applicationdevelopment`
  215. // 当前为布局设计器的运行态
  216. if (searchParams.get('bizObject') && searchParams.get('bizObject') !== 'null') {
  217. generateJumpBtn([
  218. {
  219. text: 'to->当前布局',
  220. title: '适用于表单页,列表页跳转之后需要切换一下布局',
  221. toUrl: `${layoutUrl}${hash}/bizObject/${searchParams.get('bizObject')}`
  222. },
  223. {
  224. text: 'to->当前实体',
  225. toUrl: `${entityUrl}#/app/${hashObject.app}/bizObject/${searchParams.get('bizObject')}`
  226. }
  227. ], container)
  228. }
  229. // 当前为自定义页面的运行态
  230. else if (searchParams.get('bizObject') === 'null') {
  231. generateJumpBtn([
  232. {
  233. text: 'to->当前页面设计',
  234. toUrl: `${layoutUrl}#/app/${hashObject.app}/page/${hashObject.page}`
  235. }
  236. ], container)
  237. }
  238. // 当前为布局设计器的设计态
  239. else if (pathname.includes(`${design_path}/layout-designer.html`) && hashObject.bizObject) {
  240. generateJumpBtn([
  241. {
  242. text: 'to->当前实体',
  243. toUrl: `${entityUrl}#/app/${hashObject.app}/bizObject/${hashObject.bizObject}`
  244. }
  245. ], container)
  246. }
  247. // 当前为设计器的设计态或者运行态
  248. if (hashObject.app) {
  249. generateJumpBtn([
  250. { text: 'to->应用主页', toUrl: `${mainPageUrl}/${hashObject.app}` }
  251. ], container)
  252. }
  253. // 当前不是本地环境,需要跳转本地环境调试
  254. if (hostname !== 'local.zte.com.cn'
  255. && (pathname.includes('zte-paas-lcap-frontendcli')
  256. || pathname.includes('zte-paas-lcap-frontendrenderdemo')
  257. || pathname.includes('zte-paas-lcap-promgr')
  258. || pathname.includes('zte-paas-lcap-promc'))) {
  259. let url = new URL(window.location.href)
  260. url.host = 'local.zte.com.cn';
  261. if (pathname.includes('zte-paas-lcap-frontendcli')) {
  262. url.host += ':8080';
  263. } else if (pathname.includes('zte-paas-lcap-frontendrenderdemo')) {
  264. url.host += ':8081';
  265. } else if (pathname.includes('zte-paas-lcap-promgr')) {
  266. url.host += ':8086';
  267. } else if (pathname.includes('zte-paas-lcap-promc')) {
  268. url.host += ':8082';
  269. }
  270. generateJumpBtn([
  271. { text: '切换到本地调试', toUrl: url.toString() }
  272. ], container)
  273. }
  274. }
  275.  
  276. // 创建基本的按钮(登录账号按钮等)
  277. function generateBasicBtn(btns, container) {
  278. btns.forEach(btn => {
  279. const button = document.createElement("button");
  280. button.textContent = btn.text;
  281. button.className = "y-panel-btn";
  282. button.onclick = btn.onclick;
  283. container.appendChild(button);
  284. if (btn.isStored) {
  285. const delete_btn = document.createElement("button");
  286. delete_btn.textContent = 'x';
  287. delete_btn.className = 'y-panel-btn_delete';
  288. delete_btn.onclick = (e) => {
  289. e.stopPropagation()
  290. GM_deleteValue(btn.text)
  291. util_refreshPanel()
  292. };
  293. button.appendChild(delete_btn);
  294. }
  295. if (btn.password) {
  296. button.title = btn?.password
  297. }
  298. button.style.backgroundColor = btn.type === 'function' && '#5ac6aa'
  299. });
  300. }
  301.  
  302. // 创建额外的按钮(跳转按钮等)
  303. function generateJumpBtn(btns, container) {
  304. btns.forEach(btn => {
  305. const button = document.createElement("button");
  306. button.textContent = btn.text;
  307. button.className = "y-panel-btn";
  308. button.style.backgroundColor = '#5ac6aa'
  309. button.onclick = () => {
  310. if (btn.toUrl) {
  311. // 不能使用window.open,低代码项目的代码里有判断是否是通过这个api打开的页面的判断逻辑,会导致接口报错(-_-)
  312. const a = document.createElement('a');
  313. a.href = btn.toUrl;
  314. a.target = '_blank';
  315. document.body.appendChild(a);
  316. a.click();
  317. document.body.removeChild(a);
  318. }
  319. };
  320. if (btn.title) {
  321. button.title = btn.title
  322. }
  323. container.appendChild(button);
  324. })
  325. }
  326.  
  327. // 创建员工信息输入框
  328. function generateEmpInfoInput(container) {
  329. const empInfo_input = document.createElement("input");
  330. empInfo_input.className = 'y-panel-input'
  331. empInfo_input.placeholder = '输入姓名+工号, 回车~'
  332. container.appendChild(empInfo_input);
  333. empInfo_input.addEventListener('keydown', (event) => {
  334. if (event.key === 'Enter') {
  335. // TODO 校验格式
  336. GM_setValue(empInfo_input.value, empInfo_input.value)
  337. func_login(empInfo_input.value)
  338. util_refreshPanel()
  339. }
  340. });
  341. }
  342.  
  343. // 构建基础按钮列表(基础功能+姓名)
  344. function getBasicBtnMap(stored_name_map) {
  345. return [
  346. {
  347. text: '清空Cookie并刷新',
  348. type: 'function',
  349. onclick: () => func_clearCookies()
  350. },
  351. {
  352. text: '切换cookie的语言',
  353. type: 'function',
  354. onclick: () => func_changeLang()
  355. },
  356. // 可以通过修改func_login的参数,添加自定义的工号和密码
  357. // {
  358. // text: '袁龙辉10331290',
  359. // password: '1',
  360. // onclick: () => func_login('袁龙辉10331290', '1')
  361. // },
  362. ...name_map.map(name => {
  363. return {
  364. text: name,
  365. password: '1',
  366. onclick: () => func_login(name)
  367. }
  368. }),
  369. ...stored_name_map.map(name => {
  370. return {
  371. text: name,
  372. isStored: true,
  373. password: '1',
  374. onclick: () => func_login(name)
  375. }
  376. })
  377. ]
  378. }
  379.  
  380. // 入口函数
  381. (function init() {
  382. const initial_btn_map = getBasicBtnMap(stored_name_map)
  383. register(initial_btn_map)
  384. })()
  385.  
  386. })();