@cc-monitoring/proxy-core 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/404.html +22 -0
- package/dist/docs/assets/app.BxFOH0P1.js +1 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.Cuu7C9vz.js +1 -0
- package/dist/docs/assets/chunks/VPLocalSearchBox.CYDhNgXW.js +9 -0
- package/dist/docs/assets/chunks/abnfDiagram-VRR7QNED.RG1C5NpS.js +1 -0
- package/dist/docs/assets/chunks/arc.C9NMazfV.js +1 -0
- package/dist/docs/assets/chunks/architectureDiagram-ZJ3FMSHR.u2IZtOa6.js +36 -0
- package/dist/docs/assets/chunks/blockDiagram-677ZJIJ3.DdHVir7t.js +132 -0
- package/dist/docs/assets/chunks/c4Diagram-LMCZKHZV.gSbgoaJo.js +10 -0
- package/dist/docs/assets/chunks/channel.Cc6zpfFP.js +1 -0
- package/dist/docs/assets/chunks/chunk-2Q5K7J3B.HRSdtksv.js +1 -0
- package/dist/docs/assets/chunks/chunk-32BRIVSS.BYzKapof.js +1 -0
- package/dist/docs/assets/chunks/chunk-5VM5RSS4.c3oeF0uS.js +15 -0
- package/dist/docs/assets/chunks/chunk-EX3LRPZG.Cz5AKl7t.js +231 -0
- package/dist/docs/assets/chunks/chunk-JWPE2WC7.DtJxsA7-.js +1 -0
- package/dist/docs/assets/chunks/chunk-MOJQB5TN.h5kO0Dtu.js +88 -0
- package/dist/docs/assets/chunks/chunk-RYQCIY6F.Ch_NfMTR.js +1 -0
- package/dist/docs/assets/chunks/chunk-V7JOEXUC.CHrHyPoW.js +206 -0
- package/dist/docs/assets/chunks/chunk-VR4S4FIN.DG8DIrH3.js +1 -0
- package/dist/docs/assets/chunks/chunk-XXDRQBXY.CSXBN12Y.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-OUVF2IWQ.DV5B4KLJ.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-EOCWNBFH.DV5B4KLJ.js +1 -0
- package/dist/docs/assets/chunks/cose-bilkent-JH36ORCC.BeFuOTgi.js +1 -0
- package/dist/docs/assets/chunks/cynefin-VYW2F7L2.DaXIfh7Y.js +178 -0
- package/dist/docs/assets/chunks/cynefinDiagram-TSTJHNR4.BrJcHEEe.js +62 -0
- package/dist/docs/assets/chunks/cytoscape.esm.CUqq0XTU.js +331 -0
- package/dist/docs/assets/chunks/dagre-VKFMJZFB.D4vaA23X.js +4 -0
- package/dist/docs/assets/chunks/defaultLocale.DX6XiGOO.js +1 -0
- package/dist/docs/assets/chunks/diagram-FQU43EPY.uwRFLKRx.js +3 -0
- package/dist/docs/assets/chunks/diagram-G47NLZAW.Byfc9d0H.js +24 -0
- package/dist/docs/assets/chunks/diagram-NH7WQ7WH.CxjBEGZX.js +24 -0
- package/dist/docs/assets/chunks/diagram-OA4YK3LP.CU1jGXMi.js +30 -0
- package/dist/docs/assets/chunks/diagram-WEI45ONY.yXgVkURA.js +41 -0
- package/dist/docs/assets/chunks/ebnfDiagram-CCIWWBDH.UucqGQ_d.js +1 -0
- package/dist/docs/assets/chunks/erDiagram-Q63AITRT.C6qmOrvh.js +85 -0
- package/dist/docs/assets/chunks/flowDiagram-23GEKE2U.BZLu-WUl.js +156 -0
- package/dist/docs/assets/chunks/framework.D_Xv2a7c.js +19 -0
- package/dist/docs/assets/chunks/ganttDiagram-NO4QXBWP.DUzsw4Yr.js +292 -0
- package/dist/docs/assets/chunks/gitGraphDiagram-IHSO6WYX.BqLfYTI7.js +106 -0
- package/dist/docs/assets/chunks/graph.C2PyVmSI.js +1 -0
- package/dist/docs/assets/chunks/infoDiagram-FWYZ7A6U.CiKWveW9.js +2 -0
- package/dist/docs/assets/chunks/init.Gi6I4Gst.js +1 -0
- package/dist/docs/assets/chunks/ishikawaDiagram-FXEZZL3T.jerUXEXA.js +70 -0
- package/dist/docs/assets/chunks/journeyDiagram-5HDEW3XC.Cqzvo6I_.js +139 -0
- package/dist/docs/assets/chunks/kanban-definition-HUTT4EX6.BzJ4OPe5.js +89 -0
- package/dist/docs/assets/chunks/katex.C5jXJg4s.js +257 -0
- package/dist/docs/assets/chunks/layout.BG3qr61M.js +1 -0
- package/dist/docs/assets/chunks/linear.hFjgYGMN.js +1 -0
- package/dist/docs/assets/chunks/map.DwDi8XlU.js +1 -0
- package/dist/docs/assets/chunks/mermaid-client.D3gEaJ5e.js +2 -0
- package/dist/docs/assets/chunks/mermaid.core.CEHdFh45.js +314 -0
- package/dist/docs/assets/chunks/mindmap-definition-LN4V7U3C.ChC5FJW6.js +96 -0
- package/dist/docs/assets/chunks/ordinal.BYWQX77i.js +1 -0
- package/dist/docs/assets/chunks/pegDiagram-2B236MQR.ClnjsRYs.js +1 -0
- package/dist/docs/assets/chunks/pieDiagram-ENE6RG2P.Bb0MqerK.js +39 -0
- package/dist/docs/assets/chunks/quadrantDiagram-ABIIQ3AL.Do6HK_yb.js +7 -0
- package/dist/docs/assets/chunks/railroadDiagram-RFXS5EU6.D35m6hQn.js +1 -0
- package/dist/docs/assets/chunks/requirementDiagram-TGXJPOKE.DMtjRYUg.js +84 -0
- package/dist/docs/assets/chunks/sankeyDiagram-HTMAVEWB.dfXDu62B.js +40 -0
- package/dist/docs/assets/chunks/sequenceDiagram-DBY2YBRQ.CLZ0rZTY.js +162 -0
- package/dist/docs/assets/chunks/sizeCapture-X5ZJPWSS.DWvGYLUT.js +1 -0
- package/dist/docs/assets/chunks/stateDiagram-2N3HPSRC.DY8sDkI0.js +1 -0
- package/dist/docs/assets/chunks/stateDiagram-v2-6OUMAXLB.B9v-Vq5L.js +1 -0
- package/dist/docs/assets/chunks/swimlanes-5IMT3BWC.Dy9SffeT.js +2 -0
- package/dist/docs/assets/chunks/swimlanesDiagram-G3AALYLV.Kb9LnCTH.js +8 -0
- package/dist/docs/assets/chunks/theme.BLEczZWC.js +2 -0
- package/dist/docs/assets/chunks/timeline-definition-FHXFAJF6.CH6uzgIu.js +120 -0
- package/dist/docs/assets/chunks/vennDiagram-L72KCM5P.7EBCJmyP.js +34 -0
- package/dist/docs/assets/chunks/wardleyDiagram-EHGQE667.DPHAQssL.js +78 -0
- package/dist/docs/assets/chunks/xychartDiagram-FW5EYKEG.aKgxZVbK.js +7 -0
- package/dist/docs/assets/index.md.p9floL_p.js +1 -0
- package/dist/docs/assets/index.md.p9floL_p.lean.js +1 -0
- package/dist/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/dist/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/dist/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/dist/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/dist/docs/assets/overview.md.BKVdLT3o.js +70 -0
- package/dist/docs/assets/overview.md.BKVdLT3o.lean.js +1 -0
- package/dist/docs/assets/packages-utils.md.CvgYp5Ll.js +31 -0
- package/dist/docs/assets/packages-utils.md.CvgYp5Ll.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.js +40 -0
- package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.js +38 -0
- package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.js +48 -0
- package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.js +51 -0
- package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.js +106 -0
- package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.js +66 -0
- package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.js +1 -0
- package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.js +83 -0
- package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.js +23 -0
- package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.js +46 -0
- package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.js +84 -0
- package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.js +14 -0
- package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.js +42 -0
- package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.js +87 -0
- package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.js +34 -0
- package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.js +34 -0
- package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.lean.js +1 -0
- package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.js +152 -0
- package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.lean.js +1 -0
- package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.js +37 -0
- package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.lean.js +1 -0
- package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.js +83 -0
- package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.lean.js +1 -0
- package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.js +85 -0
- package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.lean.js +1 -0
- package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.js +90 -0
- package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.lean.js +1 -0
- package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.js +55 -0
- package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.lean.js +1 -0
- package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.js +79 -0
- package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.lean.js +1 -0
- package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.js +1 -0
- package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.lean.js +1 -0
- package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.js +46 -0
- package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.lean.js +1 -0
- package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.js +42 -0
- package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.lean.js +1 -0
- package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.js +100 -0
- package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.lean.js +1 -0
- package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.js +27 -0
- package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.lean.js +1 -0
- package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.js +63 -0
- package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.lean.js +1 -0
- package/dist/docs/assets/quickstart.md.Cy_FmXIY.js +38 -0
- package/dist/docs/assets/quickstart.md.Cy_FmXIY.lean.js +1 -0
- package/dist/docs/assets/request-flow.md.C1fyxdPE.js +146 -0
- package/dist/docs/assets/request-flow.md.C1fyxdPE.lean.js +1 -0
- package/dist/docs/assets/style.DU_kNMWy.css +1 -0
- package/dist/docs/hashmap.json +1 -0
- package/dist/docs/index.html +25 -0
- package/dist/docs/overview.html +94 -0
- package/dist/docs/packages-utils.html +55 -0
- package/dist/docs/proxy-admin/env-and-build.html +64 -0
- package/dist/docs/proxy-admin/index.html +62 -0
- package/dist/docs/proxy-admin/layout-and-menu.html +72 -0
- package/dist/docs/proxy-admin/pages.html +75 -0
- package/dist/docs/proxy-admin/routing-and-auth.html +130 -0
- package/dist/docs/proxy-admin/services-and-mock.html +90 -0
- package/dist/docs/proxy-cli/api-layer.html +38 -0
- package/dist/docs/proxy-cli/app-shell.html +107 -0
- package/dist/docs/proxy-cli/components-common.html +47 -0
- package/dist/docs/proxy-cli/components-config.html +70 -0
- package/dist/docs/proxy-cli/components-requests.html +108 -0
- package/dist/docs/proxy-cli/components-stats.html +38 -0
- package/dist/docs/proxy-cli/components-status.html +66 -0
- package/dist/docs/proxy-cli/data-hooks.html +111 -0
- package/dist/docs/proxy-cli/index.html +58 -0
- package/dist/docs/proxy-cli/utils-and-i18n.html +58 -0
- package/dist/docs/proxy-core/chat-api.html +176 -0
- package/dist/docs/proxy-core/cli.html +61 -0
- package/dist/docs/proxy-core/config.html +107 -0
- package/dist/docs/proxy-core/data-layer.html +109 -0
- package/dist/docs/proxy-core/entry.html +114 -0
- package/dist/docs/proxy-core/index.html +79 -0
- package/dist/docs/proxy-core/pm2.html +103 -0
- package/dist/docs/proxy-core/providers.html +39 -0
- package/dist/docs/proxy-core/proxy.html +70 -0
- package/dist/docs/proxy-core/stats.html +66 -0
- package/dist/docs/proxy-core/tool.html +124 -0
- package/dist/docs/proxy-core/ui-routes.html +51 -0
- package/dist/docs/proxy-core/utilities.html +87 -0
- package/dist/docs/quickstart.html +62 -0
- package/dist/docs/request-flow.html +170 -0
- package/dist/docs/vp-icons.css +0 -0
- package/dist/server/proxy.js +2 -1
- package/dist/ui/assets/{1c-KmWe8RWs.js → 1c-DPsrzNHI.js} +1 -1
- package/dist/ui/assets/{abnf-BKQ6qIuo.js → abnf-DNkBIQRO.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VRR7QNED-CkRuDPu1.js → abnfDiagram-VRR7QNED-BqvHvzR8.js} +1 -1
- package/dist/ui/assets/{accesslog-DD9H5Ktc.js → accesslog-D5NxQ43Q.js} +1 -1
- package/dist/ui/assets/{actionscript-CAjf2Qtd.js → actionscript-DLr-LB2m.js} +1 -1
- package/dist/ui/assets/{ada-BXkXW16O.js → ada-BRSz3tHX.js} +1 -1
- package/dist/ui/assets/{angelscript-BxT7o0Up.js → angelscript-DMtEGgIa.js} +1 -1
- package/dist/ui/assets/{apache-C5z_tmVm.js → apache-C4gn4cSd.js} +1 -1
- package/dist/ui/assets/{applescript-DdIxl8rr.js → applescript-DoodcTwg.js} +1 -1
- package/dist/ui/assets/{arc-hSdFaqKn.js → arc-HmnzaGf9.js} +1 -1
- package/dist/ui/assets/{arcade-D5m0roat.js → arcade-RJZZSHSl.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-DOSHSqzf.js → architectureDiagram-ZJ3FMSHR-BUfDpSIw.js} +1 -1
- package/dist/ui/assets/{arduino-FDap8kq-.js → arduino-n6Dpx6Ig.js} +1 -1
- package/dist/ui/assets/{armasm-Kzp-Jr1v.js → armasm-DzCVITGB.js} +1 -1
- package/dist/ui/assets/{asciidoc-DbGMW3EE.js → asciidoc-CaqMsApq.js} +1 -1
- package/dist/ui/assets/{aspectj-CVYMmBCO.js → aspectj-B0kIcV0v.js} +1 -1
- package/dist/ui/assets/{autohotkey-9PmBGTPd.js → autohotkey-xUEXewap.js} +1 -1
- package/dist/ui/assets/{autoit-B4F86jgh.js → autoit-D3OfN2VX.js} +1 -1
- package/dist/ui/assets/{avrasm-CSzv2eHX.js → avrasm-Cbf0F4Kf.js} +1 -1
- package/dist/ui/assets/{awk-CjsvYvZE.js → awk-Cc0rWEwe.js} +1 -1
- package/dist/ui/assets/{axapta-BVgMoNRY.js → axapta-BKEeoUEe.js} +1 -1
- package/dist/ui/assets/{bash-IeBjW3pt.js → bash-D6JH6L3m.js} +1 -1
- package/dist/ui/assets/{basic-BTFJfmV1.js → basic-ka6JXc9C.js} +1 -1
- package/dist/ui/assets/{blockDiagram-677ZJIJ3-DLw3Bbhf.js → blockDiagram-677ZJIJ3-BHXRSjnM.js} +1 -1
- package/dist/ui/assets/{bnf-rCkeRYk0.js → bnf-Bxclk5tZ.js} +1 -1
- package/dist/ui/assets/{brainfuck-DBHuB3uZ.js → brainfuck--s_Fd8b9.js} +1 -1
- package/dist/ui/assets/{coq-TwFFolHa.js → c-BsgdDna0.js} +1 -1
- package/dist/ui/assets/{c-like-CK1xGeX_.js → c-like-CNkOkbqh.js} +1 -1
- package/dist/ui/assets/{c4Diagram-LMCZKHZV-cqY51yJw.js → c4Diagram-LMCZKHZV-Bp1uSrW8.js} +1 -1
- package/dist/ui/assets/{cal-BxGPpEZK.js → cal-LVlIOy9W.js} +1 -1
- package/dist/ui/assets/{capnproto-Bo2fgXF9.js → capnproto-r9DiQ1H8.js} +1 -1
- package/dist/ui/assets/{ceylon-C4Bb4pNB.js → ceylon-CTNzyZJX.js} +1 -1
- package/dist/ui/assets/channel-_rFUXR2i.js +1 -0
- package/dist/ui/assets/{chunk-2Q5K7J3B-CGTiTBmo.js → chunk-2Q5K7J3B-nnLVtUW3.js} +1 -1
- package/dist/ui/assets/{chunk-32BRIVSS-DWagYBp9.js → chunk-32BRIVSS-BDNS6igp.js} +1 -1
- package/dist/ui/assets/{chunk-5VM5RSS4-BzSBMKJX.js → chunk-5VM5RSS4-D713xBhI.js} +1 -1
- package/dist/ui/assets/{chunk-EX3LRPZG-4-aKwCgZ.js → chunk-EX3LRPZG-DExsU6Rd.js} +1 -1
- package/dist/ui/assets/{chunk-JWPE2WC7-CPC_cBN0.js → chunk-JWPE2WC7-DcpW5RnW.js} +1 -1
- package/dist/ui/assets/{chunk-MOJQB5TN-DrDE4H9w.js → chunk-MOJQB5TN-BQiSZNTn.js} +1 -1
- package/dist/ui/assets/{chunk-RYQCIY6F-DkdXe_kU.js → chunk-RYQCIY6F-DfblgZPd.js} +1 -1
- package/dist/ui/assets/{chunk-V7JOEXUC-Da6EWcQt.js → chunk-V7JOEXUC-np--VgmN.js} +1 -1
- package/dist/ui/assets/{chunk-VR4S4FIN-nP6dstD5.js → chunk-VR4S4FIN-BG0IhjO6.js} +1 -1
- package/dist/ui/assets/{chunk-XXDRQBXY-Bi_rRAPA.js → chunk-XXDRQBXY-DHuoh-RB.js} +1 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-DqgbMzM1.js +1 -0
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-DqgbMzM1.js +1 -0
- package/dist/ui/assets/{clean-cc1m9AxK.js → clean-CtVj0-EB.js} +1 -1
- package/dist/ui/assets/{clojure-DX5V8QA8.js → clojure-CZwle60-.js} +1 -1
- package/dist/ui/assets/{clojure-repl-FzjnVNWQ.js → clojure-repl-DJXWH00I.js} +1 -1
- package/dist/ui/assets/{cmake-COZZyrKs.js → cmake-Boxf0e7r.js} +1 -1
- package/dist/ui/assets/{coffeescript-DBsnOmC4.js → coffeescript-h85ZW4Gm.js} +1 -1
- package/dist/ui/assets/{c-C95V0zHL.js → coq-CVLui3m8.js} +1 -1
- package/dist/ui/assets/{cos-Dm5g-IQT.js → cos-CL0igafw.js} +1 -1
- package/dist/ui/assets/{cose-bilkent-JH36ORCC-B3-weOQF.js → cose-bilkent-JH36ORCC-CnXyotYB.js} +1 -1
- package/dist/ui/assets/{cpp-_RZxQjg7.js → cpp-vite1NvJ.js} +1 -1
- package/dist/ui/assets/{crmsh-DGPJ11Gt.js → crmsh-DqT9g0Iq.js} +1 -1
- package/dist/ui/assets/{crystal-BOMSPGge.js → crystal-Oans-K8G.js} +1 -1
- package/dist/ui/assets/{csharp-DZXiHH72.js → csharp-sCaDAzIB.js} +1 -1
- package/dist/ui/assets/{csp-DDSIMUoU.js → csp-rMcp93pK.js} +1 -1
- package/dist/ui/assets/{css-Bjye-ZWr.js → css-BwDLHi_h.js} +1 -1
- package/dist/ui/assets/{cynefin-VYW2F7L2-Cj5c4L3y.js → cynefin-VYW2F7L2-D8Bmecdd.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-BYsfTeNX.js → cynefinDiagram-TSTJHNR4-BT2YFmPZ.js} +1 -1
- package/dist/ui/assets/{d-22pfurOx.js → d-BFgZm0RV.js} +1 -1
- package/dist/ui/assets/{dagre-VKFMJZFB-DiEob-by.js → dagre-VKFMJZFB-BeJU73ex.js} +1 -1
- package/dist/ui/assets/{dart-Doiu8cDW.js → dart-rIo85iL3.js} +1 -1
- package/dist/ui/assets/{delphi-CQ7epp84.js → delphi-Bi2Rfp1o.js} +1 -1
- package/dist/ui/assets/{diagram-FQU43EPY-BOPbQcL4.js → diagram-FQU43EPY-CHQiS5Fr.js} +1 -1
- package/dist/ui/assets/{diagram-G47NLZAW-C1UWDJTx.js → diagram-G47NLZAW-EVerd4V8.js} +1 -1
- package/dist/ui/assets/{diagram-NH7WQ7WH-CYsBqW3J.js → diagram-NH7WQ7WH-DMP0VOAs.js} +1 -1
- package/dist/ui/assets/{diagram-OA4YK3LP-Dnag0x_3.js → diagram-OA4YK3LP-CAur5jK9.js} +1 -1
- package/dist/ui/assets/{diagram-WEI45ONY-Bo4CsDoj.js → diagram-WEI45ONY-DvmKkPH7.js} +1 -1
- package/dist/ui/assets/{diff-Cs6VQQZt.js → diff-CZZCIG00.js} +1 -1
- package/dist/ui/assets/{django-Bo3okOrw.js → django-D88PKHy-.js} +1 -1
- package/dist/ui/assets/{dns-BpG60eIX.js → dns-DX4hzjUh.js} +1 -1
- package/dist/ui/assets/{dockerfile-BWyH8SlV.js → dockerfile-1lgzEXn1.js} +1 -1
- package/dist/ui/assets/{dos-DWlNbaB9.js → dos-CwrC1ROy.js} +1 -1
- package/dist/ui/assets/{dsconfig-D_8y8YrJ.js → dsconfig-tvVdBv4w.js} +1 -1
- package/dist/ui/assets/{dts-Cz4SyMYR.js → dts-DTgQkdRs.js} +1 -1
- package/dist/ui/assets/{dust-Cu4qLkeH.js → dust-BbLlyCpf.js} +1 -1
- package/dist/ui/assets/{ebnf-CTVHui3r.js → ebnf-D6Dc4oRr.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-epcXQLEj.js → ebnfDiagram-CCIWWBDH-Kvilk1RF.js} +1 -1
- package/dist/ui/assets/{elixir-MAlwXhfU.js → elixir-CnMolQVs.js} +1 -1
- package/dist/ui/assets/{elm-Bdmwbvef.js → elm-BQ7VQFn7.js} +1 -1
- package/dist/ui/assets/{erDiagram-Q63AITRT-Bb60TqAM.js → erDiagram-Q63AITRT-C-S9oHZd.js} +1 -1
- package/dist/ui/assets/{erb-Ce9TpP4g.js → erb-B_1g6fXE.js} +1 -1
- package/dist/ui/assets/{erlang-CN2GEiqk.js → erlang-3b3ITXJu.js} +1 -1
- package/dist/ui/assets/{erlang-repl-D8K4O_cp.js → erlang-repl-Cy6Z3TdH.js} +1 -1
- package/dist/ui/assets/{excel-eVZU1r0f.js → excel-DtkATto8.js} +1 -1
- package/dist/ui/assets/{fix-BzKerEv0.js → fix-DsEG7TDI.js} +1 -1
- package/dist/ui/assets/{flix-B9CE3skV.js → flix-CQ-rKwGO.js} +1 -1
- package/dist/ui/assets/{flowDiagram-23GEKE2U-DzMLZIyt.js → flowDiagram-23GEKE2U-EbHDNMCC.js} +1 -1
- package/dist/ui/assets/{fortran-B4__3vos.js → fortran-AqzaRCEt.js} +1 -1
- package/dist/ui/assets/{fsharp-BJ3-ARHz.js → fsharp-CCzWGasu.js} +1 -1
- package/dist/ui/assets/{gams-Cu43oSYT.js → gams-Bqa6CB_r.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-NO4QXBWP-D_aAoMRP.js → ganttDiagram-NO4QXBWP-B6jvc6O7.js} +1 -1
- package/dist/ui/assets/{gauss-T8vk_TpE.js → gauss-D4Utubeh.js} +1 -1
- package/dist/ui/assets/{gcode-9j3BicpZ.js → gcode-By3KwWjb.js} +1 -1
- package/dist/ui/assets/{gherkin-Dyh5KFG-.js → gherkin-PXOPjT7Y.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-CMxCHC-Z.js → gitGraphDiagram-IHSO6WYX-C5l6rHvK.js} +1 -1
- package/dist/ui/assets/{glsl-DWWjN4ts.js → glsl-KmmyBk93.js} +1 -1
- package/dist/ui/assets/{gml-BcYE-D5A.js → gml-C1Qw_Nrt.js} +1 -1
- package/dist/ui/assets/{go-DUnUzOEI.js → go-DaBQtdp1.js} +1 -1
- package/dist/ui/assets/{golo-BDoc1QQL.js → golo-D7PDzNpb.js} +1 -1
- package/dist/ui/assets/{gradle-B_WRa_bT.js → gradle-nXueCYH-.js} +1 -1
- package/dist/ui/assets/{groovy-CgjqFq1e.js → groovy-DFDsQDhl.js} +1 -1
- package/dist/ui/assets/{haml-DCqcg7Ti.js → haml-B_zxHzy_.js} +1 -1
- package/dist/ui/assets/{handlebars-DSDUQrnw.js → handlebars-BdMY-8KA.js} +1 -1
- package/dist/ui/assets/{haskell-DPVnctVi.js → haskell-CftsIPps.js} +1 -1
- package/dist/ui/assets/{haxe-BuCGXBa4.js → haxe-BFZb0OIE.js} +1 -1
- package/dist/ui/assets/{hsp-BTKpS_u0.js → hsp-EPTuqwtZ.js} +1 -1
- package/dist/ui/assets/{htmlbars-Cql3Jvy2.js → htmlbars-B7ZSC-iN.js} +1 -1
- package/dist/ui/assets/{http-BB8I9jUh.js → http-BxSd_aa1.js} +1 -1
- package/dist/ui/assets/{hy-DG7xkZNz.js → hy-D-rBN9MQ.js} +1 -1
- package/dist/ui/assets/index-CWFn1h-J.css +10 -0
- package/dist/ui/assets/{index-CfTIGTiY.js → index-DSGZBcd1.js} +166 -171
- package/dist/ui/assets/{index-DqIiCkSD.js → index-Dlp8uGHu.js} +3 -3
- package/dist/ui/assets/{infoDiagram-FWYZ7A6U-DIzEV-BJ.js → infoDiagram-FWYZ7A6U-BOF_kBqe.js} +1 -1
- package/dist/ui/assets/{inform7-BWNpVEkA.js → inform7-OjpbRXZf.js} +1 -1
- package/dist/ui/assets/{ini-BMw_C8EP.js → ini-Dc-QApXQ.js} +1 -1
- package/dist/ui/assets/{irpf90-Cy42ibFZ.js → irpf90-C4OfYiST.js} +1 -1
- package/dist/ui/assets/{isbl-CjFSc0hz.js → isbl-9km6K6Sf.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-BZcxp5am.js → ishikawaDiagram-FXEZZL3T-BvKSD8LY.js} +1 -1
- package/dist/ui/assets/{java-BDxe9dp1.js → java-C2mOf3QX.js} +1 -1
- package/dist/ui/assets/{javascript-CgLkkj7h.js → javascript-_i0Q5MkQ.js} +1 -1
- package/dist/ui/assets/{jboss-cli-C8biclrb.js → jboss-cli-BS5ipQOv.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-5HDEW3XC-BbJu6m6Q.js → journeyDiagram-5HDEW3XC-yKdSl63P.js} +1 -1
- package/dist/ui/assets/{json-BjJKhmM6.js → json-Dci0MO4x.js} +1 -1
- package/dist/ui/assets/{julia-DvKEpg-R.js → julia-bEqo4nlV.js} +1 -1
- package/dist/ui/assets/{julia-repl-BDJWZxkU.js → julia-repl-Co6hf47q.js} +1 -1
- package/dist/ui/assets/{kanban-definition-HUTT4EX6-DeIVPlbv.js → kanban-definition-HUTT4EX6-B7BbZCd6.js} +1 -1
- package/dist/ui/assets/{kotlin-DCoXcnEb.js → kotlin-krx8WewB.js} +1 -1
- package/dist/ui/assets/{lasso-C7m0QmV2.js → lasso-d3ZTv9Tj.js} +1 -1
- package/dist/ui/assets/{latex-SHnTG9Eq.js → latex-BNWbHYxK.js} +1 -1
- package/dist/ui/assets/{ldif-_6hUnKPV.js → ldif-Bs8eb63L.js} +1 -1
- package/dist/ui/assets/{leaf-Co9qxlaF.js → leaf-BTbRDVWB.js} +1 -1
- package/dist/ui/assets/{less-CJRDPwNA.js → less-DH5cqJTD.js} +1 -1
- package/dist/ui/assets/{lisp-JEHGYbiW.js → lisp-CBUvBYtR.js} +1 -1
- package/dist/ui/assets/{livecodeserver-BSYaUj4k.js → livecodeserver-CkM7-E4a.js} +1 -1
- package/dist/ui/assets/{livescript-WQMCQeuz.js → livescript-DomXyXUO.js} +1 -1
- package/dist/ui/assets/{llvm-DnAHqj5I.js → llvm-e_-ff59-.js} +1 -1
- package/dist/ui/assets/{lsl--k-ghYia.js → lsl-BNDsGOmv.js} +1 -1
- package/dist/ui/assets/{lua-CXb23hbC.js → lua-_ZmkXwc_.js} +1 -1
- package/dist/ui/assets/{makefile-CM7o86yn.js → makefile-BhG7cThe.js} +1 -1
- package/dist/ui/assets/{markdown-HB3HvChQ.js → markdown-ClW2SRy6.js} +1 -1
- package/dist/ui/assets/{mathematica-9NTuf22N.js → mathematica-kqoCR611.js} +1 -1
- package/dist/ui/assets/{matlab-CWv-ik4r.js → matlab-DqawyK3q.js} +1 -1
- package/dist/ui/assets/{maxima-CqYiKCrw.js → maxima-B0qzCXe1.js} +1 -1
- package/dist/ui/assets/{mel-BbsRpUm5.js → mel-BZaSas3B.js} +1 -1
- package/dist/ui/assets/{mercury-Cz2j4HhU.js → mercury-ByD0wyJH.js} +1 -1
- package/dist/ui/assets/{mindmap-definition-LN4V7U3C-WyJS8oye.js → mindmap-definition-LN4V7U3C-Ce6QsaH5.js} +1 -1
- package/dist/ui/assets/{mipsasm-BqWSRbQV.js → mipsasm-B08lqZSo.js} +1 -1
- package/dist/ui/assets/{mizar-JLBfQ6vt.js → mizar-7iaUqWPq.js} +1 -1
- package/dist/ui/assets/{mojolicious-D0LbMmyk.js → mojolicious-CbH-d8Wh.js} +1 -1
- package/dist/ui/assets/{monkey-DAGL6-JN.js → monkey-D5z6-hFH.js} +1 -1
- package/dist/ui/assets/{moonscript-DzbwNSKy.js → moonscript-DuLd7pdm.js} +1 -1
- package/dist/ui/assets/{n1ql-dkgKq6Yv.js → n1ql-EbVfQMfD.js} +1 -1
- package/dist/ui/assets/{nginx-AUoaDPV4.js → nginx-D-4AxpHP.js} +1 -1
- package/dist/ui/assets/{nim-CdqYmVrl.js → nim-wPHQEX5v.js} +1 -1
- package/dist/ui/assets/{nix-CxmVjwwo.js → nix-6SVkxAXi.js} +1 -1
- package/dist/ui/assets/{node-repl-B1Z3zUAh.js → node-repl-CaFKEOyj.js} +1 -1
- package/dist/ui/assets/{nsis-CTAuPWhe.js → nsis-BmqbwVv_.js} +1 -1
- package/dist/ui/assets/{objectivec-CvbKeAPz.js → objectivec-BX0R-sI2.js} +1 -1
- package/dist/ui/assets/{ocaml-DCiyXKOH.js → ocaml-CyfdrIqo.js} +1 -1
- package/dist/ui/assets/{openscad-CPGUwmeR.js → openscad-B5qfaF1E.js} +1 -1
- package/dist/ui/assets/{oxygene-CI_bD1Gw.js → oxygene-CmlCgXLr.js} +1 -1
- package/dist/ui/assets/{parser3-C91CVs85.js → parser3-DdpPyZkn.js} +1 -1
- package/dist/ui/assets/{pegDiagram-2B236MQR-yF8AW7GR.js → pegDiagram-2B236MQR-ByyVqaXh.js} +1 -1
- package/dist/ui/assets/{perl-ChxfKl-n.js → perl-D3qc2wEe.js} +1 -1
- package/dist/ui/assets/{pf-CKCHkzIA.js → pf-Bv3zza37.js} +1 -1
- package/dist/ui/assets/{pgsql-BwOP20uH.js → pgsql-BZIppw1a.js} +1 -1
- package/dist/ui/assets/{php-B7Rs2tM5.js → php-D1ScecZC.js} +1 -1
- package/dist/ui/assets/{php-template-Cx-Fh4AR.js → php-template-sEqzzKWJ.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ENE6RG2P-BS4hnGNX.js → pieDiagram-ENE6RG2P-T1OgWN3l.js} +1 -1
- package/dist/ui/assets/{plaintext-U7qkdtgS.js → plaintext-DO7Jy_T2.js} +1 -1
- package/dist/ui/assets/{pony-_fGYgePh.js → pony-CTXTp2Tb.js} +1 -1
- package/dist/ui/assets/{powershell-CFBTcUce.js → powershell-C9lzZsbj.js} +1 -1
- package/dist/ui/assets/{processing-BWHneU0K.js → processing-hzJAP_Li.js} +1 -1
- package/dist/ui/assets/{profile-BJ-HxhzS.js → profile-bFiAkh7e.js} +1 -1
- package/dist/ui/assets/{prolog-ChHo7n6L.js → prolog-CE0trHSn.js} +1 -1
- package/dist/ui/assets/{properties-e_DOYclC.js → properties-MeANnTVc.js} +1 -1
- package/dist/ui/assets/{protobuf-5aGSIv7w.js → protobuf-S-rp7SK0.js} +1 -1
- package/dist/ui/assets/{puppet-D2vQatzX.js → puppet-B5YT8Ct1.js} +1 -1
- package/dist/ui/assets/{purebasic-n6krfaeF.js → purebasic-DO-5HeDl.js} +1 -1
- package/dist/ui/assets/{python-CbIo0XxP.js → python-DVGTQbwU.js} +1 -1
- package/dist/ui/assets/{python-repl-BpIq9kyr.js → python-repl-CQ4VlKLC.js} +1 -1
- package/dist/ui/assets/{q-jntnvcCx.js → q-nS96imov.js} +1 -1
- package/dist/ui/assets/{qml-BafQlZNV.js → qml-BkzkCgUU.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-C3Th8mUJ.js → quadrantDiagram-ABIIQ3AL-BkaCzlXD.js} +1 -1
- package/dist/ui/assets/{r-CHgvQFLK.js → r-y4Q5t85r.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CMQkbGJl.js → railroadDiagram-RFXS5EU6-C1lbwk19.js} +1 -1
- package/dist/ui/assets/{reasonml-DNwlPD_T.js → reasonml-Bzhzc5Ao.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-TGXJPOKE-B70_oR7v.js → requirementDiagram-TGXJPOKE-C8Rw6N2I.js} +1 -1
- package/dist/ui/assets/{rib-CX4e9JSF.js → rib-BP3Y9dW3.js} +1 -1
- package/dist/ui/assets/{roboconf-ee4qsPGf.js → roboconf-87QE7cIh.js} +1 -1
- package/dist/ui/assets/{routeros-BJSwvu2L.js → routeros-BV3nt8wW.js} +1 -1
- package/dist/ui/assets/{rsl-BiKdMl_F.js → rsl-DfQf4CW_.js} +1 -1
- package/dist/ui/assets/{ruby-CAXTU5LY.js → ruby-DQxFKbgX.js} +1 -1
- package/dist/ui/assets/{ruleslanguage-C1kgDGXM.js → ruleslanguage-B8oCm_aw.js} +1 -1
- package/dist/ui/assets/{rust-DyEf_GXL.js → rust-DzZgPf9W.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-CvUfseMg.js → sankeyDiagram-HTMAVEWB-Dxiuo8Hz.js} +1 -1
- package/dist/ui/assets/{sas-Q1rlUxPH.js → sas-CFh-Rsrv.js} +1 -1
- package/dist/ui/assets/{scala-Dg6KNmge.js → scala-3UDyJBiS.js} +1 -1
- package/dist/ui/assets/{scheme-D9iooUxI.js → scheme-KaUTge9W.js} +1 -1
- package/dist/ui/assets/{scilab-CztEJXJY.js → scilab-CLSBZzuh.js} +1 -1
- package/dist/ui/assets/{scss-BMh-JkdE.js → scss-DaEkfHWX.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DB0c9kf4.js → sequenceDiagram-DBY2YBRQ-Cv__zR2v.js} +1 -1
- package/dist/ui/assets/{shell-DWo6z0MG.js → shell-B0d4cZTk.js} +1 -1
- package/dist/ui/assets/{sizeCapture-X5ZJPWSS-BcQlgjfD.js → sizeCapture-X5ZJPWSS-C4nD-ShQ.js} +1 -1
- package/dist/ui/assets/{smali-Cijeb6pL.js → smali-CLhfky4R.js} +1 -1
- package/dist/ui/assets/{smalltalk-D0lvqa_d.js → smalltalk-B4aaTMO5.js} +1 -1
- package/dist/ui/assets/{sml-B-vqWZ3b.js → sml-x4CTxWEZ.js} +1 -1
- package/dist/ui/assets/{sqf-BJ-1Q583.js → sqf-G_0vdVVs.js} +1 -1
- package/dist/ui/assets/{sql-CMGLxEYV.js → sql-C--WH0Fo.js} +1 -1
- package/dist/ui/assets/{sql_more-gsRmbNCH.js → sql_more-B4LrzCtd.js} +1 -1
- package/dist/ui/assets/{stan-D1AlTSpf.js → stan-CACDFOA0.js} +1 -1
- package/dist/ui/assets/{stata-DnEYviI0.js → stata-BP9M7sZt.js} +1 -1
- package/dist/ui/assets/{stateDiagram-2N3HPSRC-BSRgVsHO.js → stateDiagram-2N3HPSRC-z3-31Cr2.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BKIXFHzO.js +1 -0
- package/dist/ui/assets/{step21-DbQV9sMo.js → step21-MAOu4dNb.js} +1 -1
- package/dist/ui/assets/{stylus-Cyc7vdUc.js → stylus-CpuP3pvE.js} +1 -1
- package/dist/ui/assets/{subunit-16ipyMie.js → subunit-NWzuqFhT.js} +1 -1
- package/dist/ui/assets/{swift-DTNnw4qS.js → swift-DuFKNmKv.js} +1 -1
- package/dist/ui/assets/{swimlanes-5IMT3BWC-DgOdcc4_.js → swimlanes-5IMT3BWC-E463-rXd.js} +2 -2
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-CkQvBOYs.js +8 -0
- package/dist/ui/assets/{taggerscript-DM6pvUWE.js → taggerscript-BDnv2jvg.js} +1 -1
- package/dist/ui/assets/{tap-Ch-uyKZq.js → tap-aB2cLXdf.js} +1 -1
- package/dist/ui/assets/{tcl-D0T_V5dA.js → tcl-7WepIaIa.js} +1 -1
- package/dist/ui/assets/{thrift-D9xJjYw4.js → thrift-BLh6pdjc.js} +1 -1
- package/dist/ui/assets/{timeline-definition-FHXFAJF6-BBeDMHxb.js → timeline-definition-FHXFAJF6-FA_RNhFQ.js} +1 -1
- package/dist/ui/assets/{tp-kUrCGo9X.js → tp-D1rt5u_j.js} +1 -1
- package/dist/ui/assets/{twig-Cgub6rxA.js → twig-DgfeYg4W.js} +1 -1
- package/dist/ui/assets/{typescript-BxNP9Ap9.js → typescript-oU560Q8V.js} +1 -1
- package/dist/ui/assets/{vala-DF9ZZagU.js → vala-DlXsaz2B.js} +1 -1
- package/dist/ui/assets/{vbnet-Cf46ypDg.js → vbnet-BjpxjeMZ.js} +1 -1
- package/dist/ui/assets/{vbscript-DNs-QKLH.js → vbscript-DfNdtdO3.js} +1 -1
- package/dist/ui/assets/{vbscript-html-DyS6I5L1.js → vbscript-html-D09WPsgK.js} +1 -1
- package/dist/ui/assets/{vennDiagram-L72KCM5P-8WpWycE-.js → vennDiagram-L72KCM5P-zaCDWwTs.js} +1 -1
- package/dist/ui/assets/{verilog-CF5wC4X-.js → verilog-B9vENtLK.js} +1 -1
- package/dist/ui/assets/{vhdl-Dm0jpDMn.js → vhdl-CJLTZOu1.js} +1 -1
- package/dist/ui/assets/{vim-nyO2DRAx.js → vim-FuPhupu9.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-EHGQE667-UeIOK-jv.js → wardleyDiagram-EHGQE667-BS8ApwmV.js} +1 -1
- package/dist/ui/assets/{x86asm-BNw2-6GG.js → x86asm-kX_Cp6wB.js} +1 -1
- package/dist/ui/assets/{xl-D-YHxr6V.js → xl-MuHNmLUj.js} +1 -1
- package/dist/ui/assets/{xml-BijAlrow.js → xml-Mbn2z12n.js} +1 -1
- package/dist/ui/assets/{xquery-z0wxWBKz.js → xquery-Dy4lt-m-.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-FW5EYKEG-BNzHLweN.js → xychartDiagram-FW5EYKEG-DoNZtZus.js} +1 -1
- package/dist/ui/assets/{yaml-n5TIQArR.js → yaml-CxxAisfE.js} +1 -1
- package/dist/ui/assets/{zephir-DrGhH8jG.js → zephir-WWG8qyld.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +2 -2
- package/dist/ui/assets/channel-D9Y4iN1l.js +0 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-C4UVH6RI.js +0 -1
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-C4UVH6RI.js +0 -1
- package/dist/ui/assets/index-CK_lJsTu.css +0 -10
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BLdfpGJO.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DRVnkg3M.js +0 -8
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import{_ as i,o as a,c as t,a2 as h}from"./chunks/framework.D_Xv2a7c.js";const g=JSON.parse('{"title":"proxy-admin / 页面清单","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-admin/pages.md","filePath":"proxy-admin/pages.md"}'),n={name:"proxy-admin/pages.md"};function l(k,s,p,e,d,r){return a(),t("div",null,[...s[0]||(s[0]=[h(`<h1 id="proxy-admin-页面清单" tabindex="-1">proxy-admin / 页面清单 <a class="header-anchor" href="#proxy-admin-页面清单" aria-label="Permalink to "proxy-admin / 页面清单""></a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to "本文档覆盖的源文件""></a></h2><ul><li><code>apps/proxy-admin/src/pages/Login.tsx</code></li><li><code>apps/proxy-admin/src/pages/Dashboard.tsx</code></li><li><code>apps/proxy-admin/src/pages/UserManagement.tsx</code></li><li><code>apps/proxy-admin/src/pages/SupplierManagement.tsx</code></li><li><code>apps/proxy-admin/src/pages/LogManagement.tsx</code></li><li><code>apps/proxy-admin/src/pages/SystemSettings.tsx</code></li></ul><h2 id="login" tabindex="-1">Login <a class="header-anchor" href="#login" aria-label="Permalink to "Login""></a></h2><p><code>apps/proxy-admin/src/pages/Login.tsx</code>。整个应用最富视觉设计的页面,用了 <strong>玻璃拟态</strong>(glassmorphism):</p><h3 id="视觉设计" tabindex="-1">视觉设计 <a class="header-anchor" href="#视觉设计" aria-label="Permalink to "视觉设计""></a></h3><ul><li>全屏深色背景 <code>#020617</code></li><li>两个模糊光斑(左上绿、右下蓝)作装饰</li><li>中央玻璃卡片:<code>backdrop-blur-2xl</code> + <code>bg-[#0F172A]/40</code> + 6s 呼吸动画(<code>pulse-glass</code> keyframes)</li><li>Logo 圆形(LockOutlined 图标)</li><li>深色输入框,focus 时绿色高亮边框</li></ul><h3 id="表单" tabindex="-1">表单 <a class="header-anchor" href="#表单" aria-label="Permalink to "表单""></a></h3><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Form</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> form</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{form} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">onFinish</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{handleLogin} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">size</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"large"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> layout</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"vertical"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Form.Item</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> name</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"username"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> rules</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{[{ required: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }]}></span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Input</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> prefix</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{<</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">UserOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">defaultValue</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"admin"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /></span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Form.Item</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Form.Item</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> name</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"password"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> rules</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{[{ required: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }]}></span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Input.Password</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> prefix</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{<</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">LockOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">defaultValue</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"123456"</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> iconRender</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">visible</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> visible </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">EyeInvisibleOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">EyeOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />} /></span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Form.Item</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Button</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> type</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"primary"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> htmlType</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"submit"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> loading</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{loading}>登录</</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Button</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Form</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span></code></pre></div><ul><li><strong>默认值 admin / 123456</strong>:与 mock 校验一致,方便直接点登录</li><li>底部提示卡片明示默认账号</li><li>密码可见性 toggle(<code>iconRender</code>)</li></ul><h3 id="登录处理" tabindex="-1">登录处理 <a class="header-anchor" href="#登录处理" aria-label="Permalink to "登录处理""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> handleLogin</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">values</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> LoginParams</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setLoading</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> response</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> loginApi</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(values)</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (response.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> login</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(response.data.token, response.data.user)</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">success</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'登录成功'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> navigate</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/dashboard'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
19
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) {</span></span>
|
|
20
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'Login failed:'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, error)</span></span>
|
|
21
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">finally</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
22
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setLoading</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li>axios 拦截器处理错误 message,这里只 log</li><li>成功后调用 <code>AuthContext.login()</code> + <code>navigate('/dashboard')</code></li></ul><h3 id="减动画支持" tabindex="-1">减动画支持 <a class="header-anchor" href="#减动画支持" aria-label="Permalink to "减动画支持""></a></h3><div class="language-css vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">css</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">@media</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (prefers-reduced-motion: reduce) {</span></span>
|
|
25
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> .ant-card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">animation</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">none</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !important</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; }</span></span>
|
|
26
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>尊重用户无障碍设置。</p><h3 id="内联全局-style" tabindex="-1">内联全局 <code><style></code> <a class="header-anchor" href="#内联全局-style" aria-label="Permalink to "内联全局 \`<style>\`""></a></h3><p>Login 里内联 <code><style></code> 覆盖 antd 组件样式(<code>.ant-card</code>, <code>.ant-input-affix-wrapper</code> 等 100+ 行 CSS)。<strong>这些样式泄漏到全站</strong>——如果切换其他页面且未 unmount Login(无此情况,因路由切换会 unmount),会影响。当前实现有效但脆弱。</p><h2 id="dashboard" tabindex="-1">Dashboard <a class="header-anchor" href="#dashboard" aria-label="Permalink to "Dashboard""></a></h2><p><code>apps/proxy-admin/src/pages/Dashboard.tsx</code>。<strong>静态占位</strong>:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Row</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> gutter</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">16</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"mb-6"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
27
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> span</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">6</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Statistic</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> title</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"用户总数"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> value</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">128</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">prefix</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{<</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">UserOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />} /></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
28
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> span</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">6</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Statistic</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> title</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"供应商总数"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> value</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">8</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">prefix</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{<</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">ShopOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />} /></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
29
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> span</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">6</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Statistic</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> title</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"今日请求量"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> value</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">12580</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">prefix</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{<</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">RiseOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />} /></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
30
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> span</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">6</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Statistic</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> title</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"日志总数"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> value</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">125800</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">prefix</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{<</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">FileTextOutlined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />} /></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Col</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
31
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Row</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
32
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> title</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"TODO"</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"text-center py-12"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
33
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">p</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"text-gray-500"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">>看板详细内容待后续设计补充</</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">p</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
34
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span></code></pre></div><p>四张写死数字的卡片 + 一个 TODO 占位。无数据加载、无接口调用。</p><h2 id="usermanagement" tabindex="-1">UserManagement <a class="header-anchor" href="#usermanagement" aria-label="Permalink to "UserManagement""></a></h2><p><code>apps/proxy-admin/src/pages/UserManagement.tsx</code>。用户列表 + 创建 Modal。</p><h3 id="表格列" tabindex="-1">表格列 <a class="header-anchor" href="#表格列" aria-label="Permalink to "表格列""></a></h3><ul><li>ID (80px)</li><li>用户名</li><li>昵称</li><li>邮箱</li><li>操作(编辑 / 删除按钮,<strong>均未实现 onClick</strong>)</li></ul><h3 id="数据加载" tabindex="-1">数据加载 <a class="header-anchor" href="#数据加载" aria-label="Permalink to "数据加载""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> loadUserList</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setLoading</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
36
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
37
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> response</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getUserList</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
38
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (response.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setUsers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(response.data.list)</span></span>
|
|
39
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
40
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> finally</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setLoading</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) }</span></span>
|
|
41
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
42
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">useEffect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">loadUserList</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() }, [])</span></span></code></pre></div><p><code>getUserList()</code> → <code>GET /api/user/list</code> → mock 返回 3 个用户。</p><h3 id="创建用户-modal" tabindex="-1">创建用户 Modal <a class="header-anchor" href="#创建用户-modal" aria-label="Permalink to "创建用户 Modal""></a></h3><p>四个字段:用户名 / 昵称 / 邮箱 / 头像。用 antd <code>Form</code> + <code>rules</code> 校验。邮箱额外 <code>type: 'email'</code> 校验格式。提交调 <code>createUser(values)</code> → mock 返回。</p><h3 id="未实现" tabindex="-1">未实现 <a class="header-anchor" href="#未实现" aria-label="Permalink to "未实现""></a></h3><ul><li>编辑/删除按钮无 handler</li><li>无分页控件(表格默认分页)</li><li>无搜索/筛选</li></ul><h2 id="suppliermanagement" tabindex="-1">SupplierManagement <a class="header-anchor" href="#suppliermanagement" aria-label="Permalink to "SupplierManagement""></a></h2><p><code>apps/proxy-admin/src/pages/SupplierManagement.tsx</code>。供应商列表 + 添加 Modal。</p><h3 id="表格列-1" tabindex="-1">表格列 <a class="header-anchor" href="#表格列-1" aria-label="Permalink to "表格列""></a></h3><ul><li>ID</li><li>供应商名称</li><li>类型(<code><Tag color="blue"></code>)</li><li>状态(<code>active/inactive</code> → 绿/红 Tag,中文「启用/禁用」)</li><li>创建时间</li><li>操作</li></ul><h3 id="加载数据" tabindex="-1">加载数据 <a class="header-anchor" href="#加载数据" aria-label="Permalink to "加载数据""></a></h3><p><code>getSupplierList()</code> → <code>GET /api/supplier/list</code> → mock 返回 OpenAI / Anthropic / Google Gemini 3 家。</p><h3 id="添加供应商-modal" tabindex="-1">添加供应商 Modal <a class="header-anchor" href="#添加供应商-modal" aria-label="Permalink to "添加供应商 Modal""></a></h3><p>字段:</p><ul><li>供应商名称</li><li>类型(Select:<code>llm / embedding / image / audio</code>)</li><li>状态(Switch,默认启用)</li><li>API Key(Password 输入)</li><li>API 地址(可选)</li><li>支持模型(英文逗号分隔字符串)</li></ul><p>数据字段用 <code>name={['config', 'apiKey']}</code> 嵌套结构对应 <code>Supplier.config</code>。</p><h3 id="与-proxy-core-供应商的关系" tabindex="-1">与 proxy-core 供应商的关系 <a class="header-anchor" href="#与-proxy-core-供应商的关系" aria-label="Permalink to "与 proxy-core 供应商的关系""></a></h3><p><strong>完全独立</strong>。proxy-core 有自己的 SQLite <code>providers</code> 表和 REST 端点 <code>/ui/api/providers</code>;proxy-admin 这里的 supplier 是<strong>规划中的全局供应商概念</strong>,走 <code>/api/supplier/*</code>,目前只有 mock。未来接入时需要决定:</p><ul><li>proxy-admin 是否直接读写 proxy-core 的 SQLite?</li><li>是否需要独立的数据库存管理员级配置?</li><li>与 proxy-cli 的 ProviderManagerModal 如何分工?</li></ul><h2 id="logmanagement" tabindex="-1">LogManagement <a class="header-anchor" href="#logmanagement" aria-label="Permalink to "LogManagement""></a></h2><p><code>apps/proxy-admin/src/pages/LogManagement.tsx</code>。<strong>只有 17 行</strong>——完全占位:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"text-center py-12"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
43
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Empty</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> description</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"日志功能待后续设计补充"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /></span></span>
|
|
44
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Card</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span></code></pre></div><p>未来接入 proxy-core 后应该:<code>GET /ui/api/requests</code> 列表 + <code>/ui/api/logs/stream</code> WebSocket 日志流。</p><h2 id="systemsettings" tabindex="-1">SystemSettings <a class="header-anchor" href="#systemsettings" aria-label="Permalink to "SystemSettings""></a></h2><p><code>apps/proxy-admin/src/pages/SystemSettings.tsx</code>。系统级配置表单:</p><h3 id="字段" tabindex="-1">字段 <a class="header-anchor" href="#字段" aria-label="Permalink to "字段""></a></h3><ul><li>站点名称(required)</li><li>站点描述(Text Area 3 行)</li><li>最大上传大小 MB(InputNumber 1..1024, required)</li><li>开放注册(Switch)</li></ul><h3 id="加载-保存" tabindex="-1">加载 & 保存 <a class="header-anchor" href="#加载-保存" aria-label="Permalink to "加载 & 保存""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> loadSettings</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> response</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getSystemSettings</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
46
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (response.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) form.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setFieldsValue</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(response.data)</span></span>
|
|
47
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
48
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> handleSave</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">values</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
49
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> response</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> saveSystemSettings</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(values)</span></span>
|
|
50
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (response.code </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) message.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">success</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'保存成功'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
51
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p><code>getSystemSettings</code> / <code>saveSystemSettings</code> 都走 mock(<code>/api/system/settings</code>)。</p><p><strong>注意字段与 proxy-core config 不重叠</strong>:这些字段(siteName / siteDescription 等)是 proxy-admin 独立的管理域,不影响 proxy-core 的运行配置。未来若统一,需要设计映射关系。</p><h2 id="状态对比" tabindex="-1">状态对比 <a class="header-anchor" href="#状态对比" aria-label="Permalink to "状态对比""></a></h2><table tabindex="0"><thead><tr><th>页面</th><th>功能完成度</th><th>数据源</th><th>备注</th></tr></thead><tbody><tr><td>Login</td><td>✅ 完整(含视觉)</td><td>mock</td><td>admin/123456</td></tr><tr><td>Dashboard</td><td>❌ 静态占位</td><td>无</td><td>4 张写死卡 + TODO</td></tr><tr><td>UserManagement</td><td>⚠️ 部分(列表+创建)</td><td>mock</td><td>编辑/删除按钮无 handler</td></tr><tr><td>SupplierManagement</td><td>⚠️ 部分(列表+添加)</td><td>mock</td><td>编辑/删除按钮无 handler</td></tr><tr><td>LogManagement</td><td>❌ 完全占位</td><td>无</td><td>仅 <code><Empty></code></td></tr><tr><td>SystemSettings</td><td>✅ 完整(表单)</td><td>mock</td><td>但字段和 proxy-core 无关</td></tr></tbody></table><h2 id="相关" tabindex="-1">相关 <a class="header-anchor" href="#相关" aria-label="Permalink to "相关""></a></h2><ul><li>服务层与 mock → <a href="./services-and-mock.html">services-and-mock.md</a></li><li>布局 → <a href="./layout-and-menu.html">layout-and-menu.md</a></li></ul>`,62)])])}const o=i(n,[["render",l]]);export{g as __pageData,o as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as i,o as a,c as t,a2 as h}from"./chunks/framework.D_Xv2a7c.js";const g=JSON.parse('{"title":"proxy-admin / 页面清单","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-admin/pages.md","filePath":"proxy-admin/pages.md"}'),n={name:"proxy-admin/pages.md"};function l(k,s,p,e,d,r){return a(),t("div",null,[...s[0]||(s[0]=[h("",62)])])}const o=i(n,[["render",l]]);export{g as __pageData,o as default};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import{_ as i,o as a,c as n,a2 as t}from"./chunks/framework.D_Xv2a7c.js";const g=JSON.parse('{"title":"proxy-admin / 路由与认证","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-admin/routing-and-auth.md","filePath":"proxy-admin/routing-and-auth.md"}'),h={name:"proxy-admin/routing-and-auth.md"};function l(k,s,p,e,E,r){return a(),n("div",null,[...s[0]||(s[0]=[t(`<h1 id="proxy-admin-路由与认证" tabindex="-1">proxy-admin / 路由与认证 <a class="header-anchor" href="#proxy-admin-路由与认证" aria-label="Permalink to "proxy-admin / 路由与认证""></a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to "本文档覆盖的源文件""></a></h2><ul><li><code>apps/proxy-admin/src/router/index.tsx</code></li><li><code>apps/proxy-admin/src/router/guard.ts</code></li><li><code>apps/proxy-admin/src/contexts/AuthContext.tsx</code></li><li><code>apps/proxy-admin/src/types/auth.ts</code></li><li><code>apps/proxy-admin/src/main.tsx</code></li><li><code>apps/proxy-admin/src/App.tsx</code></li></ul><h2 id="路由骨架" tabindex="-1">路由骨架 <a class="header-anchor" href="#路由骨架" aria-label="Permalink to "路由骨架""></a></h2><p><code>apps/proxy-admin/src/router/index.tsx</code>:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> router</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createBrowserRouter</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">([</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/login'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Login</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />,</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> loader: publicLoader,</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">MainLayout</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> />,</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> loader: authLoader,</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> children: [</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">''</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Dashboard</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> },</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'dashboard'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Dashboard</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> },</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'user'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">UserManagement</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> },</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'supplier'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">SupplierManagement</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> },</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'log'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">LogManagement</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> },</span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'system'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, element: <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">SystemSettings</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> },</span></span>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ],</span></span>
|
|
19
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
20
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">])</span></span>
|
|
21
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Router</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">RouterProvider</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> router</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{router} /> }</span></span></code></pre></div><p>两个根路由:</p><ul><li><code>/login</code> — 公开路由,<code>publicLoader</code> 守卫</li><li><code>/</code> 及所有子路径 — 受保护,<code>authLoader</code> 守卫,<code>MainLayout</code> 提供外壳</li></ul><p><code>Dashboard</code> 挂了两条:<code>path: ''</code>(<code>/</code>)和 <code>path: 'dashboard'</code>(<code>/dashboard</code>)都指向它。</p><h2 id="守卫" tabindex="-1">守卫 <a class="header-anchor" href="#守卫" aria-label="Permalink to "守卫""></a></h2><p><code>apps/proxy-admin/src/router/guard.ts</code>:</p><h3 id="authloader-保护路由" tabindex="-1"><code>authLoader</code>(保护路由) <a class="header-anchor" href="#authloader-保护路由" aria-label="Permalink to "\`authLoader\`(保护路由)""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> authLoader</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
22
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> token</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> user</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'user'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
24
|
+
<span class="line"></span>
|
|
25
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">token </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">||</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">user) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> redirect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/login'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
26
|
+
<span class="line"></span>
|
|
27
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { user: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">JSON</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">parse</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(user) }</span></span>
|
|
28
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li>缺 token 或 user → <code>redirect('/login')</code>(Router v6 loader 支持返回 redirect)</li><li>全 → 返回 user 供页面通过 <code>useLoaderData()</code> 拿(当前页面未使用)</li></ul><p><strong>不验证 token 有效性</strong>:验证委托给 <code>axios</code> 响应拦截器(<code>services/request.ts:55-61</code>)——真实请求 401 时清 storage 跳转登录。</p><h3 id="publicloader-登录页" tabindex="-1"><code>publicLoader</code>(登录页) <a class="header-anchor" href="#publicloader-登录页" aria-label="Permalink to "\`publicLoader\`(登录页)""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> publicLoader</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
29
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> token</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
30
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (token) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> redirect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'/dashboard'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
31
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span></span>
|
|
32
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>已登录用户访问 <code>/login</code> → 跳到 dashboard。</p><h2 id="authcontext" tabindex="-1">AuthContext <a class="header-anchor" href="#authcontext" aria-label="Permalink to "AuthContext""></a></h2><p><code>apps/proxy-admin/src/contexts/AuthContext.tsx</code>。React Context + useReducer 管理认证状态。</p><h3 id="state-reducer" tabindex="-1">State + Reducer <a class="header-anchor" href="#state-reducer" aria-label="Permalink to "State + Reducer""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AuthState</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
33
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> token</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span></span>
|
|
34
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> user</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> UserInfo</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span></span>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> isAuthenticated</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> boolean</span></span>
|
|
36
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
37
|
+
<span class="line"></span>
|
|
38
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> initialState</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AuthState</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
39
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> token: localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
40
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> user: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">JSON</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">parse</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'user'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">||</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'null'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
41
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> isAuthenticated: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
42
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
43
|
+
<span class="line"></span>
|
|
44
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">type</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AuthAction</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">type</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'LOGIN'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">payload</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">token</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">|</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">type</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'LOGOUT'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p><strong>初始 state 从 localStorage 恢复</strong>——刷新页面后 state 与 storage 一致。</p><h3 id="提供的方法" tabindex="-1">提供的方法 <a class="header-anchor" href="#提供的方法" aria-label="Permalink to "提供的方法""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> login</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">token</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">user</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, token)</span></span>
|
|
46
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'user'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">JSON</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">stringify</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(user))</span></span>
|
|
47
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> dispatch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'LOGIN'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, payload: { token, user } })</span></span>
|
|
48
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
49
|
+
<span class="line"></span>
|
|
50
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> logout</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
51
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">removeItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
52
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">removeItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'user'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
53
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> dispatch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'LOGOUT'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
|
|
54
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p><strong>双写</strong>:localStorage + React state 同步更新。守卫读 storage,组件读 context。</p><h3 id="hook" tabindex="-1">Hook <a class="header-anchor" href="#hook" aria-label="Permalink to "Hook""></a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useAuth</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
55
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> context</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useContext</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(AuthContext)</span></span>
|
|
56
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (context </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> undefined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">throw</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'useAuth must be used within an AuthProvider'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
57
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> context</span></span>
|
|
58
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>标准 Context 消费包装。使用点:<code>Login.tsx</code> 调 <code>login()</code>,<code>MainLayout.tsx</code> 显示 <code>user.nickname / user.avatar</code> 和调 <code>logout()</code>。</p><h2 id="provider-树" tabindex="-1">Provider 树 <a class="header-anchor" href="#provider-树" aria-label="Permalink to "Provider 树""></a></h2><p><code>apps/proxy-admin/src/main.tsx</code>:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">React.StrictMode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
59
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">AuthProvider</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
60
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">ConfigProvider</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> locale</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{zhCN}></span></span>
|
|
61
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Router</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /></span></span>
|
|
62
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">ConfigProvider</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
63
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> </</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">AuthProvider</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span>
|
|
64
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"></</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">React.StrictMode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">></span></span></code></pre></div><ul><li><strong><code>AuthProvider</code></strong> 在最外层——路由内部组件也能用 <code>useAuth</code></li><li><strong><code>ConfigProvider locale={zhCN}</code></strong>(Ant Design)——统一中文文案(DatePicker 等)</li><li><strong><code><Router /></code></strong> 就是 <code>RouterProvider</code></li></ul><p><code>App.tsx</code> 只是:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> App</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> <</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Router</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /> }</span></span></code></pre></div><p>主逻辑都在 <code>main.tsx</code> 的 Provider 树。</p><h2 id="完整登录流程" tabindex="-1">完整登录流程 <a class="header-anchor" href="#完整登录流程" aria-label="Permalink to "完整登录流程""></a></h2><div class="language-mermaid vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">mermaid</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">sequenceDiagram</span></span>
|
|
65
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> actor U as 用户</span></span>
|
|
66
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant L as Login 页</span></span>
|
|
67
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant API as loginApi</span></span>
|
|
68
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant M as mock/user.ts</span></span>
|
|
69
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant A as AuthContext</span></span>
|
|
70
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant LS as localStorage</span></span>
|
|
71
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant R as Router</span></span>
|
|
72
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant AL as authLoader</span></span>
|
|
73
|
+
<span class="line"></span>
|
|
74
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> U->>L: 输入 admin / 123456</span></span>
|
|
75
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> L->>API: login({ username, password })</span></span>
|
|
76
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> API->>M: POST /api/login (mock)</span></span>
|
|
77
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> M-->>API: { code: 0, data: { token, user } }</span></span>
|
|
78
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> API-->>L: response</span></span>
|
|
79
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> L->>A: login(token, user)</span></span>
|
|
80
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> A->>LS: setItem('token'/'user')</span></span>
|
|
81
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> A->>A: dispatch LOGIN</span></span>
|
|
82
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> L->>R: navigate('/dashboard')</span></span>
|
|
83
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> R->>AL: authLoader()</span></span>
|
|
84
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> AL->>LS: getItem</span></span>
|
|
85
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> AL-->>R: { user } (通过校验)</span></span>
|
|
86
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> R->>MainLayout: render</span></span></code></pre></div><h2 id="完整登出流程" tabindex="-1">完整登出流程 <a class="header-anchor" href="#完整登出流程" aria-label="Permalink to "完整登出流程""></a></h2><div class="language-mermaid vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">mermaid</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">sequenceDiagram</span></span>
|
|
87
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant ML as MainLayout</span></span>
|
|
88
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant API as logoutApi</span></span>
|
|
89
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant A as AuthContext</span></span>
|
|
90
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant LS as localStorage</span></span>
|
|
91
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant N as navigate</span></span>
|
|
92
|
+
<span class="line"></span>
|
|
93
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ML->>API: logoutApi()</span></span>
|
|
94
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> API-->>ML: { code: 0 }</span></span>
|
|
95
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ML->>A: logout()</span></span>
|
|
96
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> A->>LS: removeItem('token'/'user')</span></span>
|
|
97
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> A->>A: dispatch LOGOUT</span></span>
|
|
98
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ML->>N: navigate('/login')</span></span></code></pre></div><p>失败也调 <code>logout() + navigate('/login')</code>(<code>MainLayout.tsx:29-33</code>)——保证 UI 一致。</p><h2 id="token-过期处理" tabindex="-1">Token 过期处理 <a class="header-anchor" href="#token-过期处理" aria-label="Permalink to "Token 过期处理""></a></h2><p><code>services/request.ts</code> 拦截器(详见 <a href="./services-and-mock.html">services-and-mock.md</a>)在 401 时:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error.response?.status </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 401</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
99
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'登录已过期,请重新登录'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
100
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">removeItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'token'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
101
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">removeItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'user'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
102
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> window.location.href </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '/login'</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 硬跳转</span></span>
|
|
103
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>用 <code>window.location.href</code> 而非 <code>navigate</code> —— 拦截器在 React 组件外,无法用 Router hooks。硬跳转会重新加载整个 app,AuthProvider 重新读 localStorage 得到 unauthenticated state。</p><h2 id="types" tabindex="-1">Types <a class="header-anchor" href="#types" aria-label="Permalink to "Types""></a></h2><p><code>apps/proxy-admin/src/types/auth.ts</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> UserInfo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">username</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">nickname</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">avatar</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">email</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
104
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AuthState</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">token</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">user</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> UserInfo</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">isAuthenticated</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
105
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> LoginParams</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">username</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">password</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
106
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AuthContextType</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> extends</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AuthState</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">login</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">u</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">), </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">logout</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() }</span></span></code></pre></div><h2 id="相关" tabindex="-1">相关 <a class="header-anchor" href="#相关" aria-label="Permalink to "相关""></a></h2><ul><li>布局与顶部菜单 → <a href="./layout-and-menu.html">layout-and-menu.md</a></li><li>axios 拦截器 → <a href="./services-and-mock.html">services-and-mock.md</a></li></ul>`,50)])])}const o=i(h,[["render",l]]);export{g as __pageData,o as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as i,o as a,c as n,a2 as t}from"./chunks/framework.D_Xv2a7c.js";const g=JSON.parse('{"title":"proxy-admin / 路由与认证","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-admin/routing-and-auth.md","filePath":"proxy-admin/routing-and-auth.md"}'),h={name:"proxy-admin/routing-and-auth.md"};function l(k,s,p,e,E,r){return a(),n("div",null,[...s[0]||(s[0]=[t("",50)])])}const o=i(h,[["render",l]]);export{g as __pageData,o as default};
|