mobile-menu-icon-color-demo.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1" />
  6. <title>主页菜单图标 · 配色挑选</title>
  7. <style>
  8. :root {
  9. --ink: #1f2a26;
  10. --muted: #6b7b74;
  11. --line: #e2e8e5;
  12. --page: #f5f8f7;
  13. --brand: #16a34a;
  14. }
  15. * { box-sizing: border-box; }
  16. body {
  17. margin: 0;
  18. font-family: "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", system-ui, sans-serif;
  19. color: var(--ink);
  20. background:
  21. radial-gradient(900px 480px at 0% -10%, #dcfce7 0%, transparent 50%),
  22. radial-gradient(800px 420px at 100% 0%, #e0e7ff 0%, transparent 45%),
  23. var(--page);
  24. line-height: 1.45;
  25. }
  26. .wrap { max-width: 1100px; margin: 0 auto; padding: 24px 18px 100px; }
  27. h1 { margin: 0 0 8px; font-size: 24px; letter-spacing: -0.02em; }
  28. .sub { margin: 0; color: var(--muted); font-size: 14px; max-width: 720px; }
  29. .note {
  30. margin: 14px 0 0;
  31. padding: 10px 12px;
  32. border-radius: 10px;
  33. background: #fff;
  34. border: 1px solid var(--line);
  35. font-size: 13px;
  36. color: var(--muted);
  37. }
  38. .note code {
  39. font-family: ui-monospace, Menlo, monospace;
  40. font-size: 12px;
  41. background: #f1f5f4;
  42. padding: 1px 6px;
  43. border-radius: 4px;
  44. color: var(--ink);
  45. }
  46. .phone {
  47. margin: 20px 0 8px;
  48. max-width: 390px;
  49. background: #fff;
  50. border: 1px solid var(--line);
  51. border-radius: 22px;
  52. overflow: hidden;
  53. box-shadow: 0 16px 40px rgba(20,40,30,.08);
  54. }
  55. .phone-hd {
  56. padding: 18px 16px 14px;
  57. background: linear-gradient(155deg, #14532d 0%, #16a34a 48%, #22c55e 100%);
  58. color: #fff;
  59. }
  60. .phone-hd .brand { font-size: 12px; opacity: .85; }
  61. .phone-hd .hello { font-size: 18px; font-weight: 650; margin-top: 6px; }
  62. .phone-body { padding: 14px; background: #f5f8f7; }
  63. .panel {
  64. background: #fff;
  65. border-radius: 14px;
  66. border: 1px solid var(--line);
  67. padding: 12px;
  68. }
  69. .panel-hd {
  70. display: flex; justify-content: space-between; align-items: baseline;
  71. margin-bottom: 12px;
  72. }
  73. .panel-title { font-size: 14px; font-weight: 650; }
  74. .hint { font-size: 12px; color: var(--muted); }
  75. .menu-grid {
  76. display: grid;
  77. grid-template-columns: repeat(4, 1fr);
  78. gap: 10px 6px;
  79. }
  80. .menu-card {
  81. display: flex; flex-direction: column; align-items: center; gap: 8px;
  82. padding: 8px 4px;
  83. border-radius: 12px;
  84. }
  85. .menu-icon {
  86. width: 48px; height: 48px; border-radius: 14px;
  87. display: flex; align-items: center; justify-content: center;
  88. box-shadow: inset 0 0 0 1px rgba(0,0,0,.04);
  89. }
  90. .menu-icon svg { width: 26px; height: 26px; display: block; }
  91. .menu-title {
  92. font-size: 12px; text-align: center; color: var(--ink);
  93. max-width: 72px; line-height: 1.2;
  94. }
  95. .sec {
  96. margin: 28px 0 10px;
  97. font-size: 14px; color: var(--muted);
  98. display: flex; align-items: center; gap: 8px;
  99. }
  100. .sec::after { content: ""; flex: 1; height: 1px; background: var(--line); }
  101. .grid {
  102. display: grid;
  103. grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  104. gap: 12px;
  105. }
  106. .card {
  107. background: #fff;
  108. border: 1px solid var(--line);
  109. border-radius: 14px;
  110. padding: 14px 12px 12px;
  111. cursor: pointer;
  112. transition: .15s;
  113. text-align: center;
  114. }
  115. .card:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(0,0,0,.06); }
  116. .card.is-current { outline: 2px dashed #94a3b8; outline-offset: -2px; }
  117. .card.is-selected {
  118. border-color: var(--fg, #2563eb);
  119. box-shadow: 0 0 0 3px color-mix(in srgb, var(--fg) 25%, transparent);
  120. }
  121. .card .icon-box {
  122. width: 56px; height: 56px; border-radius: 16px;
  123. margin: 0 auto 10px;
  124. display: flex; align-items: center; justify-content: center;
  125. box-shadow: inset 0 0 0 1px rgba(0,0,0,.05);
  126. }
  127. .card .icon-box svg { width: 30px; height: 30px; }
  128. .card .name { font-size: 13px; font-weight: 650; margin: 0 0 4px; }
  129. .card .meta {
  130. font-size: 11px; color: var(--muted);
  131. font-family: ui-monospace, Menlo, monospace;
  132. line-height: 1.4;
  133. }
  134. .tag {
  135. display: inline-block; margin-top: 8px;
  136. font-size: 11px; padding: 2px 8px; border-radius: 999px;
  137. background: #f1f5f4; color: var(--muted);
  138. }
  139. .tag.rec { background: #eff6ff; color: #1d4ed8; }
  140. .tag.hot { background: #fff7ed; color: #c2410c; }
  141. .footer {
  142. position: sticky; bottom: 12px; margin-top: 22px;
  143. background: rgba(255,255,255,.94);
  144. border: 1px solid var(--line);
  145. border-radius: 14px;
  146. padding: 12px 14px;
  147. display: flex; flex-wrap: wrap; gap: 12px;
  148. align-items: center; justify-content: space-between;
  149. backdrop-filter: blur(10px);
  150. box-shadow: 0 10px 30px rgba(0,0,0,.08);
  151. }
  152. .picked { display: flex; align-items: center; gap: 10px; font-size: 13px; }
  153. .picked .sw {
  154. width: 44px; height: 44px; border-radius: 12px;
  155. display: flex; align-items: center; justify-content: center;
  156. box-shadow: inset 0 0 0 1px rgba(0,0,0,.06);
  157. }
  158. .picked .sw svg { width: 24px; height: 24px; }
  159. .picked strong { display: block; font-size: 14px; }
  160. .picked span { color: var(--muted); font-size: 12px; font-family: ui-monospace, Menlo, monospace; }
  161. .actions { display: flex; gap: 8px; flex-wrap: wrap; }
  162. .actions button {
  163. height: 36px; padding: 0 14px; border-radius: 8px;
  164. border: 1px solid var(--line); background: #fff;
  165. font: inherit; font-size: 13px; cursor: pointer;
  166. }
  167. .actions button.primary {
  168. background: var(--brand); border-color: transparent; color: #fff; font-weight: 600;
  169. }
  170. .toast {
  171. position: fixed; left: 50%; bottom: 88px; transform: translateX(-50%) translateY(10px);
  172. background: #1f2a26; color: #fff; padding: 8px 14px; border-radius: 999px;
  173. font-size: 13px; opacity: 0; transition: .2s; pointer-events: none; z-index: 20;
  174. }
  175. .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
  176. </style>
  177. </head>
  178. <body>
  179. <!-- 印章/发起审批图标:用 currentColor 便于换色 -->
  180. <svg xmlns="http://www.w3.org/2000/svg" style="display:none">
  181. <symbol id="icon-approve" viewBox="0 0 1024 1024">
  182. <path fill="currentColor" d="M645.51 854.33c15.49-57.33 86.49-42 86.49-42s-43.54-44.53-23-112.67c11.22-37.2 39.58-67.99 79.81-76.43 20.41-4.28 56.37-4.23 69.42 0.55 3.66-18.04 7.33-36.14 10.85-54.39l23.84-117.26c7.41-37.35 14.81-74.7 22.78-112.05 6.27-32.55 13.19-65.1 19.53-97.81 4.72-24.74 10.09-49.48 14.81-74.71 2.6-14.16 5.86-28.31 8.46-42.07 0.61-2.04 0.96-4.14 1.06-6.26-1.06-24.66-1.06-41.01-16.93-48.83-16.43-7.89-32.38-7.89-40.85 0-21.65 10.98-43.45 21.48-65.1 32.55-54.04 26.85-107.41 53.7-161.45 80.48L468.71 285.97c-59.16 29.46-118.4 60.46-178.21 88.78-45.57 21.56-90 45.81-135.08 67.38-19.53 9.44-40.2 15.79-59.73 25.71-15.79 7.97-31.25 20.02-31.25 39.55 0 8.87 1.63 21.48 8.95 27.83 2.68 2.03 5.94 3.58 8.46 5.69 40.28 22.14 78.44 48.42 117.58 72.67l76.17 47.2h0.57c16.44 7.98 32.31 7.98 48.74-7.81l0.49-0.57c0.49-0.57 0.98-0.57 0.98-1.05 0.65-0.49 1.71-1.06 2.2-2.04 1.14-1.14 2.11-1.63 3.25-2.68 0.98-1.06 2.61-2.04 3.66-3.17 1.63-1.55 3.17-2.61 4.23-4.15 1.62-1.73 3.39-3.31 5.29-4.72 2.11-1.63 3.66-3.66 5.77-5.29 2.2-2.11 4.31-3.66 6.35-5.7 2.11-2.19 4.8-4.23 6.91-6.43 2.68-2.03 4.8-4.72 7.49-6.83 2.61-2.61 5.21-4.72 7.81-7.32 2.77-2.61 5.86-5.29 8.46-7.89 3.25-2.61 5.86-5.21 9.03-7.89 3.25-2.61 6.35-5.86 9.52-8.38 3.25-3.26 6.43-5.86 10.09-8.95 3.17-3.17 6.91-6.35 10.09-8.95 3.67-3.17 6.84-6.34 10.58-9.44 3.76-3.08 7.3-6.43 10.58-10.01 3.66-3.17 7.32-6.92 11.15-10.09 3.66-3.1 7.33-6.76 11.07-9.93 3.66-3.66 7.97-6.83 11.64-10.5 3.74-3.66 7.98-6.84 11.72-10.58 3.66-3.66 7.81-6.83 11.64-10.41 4.07-3.74 7.89-7.32 12.13-10.58 4.23-3.67 7.97-7.33 12.21-10.58 4.15-3.58 7.89-7.32 12.21-10.98 4.15-3.66 7.89-7.32 12.12-10.98 4.15-3.74 7.98-7.4 12.13-10.58 3.74-3.58 7.65-7.08 11.72-10.41 3.66-3.74 7.89-6.83 11.64-10.58 3.66-3.67 7.89-6.84 11.64-10.5 3.66-3.74 7.32-6.83 11.64-10.58 3.66-3.09 7.32-6.75 11.15-9.93 3.66-3.25 7.32-6.83 11.07-10.01 3.67-3.01 7.25-6.19 10.58-9.44 3.74-3.17 6.83-6.35 10.58-9.52 3.25-3.1 6.83-6.27 10.09-8.95 3.25-3.17 6.34-5.7 9.52-8.87 3.17-2.68 6.35-5.78 9.52-8.46 3.25-2.6 5.86-5.21 8.95-7.89 2.68-2.6 5.86-5.21 8.54-7.89 2.6-2.6 5.21-4.72 7.89-7.32 2.64-2.11 5.14-4.39 7.49-6.83 2.03-2.12 4.72-4.23 6.83-6.35 2.11-2.11 4.23-3.66 6.34-5.69 2.12-1.63 3.66-3.26 5.86-5.29l4.72-4.72c1.62-1.14 2.6-2.68 4.23-3.74 1.05-0.98 2.19-2.11 3.66-3.09 1.13-1.14 2.19-1.63 2.68-2.69l3.17-3.09h0.57c2.68 0.98 5.29 2.53 7.89 3.58 1.63 0.65 2.69 1.63 4.23 2.2 0.57 0.49 1.14 0.49 2.12 0.98 0.56 0 2.11 0.57 2.11 1.14v0.49c-0.57 0.49-1.06 0.49-1.06 0.98l-1.62 1.63-6.84 6.83a76.647 76.647 0 0 0-8.95 10.01c-2.12 2.12-4.31 4.72-6.35 6.84a22.64 22.64 0 0 0-3.25 3.66l-1.55 1.62c-0.57 0.49-1.05 1.47-1.62 1.47-9.44 10.09-19.04 20.59-28.48 30.59l-74.7 78.94c-28.56 29.86-56.64 59.89-85.28 89.83-26.93 28.4-53.95 56.8-80.4 85.2-20.67 21.56-40.69 43.13-61.36 64.69-8.95 9.44-18.06 18.88-27.02 28.88l-0.57 0.57c-7.89 7.81-7.89 16.28-7.89 24.17v177.81c0 16.28 7.89 31.98 24.33 40.36 16.36 7.97 32.31 0 40.69-7.89l62.98-62.5c10.66-10.58 20.75-21.07 30.76-31.57 1.13-1.06 2.11-2.11 3.25-2.11 1.46-0.57 3.58 0.57 4.72 1.62 22.7 14.9 97.27 71.69 97.27 71.69s3.59-31.79 6.31-41.84z"/>
  183. <path fill="currentColor" d="M699.65 908.97H948.6c7.12 0 13.06-7.66 11.87-15.33l-4.75-28.07c-2.37-11.5-11.87-20.41-22.52-20.41h-76.72l-4.75-31.9c26.08-11.5 43.89-38.29 43.89-70.19 0-42.12-32.02-76.58-71.16-76.58-39.14 0-71.2 34.42-71.2 76.55 0 31.9 17.78 58.7 43.89 70.19l-3.56 31.9h-77.33c-10.68 0-21.34 8.94-22.52 20.41L689 893.61c-2.4 7.69 3.53 15.36 10.65 15.36z m248.89 19.12M944.08 960.22h-239.4c-9.34 0-16.92-7.58-16.92-16.92v-0.91c0-9.34 7.58-16.92 16.92-16.92h239.4c9.34 0 16.92 7.58 16.92 16.92v0.91c0 9.35-7.57 16.92-16.92 16.92z"/>
  184. </symbol>
  185. </svg>
  186. <div class="wrap">
  187. <h1>主页菜单图标 · 配色挑选</h1>
  188. <p class="sub">
  189. 针对「发起审批」图标底色 + 图形色。未来多个入口应各自配色,避免整屏同一种绿。
  190. 点选下方色卡,顶部手机预览会同步;底部可复制 <code>iconBg / iconFg</code>。
  191. </p>
  192. <p class="note">
  193. 当前实现:底色靠 CSS <code>.tone-approve</code>(浅绿),SVG 内写死 <code>fill="#16a34a"</code>。
  194. 目标:菜单项可配置 <code>iconBg</code> + <code>iconFg</code>(或复用已有 OA 色对)。
  195. </p>
  196. <div class="phone">
  197. <div class="phone-hd">
  198. <div class="brand">中科兴皖 · 移动工作台</div>
  199. <div class="hello">您好,示例用户</div>
  200. </div>
  201. <div class="phone-body">
  202. <div class="panel">
  203. <div class="panel-hd">
  204. <span class="panel-title">功能菜单</span>
  205. <span class="hint">配色预览</span>
  206. </div>
  207. <div class="menu-grid" id="liveGrid"></div>
  208. </div>
  209. </div>
  210. </div>
  211. <div class="sec">当前(对照)</div>
  212. <div class="grid" id="g-current"></div>
  213. <div class="sec">OA 审批色对(与发起页 ep 图标一致,推荐复用)</div>
  214. <div class="grid" id="g-oa"></div>
  215. <div class="sec">扩展色对(非绿,适合多入口区分)</div>
  216. <div class="grid" id="g-extra"></div>
  217. <div class="footer">
  218. <div class="picked">
  219. <div class="sw" id="pickedSw"></div>
  220. <div>
  221. <strong id="pickedName">未选择</strong>
  222. <span id="pickedHex">点击色卡挑选</span>
  223. </div>
  224. </div>
  225. <div class="actions">
  226. <button type="button" id="copyPair">复制 bg, fg</button>
  227. <button type="button" class="primary" id="copyJson">复制菜单字段 JSON</button>
  228. </div>
  229. </div>
  230. </div>
  231. <div class="toast" id="toast">已复制</div>
  232. <script>
  233. const ICON = `<svg viewBox="0 0 1024 1024" aria-hidden="true"><use href="#icon-approve"/></svg>`;
  234. /** 与 mobile-h5/utils/oa-app-icons.js 对齐 */
  235. const OA_PAIRS = [
  236. { id: 'oa-0', name: '翠绿', bg: '#d1fae5', fg: '#059669', tag: 'OA', tagClass: '' },
  237. { id: 'oa-1', name: '青蓝', bg: '#cffafe', fg: '#0891b2', tag: 'OA · 推荐', tagClass: 'rec' },
  238. { id: 'oa-2', name: '天蓝', bg: '#dbeafe', fg: '#2563eb', tag: 'OA · 推荐', tagClass: 'rec' },
  239. { id: 'oa-3', name: '靛蓝', bg: '#e0e7ff', fg: '#4f46e5', tag: 'OA', tagClass: '' },
  240. { id: 'oa-4', name: '紫罗兰', bg: '#ede9fe', fg: '#7c3aed', tag: 'OA', tagClass: '' },
  241. { id: 'oa-5', name: '玫粉', bg: '#fce7f3', fg: '#db2777', tag: 'OA', tagClass: '' },
  242. { id: 'oa-6', name: '橙', bg: '#ffedd5', fg: '#ea580c', tag: 'OA · 推荐', tagClass: 'rec' },
  243. { id: 'oa-7', name: '琥珀', bg: '#fef3c7', fg: '#d97706', tag: 'OA', tagClass: '' }
  244. ];
  245. const CURRENT = [
  246. {
  247. id: 'current',
  248. name: '当前 tone-approve',
  249. bg: '#c8f5de',
  250. fg: '#16a34a',
  251. tag: '当前',
  252. tagClass: 'hot',
  253. current: true
  254. }
  255. ];
  256. const EXTRA = [
  257. { id: 'ex-slate', name: '石板灰', bg: '#eef2f1', fg: '#3d524a', tag: '克制', tagClass: '' },
  258. { id: 'ex-sky', name: '晴空蓝', bg: '#e0f2fe', fg: '#0284c7', tag: '清爽', tagClass: 'rec' },
  259. { id: 'ex-royal', name: '宝蓝', bg: '#dbeafe', fg: '#1d4ed8', tag: '正式', tagClass: 'rec' },
  260. { id: 'ex-indigo', name: '深靛', bg: '#e0e7ff', fg: '#3730a3', tag: '稳重', tagClass: '' },
  261. { id: 'ex-violet', name: '葡萄紫', bg: '#f3e8ff', fg: '#7e22ce', tag: '个性', tagClass: '' },
  262. { id: 'ex-rose', name: '玫瑰红', bg: '#ffe4e6', fg: '#e11d48', tag: '醒目', tagClass: '' },
  263. { id: 'ex-coral', name: '珊瑚', bg: '#ffedd5', fg: '#c2410c', tag: '温暖', tagClass: '' },
  264. { id: 'ex-amber', name: '大麦黄邻', bg: '#fff7e8', fg: '#a67b20', tag: '已有 tone', tagClass: '' },
  265. { id: 'ex-teal', name: '孔雀石', bg: '#ccfbf1', fg: '#0f766e', tag: '青绿', tagClass: '' },
  266. { id: 'ex-lime', name: '青柠', bg: '#ecfccb', fg: '#4d7c0f', tag: '活力', tagClass: '' },
  267. { id: 'ex-brown', name: '咖啡', bg: '#f5e6d3', fg: '#92400e', tag: '沉稳', tagClass: '' },
  268. { id: 'ex-ink', name: '墨蓝', bg: '#e2e8f0', fg: '#334155', tag: '极简', tagClass: '' }
  269. ];
  270. /** 预览宫格:第 1 个跟随选中的「发起审批」配色,其余用固定多色演示可定制 */
  271. const PREVIEW_OTHERS = [
  272. { title: '待办', bg: '#dbeafe', fg: '#2563eb', glyph: '☰' },
  273. { title: '已办', bg: '#ffedd5', fg: '#ea580c', glyph: '▤' },
  274. { title: '抄送', bg: '#ede9fe', fg: '#7c3aed', glyph: '↗' },
  275. { title: '统计', bg: '#fef3c7', fg: '#d97706', glyph: '¥' },
  276. { title: '通讯录', bg: '#fce7f3', fg: '#db2777', glyph: '☺' },
  277. { title: '设置', bg: '#eef2f1', fg: '#3d524a', glyph: '⚙' },
  278. { title: '更多', bg: '#cffafe', fg: '#0891b2', glyph: '▦' }
  279. ];
  280. let selected = CURRENT[0];
  281. function toast(msg) {
  282. const el = document.getElementById('toast');
  283. el.textContent = msg;
  284. el.classList.add('show');
  285. clearTimeout(toast._t);
  286. toast._t = setTimeout(() => el.classList.remove('show'), 1400);
  287. }
  288. async function copyText(t) {
  289. try {
  290. await navigator.clipboard.writeText(t);
  291. } catch {
  292. const ta = document.createElement('textarea');
  293. ta.value = t;
  294. document.body.appendChild(ta);
  295. ta.select();
  296. document.execCommand('copy');
  297. ta.remove();
  298. }
  299. toast('已复制');
  300. }
  301. function renderCard(p, host) {
  302. const el = document.createElement('article');
  303. el.className = 'card' + (p.current ? ' is-current' : '') + (selected?.id === p.id ? ' is-selected' : '');
  304. el.style.setProperty('--fg', p.fg);
  305. el.innerHTML = `
  306. <div class="icon-box" style="background:${p.bg};color:${p.fg}">${ICON}</div>
  307. <div class="name">${p.name}</div>
  308. <div class="meta">${p.bg}<br/>${p.fg}</div>
  309. <span class="tag ${p.tagClass || ''}">${p.tag || ''}</span>
  310. `;
  311. el.addEventListener('click', () => {
  312. selected = p;
  313. sync();
  314. });
  315. host.appendChild(el);
  316. }
  317. function renderLiveGrid() {
  318. const grid = document.getElementById('liveGrid');
  319. const first = `
  320. <div class="menu-card">
  321. <div class="menu-icon" style="background:${selected.bg};color:${selected.fg}">${ICON}</div>
  322. <div class="menu-title">发起审批</div>
  323. </div>`;
  324. const rest = PREVIEW_OTHERS.map(
  325. (o) => `
  326. <div class="menu-card">
  327. <div class="menu-icon" style="background:${o.bg};color:${o.fg}">
  328. <span style="font-size:20px;line-height:1;color:${o.fg}">${o.glyph}</span>
  329. </div>
  330. <div class="menu-title">${o.title}</div>
  331. </div>`
  332. ).join('');
  333. grid.innerHTML = first + rest;
  334. }
  335. function syncFooter() {
  336. const sw = document.getElementById('pickedSw');
  337. sw.style.background = selected.bg;
  338. sw.style.color = selected.fg;
  339. sw.innerHTML = ICON;
  340. document.getElementById('pickedName').textContent = selected.name;
  341. document.getElementById('pickedHex').textContent = `${selected.bg} / ${selected.fg}`;
  342. }
  343. function sync() {
  344. document.getElementById('g-current').innerHTML = '';
  345. document.getElementById('g-oa').innerHTML = '';
  346. document.getElementById('g-extra').innerHTML = '';
  347. CURRENT.forEach((p) => renderCard(p, document.getElementById('g-current')));
  348. OA_PAIRS.forEach((p) => renderCard(p, document.getElementById('g-oa')));
  349. EXTRA.forEach((p) => renderCard(p, document.getElementById('g-extra')));
  350. renderLiveGrid();
  351. syncFooter();
  352. }
  353. document.getElementById('copyPair').addEventListener('click', () => {
  354. copyText(`${selected.bg}, ${selected.fg}`);
  355. });
  356. document.getElementById('copyJson').addEventListener('click', () => {
  357. const json = JSON.stringify(
  358. {
  359. title: '发起审批',
  360. icon: 'approve',
  361. iconBg: selected.bg,
  362. iconFg: selected.fg
  363. },
  364. null,
  365. 2
  366. );
  367. copyText(json);
  368. });
  369. // 默认推荐:天蓝(正式、非绿)
  370. selected = OA_PAIRS[2];
  371. sync();
  372. </script>
  373. </body>
  374. </html>