From 554a4ab5015124b4fba1cc21f9ac919e11087710 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Sat, 15 Aug 2026 15:29:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=9C=80=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/admin/.nuxt/components.d.ts | 2 + apps/admin/.nuxt/imports.d.ts | 7 +- .../9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json | 1 + apps/admin/.nuxt/nuxt.d.ts | 2 +- apps/admin/.nuxt/nuxt.node.d.ts | 2 +- apps/admin/.nuxt/tailwind/postcss.mjs | 2 +- apps/admin/.nuxt/tsconfig.app.json | 2 +- apps/admin/.nuxt/tsconfig.json | 2 +- apps/admin/.nuxt/tsconfig.shared.json | 2 +- apps/admin/.nuxt/types/components.d.ts | 2 + apps/admin/.nuxt/types/imports.d.ts | 26 + apps/admin/.output/nitro.json | 2 +- apps/admin/.output/public/_nuxt/0sLOmni-.js | 1 - .../public/_nuxt/{DBs5psLk.js => 32rNuZwS.js} | 2 +- apps/admin/.output/public/_nuxt/5wqzuVoy.js | 1 - .../public/_nuxt/{DhK7Qd_G.js => B8hrjpgL.js} | 2 +- .../public/_nuxt/{BZjLILU0.js => B9UHsPCY.js} | 2 +- .../public/_nuxt/{BIbETX06.js => BAkLwAvM.js} | 2 +- apps/admin/.output/public/_nuxt/BDDumZok.js | 1 + .../public/_nuxt/{Bj3tUDmW.js => BFjsaYIf.js} | 2 +- .../public/_nuxt/{DOqVQ2Td.js => BKXYxnNU.js} | 2 +- .../public/_nuxt/{SCeBFRND.js => BSO50kj0.js} | 2 +- .../public/_nuxt/BZKwWPxz.js} | 2 +- .../public/_nuxt/Bad2XFSd.js} | 2 +- .../public/_nuxt/{DhTcVEsy.js => Bm2Gu08J.js} | 2 +- .../public/_nuxt/{DWZBXvpA.js => Bp86Q8ON.js} | 2 +- .../public/_nuxt/{DckJLiId.js => Bs6lDwyi.js} | 2 +- .../public/_nuxt/C9zSjFPi.js} | 2 +- .../public/_nuxt/CLee_yMD.js} | 2 +- apps/admin/.output/public/_nuxt/CP0kHyLA.js | 1 - .../public/_nuxt/{B_xVdhjt.js => CUR2rcGX.js} | 2 +- .../public/_nuxt/ChqjEN2N.js} | 2 +- .../public/_nuxt/{BVhsT8W5.js => Cy52Ecc0.js} | 2 +- .../public/_nuxt/{mgru9RGc.js => D4Um3zt0.js} | 2 +- .../public/_nuxt/{9ezUT6H5.js => D5EVRMZE.js} | 2 +- .../public/_nuxt/{BCQoRucv.js => D5UrQ7F3.js} | 2 +- .../public/_nuxt/{Cx8Ep4Vy.js => D8jvJLAX.js} | 2 +- apps/admin/.output/public/_nuxt/DAaIRqev.js | 1 + .../public/_nuxt/{Dp8jCjr5.js => DBJku-16.js} | 2 +- .../public/_nuxt/DBzpctzV.js} | 2 +- apps/admin/.output/public/_nuxt/DGABB0pc.js | 1 - .../public/_nuxt/{DMxDLVSv.js => DSy_gLdM.js} | 4 +- .../public/_nuxt/{DiAHNWP8.js => DVest5s8.js} | 2 +- .../public/_nuxt/DhKR78CK.js} | 2 +- .../public/_nuxt/{D2MTseeT.js => DlgycG-C.js} | 2 +- .../public/_nuxt/{B-sqZCu-.js => EeX3zgoF.js} | 2 +- .../public/_nuxt/{BEUZObrB.js => GUJrhX2S.js} | 2 +- .../public/_nuxt/{CCZrj3X-.js => NtXZuCUg.js} | 2 +- apps/admin/.output/public/_nuxt/PbGQRI_R.js | 1 + .../.output/public/_nuxt/agents.Ba_0YWqu.css | 1 - .../.output/public/_nuxt/agents.DyZqnyeq.css | 1 + .../.output/public/_nuxt/builds/latest.json | 2 +- .../12df8bde-c7e1-423a-8c26-514d561b95ec.json | 1 + .../997f9c5b-5ea7-4cda-a9d8-aeefc19242d7.json | 1 - .../public/_nuxt/calltranslate.CJXjjd14.css | 1 - .../public/_nuxt/calltranslate.blzoinPN.css | 1 + .../public/_nuxt/channels.4kXMd4_X.css | 1 - .../public/_nuxt/channels.DbnY_8Am.css | 1 + ...{entry.w5iImZWY.css => entry.CF8jJHbs.css} | 2 +- .../public/_nuxt/{CYxZMiFx.js => obp34o1K.js} | 2 +- .../public/_nuxt/rUi_Q6ng.js} | 2 +- .../public/_nuxt/serviceconfig.FDgyvVo4.css | 1 - .../public/_nuxt/serviceconfig.UIJazB1z.css | 1 + apps/admin/.output/public/_nuxt/w_7nuVJ9.js | 1 + .../public/_nuxt/yis2MfHE.js} | 2 +- .../server/chunks/build/agents-Bh_gLb1p.mjs | 310 +++++++ .../chunks/build/agents-Bh_gLb1p.mjs.map | 1 + .../server/chunks/build/agents-DbiFqwig.mjs | 240 ------ .../chunks/build/agents-DbiFqwig.mjs.map | 1 - .../chunks/build/agents-styles.CKxmVBlz.mjs | 8 + .../build/agents-styles.CKxmVBlz.mjs.map | 1 + .../chunks/build/agents-styles.GXWAwNko.mjs | 8 - .../build/agents-styles.GXWAwNko.mjs.map | 1 - .../build/calltranslate-BllxIxWZ.mjs.map | 1 - ...llxIxWZ.mjs => calltranslate-Typ2E2m-.mjs} | 78 +- .../build/calltranslate-Typ2E2m-.mjs.map | 1 + .../build/calltranslate-styles.DejCdNUq.mjs | 8 + .../calltranslate-styles.DejCdNUq.mjs.map | 1 + .../build/calltranslate-styles.T5wE0P9E.mjs | 8 - .../calltranslate-styles.T5wE0P9E.mjs.map | 1 - ...els-DdtjGoxx.mjs => channels-CtM7-nvg.mjs} | 74 +- .../chunks/build/channels-CtM7-nvg.mjs.map | 1 + .../chunks/build/channels-DdtjGoxx.mjs.map | 1 - .../chunks/build/channels-styles.BsiooF6f.mjs | 8 - .../build/channels-styles.BsiooF6f.mjs.map | 1 - .../chunks/build/channels-styles.YMd5B91-.mjs | 8 + .../build/channels-styles.YMd5B91-.mjs.map | 1 + .../chunks/build/client.precomputed.mjs | 2 +- .../.output/server/chunks/build/server.mjs | 8 +- .../chunks/build/serviceconfig-Bq9We0Qx.mjs | 577 +++++++++++++ .../build/serviceconfig-Bq9We0Qx.mjs.map | 1 + .../chunks/build/serviceconfig-DH60tzBJ.mjs | 454 ----------- .../build/serviceconfig-DH60tzBJ.mjs.map | 1 - .../build/serviceconfig-styles.BSTefNde.mjs | 8 - .../serviceconfig-styles.BSTefNde.mjs.map | 1 - .../build/serviceconfig-styles.BoVuqbov.mjs | 8 + .../serviceconfig-styles.BoVuqbov.mjs.map | 1 + .../.output/server/chunks/build/styles.mjs | 16 +- .../.output/server/chunks/nitro/nitro.mjs | 498 ++++++------ apps/admin/app/pages/agents.vue | 218 ++++- apps/admin/app/pages/calltranslate.vue | 2 +- apps/admin/app/pages/channels.vue | 2 +- apps/admin/app/pages/serviceconfig.vue | 272 ++++++- .../nuxt/.nuxt/dist/client/_nuxt/0sLOmni-.js | 1 - .../client/_nuxt/{DBs5psLk.js => 32rNuZwS.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/5wqzuVoy.js | 1 - .../client/_nuxt/{DhK7Qd_G.js => B8hrjpgL.js} | 2 +- .../client/_nuxt/{BZjLILU0.js => B9UHsPCY.js} | 2 +- .../client/_nuxt/{BIbETX06.js => BAkLwAvM.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/BDDumZok.js | 1 + .../client/_nuxt/{Bj3tUDmW.js => BFjsaYIf.js} | 2 +- .../client/_nuxt/{DOqVQ2Td.js => BKXYxnNU.js} | 2 +- .../client/_nuxt/{SCeBFRND.js => BSO50kj0.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/BZKwWPxz.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/Bad2XFSd.js} | 2 +- .../client/_nuxt/{DhTcVEsy.js => Bm2Gu08J.js} | 2 +- .../client/_nuxt/{DWZBXvpA.js => Bp86Q8ON.js} | 2 +- .../client/_nuxt/{DckJLiId.js => Bs6lDwyi.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/C9zSjFPi.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/CLee_yMD.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/CP0kHyLA.js | 1 - .../client/_nuxt/{B_xVdhjt.js => CUR2rcGX.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/ChqjEN2N.js} | 2 +- .../client/_nuxt/{BVhsT8W5.js => Cy52Ecc0.js} | 2 +- .../client/_nuxt/{mgru9RGc.js => D4Um3zt0.js} | 2 +- .../client/_nuxt/{9ezUT6H5.js => D5EVRMZE.js} | 2 +- .../client/_nuxt/{BCQoRucv.js => D5UrQ7F3.js} | 2 +- .../client/_nuxt/{Cx8Ep4Vy.js => D8jvJLAX.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/DAaIRqev.js | 1 + .../client/_nuxt/{Dp8jCjr5.js => DBJku-16.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/DBzpctzV.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/DGABB0pc.js | 1 - .../client/_nuxt/{DMxDLVSv.js => DSy_gLdM.js} | 4 +- .../client/_nuxt/{DiAHNWP8.js => DVest5s8.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/DhKR78CK.js} | 2 +- .../client/_nuxt/{D2MTseeT.js => DlgycG-C.js} | 2 +- .../client/_nuxt/{B-sqZCu-.js => EeX3zgoF.js} | 2 +- .../client/_nuxt/{BEUZObrB.js => GUJrhX2S.js} | 2 +- .../client/_nuxt/{CCZrj3X-.js => NtXZuCUg.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/PbGQRI_R.js | 1 + .../dist/client/_nuxt/agents.Ba_0YWqu.css | 1 - .../dist/client/_nuxt/agents.DyZqnyeq.css | 1 + .../client/_nuxt/calltranslate.CJXjjd14.css | 1 - .../client/_nuxt/calltranslate.blzoinPN.css | 1 + .../dist/client/_nuxt/channels.4kXMd4_X.css | 1 - .../dist/client/_nuxt/channels.DbnY_8Am.css | 1 + ...{entry.w5iImZWY.css => entry.CF8jJHbs.css} | 2 +- .../client/_nuxt/{CYxZMiFx.js => obp34o1K.js} | 2 +- .../nuxt/.nuxt/dist/client/_nuxt/rUi_Q6ng.js} | 2 +- .../client/_nuxt/serviceconfig.FDgyvVo4.css | 1 - .../client/_nuxt/serviceconfig.UIJazB1z.css | 1 + .../nuxt/.nuxt/dist/client/_nuxt/w_7nuVJ9.js | 1 + .../nuxt/.nuxt/dist/client/_nuxt/yis2MfHE.js} | 2 +- .../dist/server/_nuxt/agents-Bh_gLb1p.js | 305 +++++++ .../dist/server/_nuxt/agents-Bh_gLb1p.js.map | 1 + .../server/_nuxt/agents-Bh_gLb1p.js.map.json | 1 + .../dist/server/_nuxt/agents-DbiFqwig.js | 235 ------ .../dist/server/_nuxt/agents-DbiFqwig.js.map | 1 - .../server/_nuxt/agents-DbiFqwig.js.map.json | 1 - .../_nuxt/agents-styles-1.mjs-BzkXHx2D.js | 5 - .../_nuxt/agents-styles-1.mjs-BzkXHx2D.js.map | 1 - .../agents-styles-1.mjs-BzkXHx2D.js.map.json | 1 - .../_nuxt/agents-styles-1.mjs-C8pM4_Q2.js | 5 + .../_nuxt/agents-styles-1.mjs-C8pM4_Q2.js.map | 1 + .../agents-styles-1.mjs-C8pM4_Q2.js.map.json | 1 + .../server/_nuxt/agents-styles.CKxmVBlz.mjs | 4 + .../server/_nuxt/agents-styles.GXWAwNko.mjs | 4 - .../_nuxt/calltranslate-BllxIxWZ.js.map | 1 - .../_nuxt/calltranslate-BllxIxWZ.js.map.json | 1 - ...-BllxIxWZ.js => calltranslate-Typ2E2m-.js} | 78 +- .../_nuxt/calltranslate-Typ2E2m-.js.map | 1 + .../_nuxt/calltranslate-Typ2E2m-.js.map.json | 1 + .../calltranslate-styles-1.mjs-DXbisy9K.js | 5 + ...calltranslate-styles-1.mjs-DXbisy9K.js.map | 1 + ...ranslate-styles-1.mjs-DXbisy9K.js.map.json | 1 + .../calltranslate-styles-1.mjs-DvCjyXm1.js | 5 - ...calltranslate-styles-1.mjs-DvCjyXm1.js.map | 1 - ...ranslate-styles-1.mjs-DvCjyXm1.js.map.json | 1 - .../_nuxt/calltranslate-styles.DejCdNUq.mjs | 4 + .../_nuxt/calltranslate-styles.T5wE0P9E.mjs | 4 - ...nnels-DdtjGoxx.js => channels-CtM7-nvg.js} | 74 +- .../server/_nuxt/channels-CtM7-nvg.js.map | 1 + .../_nuxt/channels-CtM7-nvg.js.map.json | 1 + .../server/_nuxt/channels-DdtjGoxx.js.map | 1 - .../_nuxt/channels-DdtjGoxx.js.map.json | 1 - .../_nuxt/channels-styles-1.mjs-BAM8-7CK.js | 5 + .../channels-styles-1.mjs-BAM8-7CK.js.map | 1 + ...channels-styles-1.mjs-BAM8-7CK.js.map.json | 1 + .../_nuxt/channels-styles-1.mjs-Bc-0jlqg.js | 5 - .../channels-styles-1.mjs-Bc-0jlqg.js.map | 1 - ...channels-styles-1.mjs-Bc-0jlqg.js.map.json | 1 - .../server/_nuxt/channels-styles.BsiooF6f.mjs | 4 - .../server/_nuxt/channels-styles.YMd5B91-.mjs | 4 + .../server/_nuxt/serviceconfig-Bq9We0Qx.js | 572 +++++++++++++ .../_nuxt/serviceconfig-Bq9We0Qx.js.map | 1 + .../_nuxt/serviceconfig-Bq9We0Qx.js.map.json | 1 + .../server/_nuxt/serviceconfig-DH60tzBJ.js | 449 ----------- .../_nuxt/serviceconfig-DH60tzBJ.js.map | 1 - .../_nuxt/serviceconfig-DH60tzBJ.js.map.json | 1 - .../serviceconfig-styles-1.mjs-DG7WBEIW.js | 5 - ...serviceconfig-styles-1.mjs-DG7WBEIW.js.map | 1 - ...ceconfig-styles-1.mjs-DG7WBEIW.js.map.json | 1 - .../serviceconfig-styles-1.mjs-DX7FZj_N.js | 5 + ...serviceconfig-styles-1.mjs-DX7FZj_N.js.map | 1 + ...ceconfig-styles-1.mjs-DX7FZj_N.js.map.json | 1 + .../_nuxt/serviceconfig-styles.BSTefNde.mjs | 4 - .../_nuxt/serviceconfig-styles.BoVuqbov.mjs | 4 + .../.nuxt/dist/server/client.manifest.mjs | 2 +- .../.nuxt/dist/server/client.precomputed.mjs | 2 +- .../.cache/nuxt/.nuxt/dist/server/server.mjs | 8 +- .../.cache/nuxt/.nuxt/dist/server/styles.mjs | 16 +- .../.cache/nuxt/.nuxt/manifest/latest.json | 2 +- .../12df8bde-c7e1-423a-8c26-514d561b95ec.json | 1 + .../997f9c5b-5ea7-4cda-a9d8-aeefc19242d7.json | 1 - .../node_modules/.cache/nuxt/.nuxt/nuxt.d.ts | 2 +- .../.cache/nuxt/.nuxt/nuxt.node.d.ts | 2 +- .../.cache/nuxt/.nuxt/tailwind/postcss.mjs | 2 +- .../.cache/nuxt/.nuxt/tsconfig.app.json | 2 +- .../.cache/nuxt/.nuxt/tsconfig.json | 2 +- .../.cache/nuxt/.nuxt/tsconfig.shared.json | 2 +- apps/proto/user/user_msg_v3.proto | 80 ++ apps/services/comm/agentcfg.go | 41 +- apps/services/comm/log | 2 +- apps/services/comm/module.go | 35 + apps/services/comm/ttsvoice.go | 263 ++++++ apps/services/comm/ttsvoice_test.go | 56 ++ apps/services/modules/console/api_agent.go | 77 +- apps/services/modules/console/api_config.go | 10 + .../modules/console/api_svctemplate.go | 52 +- .../console/api_svctemplate_langs_test.go | 82 ++ apps/services/modules/console/api_ttsvoice.go | 54 ++ .../services/modules/console/registry_tags.go | 22 +- apps/services/modules/console/server.go | 4 + apps/services/modules/echomeet/CLAUDE.md | 4 + apps/services/modules/echomeet/module.go | 19 + .../modules/gateway/swaggerdoc_test.go | 43 + .../modules/user/api_live_probe_test.go | 88 ++ .../modules/user/api_v2_getthirdsvcs.go | 76 +- apps/services/modules/user/api_v3.go | 45 ++ .../services/modules/user/api_v3_getagents.go | 144 ++++ .../modules/user/api_v3_getagents_test.go | 71 ++ .../modules/user/api_v3_getappconfig.go | 100 +++ apps/services/modules/user/module.go | 3 + apps/services/modules/user/svcresolve.go | 91 +++ apps/services/pb/user_msg_v3.pb.go | 755 ++++++++++++++++++ apps/services/swagger/docs.go | 327 ++++++++ apps/services/swagger/swagger.json | 327 ++++++++ apps/services/swagger/swagger.yaml | 220 +++++ deploy/README.md | 21 + deploy/dev-deploy-all.sh | 221 +++++ 250 files changed, 6124 insertions(+), 2129 deletions(-) create mode 100644 apps/admin/.nuxt/manifest/meta/9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json delete mode 100644 apps/admin/.output/public/_nuxt/0sLOmni-.js rename apps/admin/.output/public/_nuxt/{DBs5psLk.js => 32rNuZwS.js} (98%) delete mode 100644 apps/admin/.output/public/_nuxt/5wqzuVoy.js rename apps/admin/.output/public/_nuxt/{DhK7Qd_G.js => B8hrjpgL.js} (98%) rename apps/admin/.output/public/_nuxt/{BZjLILU0.js => B9UHsPCY.js} (99%) rename apps/admin/.output/public/_nuxt/{BIbETX06.js => BAkLwAvM.js} (99%) create mode 100644 apps/admin/.output/public/_nuxt/BDDumZok.js rename apps/admin/.output/public/_nuxt/{Bj3tUDmW.js => BFjsaYIf.js} (98%) rename apps/admin/.output/public/_nuxt/{DOqVQ2Td.js => BKXYxnNU.js} (95%) rename apps/admin/.output/public/_nuxt/{SCeBFRND.js => BSO50kj0.js} (98%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/ByX5RcOZ.js => .output/public/_nuxt/BZKwWPxz.js} (98%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/8OwDPhJR.js => .output/public/_nuxt/Bad2XFSd.js} (99%) rename apps/admin/.output/public/_nuxt/{DhTcVEsy.js => Bm2Gu08J.js} (94%) rename apps/admin/.output/public/_nuxt/{DWZBXvpA.js => Bp86Q8ON.js} (98%) rename apps/admin/.output/public/_nuxt/{DckJLiId.js => Bs6lDwyi.js} (99%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/Da7TefDj.js => .output/public/_nuxt/C9zSjFPi.js} (99%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BnVZ5TlV.js => .output/public/_nuxt/CLee_yMD.js} (99%) delete mode 100644 apps/admin/.output/public/_nuxt/CP0kHyLA.js rename apps/admin/.output/public/_nuxt/{B_xVdhjt.js => CUR2rcGX.js} (99%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/65zzvdWo.js => .output/public/_nuxt/ChqjEN2N.js} (98%) rename apps/admin/.output/public/_nuxt/{BVhsT8W5.js => Cy52Ecc0.js} (98%) rename apps/admin/.output/public/_nuxt/{mgru9RGc.js => D4Um3zt0.js} (97%) rename apps/admin/.output/public/_nuxt/{9ezUT6H5.js => D5EVRMZE.js} (97%) rename apps/admin/.output/public/_nuxt/{BCQoRucv.js => D5UrQ7F3.js} (71%) rename apps/admin/.output/public/_nuxt/{Cx8Ep4Vy.js => D8jvJLAX.js} (96%) create mode 100644 apps/admin/.output/public/_nuxt/DAaIRqev.js rename apps/admin/.output/public/_nuxt/{Dp8jCjr5.js => DBJku-16.js} (84%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BY3rg8Ld.js => .output/public/_nuxt/DBzpctzV.js} (97%) delete mode 100644 apps/admin/.output/public/_nuxt/DGABB0pc.js rename apps/admin/.output/public/_nuxt/{DMxDLVSv.js => DSy_gLdM.js} (98%) rename apps/admin/.output/public/_nuxt/{DiAHNWP8.js => DVest5s8.js} (93%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/D8hp1fqj.js => .output/public/_nuxt/DhKR78CK.js} (97%) rename apps/admin/.output/public/_nuxt/{D2MTseeT.js => DlgycG-C.js} (98%) rename apps/admin/.output/public/_nuxt/{B-sqZCu-.js => EeX3zgoF.js} (83%) rename apps/admin/.output/public/_nuxt/{BEUZObrB.js => GUJrhX2S.js} (98%) rename apps/admin/.output/public/_nuxt/{CCZrj3X-.js => NtXZuCUg.js} (96%) create mode 100644 apps/admin/.output/public/_nuxt/PbGQRI_R.js delete mode 100644 apps/admin/.output/public/_nuxt/agents.Ba_0YWqu.css create mode 100644 apps/admin/.output/public/_nuxt/agents.DyZqnyeq.css create mode 100644 apps/admin/.output/public/_nuxt/builds/meta/12df8bde-c7e1-423a-8c26-514d561b95ec.json delete mode 100644 apps/admin/.output/public/_nuxt/builds/meta/997f9c5b-5ea7-4cda-a9d8-aeefc19242d7.json delete mode 100644 apps/admin/.output/public/_nuxt/calltranslate.CJXjjd14.css create mode 100644 apps/admin/.output/public/_nuxt/calltranslate.blzoinPN.css delete mode 100644 apps/admin/.output/public/_nuxt/channels.4kXMd4_X.css create mode 100644 apps/admin/.output/public/_nuxt/channels.DbnY_8Am.css rename apps/admin/.output/public/_nuxt/{entry.w5iImZWY.css => entry.CF8jJHbs.css} (80%) rename apps/admin/.output/public/_nuxt/{CYxZMiFx.js => obp34o1K.js} (80%) rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BcKMjwDj.js => .output/public/_nuxt/rUi_Q6ng.js} (98%) delete mode 100644 apps/admin/.output/public/_nuxt/serviceconfig.FDgyvVo4.css create mode 100644 apps/admin/.output/public/_nuxt/serviceconfig.UIJazB1z.css create mode 100644 apps/admin/.output/public/_nuxt/w_7nuVJ9.js rename apps/admin/{node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/C8NU4rs1.js => .output/public/_nuxt/yis2MfHE.js} (99%) create mode 100644 apps/admin/.output/server/chunks/build/agents-Bh_gLb1p.mjs create mode 100644 apps/admin/.output/server/chunks/build/agents-Bh_gLb1p.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/agents-DbiFqwig.mjs delete mode 100644 apps/admin/.output/server/chunks/build/agents-DbiFqwig.mjs.map create mode 100644 apps/admin/.output/server/chunks/build/agents-styles.CKxmVBlz.mjs create mode 100644 apps/admin/.output/server/chunks/build/agents-styles.CKxmVBlz.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/agents-styles.GXWAwNko.mjs delete mode 100644 apps/admin/.output/server/chunks/build/agents-styles.GXWAwNko.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/calltranslate-BllxIxWZ.mjs.map rename apps/admin/.output/server/chunks/build/{calltranslate-BllxIxWZ.mjs => calltranslate-Typ2E2m-.mjs} (59%) create mode 100644 apps/admin/.output/server/chunks/build/calltranslate-Typ2E2m-.mjs.map create mode 100644 apps/admin/.output/server/chunks/build/calltranslate-styles.DejCdNUq.mjs create mode 100644 apps/admin/.output/server/chunks/build/calltranslate-styles.DejCdNUq.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/calltranslate-styles.T5wE0P9E.mjs delete mode 100644 apps/admin/.output/server/chunks/build/calltranslate-styles.T5wE0P9E.mjs.map rename apps/admin/.output/server/chunks/build/{channels-DdtjGoxx.mjs => channels-CtM7-nvg.mjs} (61%) create mode 100644 apps/admin/.output/server/chunks/build/channels-CtM7-nvg.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/channels-DdtjGoxx.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/channels-styles.BsiooF6f.mjs delete mode 100644 apps/admin/.output/server/chunks/build/channels-styles.BsiooF6f.mjs.map create mode 100644 apps/admin/.output/server/chunks/build/channels-styles.YMd5B91-.mjs create mode 100644 apps/admin/.output/server/chunks/build/channels-styles.YMd5B91-.mjs.map create mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-Bq9We0Qx.mjs create mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-Bq9We0Qx.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-DH60tzBJ.mjs delete mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-DH60tzBJ.mjs.map delete mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-styles.BSTefNde.mjs delete mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-styles.BSTefNde.mjs.map create mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-styles.BoVuqbov.mjs create mode 100644 apps/admin/.output/server/chunks/build/serviceconfig-styles.BoVuqbov.mjs.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/0sLOmni-.js rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DBs5psLk.js => 32rNuZwS.js} (98%) delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/5wqzuVoy.js rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DhK7Qd_G.js => B8hrjpgL.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{BZjLILU0.js => B9UHsPCY.js} (99%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{BIbETX06.js => BAkLwAvM.js} (99%) create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BDDumZok.js rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{Bj3tUDmW.js => BFjsaYIf.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DOqVQ2Td.js => BKXYxnNU.js} (95%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{SCeBFRND.js => BSO50kj0.js} (98%) rename apps/admin/{.output/public/_nuxt/ByX5RcOZ.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BZKwWPxz.js} (98%) rename apps/admin/{.output/public/_nuxt/8OwDPhJR.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/Bad2XFSd.js} (99%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DhTcVEsy.js => Bm2Gu08J.js} (94%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DWZBXvpA.js => Bp86Q8ON.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DckJLiId.js => Bs6lDwyi.js} (99%) rename apps/admin/{.output/public/_nuxt/Da7TefDj.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/C9zSjFPi.js} (99%) rename apps/admin/{.output/public/_nuxt/BnVZ5TlV.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CLee_yMD.js} (99%) delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CP0kHyLA.js rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{B_xVdhjt.js => CUR2rcGX.js} (99%) rename apps/admin/{.output/public/_nuxt/65zzvdWo.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/ChqjEN2N.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{BVhsT8W5.js => Cy52Ecc0.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{mgru9RGc.js => D4Um3zt0.js} (97%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{9ezUT6H5.js => D5EVRMZE.js} (97%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{BCQoRucv.js => D5UrQ7F3.js} (71%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{Cx8Ep4Vy.js => D8jvJLAX.js} (96%) create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DAaIRqev.js rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{Dp8jCjr5.js => DBJku-16.js} (84%) rename apps/admin/{.output/public/_nuxt/BY3rg8Ld.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DBzpctzV.js} (97%) delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DGABB0pc.js rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DMxDLVSv.js => DSy_gLdM.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{DiAHNWP8.js => DVest5s8.js} (93%) rename apps/admin/{.output/public/_nuxt/D8hp1fqj.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/DhKR78CK.js} (97%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{D2MTseeT.js => DlgycG-C.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{B-sqZCu-.js => EeX3zgoF.js} (83%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{BEUZObrB.js => GUJrhX2S.js} (98%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{CCZrj3X-.js => NtXZuCUg.js} (96%) create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/PbGQRI_R.js delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/agents.Ba_0YWqu.css create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/agents.DyZqnyeq.css delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/calltranslate.CJXjjd14.css create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/calltranslate.blzoinPN.css delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/channels.4kXMd4_X.css create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/channels.DbnY_8Am.css rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{entry.w5iImZWY.css => entry.CF8jJHbs.css} (80%) rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/{CYxZMiFx.js => obp34o1K.js} (80%) rename apps/admin/{.output/public/_nuxt/BcKMjwDj.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/rUi_Q6ng.js} (98%) delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/serviceconfig.FDgyvVo4.css create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/serviceconfig.UIJazB1z.css create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/w_7nuVJ9.js rename apps/admin/{.output/public/_nuxt/C8NU4rs1.js => node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/yis2MfHE.js} (99%) create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-Bh_gLb1p.js create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-Bh_gLb1p.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-Bh_gLb1p.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-DbiFqwig.js delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-DbiFqwig.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-DbiFqwig.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles-1.mjs-BzkXHx2D.js delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles-1.mjs-BzkXHx2D.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles-1.mjs-BzkXHx2D.js.map.json create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles-1.mjs-C8pM4_Q2.js create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles-1.mjs-C8pM4_Q2.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles-1.mjs-C8pM4_Q2.js.map.json create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles.CKxmVBlz.mjs delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/agents-styles.GXWAwNko.mjs delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-BllxIxWZ.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-BllxIxWZ.js.map.json rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/{calltranslate-BllxIxWZ.js => calltranslate-Typ2E2m-.js} (61%) create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-Typ2E2m-.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-Typ2E2m-.js.map.json create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles-1.mjs-DXbisy9K.js create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles-1.mjs-DXbisy9K.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles-1.mjs-DXbisy9K.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles-1.mjs-DvCjyXm1.js delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles-1.mjs-DvCjyXm1.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles-1.mjs-DvCjyXm1.js.map.json create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles.DejCdNUq.mjs delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/calltranslate-styles.T5wE0P9E.mjs rename apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/{channels-DdtjGoxx.js => channels-CtM7-nvg.js} (63%) create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-CtM7-nvg.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-CtM7-nvg.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-DdtjGoxx.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-DdtjGoxx.js.map.json create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles-1.mjs-BAM8-7CK.js create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles-1.mjs-BAM8-7CK.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles-1.mjs-BAM8-7CK.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles-1.mjs-Bc-0jlqg.js delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles-1.mjs-Bc-0jlqg.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles-1.mjs-Bc-0jlqg.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles.BsiooF6f.mjs create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/channels-styles.YMd5B91-.mjs create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-Bq9We0Qx.js create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-Bq9We0Qx.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-Bq9We0Qx.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-DH60tzBJ.js delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-DH60tzBJ.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-DH60tzBJ.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles-1.mjs-DG7WBEIW.js delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles-1.mjs-DG7WBEIW.js.map delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles-1.mjs-DG7WBEIW.js.map.json create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles-1.mjs-DX7FZj_N.js create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles-1.mjs-DX7FZj_N.js.map create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles-1.mjs-DX7FZj_N.js.map.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles.BSTefNde.mjs create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/dist/server/_nuxt/serviceconfig-styles.BoVuqbov.mjs create mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/manifest/meta/12df8bde-c7e1-423a-8c26-514d561b95ec.json delete mode 100644 apps/admin/node_modules/.cache/nuxt/.nuxt/manifest/meta/997f9c5b-5ea7-4cda-a9d8-aeefc19242d7.json create mode 100644 apps/proto/user/user_msg_v3.proto create mode 100644 apps/services/comm/ttsvoice.go create mode 100644 apps/services/comm/ttsvoice_test.go create mode 100644 apps/services/modules/console/api_svctemplate_langs_test.go create mode 100644 apps/services/modules/console/api_ttsvoice.go create mode 100644 apps/services/modules/gateway/swaggerdoc_test.go create mode 100644 apps/services/modules/user/api_live_probe_test.go create mode 100644 apps/services/modules/user/api_v3.go create mode 100644 apps/services/modules/user/api_v3_getagents.go create mode 100644 apps/services/modules/user/api_v3_getagents_test.go create mode 100644 apps/services/modules/user/api_v3_getappconfig.go create mode 100644 apps/services/modules/user/svcresolve.go create mode 100644 apps/services/pb/user_msg_v3.pb.go create mode 100755 deploy/dev-deploy-all.sh diff --git a/apps/admin/.nuxt/components.d.ts b/apps/admin/.nuxt/components.d.ts index eb788e7d..690f2d27 100644 --- a/apps/admin/.nuxt/components.d.ts +++ b/apps/admin/.nuxt/components.d.ts @@ -14,6 +14,7 @@ type HydrationStrategies = { type LazyComponent = DefineComponent void }> & T +export const AccountCredentialDialog: typeof import("../app/components/AccountCredentialDialog.vue")['default'] export const AppDeployTab: typeof import("../app/components/AppDeployTab.vue")['default'] export const AppLoading: typeof import("../app/components/AppLoading.vue")['default'] export const AppModuleTab: typeof import("../app/components/AppModuleTab.vue")['default'] @@ -44,6 +45,7 @@ export const Head: typeof import("../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin export const Html: typeof import("../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/head/runtime/components")['Html'] export const Body: typeof import("../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/head/runtime/components")['Body'] export const NuxtIsland: typeof import("../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/components/nuxt-island")['default'] +export const LazyAccountCredentialDialog: LazyComponent export const LazyAppDeployTab: LazyComponent export const LazyAppLoading: LazyComponent export const LazyAppModuleTab: LazyComponent diff --git a/apps/admin/.nuxt/imports.d.ts b/apps/admin/.nuxt/imports.d.ts index 1f86e85d..ad20eb3d 100644 --- a/apps/admin/.nuxt/imports.d.ts +++ b/apps/admin/.nuxt/imports.d.ts @@ -32,10 +32,11 @@ export { setInterval } from '#app/compat/interval'; export { definePageMeta, PageMeta } from '#app/composables/pages'; export { defineLazyHydrationComponent } from '#app/composables/lazy-hydration'; export { useApi } from '../app/composables/useApi'; -export { LANG_OPTIONS, langName, LangOption } from '../app/composables/useLangOptions'; +export { LANG_OPTIONS, langName, ALL_LANG_OPTIONS, LangOption } from '../app/composables/useLangOptions'; export { useLoading } from '../app/composables/useLoading'; export { useToast, ToastType, Toast } from '../app/composables/useToast'; -export { MENU_GROUPS, ALL_MENU_IDS, DEFAULT_ADMIN_ACCESS, menuItemByPath, MenuItem, MenuGroup } from '../app/utils/menus'; +export { MENU_GROUPS, ALL_MENU_IDS, DEFAULT_ADMIN_ACCESS, DEFAULT_BRAND_ACCESS, DEFAULT_DEALER_ACCESS, menuItemByPath, MenuItem, MenuGroup } from '../app/utils/menus'; +export { REGION_CN, REGION_OVERSEAS, REGION_OPTIONS, normalizeRegion, regionLabel } from '../app/utils/regions'; export { REGION_LABEL, CAT_LABEL, STATUS_META, PROBE_META, healthReason, healthLastRunText, parseCats, SvcHealth } from '../app/utils/svchealth'; -export { IDENTITY_LABELS, useAuthStore } from '../app/stores/auth'; +export { IDENTITY_LABELS, IDENTITY_ADMIN, IDENTITY_MANAGER, IDENTITY_BRAND, IDENTITY_OPERATOR, IDENTITY_DEALER, useAuthStore } from '../app/stores/auth'; export { defineStore, acceptHMRUpdate, usePinia, storeToRefs } from '../node_modules/.pnpm/@pinia+nuxt@0.11.3_magicast@0.5.3_pinia@3.0.4_typescript@5.9.3_vue@3.5.38_typescript@5.9.3__/node_modules/@pinia/nuxt/dist/runtime/composables'; \ No newline at end of file diff --git a/apps/admin/.nuxt/manifest/meta/9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json b/apps/admin/.nuxt/manifest/meta/9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/apps/admin/.nuxt/manifest/meta/9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/apps/admin/.nuxt/nuxt.d.ts b/apps/admin/.nuxt/nuxt.d.ts index 56802c21..f57c5eb1 100644 --- a/apps/admin/.nuxt/nuxt.d.ts +++ b/apps/admin/.nuxt/nuxt.d.ts @@ -1,5 +1,5 @@ -/// /// +/// /// /// /// diff --git a/apps/admin/.nuxt/nuxt.node.d.ts b/apps/admin/.nuxt/nuxt.node.d.ts index 2959d7a2..a46c5f29 100644 --- a/apps/admin/.nuxt/nuxt.node.d.ts +++ b/apps/admin/.nuxt/nuxt.node.d.ts @@ -1,5 +1,5 @@ -/// /// +/// /// /// /// diff --git a/apps/admin/.nuxt/tailwind/postcss.mjs b/apps/admin/.nuxt/tailwind/postcss.mjs index b59f7d01..513e0f04 100644 --- a/apps/admin/.nuxt/tailwind/postcss.mjs +++ b/apps/admin/.nuxt/tailwind/postcss.mjs @@ -1,4 +1,4 @@ -// generated by the @nuxtjs/tailwindcss module at 8/8/2026, 11:27:28 AM +// generated by the @nuxtjs/tailwindcss module at 8/14/2026, 11:41:43 AM import "@nuxtjs/tailwindcss/config-ctx" import configMerger from "@nuxtjs/tailwindcss/merger"; diff --git a/apps/admin/.nuxt/tsconfig.app.json b/apps/admin/.nuxt/tsconfig.app.json index 55d0933e..e347f017 100644 --- a/apps/admin/.nuxt/tsconfig.app.json +++ b/apps/admin/.nuxt/tsconfig.app.json @@ -107,7 +107,7 @@ "./imports" ], "#app-manifest": [ - "./manifest/meta/be000b5b-b015-49af-b965-1b4d373c9fb5.json" + "./manifest/meta/9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json" ], "#components": [ "./components" diff --git a/apps/admin/.nuxt/tsconfig.json b/apps/admin/.nuxt/tsconfig.json index 6cea678d..589e9e4f 100644 --- a/apps/admin/.nuxt/tsconfig.json +++ b/apps/admin/.nuxt/tsconfig.json @@ -107,7 +107,7 @@ "./imports" ], "#app-manifest": [ - "./manifest/meta/be000b5b-b015-49af-b965-1b4d373c9fb5.json" + "./manifest/meta/9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json" ], "#components": [ "./components" diff --git a/apps/admin/.nuxt/tsconfig.shared.json b/apps/admin/.nuxt/tsconfig.shared.json index 35392805..0bdd1651 100644 --- a/apps/admin/.nuxt/tsconfig.shared.json +++ b/apps/admin/.nuxt/tsconfig.shared.json @@ -107,7 +107,7 @@ "./imports" ], "#app-manifest": [ - "./manifest/meta/be000b5b-b015-49af-b965-1b4d373c9fb5.json" + "./manifest/meta/9e59d46c-ae70-43ce-82b4-ed0ffc368f78.json" ], "#build": [ "." diff --git a/apps/admin/.nuxt/types/components.d.ts b/apps/admin/.nuxt/types/components.d.ts index 0ee0bf80..6f1e2187 100644 --- a/apps/admin/.nuxt/types/components.d.ts +++ b/apps/admin/.nuxt/types/components.d.ts @@ -14,6 +14,7 @@ type HydrationStrategies = { type LazyComponent = DefineComponent void }> & T interface _GlobalComponents { + AccountCredentialDialog: typeof import("../../app/components/AccountCredentialDialog.vue")['default'] AppDeployTab: typeof import("../../app/components/AppDeployTab.vue")['default'] AppLoading: typeof import("../../app/components/AppLoading.vue")['default'] AppModuleTab: typeof import("../../app/components/AppModuleTab.vue")['default'] @@ -44,6 +45,7 @@ interface _GlobalComponents { Html: typeof import("../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/head/runtime/components")['Html'] Body: typeof import("../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/head/runtime/components")['Body'] NuxtIsland: typeof import("../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/components/nuxt-island")['default'] + LazyAccountCredentialDialog: LazyComponent LazyAppDeployTab: LazyComponent LazyAppLoading: LazyComponent LazyAppModuleTab: LazyComponent diff --git a/apps/admin/.nuxt/types/imports.d.ts b/apps/admin/.nuxt/types/imports.d.ts index 806a63ae..3716d938 100644 --- a/apps/admin/.nuxt/types/imports.d.ts +++ b/apps/admin/.nuxt/types/imports.d.ts @@ -1,14 +1,25 @@ // Generated by auto imports export {} declare global { + const ALL_LANG_OPTIONS: typeof import('../../app/composables/useLangOptions').ALL_LANG_OPTIONS const ALL_MENU_IDS: typeof import('../../app/utils/menus').ALL_MENU_IDS const CAT_LABEL: typeof import('../../app/utils/svchealth').CAT_LABEL const DEFAULT_ADMIN_ACCESS: typeof import('../../app/utils/menus').DEFAULT_ADMIN_ACCESS + const DEFAULT_BRAND_ACCESS: typeof import('../../app/utils/menus').DEFAULT_BRAND_ACCESS + const DEFAULT_DEALER_ACCESS: typeof import('../../app/utils/menus').DEFAULT_DEALER_ACCESS + const IDENTITY_ADMIN: typeof import('../../app/stores/auth').IDENTITY_ADMIN + const IDENTITY_BRAND: typeof import('../../app/stores/auth').IDENTITY_BRAND + const IDENTITY_DEALER: typeof import('../../app/stores/auth').IDENTITY_DEALER const IDENTITY_LABELS: typeof import('../../app/stores/auth').IDENTITY_LABELS + const IDENTITY_MANAGER: typeof import('../../app/stores/auth').IDENTITY_MANAGER + const IDENTITY_OPERATOR: typeof import('../../app/stores/auth').IDENTITY_OPERATOR const LANG_OPTIONS: typeof import('../../app/composables/useLangOptions').LANG_OPTIONS const MENU_GROUPS: typeof import('../../app/utils/menus').MENU_GROUPS const PROBE_META: typeof import('../../app/utils/svchealth').PROBE_META + const REGION_CN: typeof import('../../app/utils/regions').REGION_CN const REGION_LABEL: typeof import('../../app/utils/svchealth').REGION_LABEL + const REGION_OPTIONS: typeof import('../../app/utils/regions').REGION_OPTIONS + const REGION_OVERSEAS: typeof import('../../app/utils/regions').REGION_OVERSEAS const STATUS_META: typeof import('../../app/utils/svchealth').STATUS_META const abortNavigation: typeof import('../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/composables/router').abortNavigation const acceptHMRUpdate: typeof import('../../node_modules/.pnpm/@pinia+nuxt@0.11.3_magicast@0.5.3_pinia@3.0.4_typescript@5.9.3_vue@3.5.38_typescript@5.9.3__/node_modules/@pinia/nuxt/dist/runtime/composables').acceptHMRUpdate @@ -63,6 +74,7 @@ declare global { const menuItemByPath: typeof import('../../app/utils/menus').menuItemByPath const navigateTo: typeof import('../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/composables/router').navigateTo const nextTick: typeof import('vue').nextTick + const normalizeRegion: typeof import('../../app/utils/regions').normalizeRegion const onActivated: typeof import('vue').onActivated const onBeforeMount: typeof import('vue').onBeforeMount const onBeforeRouteLeave: typeof import('../../node_modules/.pnpm/vue-router@5.1.0_@vue+compiler-sfc@3.5.38_esbuild@0.28.1_pinia@3.0.4_typescript@5.9.3_v_e9d2979651266ddc95cb9659efaeda1e/node_modules/vue-router').onBeforeRouteLeave @@ -94,6 +106,7 @@ declare global { const ref: typeof import('vue').ref const refreshCookie: typeof import('../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/composables/cookie').refreshCookie const refreshNuxtData: typeof import('../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/composables/asyncData').refreshNuxtData + const regionLabel: typeof import('../../app/utils/regions').regionLabel const reloadNuxtApp: typeof import('../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/composables/chunk').reloadNuxtApp const requestIdleCallback: typeof import('../../node_modules/.pnpm/nuxt@4.4.8_@babel+plugin-syntax-jsx@7.29.7_@babel+core@7.29.7__@babel+plugin-syntax-typ_25b4a4016600149c0331b87503aafc6b/node_modules/nuxt/dist/app/compat/idle-callback').requestIdleCallback const resolveComponent: typeof import('vue').resolveComponent @@ -238,14 +251,25 @@ declare global { import { UnwrapRef } from 'vue' declare module 'vue' { interface ComponentCustomProperties { + readonly ALL_LANG_OPTIONS: UnwrapRef readonly ALL_MENU_IDS: UnwrapRef readonly CAT_LABEL: UnwrapRef readonly DEFAULT_ADMIN_ACCESS: UnwrapRef + readonly DEFAULT_BRAND_ACCESS: UnwrapRef + readonly DEFAULT_DEALER_ACCESS: UnwrapRef + readonly IDENTITY_ADMIN: UnwrapRef + readonly IDENTITY_BRAND: UnwrapRef + readonly IDENTITY_DEALER: UnwrapRef readonly IDENTITY_LABELS: UnwrapRef + readonly IDENTITY_MANAGER: UnwrapRef + readonly IDENTITY_OPERATOR: UnwrapRef readonly LANG_OPTIONS: UnwrapRef readonly MENU_GROUPS: UnwrapRef readonly PROBE_META: UnwrapRef + readonly REGION_CN: UnwrapRef readonly REGION_LABEL: UnwrapRef + readonly REGION_OPTIONS: UnwrapRef + readonly REGION_OVERSEAS: UnwrapRef readonly STATUS_META: UnwrapRef readonly abortNavigation: UnwrapRef readonly acceptHMRUpdate: UnwrapRef @@ -300,6 +324,7 @@ declare module 'vue' { readonly menuItemByPath: UnwrapRef readonly navigateTo: UnwrapRef readonly nextTick: UnwrapRef + readonly normalizeRegion: UnwrapRef readonly onActivated: UnwrapRef readonly onBeforeMount: UnwrapRef readonly onBeforeRouteLeave: UnwrapRef @@ -331,6 +356,7 @@ declare module 'vue' { readonly ref: UnwrapRef readonly refreshCookie: UnwrapRef readonly refreshNuxtData: UnwrapRef + readonly regionLabel: UnwrapRef readonly reloadNuxtApp: UnwrapRef readonly requestIdleCallback: UnwrapRef readonly resolveComponent: UnwrapRef diff --git a/apps/admin/.output/nitro.json b/apps/admin/.output/nitro.json index e61643bb..f193cc79 100644 --- a/apps/admin/.output/nitro.json +++ b/apps/admin/.output/nitro.json @@ -1,5 +1,5 @@ { - "date": "2026-08-13T01:47:09.171Z", + "date": "2026-08-14T08:52:12.283Z", "preset": "node-server", "framework": { "name": "nuxt", diff --git a/apps/admin/.output/public/_nuxt/0sLOmni-.js b/apps/admin/.output/public/_nuxt/0sLOmni-.js deleted file mode 100644 index 0b98a7cc..00000000 --- a/apps/admin/.output/public/_nuxt/0sLOmni-.js +++ /dev/null @@ -1 +0,0 @@ -import{g as ie,C as de,c as o,a as t,q as r,s as y,F as u,r as p,l as v,H as ce,t as d,d as E,v as _,b as z,x as D,p as q,y as g,z as re,A as L,o as a,L as N,n as ue,_ as pe}from"./DMxDLVSv.js";import{u as me}from"./CCZrj3X-.js";import{u as ve}from"./B-sqZCu-.js";import{L as F}from"./DD3V9C6_.js";import{_ as P}from"./mgru9RGc.js";const _e={class:"flex items-center justify-between mb-5 flex-wrap gap-3"},be={class:"flex items-center gap-3"},ge=["value"],fe={key:0,class:"text-center py-20 text-slate-300"},xe={class:"flex items-center gap-2 mb-3"},ye={class:"text-xs text-slate-400"},ke={class:"text-xs text-slate-400"},Te={class:"agent-grid"},he=["onClick"],we={class:"flex items-start justify-between gap-2"},Se={class:"min-w-0"},Ae={class:"font-semibold text-sm text-slate-800 truncate"},Ce={class:"text-[11px] text-slate-400 mt-0.5 truncate"},Ve={class:"flex items-center gap-1 flex-shrink-0"},Ue={key:0,class:"badge badge-success badge-xs"},Le={key:1,class:"badge badge-ghost badge-xs"},Ne=["onClick"],Me={key:0,class:"text-xs text-slate-500 mt-2 line-clamp-2"},Oe={class:"flex flex-wrap items-center gap-1.5 mt-3"},$e={key:1,class:"text-[11px] text-slate-400 mt-2 truncate"},je={class:"ag-box"},Be={class:"flex items-center justify-between mb-4"},Ie={class:"flex items-center gap-3"},Ee={class:"text-base font-semibold text-slate-800"},ze={class:"scope-chip"},De={class:"ed-section"},qe={class:"type-row"},Fe=["disabled","onClick"],Pe={class:"ttab-title"},Ge={class:"ttab-desc"},Je={key:0,class:"ed-tip"},He={class:"ed-section"},Re={class:"grid grid-cols-2 gap-3"},Xe=["disabled"],Ye={class:"mt-3"},Ke={class:"grid grid-cols-3 gap-3 mt-3"},Qe={class:"ed-section"},We={class:"slot-row"},Ze={class:"slot-item"},et={class:"ed-label inline"},tt=["onUpdate:modelValue"],st={value:"",disabled:""},lt=["value"],nt={key:0,class:"slot-arrow"},ot={class:"ed-section"},at={class:"grid grid-cols-2 gap-3"},it={class:"mt-3"},dt={key:0,class:"text-xs text-slate-300 py-2"},ct=["onUpdate:modelValue"],rt=["value"],ut=["onUpdate:modelValue"],pt=["onUpdate:modelValue"],mt=["onClick"],vt={key:0,class:"ed-section"},_t={class:"mt-3"},bt={class:"flex items-center gap-2 text-sm cursor-pointer"},gt={class:"ed-footer"},ft={class:"flex items-center gap-2 text-sm cursor-pointer"},xt={class:"flex gap-2"},yt=["disabled"],G=1,J=2,kt=3,Tt=4,ht=5,wt=7,H=9,St=ie({__name:"agents",setup(At){const M=[{value:"chat",label:"对话",icon:"💬",hint:"STT → LLM → TTS 三段拼接",color:"#b45309",bg:"#fef9c3"},{value:"translate",label:"翻译",icon:"🧩",hint:"STT → MT → TTS 三段拼接",color:"#059669",bg:"#dcfce7"},{value:"sts-chat",label:"端到端对话",icon:"⚡",hint:"单个 STS 服务直接完成语音对话",color:"#be185d",bg:"#fce7f3"},{value:"ast-translate",label:"端到端翻译",icon:"🚀",hint:"单个 AST 服务直接完成语音翻译",color:"#c2410c",bg:"#fff7ed"}],R={chat:[{key:"stt_svc_id",slot:"STT",label:"语音识别",cats:[G],color:"#1664ff"},{key:"llm_svc_id",slot:"LLM",label:"大语言模型",cats:[ht,H],color:"#b45309"},{key:"tts_svc_id",slot:"TTS",label:"语音合成",cats:[J],color:"#7c3aed"}],translate:[{key:"stt_svc_id",slot:"STT",label:"语音识别",cats:[G],color:"#1664ff"},{key:"mt_svc_id",slot:"MT",label:"机器翻译",cats:[kt],color:"#059669"},{key:"tts_svc_id",slot:"TTS",label:"语音合成",cats:[J],color:"#7c3aed"}],"sts-chat":[{key:"sts_svc_id",slot:"STS",label:"端到端语音对话",cats:[wt],color:"#be185d"}],"ast-translate":[{key:"ast_svc_id",slot:"AST",label:"端到端语音翻译",cats:[Tt],color:"#f97316"}]};function f(n){return R[n]??[]}const{webApi:k,consoleApi:X}=me(),{success:O,error:x}=ve(),b=g(""),A=g([]),T=g([]),h=g([]),w=g(!1),m=g(!1),C=g(!1);function V(){return{app_name:"",id:"",name:"",type:"translate",description:"",avatar_url:"",enable:!0,stt_svc_id:"",llm_svc_id:"",tts_svc_id:"",mt_svc_id:"",sts_svc_id:"",ast_svc_id:"",system_prompt:"",gender:0,greeting_enabled:!1,greeting_text:"",support_langs:"",default_lang:"",voice_map:[],sort:0}}const l=re(V()),Y=L(()=>l.type==="chat"||l.type==="sts-chat"),$=L(()=>{const n=(l.support_langs||"").split(",").map(e=>e.trim()).filter(Boolean);return n.length?F.filter(e=>n.includes(e.code)):F}),K=L(()=>M.map(n=>({...n,type:n.value,items:T.value.filter(e=>e.type===n.value).sort((e,s)=>(s.sort||0)-(e.sort||0)||(e.name||"").localeCompare(s.name||""))})).filter(n=>n.items.length));async function Q(){try{const n=await X("products/list",{});A.value=(n??[]).map(e=>e.name).filter(Boolean)}catch{A.value=[]}}async function W(){try{const n=await k("getsvcconfigs",{app_name:b.value});h.value=n?.items??[]}catch{h.value=[]}}async function U(){try{const n=await k("getagents",{app_name:b.value});T.value=(n?.items??[]).map(e=>({...e,voice_map:e.voice_map??[]}))}catch(n){x(n?.message??"加载失败"),T.value=[]}}async function j(){await Promise.all([W(),U()])}function B(n){return(n.categories||"").split(",").map(Number)}function I(n){return h.value.filter(e=>e.enable&&B(e).some(s=>n.includes(s)))}function Z(n){return B(n).includes(H)}function ee(n){if(!n)return"未配置";const e=h.value.find(s=>s.id===n);return e?e.name:n}function te(n){return f(n.type).map(e=>({slot:e.slot,color:e.color,id:n[e.key]}))}function se(){Object.assign(l,V()),m.value=!1,w.value=!0}function le(n){Object.assign(l,V(),n,{voice_map:(n.voice_map??[]).map(e=>({...e}))}),m.value=!0,w.value=!0}function S(){w.value=!1}function ne(){l.voice_map.push({language:l.default_lang||"",gender:0,voice:""})}async function oe(){if(!l.id.trim()||!l.name.trim()){x("Agent ID 和 名称 必填");return}for(const n of f(l.type))if(!(l[n.key]||"").trim()){x(`${n.slot} ${n.label} 必选`);return}C.value=!0;try{const n={...JSON.parse(JSON.stringify(l)),app_name:b.value,id:l.id.trim(),name:l.name.trim(),stt_svc_id:"",llm_svc_id:"",tts_svc_id:"",mt_svc_id:"",sts_svc_id:"",ast_svc_id:""};for(const e of f(l.type))n[e.key]=l[e.key];n.voice_map=l.voice_map.filter(e=>e.language&&e.voice),await k(m.value?"updateagent":"addagent",n),O("保存成功"),S(),await U()}catch(n){x(n?.message??"保存失败")}finally{C.value=!1}}function ae(n){window.confirm(`确定删除 Agent「${n.name||n.id}」吗?引用它的通话翻译规则会失效。`)&&k("delagent",{app_name:b.value,id:n.id}).then(()=>{O("已删除"),U()}).catch(e=>x(e?.message??"删除失败"))}return de(async()=>{await Q(),await j()}),(n,e)=>(a(),o("div",null,[t("div",_e,[e[15]||(e[15]=t("div",null,[t("h2",{class:"text-lg font-semibold text-slate-800"},"Agent 配置"),t("p",{class:"text-xs text-slate-400 mt-1"}," 把已配置的第三方服务编排成可下发客户端的智能体。四种类型按需引用不同服务;通话翻译规则只能引用「翻译」与「端到端翻译」两类。 ")],-1)),t("div",be,[e[14]||(e[14]=t("span",{class:"text-sm text-slate-500"},"作用域",-1)),r(t("select",{"onUpdate:modelValue":e[0]||(e[0]=s=>b.value=s),class:"select select-bordered select-sm",onChange:j},[e[13]||(e[13]=t("option",{value:""},"全局默认",-1)),(a(!0),o(u,null,p(A.value,s=>(a(),o("option",{key:s,value:s},d(s),9,ge))),128))],544),[[y,b.value]]),t("button",{class:"btn btn-primary btn-sm text-white",onClick:se},"+ 新建 Agent")])]),T.value.length?v("",!0):(a(),o("div",fe,[...e[16]||(e[16]=[t("div",{class:"text-5xl mb-3"},"🤖",-1),t("p",{class:"text-sm"},"当前作用域下还没有 Agent",-1),t("p",{class:"text-xs mt-1"},"先在「第三方服务配置」里配好服务,再来把它们组装成 Agent",-1)])])),(a(!0),o(u,null,p(K.value,s=>(a(),o("div",{key:s.type,class:"mb-6"},[t("div",xe,[t("span",{class:"type-tag",style:N({background:s.bg,color:s.color})},d(s.icon)+" "+d(s.label),5),t("span",ye,d(s.hint),1),e[17]||(e[17]=t("span",{class:"text-xs text-slate-300"},"·",-1)),t("span",ke,d(s.items.length)+" 个",1)]),t("div",Te,[(a(!0),o(u,null,p(s.items,c=>(a(),o("div",{key:c.id,class:"agent-card",onClick:i=>le(c)},[t("div",we,[t("div",Se,[t("div",Ae,d(c.name||c.id),1),t("div",Ce,d(c.id),1)]),t("div",Ve,[c.enable?(a(),o("span",Ue,"启用")):(a(),o("span",Le,"停用")),t("button",{class:"btn btn-ghost btn-xs text-error",onClick:q(i=>ae(c),["stop"])},"删除",8,Ne)])]),c.description?(a(),o("p",Me,d(c.description),1)):v("",!0),t("div",Oe,[(a(!0),o(u,null,p(te(c),i=>(a(),o("span",{key:i.slot,class:"svc-pill",style:N({background:i.color})},d(i.slot)+": "+d(ee(i.id)),5))),128))]),c.support_langs?(a(),o("div",$e," 支持语言:"+d(c.support_langs),1)):v("",!0)],8,he))),128))])]))),128)),r(t("div",{class:"ag-overlay",onClick:q(S,["self"])},[t("div",je,[t("div",Be,[t("div",Ie,[t("h3",Ee,d(m.value?"编辑 Agent":"新建 Agent"),1),t("span",ze,d(b.value||"全局默认"),1)]),t("button",{class:"btn btn-ghost btn-xs",onClick:S},"✕ 关闭")]),t("section",De,[e[18]||(e[18]=t("div",{class:"ed-section-title"},"类型",-1)),t("div",qe,[(a(),o(u,null,p(M,s=>t("button",{key:s.value,type:"button",class:ue(["ttab",{on:l.type===s.value,locked:m.value&&l.type!==s.value}]),disabled:m.value,onClick:c=>l.type=s.value},[t("span",Pe,d(s.icon)+" "+d(s.label),1),t("span",Ge,d(s.hint),1)],10,Fe)),64))]),m.value?(a(),o("p",Je,"类型创建后不可更改;需要换类型请新建一个 Agent。")):v("",!0)]),t("section",He,[e[26]||(e[26]=t("div",{class:"ed-section-title"},"基本信息",-1)),t("div",Re,[t("div",null,[e[19]||(e[19]=t("span",{class:"ed-label"},[E("Agent ID "),t("i",{class:"req"},"*")],-1)),r(t("input",{"onUpdate:modelValue":e[1]||(e[1]=s=>l.id=s),disabled:m.value,class:"input input-bordered input-sm w-full",placeholder:"如 trans-cn-en(作用域内唯一,创建后不可改)"},null,8,Xe),[[_,l.id]])]),t("div",null,[e[20]||(e[20]=t("span",{class:"ed-label"},[E("名称 "),t("i",{class:"req"},"*")],-1)),r(t("input",{"onUpdate:modelValue":e[2]||(e[2]=s=>l.name=s),class:"input input-bordered input-sm w-full",placeholder:"展示名,如 中英实时翻译"},null,512),[[_,l.name]])])]),t("div",Ye,[e[21]||(e[21]=t("span",{class:"ed-label"},"描述",-1)),r(t("input",{"onUpdate:modelValue":e[3]||(e[3]=s=>l.description=s),class:"input input-bordered input-sm w-full",placeholder:"这个 Agent 用在什么场景"},null,512),[[_,l.description]])]),t("div",Ke,[t("div",null,[e[22]||(e[22]=t("span",{class:"ed-label"},"头像 URL",-1)),r(t("input",{"onUpdate:modelValue":e[4]||(e[4]=s=>l.avatar_url=s),class:"input input-bordered input-sm w-full",placeholder:"可留空"},null,512),[[_,l.avatar_url]])]),t("div",null,[e[23]||(e[23]=t("span",{class:"ed-label"},"排序(越大越靠前)",-1)),r(t("input",{"onUpdate:modelValue":e[5]||(e[5]=s=>l.sort=s),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,l.sort,void 0,{number:!0}]])]),t("div",null,[e[25]||(e[25]=t("span",{class:"ed-label"},"音色性别偏好",-1)),r(t("select",{"onUpdate:modelValue":e[6]||(e[6]=s=>l.gender=s),class:"select select-bordered select-sm w-full"},[...e[24]||(e[24]=[t("option",{value:0},"不限",-1),t("option",{value:1},"男",-1),t("option",{value:2},"女",-1)])],512),[[y,l.gender,void 0,{number:!0}]])])])]),t("section",Qe,[e[27]||(e[27]=t("div",{class:"ed-section-title"},"服务编排",-1)),t("div",We,[(a(!0),o(u,null,p(f(l.type),(s,c)=>(a(),o(u,{key:s.key},[t("div",Ze,[t("span",{class:"stage-tag",style:N({background:s.color})},d(s.slot),5),t("span",et,d(s.label),1),r(t("select",{"onUpdate:modelValue":i=>l[s.key]=i,class:"select select-bordered select-sm w-full"},[t("option",st,d(I(s.cats).length?"请选择服务":"(无可用服务,请先去第三方服务配置里添加)"),1),(a(!0),o(u,null,p(I(s.cats),i=>(a(),o("option",{key:i.id,value:i.id},d(i.name)+d(Z(i)?" 🖼":""),9,lt))),128))],8,tt),[[y,l[s.key]]])]),cl.support_langs=s),multiple:""},null,8,["modelValue"])]),t("div",null,[e[29]||(e[29]=t("span",{class:"ed-label"},"默认语言",-1)),z(P,{modelValue:l.default_lang,"onUpdate:modelValue":e[8]||(e[8]=s=>l.default_lang=s),options:$.value},null,8,["modelValue","options"])])]),t("div",it,[t("div",{class:"flex items-center justify-between mb-1"},[e[30]||(e[30]=t("span",{class:"ed-label mb-0"},"音色覆盖(不填则用 TTS 服务自带默认音色)",-1)),t("button",{class:"btn btn-ghost btn-xs",onClick:ne},"+ 添加一行")]),l.voice_map.length?v("",!0):(a(),o("div",dt,"未设置音色覆盖")),(a(!0),o(u,null,p(l.voice_map,(s,c)=>(a(),o("div",{key:c,class:"voice-row"},[r(t("select",{"onUpdate:modelValue":i=>s.language=i,class:"select select-bordered select-xs"},[e[31]||(e[31]=t("option",{value:""},"(语言)",-1)),(a(!0),o(u,null,p($.value,i=>(a(),o("option",{key:i.code,value:i.code},d(i.code)+" · "+d(i.name),9,rt))),128))],8,ct),[[y,s.language]]),r(t("select",{"onUpdate:modelValue":i=>s.gender=i,class:"select select-bordered select-xs"},[...e[32]||(e[32]=[t("option",{value:0},"不限",-1),t("option",{value:1},"男",-1),t("option",{value:2},"女",-1)])],8,ut),[[y,s.gender,void 0,{number:!0}]]),r(t("input",{"onUpdate:modelValue":i=>s.voice=i,class:"input input-bordered input-xs flex-1",placeholder:"音色名,如 zh-CN-XiaoxiaoNeural"},null,8,pt),[[_,s.voice]]),t("button",{class:"btn btn-ghost btn-xs text-error",onClick:i=>l.voice_map.splice(c,1)},"删除",8,mt)]))),128))])]),Y.value?(a(),o("section",vt,[e[36]||(e[36]=t("div",{class:"ed-section-title"},"对话设定",-1)),t("div",null,[e[34]||(e[34]=t("span",{class:"ed-label"},"系统提示词",-1)),r(t("textarea",{"onUpdate:modelValue":e[9]||(e[9]=s=>l.system_prompt=s),class:"textarea textarea-bordered w-full text-xs",rows:"3",placeholder:"定义这个智能体的人设与行为"},null,512),[[_,l.system_prompt]])]),t("div",_t,[t("label",bt,[r(t("input",{"onUpdate:modelValue":e[10]||(e[10]=s=>l.greeting_enabled=s),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[D,l.greeting_enabled]]),e[35]||(e[35]=t("span",null,"开场白",-1))]),l.greeting_enabled?r((a(),o("input",{key:0,"onUpdate:modelValue":e[11]||(e[11]=s=>l.greeting_text=s),class:"input input-bordered input-sm w-full mt-2",placeholder:"接通后先说的一句话"},null,512)),[[_,l.greeting_text]]):v("",!0)])])):v("",!0),t("div",gt,[t("label",ft,[r(t("input",{"onUpdate:modelValue":e[12]||(e[12]=s=>l.enable=s),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[D,l.enable]]),e[37]||(e[37]=t("span",null,"启用",-1))]),t("div",xt,[t("button",{class:"btn btn-ghost btn-sm",onClick:S},"取消"),t("button",{class:"btn btn-primary btn-sm text-white",disabled:C.value,onClick:oe},"保存",8,yt)])])])],512),[[ce,w.value]])]))}}),Mt=pe(St,[["__scopeId","data-v-4a81d81a"]]);export{Mt as default}; diff --git a/apps/admin/.output/public/_nuxt/DBs5psLk.js b/apps/admin/.output/public/_nuxt/32rNuZwS.js similarity index 98% rename from apps/admin/.output/public/_nuxt/DBs5psLk.js rename to apps/admin/.output/public/_nuxt/32rNuZwS.js index a7989610..7e9b3ee6 100644 --- a/apps/admin/.output/public/_nuxt/DBs5psLk.js +++ b/apps/admin/.output/public/_nuxt/32rNuZwS.js @@ -1 +1 @@ -import{g as E,k as L,e as q,C as U,S as j,U as N,Q as H,V as I,W as P,X as _,Y as F,Z as V,$ as D,y as W,a0 as O,a1 as z,m as f,P as M,A as x,a2 as $,a3 as B,a4 as Q,a5 as G,a6 as X,a7 as Y,a8 as Z}from"./DMxDLVSv.js";const J=(...t)=>t.find(r=>r!==void 0);function T(t){let r=t.replace(/[\u0000-\u001F\s]+/g,"");for(;r.toLowerCase().startsWith("view-source:");)r=r.slice(12);const c=r.indexOf(":");return c>0&&Q(r.slice(0,c+1))?null:t}function K(t){const r=t.componentName||"NuxtLink";function c(e){return typeof e=="string"&&e.startsWith("#")}function w(e,s,d){const a=d??t.trailingSlash;if(!e||a!=="append"&&a!=="remove")return e;if(typeof e=="string")return R(e,a);const i="path"in e&&e.path!==void 0?e.path:s(e).path;return{...e,name:void 0,path:R(i,a)}}function k(e){const s=L(),d=G(),a=x(()=>!!f(e.target)&&f(e.target)!=="_self"),i=x(()=>{const o=f(e.to)||f(e.href)||"";return typeof o=="string"&&B(o,{acceptRelative:!0})}),C=_("RouterLink"),y=typeof C!="string"?C.useLink:void 0,v=x(()=>{if(f(e.external))return!0;const o=f(e.to)||f(e.href)||"";return typeof o=="object"?!1:o===""||i.value}),l=x(()=>{const o=f(e.to)||f(e.href)||"";return v.value?o:w(o,s.resolve,f(e.trailingSlash))}),b=v.value?void 0:y?.({...e,to:l,viewTransition:f(e.viewTransition)}),m=x(()=>{const o=f(e.trailingSlash)??t.trailingSlash;if(!l.value||i.value||c(l.value)){const h=l.value;return typeof h=="string"?T(h):h}if(v.value){const h=typeof l.value=="object"&&"path"in l.value?O(l.value):l.value,p=typeof h=="object"?s.resolve(h).href:h,u=typeof p=="string"?T(p):p;return u===null?null:R(u,o)}return typeof l.value=="object"?s.resolve(l.value)?.href??null:R($(d.app.baseURL,l.value),o)});return{to:l,hasTarget:a,isAbsoluteUrl:i,isExternal:v,href:m,isActive:b?.isActive??x(()=>l.value===s.currentRoute.value.path),isExactActive:b?.isExactActive??x(()=>l.value===s.currentRoute.value.path),route:b?.route??x(()=>s.resolve(l.value)),async navigate(o){m.value!==null&&await M(m.value,{replace:f(e.replace),external:v.value||a.value})}}}return E({name:r,props:{to:{type:[String,Object],default:void 0,required:!1},href:{type:[String,Object],default:void 0,required:!1},target:{type:String,default:void 0,required:!1},rel:{type:String,default:void 0,required:!1},noRel:{type:Boolean,default:void 0,required:!1},prefetch:{type:Boolean,default:void 0,required:!1},prefetchOn:{type:[String,Object],default:void 0,required:!1},noPrefetch:{type:Boolean,default:void 0,required:!1},activeClass:{type:String,default:void 0,required:!1},exactActiveClass:{type:String,default:void 0,required:!1},prefetchedClass:{type:String,default:void 0,required:!1},replace:{type:Boolean,default:void 0,required:!1},ariaCurrentValue:{type:String,default:void 0,required:!1},external:{type:Boolean,default:void 0,required:!1},custom:{type:Boolean,default:void 0,required:!1},trailingSlash:{type:String,default:void 0,required:!1}},useLink:k,setup(e,{slots:s}){const d=L(),{to:a,href:i,navigate:C,isExternal:y,hasTarget:v,isAbsoluteUrl:l}=k(e),b=D(!1),m=W(null),o=u=>{m.value=e.custom?u?.$el?.nextElementSibling:u?.$el};function h(u){return!b.value&&(typeof e.prefetchOn=="string"?e.prefetchOn===u:e.prefetchOn?.[u]??t.prefetchOn?.[u])&&(e.prefetch??t.prefetch)!==!1&&e.noPrefetch!==!0&&e.target!=="_blank"&&!ae()}async function p(u=q()){if(b.value||i.value===null)return;b.value=!0;const g=typeof a.value=="string"?a.value:y.value?O(a.value):d.resolve(a.value).fullPath,n=y.value?new URL(g,window.location.href).href:g;await Promise.all([u.hooks.callHook("link:prefetch",n)?.catch(()=>{}),!y.value&&!v.value&&z(a.value,d).catch(()=>{})])}if(h("visibility")){const u=q();let g,n=null;U(()=>{const S=ee();j(()=>{g=N(()=>{m?.value?.tagName&&(n=S.observe(m.value,async()=>{n?.(),n=null,await p(u)}))})})}),H(()=>{g&&I(g),n?.(),n=null})}return()=>{if(!y.value&&!v.value&&!c(a.value)){const n={ref:o,to:a.value,activeClass:e.activeClass||t.activeClass,exactActiveClass:e.exactActiveClass||t.exactActiveClass,replace:e.replace,ariaCurrentValue:e.ariaCurrentValue,custom:e.custom};return e.custom||(h("interaction")&&(n.onPointerenter=p.bind(null,void 0),n.onFocus=p.bind(null,void 0)),b.value&&(n.class=e.prefetchedClass||t.prefetchedClass),n.rel=e.rel||void 0),P(_("RouterLink"),n,s.default)}const u=e.target||null,g=J(e.noRel?"":e.rel,t.externalRelAttribute,l.value||v.value?"noopener noreferrer":"")||null;return e.custom?s.default?s.default({href:i.value,navigate:C,prefetch:p,get route(){if(!i.value)return;const n=new URL(i.value,window.location.href);return{path:n.pathname,fullPath:n.pathname,get query(){return F(n.search)},hash:n.hash,params:{},name:void 0,matched:[],redirectedFrom:void 0,meta:{},href:i.value}},rel:g,target:u,isExternal:y.value||v.value,isActive:!1,isExactActive:!1}):null:P("a",{ref:m,href:i.value||null,rel:g,target:u,onClick:async n=>{if(!(y.value||v.value)){n.preventDefault();try{const S=V(i.value??"");return await(e.replace?d.replace(S):d.push(S))}finally{if(c(a.value)){const S=a.value.slice(1);let A=S;try{A=decodeURIComponent(S)}catch{}document.getElementById(A)?.focus()}}}}},s.default?.())}}})}const le=K(Z);function R(t,r){const c=r==="append"?X:Y;return B(t)&&!t.startsWith("http")?t:c(t,!0)}function ee(){const t=q();if(t._observer)return t._observer;let r=null;const c=new Map,w=(e,s)=>(r||=new IntersectionObserver(d=>{for(const a of d){const i=c.get(a.target);(a.isIntersecting||a.intersectionRatio>0)&&i&&i()}}),c.set(e,s),r.observe(e),()=>{c.delete(e),r?.unobserve(e),c.size===0&&(r?.disconnect(),r=null)});return t._observer={observe:w}}const te=/2g/;function ae(){const t=navigator.connection;return!!(t&&(t.saveData||te.test(t.effectiveType)))}export{le as _}; +import{g as E,k as L,e as q,C as U,S as j,U as N,Q as H,V as I,W as P,X as _,Y as F,Z as V,$ as D,y as W,a0 as O,a1 as z,m as f,P as M,A as x,a2 as $,a3 as B,a4 as Q,a5 as G,a6 as X,a7 as Y,a8 as Z}from"./DSy_gLdM.js";const J=(...t)=>t.find(r=>r!==void 0);function T(t){let r=t.replace(/[\u0000-\u001F\s]+/g,"");for(;r.toLowerCase().startsWith("view-source:");)r=r.slice(12);const c=r.indexOf(":");return c>0&&Q(r.slice(0,c+1))?null:t}function K(t){const r=t.componentName||"NuxtLink";function c(e){return typeof e=="string"&&e.startsWith("#")}function w(e,s,d){const a=d??t.trailingSlash;if(!e||a!=="append"&&a!=="remove")return e;if(typeof e=="string")return R(e,a);const i="path"in e&&e.path!==void 0?e.path:s(e).path;return{...e,name:void 0,path:R(i,a)}}function k(e){const s=L(),d=G(),a=x(()=>!!f(e.target)&&f(e.target)!=="_self"),i=x(()=>{const o=f(e.to)||f(e.href)||"";return typeof o=="string"&&B(o,{acceptRelative:!0})}),C=_("RouterLink"),y=typeof C!="string"?C.useLink:void 0,v=x(()=>{if(f(e.external))return!0;const o=f(e.to)||f(e.href)||"";return typeof o=="object"?!1:o===""||i.value}),l=x(()=>{const o=f(e.to)||f(e.href)||"";return v.value?o:w(o,s.resolve,f(e.trailingSlash))}),b=v.value?void 0:y?.({...e,to:l,viewTransition:f(e.viewTransition)}),m=x(()=>{const o=f(e.trailingSlash)??t.trailingSlash;if(!l.value||i.value||c(l.value)){const h=l.value;return typeof h=="string"?T(h):h}if(v.value){const h=typeof l.value=="object"&&"path"in l.value?O(l.value):l.value,p=typeof h=="object"?s.resolve(h).href:h,u=typeof p=="string"?T(p):p;return u===null?null:R(u,o)}return typeof l.value=="object"?s.resolve(l.value)?.href??null:R($(d.app.baseURL,l.value),o)});return{to:l,hasTarget:a,isAbsoluteUrl:i,isExternal:v,href:m,isActive:b?.isActive??x(()=>l.value===s.currentRoute.value.path),isExactActive:b?.isExactActive??x(()=>l.value===s.currentRoute.value.path),route:b?.route??x(()=>s.resolve(l.value)),async navigate(o){m.value!==null&&await M(m.value,{replace:f(e.replace),external:v.value||a.value})}}}return E({name:r,props:{to:{type:[String,Object],default:void 0,required:!1},href:{type:[String,Object],default:void 0,required:!1},target:{type:String,default:void 0,required:!1},rel:{type:String,default:void 0,required:!1},noRel:{type:Boolean,default:void 0,required:!1},prefetch:{type:Boolean,default:void 0,required:!1},prefetchOn:{type:[String,Object],default:void 0,required:!1},noPrefetch:{type:Boolean,default:void 0,required:!1},activeClass:{type:String,default:void 0,required:!1},exactActiveClass:{type:String,default:void 0,required:!1},prefetchedClass:{type:String,default:void 0,required:!1},replace:{type:Boolean,default:void 0,required:!1},ariaCurrentValue:{type:String,default:void 0,required:!1},external:{type:Boolean,default:void 0,required:!1},custom:{type:Boolean,default:void 0,required:!1},trailingSlash:{type:String,default:void 0,required:!1}},useLink:k,setup(e,{slots:s}){const d=L(),{to:a,href:i,navigate:C,isExternal:y,hasTarget:v,isAbsoluteUrl:l}=k(e),b=D(!1),m=W(null),o=u=>{m.value=e.custom?u?.$el?.nextElementSibling:u?.$el};function h(u){return!b.value&&(typeof e.prefetchOn=="string"?e.prefetchOn===u:e.prefetchOn?.[u]??t.prefetchOn?.[u])&&(e.prefetch??t.prefetch)!==!1&&e.noPrefetch!==!0&&e.target!=="_blank"&&!ae()}async function p(u=q()){if(b.value||i.value===null)return;b.value=!0;const g=typeof a.value=="string"?a.value:y.value?O(a.value):d.resolve(a.value).fullPath,n=y.value?new URL(g,window.location.href).href:g;await Promise.all([u.hooks.callHook("link:prefetch",n)?.catch(()=>{}),!y.value&&!v.value&&z(a.value,d).catch(()=>{})])}if(h("visibility")){const u=q();let g,n=null;U(()=>{const S=ee();j(()=>{g=N(()=>{m?.value?.tagName&&(n=S.observe(m.value,async()=>{n?.(),n=null,await p(u)}))})})}),H(()=>{g&&I(g),n?.(),n=null})}return()=>{if(!y.value&&!v.value&&!c(a.value)){const n={ref:o,to:a.value,activeClass:e.activeClass||t.activeClass,exactActiveClass:e.exactActiveClass||t.exactActiveClass,replace:e.replace,ariaCurrentValue:e.ariaCurrentValue,custom:e.custom};return e.custom||(h("interaction")&&(n.onPointerenter=p.bind(null,void 0),n.onFocus=p.bind(null,void 0)),b.value&&(n.class=e.prefetchedClass||t.prefetchedClass),n.rel=e.rel||void 0),P(_("RouterLink"),n,s.default)}const u=e.target||null,g=J(e.noRel?"":e.rel,t.externalRelAttribute,l.value||v.value?"noopener noreferrer":"")||null;return e.custom?s.default?s.default({href:i.value,navigate:C,prefetch:p,get route(){if(!i.value)return;const n=new URL(i.value,window.location.href);return{path:n.pathname,fullPath:n.pathname,get query(){return F(n.search)},hash:n.hash,params:{},name:void 0,matched:[],redirectedFrom:void 0,meta:{},href:i.value}},rel:g,target:u,isExternal:y.value||v.value,isActive:!1,isExactActive:!1}):null:P("a",{ref:m,href:i.value||null,rel:g,target:u,onClick:async n=>{if(!(y.value||v.value)){n.preventDefault();try{const S=V(i.value??"");return await(e.replace?d.replace(S):d.push(S))}finally{if(c(a.value)){const S=a.value.slice(1);let A=S;try{A=decodeURIComponent(S)}catch{}document.getElementById(A)?.focus()}}}}},s.default?.())}}})}const le=K(Z);function R(t,r){const c=r==="append"?X:Y;return B(t)&&!t.startsWith("http")?t:c(t,!0)}function ee(){const t=q();if(t._observer)return t._observer;let r=null;const c=new Map,w=(e,s)=>(r||=new IntersectionObserver(d=>{for(const a of d){const i=c.get(a.target);(a.isIntersecting||a.intersectionRatio>0)&&i&&i()}}),c.set(e,s),r.observe(e),()=>{c.delete(e),r?.unobserve(e),c.size===0&&(r?.disconnect(),r=null)});return t._observer={observe:w}}const te=/2g/;function ae(){const t=navigator.connection;return!!(t&&(t.saveData||te.test(t.effectiveType)))}export{le as _}; diff --git a/apps/admin/.output/public/_nuxt/5wqzuVoy.js b/apps/admin/.output/public/_nuxt/5wqzuVoy.js deleted file mode 100644 index 94a12a9a..00000000 --- a/apps/admin/.output/public/_nuxt/5wqzuVoy.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as Ze}from"./mgru9RGc.js";import{g as et,C as tt,c as a,l as _,a as e,d as V,q as c,s as R,F as b,r as k,t as d,p as Ue,L as F,v as y,x as j,n as C,H as Se,y as m,z as Te,A as Q,o,I as z,D as ee,_ as lt}from"./DMxDLVSv.js";import{u as st}from"./CCZrj3X-.js";import{u as ot}from"./B-sqZCu-.js";import"./DD3V9C6_.js";const nt={key:0,class:"mb-4 rounded-lg px-4 py-3 text-sm",style:{background:"#fffbeb",border:"1px solid #fde68a",color:"#92400e"}},at={class:"flex items-center justify-between mb-5"},it={class:"flex items-center gap-3"},dt=["value"],ut=["value"],rt={key:1,class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},ct={key:2,class:"flex flex-col gap-6"},pt={class:"flex items-center gap-2 mb-3"},vt={class:"text-sm font-semibold text-slate-700"},bt={class:"text-xs text-slate-400"},mt={class:"svc-grid"},xt=["onClick"],yt={class:"card-head"},_t={class:"head-text"},ht={class:"name-line"},kt=["title"],gt=["title"],ft=["title"],wt={class:"chip-row"},Vt=["title"],Ct={class:"field-count"},Ut={key:1,class:"lock-badge"},St=["title"],Tt=["onClick"],$t={class:"text-xs text-slate-400 mt-1"},Mt={key:3,class:"bg-white rounded-2xl border border-slate-100 shadow-sm text-center text-slate-300 py-20"},At={class:"svc-box"},zt={class:"flex items-center justify-between mb-5"},Dt={class:"flex items-center gap-3"},Ft={class:"text-base font-semibold text-slate-800"},jt={class:"text-xs text-slate-400 mt-0.5"},Lt={key:0},Et={class:"flex gap-2"},It={class:"grid grid-cols-2 gap-4 mb-4"},Nt={class:"form-control"},Rt={class:"form-control"},Ot={class:"form-control mb-4"},Pt={class:"mb-4"},Bt={class:"text-xs text-slate-500 ml-2"},Ht={key:0,class:"rounded-lg px-3 py-2 mb-3 text-xs",style:{background:"#f0fdfa",border:"1px solid #99f6e4",color:"#0f766e"}},Jt={key:0,class:"text-xs text-slate-400 py-4 text-center"},qt={key:1,class:"overflow-x-auto"},Gt={class:"table text-xs"},Kt=["onUpdate:modelValue","title"],Qt=["onUpdate:modelValue"],Wt={class:"text-center"},Xt=["onUpdate:modelValue"],Yt={class:"relative"},Zt=["type","onUpdate:modelValue"],el=["onClick"],tl=["onUpdate:modelValue"],ll=["onUpdate:modelValue"],sl=["onClick"],ol={class:"wizard-steps mb-5"},nl={key:0},al={key:0},il={class:"type-grid"},dl=["onClick"],ul={class:"text-sm text-slate-700 mt-2"},rl={class:"flex items-center justify-between mb-3"},cl={class:"text-sm text-slate-500"},pl={class:"type-grid"},vl=["onClick"],bl={class:"provider-chip"},ml={class:"text-sm text-slate-700 mt-2"},xl={class:"text-[11px] text-slate-400 mt-0.5"},yl={key:0,class:"text-xs text-slate-400 mt-2"},_l={class:"flex items-center justify-between mb-3"},hl={class:"flex items-center gap-2"},kl={key:0,class:"provider-chip"},gl={class:"flex gap-2"},fl={class:"grid grid-cols-2 gap-4 mb-4"},wl={class:"form-control"},Vl={class:"form-control"},Cl={class:"grid grid-cols-2 gap-4 mb-4"},Ul={class:"form-control"},Sl={class:"form-control"},Tl={class:"form-control mb-4"},$l={key:0,class:"text-xs text-slate-400 py-4 text-center"},Ml={key:1,class:"overflow-x-auto"},Al={class:"table text-xs"},zl=["onUpdate:modelValue","title"],Dl=["onUpdate:modelValue"],Fl={class:"text-center"},jl=["onUpdate:modelValue"],Ll={class:"relative"},El=["type","onUpdate:modelValue"],Il=["onClick"],Nl=["onUpdate:modelValue"],Rl=["onUpdate:modelValue"],Ol=["onClick"],Pl={key:0,class:"text-center py-10 text-slate-400"},Bl={class:"flex items-center justify-between mb-5"},Hl={class:"flex items-center gap-3"},Jl={class:"text-base font-semibold text-slate-800"},ql={class:"badge badge-warning badge-sm mt-0.5"},Gl={class:"flex gap-2"},Kl={class:"rounded-lg px-3 py-2 mb-4 text-xs",style:{background:"#fefce8",border:"1px solid #fde047",color:"#854d0e"}},Ql={class:"overflow-x-auto"},Wl={class:"table text-xs"},Xl=["title"],Yl={class:"text-slate-500"},Zl={class:"text-center"},es={key:0,class:"disabled-badge"},ts={key:1,class:"override-badge"},ls={key:2,class:"inherit-badge"},ss={class:"text-center"},os=["onUpdate:modelValue"],ns={class:"relative"},as=["type","onUpdate:modelValue","disabled"],is=["onClick"],ds=["onUpdate:modelValue","disabled"],us=["onUpdate:modelValue","disabled","placeholder"],rs={key:0},cs={class:"divider text-xs text-slate-400 my-3"},ps={key:0,class:"text-xs text-slate-400 py-2 text-center"},vs={key:1,class:"overflow-x-auto"},bs={class:"table text-xs"},ms=["onUpdate:modelValue","title"],xs=["onUpdate:modelValue"],ys={class:"text-center"},_s=["onUpdate:modelValue"],hs={class:"relative"},ks=["type","onUpdate:modelValue"],gs=["onClick"],fs=["onUpdate:modelValue"],ws=["onClick"],Vs={class:"modal-overlay",style:{"z-index":"120"}},Cs={class:"sync-box"},Us={class:"flex items-start gap-3 mb-4"},Ss={style:{width:"42px",height:"42px",background:"linear-gradient(135deg,#4f46e5,#7c3aed)","border-radius":"13px",display:"flex","align-items":"center","justify-content":"center","flex-shrink":"0"}},Ts={style:{width:"20px",height:"20px",color:"#fff"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},$s={class:"text-xs text-slate-400 mt-1"},Ms=["innerHTML"],As={class:"flex items-center justify-between mb-1"},zs={class:"flex gap-2"},Ds={class:"sync-region-grid"},Fs=["onClick"],js=["checked","onClick"],Ls={class:"modal-overlay",style:{"z-index":"130"}},Es={class:"tpl-box"},Is={class:"flex items-center justify-between mb-4"},Ns={class:"flex gap-2"},Rs={class:"tpl-list"},Os={class:"text-xs font-semibold text-slate-500 mb-1"},Ps={style:{"min-width":"0",flex:"1"}},Bs={class:"flex items-center gap-2"},Hs={class:"font-semibold text-sm text-slate-800 truncate"},Js={class:"provider-chip"},qs={key:0,class:"badge badge-xs badge-ghost"},Gs={class:"text-xs text-slate-400 mt-0.5"},Ks={class:"flex gap-1"},Qs=["onClick"],Ws=["onClick"],Xs={key:0,class:"text-xs text-slate-400 text-center py-6"},Ys={class:"flex items-center justify-between mb-4"},Zs={class:"text-base font-semibold text-slate-800"},eo={class:"flex gap-2"},to={class:"grid grid-cols-2 gap-3 mb-3"},lo={class:"form-control"},so=["disabled"],oo={class:"form-control"},no=["value"],ao={class:"form-control"},io={class:"form-control"},uo={class:"form-control mb-3"},ro={class:"overflow-x-auto",style:{"max-height":"34vh"}},co={class:"table text-xs"},po=["onUpdate:modelValue","title"],vo=["onUpdate:modelValue"],bo={class:"text-center"},mo=["onUpdate:modelValue"],xo=["onUpdate:modelValue"],yo=["onClick"],_o={key:0},$e=10,ho=et({__name:"serviceconfig",setup(ko){const O=[{value:1,label:"中国"},{value:2,label:"美国"},{value:3,label:"东亚"},{value:4,label:"东南亚"},{value:5,label:"南亚"},{value:6,label:"中东"},{value:7,label:"欧洲"},{value:8,label:"俄罗斯"},{value:9,label:"非洲"},{value:10,label:"南美"},{value:11,label:"北美"},{value:12,label:"大洋洲"},{value:13,label:"巴西"},{value:14,label:"印度"}],P=[{v:1,label:"STT 语音识别",short:"STT",color:"#0369a1",bg:"#dbeafe"},{v:8,label:"录音文件识别",short:"录音识别",color:"#0e7490",bg:"#cffafe"},{v:2,label:"TTS 语音合成",short:"TTS",color:"#7c3aed",bg:"#ede9fe"},{v:3,label:"MT 机器翻译",short:"MT",color:"#059669",bg:"#dcfce7"},{v:4,label:"AST 端到端翻译",short:"AST",color:"#c2410c",bg:"#fff7ed"},{v:5,label:"LLM 文本大模型",short:"文本LLM",color:"#b45309",bg:"#fef9c3"},{v:9,label:"多媒体大模型",short:"多媒体LLM",color:"#9333ea",bg:"#f3e8ff"},{v:7,label:"STS 端到端对话",short:"STS",color:"#be185d",bg:"#fce7f3"},{v:6,label:"存储 OSS/COS",short:"存储",color:"#475569",bg:"#f1f5f9"},{v:10,label:"MCP 服务",short:"MCP",color:"#0d9488",bg:"#ccfbf1"}],{webApi:U,consoleApi:Me}=st(),{success:L,error:S}=ot(),M=m(""),te=m([]);async function Ae(){try{const s=await Me("products/list",{});te.value=(s??[]).map(l=>l.name).filter(Boolean)}catch{te.value=[]}}function ze(){w(),N()}function T(s){return P.find(l=>l.v===s)||{short:"?",color:"#999",bg:"#eee",v:0,label:""}}function W(){return x.value===$e?!0:!!p.value&&X(p.value.categories).includes($e)}function X(s){return(s||"").split(",").map(l=>parseInt(l)||0).filter(l=>l>0)}function ce(s){return(s.fields||[]).filter(l=>l.encrypted).length}function le(s){const l=oe.value[s.id]||[],r=l.map(t=>O.find(i=>i.value===t)?.label||"区域"+t);return g.value===0?l.length?{text:l.length+" 区域分叉",cls:"has",title:"已分叉:"+r.join("、")}:{text:"全区域通用",cls:"plain",title:"未做任何区域分叉,各区域都用默认配置"}:l.includes(g.value)?{text:"本区域已分叉",cls:"has",title:I.value+"有独立的字段配置"}:{text:"继承默认",cls:"plain",title:I.value+"未分叉,使用默认配置"}}const se=m(!0),B=m([]),oe=m({}),p=m(null),g=m(0),Y=m(!1),E=m("default"),u=Te({id:"",name:"",provider:"",description:"",enable:!1}),x=m(0),f=m([]),H=m(""),h=m(1),J=m([]),D=m([]),ne=m(!1),q=m([]),I=Q(()=>{const s=O.find(l=>l.value===g.value);return s?s.label:"区域"+g.value}),pe=Q(()=>{const s=P.map(r=>({...r,items:B.value.filter(t=>X(t.categories).includes(r.v))})).filter(r=>r.items.length),l=B.value.filter(r=>!X(r.categories).length);return l.length&&s.push({v:0,label:"未分类",short:"未分类",color:"#64748b",bg:"#f1f5f9",items:l}),s}),De=Q(()=>P.map(s=>({cat:s.v,label:s.label,items:q.value.filter(l=>l.category===s.v)})).filter(s=>s.items.length));async function N(){try{const s=await U("getsvcconfigs",{app_name:M.value});B.value=s?.items??[],oe.value=s?.regions??{},se.value=!0}catch{se.value=!1,B.value=[],oe.value={};return}if(p.value){const s=B.value.find(l=>l.id===p.value.id);s&&(p.value=s)}}async function Z(){try{const s=await U("getsvctemplates",{});q.value=s?.items??[]}catch{q.value=[]}}function Fe(){w()}function je(s){s&&(p.value=s,Y.value=!0,g.value===0?Le():Ie())}function w(){Y.value=!1,p.value=null}function Le(){const s=p.value;u.id=s.id,u.name=s.name||"",u.provider=s.provider||"",u.description=s.description||"",u.enable=!!s.enable,x.value=X(s.categories)[0]||0,f.value=JSON.parse(JSON.stringify(s.fields||[])).map(l=>({...l,_show:!1})),E.value="default"}function ae(s=0){p.value=null,u.id="",u.name="",u.provider="",u.description="",u.enable=!1,x.value=s,f.value=[],H.value="",h.value=s?2:1,E.value="new",Y.value=!0}const ve=Q(()=>q.value.filter(s=>s.category===x.value));function Ee(s){x.value!==s&&(x.value=s,H.value="",u.provider="",f.value=[]),h.value=2}function be(s){s?(H.value=s.id,u.provider=s.provider||"",u.name||(u.name=s.name||""),u.id||(u.id=s.id||""),u.description||(u.description=s.description||""),f.value=(s.fields||[]).map(l=>({key:l.key,description:l.description,type:l.type||"",encrypted:!!l.encrypted,def_value:l.def_value||"",sort:l.sort,_show:!1}))):(H.value="",u.provider="",f.value=[]),h.value=3}function me(){f.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:f.value.length,_show:!1})}function xe(s){f.value.splice(s,1),f.value.forEach((l,r)=>{l.sort=r})}async function Ie(){const s=p.value;ne.value=!0,E.value="region";try{const r=(await U("getsvcregionoverride",{app_name:M.value,svc_id:s.id,region:g.value}))?.fields??[];J.value=r.filter(t=>!t.region_only).map(t=>({key:t.key,description:t.description,type:t.type||"",encrypted:!!t.encrypted,is_overridden:!!t.is_overridden,disabled:!!t.disabled,value:t.value||"",_input:t.encrypted?"":t.is_overridden&&t.value||"",_show:!1})),D.value=r.filter(t=>t.region_only).map(t=>({key:t.key,description:t.description,encrypted:!!t.encrypted,_input:t.encrypted?"":t.value||"",_show:!1}))}catch(l){S(l?.message??"加载区域分叉失败"),J.value=[],D.value=[]}finally{ne.value=!1}}function Ne(){D.value.push({key:"",description:"",encrypted:!1,_input:"",_show:!1})}function Re(s){D.value.splice(s,1)}function Oe(s){const l={name:u.name||"",provider:u.provider||"",description:u.description||"",categories:x.value?String(x.value):"",enable:u.enable||!1,fields:f.value.map(r=>({key:r.key,description:r.description,type:r.type||"",encrypted:r.encrypted,def_value:r.def_value,sort:r.sort}))};return s?l.id=u.id||"":l.id=p.value.id,l.app_name=M.value,l}function Pe(){const s={},l=[];J.value.forEach(t=>{s[t.key]=t._input||"",t.disabled&&l.push(t.key)});const r=D.value.filter(t=>(t.key||"").trim()).map((t,i)=>({key:t.key.trim(),description:t.description,encrypted:t.encrypted,def_value:t._input||"",sort:i}));return{overrides:s,disabled_keys:l,extra_fields:r}}async function ye(s){const l=s||!p.value;if(g.value===0){const r=Oe(l);if(!r.id||!r.name)return S("服务ID 和名称 必填"),!1;const t=l?"addsvcconfig":"updatesvcconfig";try{const i=await U(t,r);return p.value=i,await N(),L("保存成功"),!0}catch(i){return S(i?.message??"保存失败"),!1}}else{const{overrides:r,disabled_keys:t,extra_fields:i}=Pe();try{return await U("savesvcregionoverride",{app_name:M.value,svc_id:p.value.id,region:g.value,overrides:r,disabled_keys:t,extra_fields:i}),await N(),L("区域分叉已保存"),!0}catch(n){return S(n?.message??"保存失败"),!1}}}async function Be(){if(p.value&&window.confirm("确定删除服务「"+p.value.name+"」及其所有区域分叉?")){try{await U("delsvcconfig",{app_name:M.value,id:p.value.id})}catch(s){S(s?.message??"删除失败");return}w(),L("已删除"),await N()}}const ie=m(!1),de=m(!1),_e=m(""),he=m(""),A=m([]),ke=Q(()=>O.filter(s=>s.value!==g.value));function ue(s){de.value=s;const l=p.value?p.value.name:u.name||"新服务",r=g.value===0;_e.value=r?"「"+l+"」默认配置将保存,可同步推送到其他区域。":"「"+l+"」在当前区域的字段分叉将保存,可同步到其他区域。",he.value=r?"✦ 同步内容:各字段默认值推送为目标区域「覆盖值」,目标区域原有分叉将被替换。":"✦ 同步内容:当前区域的值覆盖 / 区域专属字段 / 停用字段整体复制到目标区域。",A.value=[],ie.value=!0}function ge(s){const l=A.value.indexOf(s);l>=0?A.value.splice(l,1):A.value.push(s)}function fe(s){A.value=s?ke.value.map(l=>l.value):[]}function we(){ie.value=!1}async function He(){we(),await ye(de.value)&&w()}async function Je(){const s=A.value.slice();if(we(),!await ye(de.value))return;const r=p.value?p.value.id:null;if(!s.length||!r){w();return}let t=0;try{t=(await U("syncsvctoregins",{app_name:M.value,svc_id:r,src_region:g.value,target_regions:s}))?.synced??0}catch(n){S(n?.message??"同步失败");return}await N();const i=s.map(n=>{const Ce=O.find(Ye=>Ye.value===n);return Ce?Ce.label:"区域"+n});L("已保存并同步到:"+i.join("、")+"("+t+" 个)"),w()}const re=m(!1),G=m("list"),K=m(!1),v=Te({id:"",category:2,provider:"",name:"",description:""}),$=m([]);function qe(){G.value="list",re.value=!0,Z()}function Ge(){re.value=!1}function Ve(s){s?(K.value=!0,v.id=s.id,v.category=s.category||2,v.provider=s.provider||"",v.name=s.name||"",v.description=s.description||"",$.value=(s.fields||[]).map(l=>({key:l.key,description:l.description,type:l.type||"",encrypted:!!l.encrypted,def_value:l.def_value||"",sort:l.sort}))):(K.value=!1,v.id="",v.category=2,v.provider="",v.name="",v.description="",$.value=[]),G.value="form"}function Ke(){$.value.push({key:"",description:"",encrypted:!1,def_value:"",sort:$.value.length})}function Qe(s){$.value.splice(s,1),$.value.forEach((l,r)=>{l.sort=r})}async function We(){if(!v.id.trim()||!v.name.trim()||!v.provider.trim()){S("模板ID / 展示名 / 服务商标识 必填");return}const s={id:v.id.trim(),category:Number(v.category)||0,provider:v.provider.trim(),name:v.name.trim(),description:v.description.trim(),fields:$.value.map((l,r)=>({key:l.key,description:l.description,type:l.type||"",encrypted:l.encrypted,def_value:l.def_value,sort:r}))};try{await U(K.value?"updatesvctemplate":"addsvctemplate",s)}catch(l){S(l?.message??"保存失败");return}L("模板已保存"),await Z(),G.value="list"}async function Xe(s){if(window.confirm("确定删除模板「"+s.name+"」?"+(s.builtin?"(内置模板下次启动会被重新补回)":""))){try{await U("delsvctemplate",{id:s.id})}catch(l){S(l?.message??"删除失败");return}L("已删除"),await Z()}}return tt(()=>{Ae(),N(),Z()}),(s,l)=>{const r=Ze;return o(),a("div",null,[se.value?_("",!0):(o(),a("div",nt," ⚠ 「第三方服务配置」后端接口暂不可用(连接失败),请检查 console 服务是否运行。 ")),e("div",at,[l[31]||(l[31]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"第三方服务配置"),e("p",{class:"text-xs text-slate-400 mt-1"},[V("按服务类型分组管理已接入的第三方服务(火山引擎、阿里云、Azure 等)。默认展示"),e("b",null,"全局默认"),V("配置,可切换到具体应用;区域默认"),e("b",null,"中国"),V(",切换区域后点击卡片可为该区域覆盖字段值。")])],-1)),e("div",it,[c(e("select",{"onUpdate:modelValue":l[0]||(l[0]=t=>M.value=t),class:"select select-bordered select-sm",onChange:ze},[l[29]||(l[29]=e("option",{value:""},"全局默认",-1)),(o(!0),a(b,null,k(te.value,t=>(o(),a("option",{key:t,value:t},"应用:"+d(t),9,dt))),128))],544),[[R,M.value]]),c(e("select",{"onUpdate:modelValue":l[1]||(l[1]=t=>g.value=t),class:"select select-bordered select-sm",onChange:Fe},[l[30]||(l[30]=e("option",{value:0},"默认(全区域)",-1)),(o(),a(b,null,k(O,t=>e("option",{key:t.value,value:t.value},d(t.label),9,ut)),64))],544),[[R,g.value,void 0,{number:!0}]]),e("button",{class:"btn btn-ghost btn-sm",onClick:qe},"服务商模板"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[2]||(l[2]=t=>ae())},"+ 添加服务")])]),g.value!==0?(o(),a("div",rt," ✦ 当前处于「"+d(I.value)+"」区域视图:点击服务卡片编辑该区域的字段分叉(覆盖值 / 停用字段 / 区域专属字段)。要改服务本身的默认配置,请切回「默认(全区域)」。 ",1)):_("",!0),pe.value.length?(o(),a("div",ct,[(o(!0),a(b,null,k(pe.value,t=>(o(),a("section",{key:t.v},[e("div",pt,[e("span",{class:"cat-chip",style:F({color:t.color,background:t.bg})},d(t.short),5),e("h3",vt,d(t.label),1),e("span",bt,d(t.items.length)+" 个服务",1),l[32]||(l[32]=e("div",{class:"flex-1 h-px bg-slate-100 ml-2"},null,-1))]),e("div",mt,[(o(!0),a(b,null,k(t.items,i=>(o(),a("div",{key:i.id,class:C(["svc-card",{off:!i.enable}]),onClick:n=>je(i)},[e("div",yt,[e("div",{class:"svc-logo",style:F({background:i.color||"#6366f1"})},d(i.icon||(i.name||"").charAt(0)),5),e("div",_t,[e("div",ht,[e("span",{class:"svc-name",title:i.name},d(i.name),9,kt),e("span",{class:C(["state-chip",i.enable?"on":"off"])},d(i.enable?"启用":"停用"),3)]),e("p",{class:"svc-id",title:i.id},d(i.id),9,gt)])]),e("p",{class:"svc-desc",title:i.description||""},d(i.description||"—"),9,ft),e("div",wt,[i.provider?(o(),a("span",{key:0,class:"provider-chip",title:i.provider},d(i.provider),9,Vt)):_("",!0),e("span",Ct,d((i.fields||[]).length)+" 字段",1),ce(i)?(o(),a("span",Ut,"🔒"+d(ce(i)),1)):_("",!0),e("span",{class:C(["region-chip",le(i).cls]),title:le(i).title},d(le(i).text),11,St)])],10,xt))),128)),e("div",{class:"svc-card add-card",onClick:i=>ae(t.v)},[l[33]||(l[33]=e("span",{class:"text-2xl text-slate-300"},"+",-1)),e("span",$t,"添加"+d(t.short)+"服务",1)],8,Tt)])]))),128))])):(o(),a("div",Mt,[l[34]||(l[34]=e("div",{class:"text-5xl mb-3"},"⚙️",-1)),l[35]||(l[35]=e("p",{class:"text-sm mb-4"},"尚未配置任何第三方服务",-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[3]||(l[3]=t=>ae())},"+ 添加服务")])),Y.value?(o(),a("div",{key:4,class:"modal-overlay",onClick:Ue(w,["self"])},[e("div",At,[E.value==="default"&&p.value?(o(),a(b,{key:0},[e("div",zt,[e("div",Dt,[e("div",{class:"svc-logo",style:F({background:p.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(p.value.icon||(p.value.name||"").charAt(0)),5),e("div",null,[e("h3",Ft,d(p.value.name),1),e("p",jt,[V(d(p.value.id),1),u.provider?(o(),a("span",Lt," · 服务商 "+d(u.provider),1)):_("",!0)])])]),e("div",Et,[e("button",{class:"btn btn-error btn-sm btn-outline",onClick:Be},"删除服务"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[4]||(l[4]=t=>ue(!1))},"保存"),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"关闭")])]),l[45]||(l[45]=e("div",{class:"divider text-xs text-slate-400 my-3"},"基本信息",-1)),e("div",It,[e("div",Nt,[l[36]||(l[36]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),c(e("input",{"onUpdate:modelValue":l[5]||(l[5]=t=>u.name=t),class:"input input-bordered"},null,512),[[y,u.name]])]),e("div",Rt,[l[37]||(l[37]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),c(e("input",{"onUpdate:modelValue":l[6]||(l[6]=t=>u.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[j,u.enable]])])]),e("div",Ot,[l[38]||(l[38]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),c(e("input",{"onUpdate:modelValue":l[7]||(l[7]=t=>u.description=t),class:"input input-bordered"},null,512),[[y,u.description]])]),e("div",Pt,[l[39]||(l[39]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"服务类型",-1)),x.value?(o(),a("span",{key:0,class:"cat-chip",style:F({color:T(x.value).color,background:T(x.value).bg})},d(T(x.value).short),5)):_("",!0),e("span",Bt,d(x.value?T(x.value).label:"未设置"),1),l[40]||(l[40]=e("span",{class:"text-[11px] text-slate-400 ml-2"},"(类型在创建时确定,不可更改)",-1))]),l[46]||(l[46]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段(全区域共用)",-1)),W()?(o(),a("div",Ht,[...l[41]||(l[41]=[V(" ✦ MCP 服务与其他第三方服务同表存储(svc_config):这里填的 url/type/tools 为",-1),e("b",null,"全区域默认",-1),V("; 只在某些区域生效的地址,切到对应区域做分叉即可,卡片上会显示已分叉的区域数。 ",-1)])])):_("",!0),e("div",null,[f.value.length?(o(),a("div",qt,[e("table",Gt,[l[44]||(l[44]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"默认值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(o(!0),a(b,null,k(f.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,Kt),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,Qt),[[y,t.description]])]),e("td",Wt,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,Xt),[[j,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(o(),a(b,{key:2},[e("div",Yt,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t.def_value=n,placeholder:"留空保留原值"},null,8,Zt),[[ee,t.def_value]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,el)]),l[42]||(l[42]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):W()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},[...l[43]||(l[43]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,tl)),[[R,t.def_value]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},null,8,ll)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>xe(i)},"×",8,sl)])]))),128))])])])):(o(),a("p",Jt,"尚无字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:me},"+ 添加字段")])],64)):E.value==="new"?(o(),a(b,{key:1},[e("div",{class:"flex items-center justify-between mb-4"},[l[47]||(l[47]=e("h3",{class:"text-base font-semibold text-slate-800"},"新增第三方服务",-1)),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"取消")]),e("div",ol,[e("div",{class:C(["wstep",{on:h.value>=1,cur:h.value===1}]),onClick:l[8]||(l[8]=t=>h.value=1)},[l[48]||(l[48]=V("① 服务类型",-1)),x.value?(o(),a("span",nl," · "+d(T(x.value).short),1)):_("",!0)],2),l[50]||(l[50]=e("div",{class:"wline"},null,-1)),e("div",{class:C(["wstep",{on:h.value>=2,cur:h.value===2,disabled:!x.value}]),onClick:l[9]||(l[9]=t=>x.value&&(h.value=2))},[l[49]||(l[49]=V("② 服务商",-1)),u.provider?(o(),a("span",al," · "+d(u.provider),1)):_("",!0)],2),l[51]||(l[51]=e("div",{class:"wline"},null,-1)),e("div",{class:C(["wstep",{on:h.value>=3,cur:h.value===3,disabled:h.value<3}])},"③ 配置",2)]),h.value===1?(o(),a(b,{key:0},[l[52]||(l[52]=e("p",{class:"text-sm text-slate-500 mb-3"},"请选择要接入的服务类型(每个服务归属单一类型,独立配置):",-1)),e("div",il,[(o(),a(b,null,k(P,t=>e("div",{key:t.v,class:C(["type-card",{on:x.value===t.v}]),onClick:i=>Ee(t.v)},[e("span",{class:"cat-chip",style:F({color:t.color,background:t.bg})},d(t.short),5),e("span",ul,d(t.label),1)],10,dl)),64))])],64)):h.value===2?(o(),a(b,{key:1},[e("div",rl,[e("p",cl,"为「"+d(T(x.value).label)+"」选择服务商:",1),e("button",{class:"btn btn-ghost btn-xs",onClick:l[10]||(l[10]=t=>h.value=1)},"← 上一步")]),e("div",pl,[(o(!0),a(b,null,k(ve.value,t=>(o(),a("div",{key:t.id,class:C(["type-card",{on:H.value===t.id}]),onClick:i=>be(t)},[e("span",bl,d(t.provider),1),e("span",ml,d(t.name),1),e("span",xl,d((t.fields||[]).length)+" 字段",1)],10,vl))),128)),e("div",{class:"type-card",onClick:l[11]||(l[11]=t=>be(null))},[...l[53]||(l[53]=[e("span",{class:"provider-chip",style:{background:"#f1f5f9",color:"#475569"}},"自定义",-1),e("span",{class:"text-sm text-slate-700 mt-2"},"空白自定义",-1),e("span",{class:"text-[11px] text-slate-400 mt-0.5"},"手动添加字段",-1)])])]),ve.value.length?_("",!0):(o(),a("p",yl,"该类型暂无内置模板,可选「空白自定义」,或到「服务商模板」新增。"))],64)):(o(),a(b,{key:2},[e("div",_l,[e("div",hl,[e("span",{class:"cat-chip",style:F({color:T(x.value).color,background:T(x.value).bg})},d(T(x.value).short),5),u.provider?(o(),a("span",kl,d(u.provider),1)):_("",!0)]),e("div",gl,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[12]||(l[12]=t=>h.value=2)},"← 上一步"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[13]||(l[13]=t=>ue(!0))},"创建")])]),e("div",fl,[e("div",wl,[l[54]||(l[54]=e("label",{class:"label"},[e("span",{class:"label-text"},[V("服务ID * "),e("span",{class:"text-slate-400 text-xs"},"(唯一,如 tts_azure)")])],-1)),c(e("input",{"onUpdate:modelValue":l[14]||(l[14]=t=>u.id=t),class:"input input-bordered font-mono",placeholder:"tts_azure"},null,512),[[y,u.id]])]),e("div",Vl,[l[55]||(l[55]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务名称 *")],-1)),c(e("input",{"onUpdate:modelValue":l[15]||(l[15]=t=>u.name=t),class:"input input-bordered",placeholder:"微软 Azure TTS"},null,512),[[y,u.name]])])]),e("div",Cl,[e("div",Ul,[l[56]||(l[56]=e("label",{class:"label"},[e("span",{class:"label-text"},[V("服务商标识 "),e("span",{class:"text-slate-400 text-xs"},"(如 azure/alibaba)")])],-1)),c(e("input",{"onUpdate:modelValue":l[16]||(l[16]=t=>u.provider=t),class:"input input-bordered font-mono",placeholder:"azure"},null,512),[[y,u.provider]])]),e("div",Sl,[l[57]||(l[57]=e("label",{class:"label"},[e("span",{class:"label-text"},"启用")],-1)),c(e("input",{"onUpdate:modelValue":l[17]||(l[17]=t=>u.enable=t),type:"checkbox",class:"toggle toggle-primary mt-3"},null,512),[[j,u.enable]])])]),e("div",Tl,[l[58]||(l[58]=e("label",{class:"label"},[e("span",{class:"label-text"},"服务描述")],-1)),c(e("input",{"onUpdate:modelValue":l[18]||(l[18]=t=>u.description=t),class:"input input-bordered",placeholder:"简述该服务的用途"},null,512),[[y,u.description]])]),l[62]||(l[62]=e("div",{class:"divider text-xs text-slate-400 my-3"},"配置字段",-1)),e("div",null,[f.value.length?(o(),a("div",Ml,[e("table",Al,[l[61]||(l[61]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"默认值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(o(!0),a(b,null,k(f.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,zl),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,Dl),[[y,t.description]])]),e("td",Fl,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,jl),[[j,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):t.encrypted?(o(),a(b,{key:2},[e("div",Ll,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t.def_value=n,placeholder:"留空保留原值"},null,8,El),[[ee,t.def_value]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,Il)]),l[59]||(l[59]=e("span",{class:"lock-badge ml-1"},"🔒 加密",-1))],64)):W()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},[...l[60]||(l[60]=[e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,Nl)),[[R,t.def_value]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t.def_value=n},null,8,Rl)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>xe(i)},"×",8,Ol)])]))),128))])])])):(o(),a("p",$l,"尚无字段,选模板自动带出或点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:me},"+ 添加字段")])],64))],64)):E.value==="region"&&p.value?(o(),a(b,{key:2},[ne.value?(o(),a("div",Pl,"加载中...")):(o(),a(b,{key:1},[e("div",Bl,[e("div",Hl,[e("div",{class:"svc-logo",style:F({background:p.value.color||"#6366f1",width:"44px",height:"44px",fontSize:"20px"})},d(p.value.icon||(p.value.name||"").charAt(0)),5),e("div",null,[e("h3",Jl,d(p.value.name),1),e("span",ql,d(I.value)+" 分叉模式",1)])]),e("div",Gl,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[19]||(l[19]=t=>ue(!1))},"保存分叉"),e("button",{class:"btn btn-ghost btn-sm",onClick:w},"关闭")])]),e("div",Kl," ✦ 当前编辑「"+d(I.value)+"」的字段分叉:默认字段可覆盖值或勾选「不适用」停用;也可新增本区域专属字段。留空的覆盖字段继承默认值,加密字段留空保留已存储密文。 ",1),l[69]||(l[69]=e("p",{class:"text-sm font-medium text-slate-700 mb-2"},"默认字段",-1)),e("div",Ql,[e("table",Wl,[l[66]||(l[66]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-24 text-center"},"状态"),e("th",{class:"w-20 text-center"},"本区域不适用"),e("th",null,"有效值")])],-1)),e("tbody",null,[(o(!0),a(b,null,k(J.value,(t,i)=>(o(),a("tr",{key:i,class:C({"opacity-50":t.disabled})},[e("td",{class:"font-mono text-slate-700 break-all",title:t.key},d(t.key),9,Xl),e("td",Yl,d(t.description),1),e("td",Zl,[t.disabled?(o(),a("span",es,"停用")):t.is_overridden?(o(),a("span",ts,"覆盖")):(o(),a("span",ls,"继承"))]),e("td",ss,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs","onUpdate:modelValue":n=>t.disabled=n},null,8,os),[[j,t.disabled]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t._input,"onUpdate:modelValue":n=>t._input=n,multiple:!0,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t._input,"onUpdate:modelValue":n=>t._input=n,disabled:t.disabled},null,8,["modelValue","onUpdate:modelValue","disabled"])):t.encrypted?(o(),a(b,{key:2},[e("div",ns,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled,placeholder:"留空继承默认"},null,8,as),[[ee,t._input]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,is)]),l[63]||(l[63]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):W()&&t.key==="type"?c((o(),a("select",{key:3,class:"field-input","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled},[...l[64]||(l[64]=[e("option",{value:""},"继承默认",-1),e("option",{value:"0"},"HTTP",-1),e("option",{value:"1"},"SSE",-1)])],8,ds)),[[R,t._input]]):c((o(),a("input",{key:4,class:"field-input","onUpdate:modelValue":n=>t._input=n,disabled:t.disabled,placeholder:"留空继承:"+(t.value||"")},null,8,us)),[[y,t._input]])])],2))),128)),J.value.length?_("",!0):(o(),a("tr",rs,[...l[65]||(l[65]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-3"},"该服务尚无默认字段",-1)])]))])])]),e("div",cs,d(I.value)+" 专属字段",1),e("div",null,[D.value.length?(o(),a("div",vs,[e("table",bs,[l[68]||(l[68]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(o(!0),a(b,null,k(D.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,ms),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,xs),[[y,t.description]])]),e("td",ys,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,_s),[[j,t.encrypted]])]),e("td",null,[t.encrypted?(o(),a(b,{key:0},[e("div",hs,[c(e("input",{type:t._show?"text":"password",class:"field-input pr-14","onUpdate:modelValue":n=>t._input=n,placeholder:"留空保留原值"},null,8,ks),[[ee,t._input]]),e("button",{type:"button",class:"absolute right-2 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700",onClick:n=>t._show=!t._show},d(t._show?"隐藏":"显示"),9,gs)]),l[67]||(l[67]=e("span",{class:"lock-badge ml-1"},"🔒",-1))],64)):c((o(),a("input",{key:1,class:"field-input","onUpdate:modelValue":n=>t._input=n},null,8,fs)),[[y,t._input]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Re(i)},"×",8,ws)])]))),128))])])])):(o(),a("p",ps,"尚无区域专属字段,点击下方添加")),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:Ne},"+ 添加区域专属字段")])],64))],64)):_("",!0)])])):_("",!0),c(e("div",Vs,[e("div",Cs,[e("div",Us,[e("div",Ss,[(o(),a("svg",Ts,[...l[70]||(l[70]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"},null,-1)])]))]),e("div",null,[l[71]||(l[71]=e("h3",{class:"text-base font-semibold text-slate-800"},"同步到其他区域",-1)),e("p",$s,d(_e.value),1)])]),e("div",{class:"text-xs px-3 py-2 rounded-lg mb-3",style:{background:"#f0fdf4",border:"1px solid #bbf7d0",color:"#15803d"},innerHTML:he.value},null,8,Ms),e("div",As,[l[72]||(l[72]=e("span",{class:"text-xs font-semibold text-slate-500"},"选择目标区域",-1)),e("div",zs,[e("button",{class:"btn btn-ghost btn-xs",onClick:l[20]||(l[20]=t=>fe(!0))},"全选"),e("button",{class:"btn btn-ghost btn-xs",onClick:l[21]||(l[21]=t=>fe(!1))},"清空")])]),e("div",Ds,[(o(!0),a(b,null,k(ke.value,t=>(o(),a("label",{key:t.value,class:C(["sync-region-item",{checked:A.value.includes(t.value)}]),onClick:i=>ge(t.value)},[e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:A.value.includes(t.value),onClick:Ue(i=>ge(t.value),["stop"])},null,8,js),e("span",null,d(t.label),1)],10,Fs))),128))]),l[73]||(l[73]=e("p",{class:"text-[11px] text-slate-400 mb-5"},"⚠ 已勾选区域将被当前配置(值覆盖 / 区域专属字段 / 停用字段)整体替换;加密字段密文一并同步。",-1)),e("div",{class:"flex gap-3 justify-end"},[e("button",{class:"btn btn-ghost",onClick:He},"仅保存当前区域"),e("button",{class:"btn btn-primary text-white",onClick:Je},"保存并同步")])])],512),[[Se,ie.value]]),c(e("div",Ls,[e("div",Es,[G.value==="list"?(o(),a(b,{key:0},[e("div",Is,[l[74]||(l[74]=e("div",null,[e("h3",{class:"text-base font-semibold text-slate-800"},"服务商模板"),e("p",{class:"text-xs text-slate-400 mt-1"},"模板是字段预设,新增服务时可一键带出。内置模板可编辑;删除后重启会被重新补回。")],-1)),e("div",Ns,[e("button",{class:"btn btn-primary btn-sm text-white",onClick:l[22]||(l[22]=t=>Ve())},"+ 新增模板"),e("button",{class:"btn btn-ghost btn-sm",onClick:Ge},"关闭")])]),e("div",Rs,[(o(!0),a(b,null,k(De.value,t=>(o(),a("div",{key:t.cat,class:"mb-3"},[e("p",Os,d(t.label),1),(o(!0),a(b,null,k(t.items,i=>(o(),a("div",{key:i.id,class:"tpl-row"},[e("div",Ps,[e("div",Bs,[e("span",Hs,d(i.name),1),e("span",Js,d(i.provider),1),i.builtin?(o(),a("span",qs,"内置")):_("",!0)]),e("p",Gs,d(i.id)+" · "+d((i.fields||[]).length)+" 字段",1)]),e("div",Ks,[e("button",{class:"btn btn-ghost btn-xs",onClick:n=>Ve(i)},"编辑",8,Qs),e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Xe(i)},"删除",8,Ws)])]))),128))]))),128)),q.value.length?_("",!0):(o(),a("p",Xs,"暂无模板"))])],64)):(o(),a(b,{key:1},[e("div",Ys,[e("h3",Zs,d(K.value?"编辑模板":"新增模板"),1),e("div",eo,[e("button",{class:"btn btn-ghost btn-sm",onClick:l[23]||(l[23]=t=>G.value="list")},"返回"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:We},"保存")])]),e("div",to,[e("div",lo,[l[75]||(l[75]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"模板ID *")],-1)),c(e("input",{"onUpdate:modelValue":l[24]||(l[24]=t=>v.id=t),disabled:K.value,class:"input input-bordered input-sm font-mono",placeholder:"tts_azure"},null,8,so),[[y,v.id]])]),e("div",oo,[l[76]||(l[76]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"类别 *")],-1)),c(e("select",{"onUpdate:modelValue":l[25]||(l[25]=t=>v.category=t),class:"select select-bordered select-sm"},[(o(),a(b,null,k(P,t=>e("option",{key:t.v,value:t.v},d(t.label),9,no)),64))],512),[[R,v.category,void 0,{number:!0}]])]),e("div",ao,[l[77]||(l[77]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"服务商标识 *")],-1)),c(e("input",{"onUpdate:modelValue":l[26]||(l[26]=t=>v.provider=t),class:"input input-bordered input-sm font-mono",placeholder:"azure"},null,512),[[y,v.provider]])]),e("div",io,[l[78]||(l[78]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"展示名 *")],-1)),c(e("input",{"onUpdate:modelValue":l[27]||(l[27]=t=>v.name=t),class:"input input-bordered input-sm",placeholder:"微软 Azure TTS"},null,512),[[y,v.name]])])]),e("div",uo,[l[79]||(l[79]=e("label",{class:"label"},[e("span",{class:"label-text text-xs"},"描述")],-1)),c(e("input",{"onUpdate:modelValue":l[28]||(l[28]=t=>v.description=t),class:"input input-bordered input-sm"},null,512),[[y,v.description]])]),l[82]||(l[82]=e("p",{class:"text-sm font-medium text-slate-700 mb-1"},"字段",-1)),e("div",ro,[e("table",co,[l[81]||(l[81]=e("thead",null,[e("tr",null,[e("th",{class:"w-44"},"字段名"),e("th",null,"字段描述"),e("th",{class:"w-16 text-center"},"加密"),e("th",null,"默认/提示值"),e("th",{class:"w-12"})])],-1)),e("tbody",null,[(o(!0),a(b,null,k($.value,(t,i)=>(o(),a("tr",{key:i},[e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.key=n,placeholder:"key",title:t.key},null,8,po),[[y,t.key]])]),e("td",null,[c(e("input",{class:"field-input","onUpdate:modelValue":n=>t.description=n,placeholder:"用途描述"},null,8,vo),[[y,t.description]])]),e("td",bo,[c(e("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","onUpdate:modelValue":n=>t.encrypted=n},null,8,mo),[[j,t.encrypted]])]),e("td",null,[t.type==="langs"?(o(),z(r,{key:0,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n,multiple:!0},null,8,["modelValue","onUpdate:modelValue"])):t.type==="lang"?(o(),z(r,{key:1,modelValue:t.def_value,"onUpdate:modelValue":n=>t.def_value=n},null,8,["modelValue","onUpdate:modelValue"])):c((o(),a("input",{key:2,class:"field-input","onUpdate:modelValue":n=>t.def_value=n,placeholder:"可留空"},null,8,xo)),[[y,t.def_value]])]),e("td",null,[e("button",{class:"btn btn-ghost btn-xs text-error",onClick:n=>Qe(i)},"×",8,yo)])]))),128)),$.value.length?_("",!0):(o(),a("tr",_o,[...l[80]||(l[80]=[e("td",{colspan:"5",class:"text-center text-slate-400 py-2"},"尚无字段",-1)])]))])])]),e("button",{class:"btn btn-ghost btn-sm mt-2 text-primary",onClick:Ke},"+ 添加字段")],64))])],512),[[Se,re.value]])])}}}),Uo=lt(ho,[["__scopeId","data-v-8fc1a20c"]]);export{Uo as default}; diff --git a/apps/admin/.output/public/_nuxt/DhK7Qd_G.js b/apps/admin/.output/public/_nuxt/B8hrjpgL.js similarity index 98% rename from apps/admin/.output/public/_nuxt/DhK7Qd_G.js rename to apps/admin/.output/public/_nuxt/B8hrjpgL.js index a36787ef..eb40608e 100644 --- a/apps/admin/.output/public/_nuxt/DhK7Qd_G.js +++ b/apps/admin/.output/public/_nuxt/B8hrjpgL.js @@ -1 +1 @@ -import{g as P,C as R,c as r,q as n,H as V,a as t,l as B,F as H,r as I,t as i,p as z,v as a,x as L,y as b,z as E,A as O,o as u,n as T,d as q}from"./DMxDLVSv.js";import{u as G}from"./CCZrj3X-.js";import{u as K}from"./B-sqZCu-.js";const Y={class:"flex items-center justify-between mb-5"},J={class:"bg-white rounded-xl shadow-sm border border-slate-100"},Q={class:"overflow-x-auto"},W={class:"table table-zebra text-sm"},X={key:0},Z={key:1},tt={class:"font-mono"},st={class:"font-medium"},et={class:"font-mono text-xs text-slate-500"},lt={class:"text-xs text-slate-500"},ot={key:0,class:"text-green-600"},nt={key:1,class:"text-slate-400"},at={class:"flex gap-1"},dt=["onClick"],it=["onClick"],rt={class:"flex items-center gap-3 mb-5"},ut={class:"text-lg font-semibold text-slate-800"},pt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-3xl"},mt={class:"grid grid-cols-2 gap-4"},bt={class:"form-control"},ft={class:"form-control"},ct={class:"grid grid-cols-3 gap-4"},xt={class:"form-control col-span-2"},vt={class:"form-control"},gt={class:"form-control mt-4"},yt={class:"form-control mt-4"},_t={class:"grid grid-cols-2 gap-4"},kt={class:"form-control"},wt={class:"form-control"},ht={class:"form-control"},St={class:"form-control"},Vt={class:"grid grid-cols-2 gap-4"},Ct={class:"form-control"},Ut={class:"form-control"},Ht={class:"grid grid-cols-2 gap-4 mt-4"},It={class:"form-control"},Et={class:"form-control"},Tt={class:"form-control mt-4"},Dt={class:"flex items-center gap-2 mt-4"},Nt={class:"flex items-center gap-2 cursor-pointer"},$t={class:"mt-4 text-sm space-y-0.5"},At={class:"flex gap-3 mt-6"},jt=["disabled"],Ft=["disabled"],zt=P({__name:"environments",setup(Mt){const{consoleApi:c}=G(),{success:_,error:m}=K(),x=b("list"),v=b([]),k=b(!1),g=b(!1),f=b(!1),y=b(!1),d=E({show:!1,ok:!1,ssh_ok:!1,ssh_msg:"",etcd_ok:!1,etcd_msg:"",redis_ok:!1,redis_msg:"",nats_ok:!1,nats_msg:""}),D=O(()=>[{key:"ssh",label:"SSH 部署机",ok:d.ssh_ok,msg:d.ssh_msg},{key:"etcd",label:"ETCD",ok:d.etcd_ok,msg:d.etcd_msg},{key:"redis",label:"Redis",ok:d.redis_ok,msg:d.redis_msg},{key:"nats",label:"NATS",ok:d.nats_ok,msg:d.nats_msg}]);function w(){return{id:0,name:"",code:"",remark:"",enabled:!0,ssh_host:"",ssh_port:22,ssh_user:"root",ssh_private_key:"",registry:"",registry_user:"",registry_pass:"",docker_network:"1panel-network",etcd_servers:"",redis_addr:"",redis_pwd:"",nats_url:""}}const l=E(w());function C(o){Object.assign(l,w(),o)}function N(o){return o.ssh_host?`${o.ssh_user||"root"}@${o.ssh_host}:${o.ssh_port||22}`:"-"}function $(o){return o.registry||"-"}async function h(){k.value=!0;try{const o=await c("envs/list",{});v.value=o??[]}catch(o){m(o?.message??"获取环境列表失败"),v.value=[]}finally{k.value=!1}}function p(){f.value=!1,d.show=!1}function S(){x.value="list",h()}function U(o){o?(g.value=!0,C(o)):(g.value=!1,C(w())),p(),x.value="form"}async function A(){if(!l.ssh_host.trim()){m("请先填 SSH 主机");return}y.value=!0;try{const o=await c("envs/test",{...l});Object.assign(d,o,{show:!0}),f.value=!!o.ok,f.value?_("SSH 握手成功,可以保存"):m("SSH 未通过,请检查主机/私钥/用户")}catch(o){m(o?.message??"测试失败")}finally{y.value=!1}}async function j(){if(!f.value){m("请先「测试连接」通过再保存");return}const o={...l};let s="envs/add";g.value&&l.id?(o.id=Number(l.id),s="envs/update"):delete o.id;try{await c(s,o),_("保存成功"),S()}catch(e){m(e?.message??"失败")}}function F(o){window.confirm(`删除环境 #${o} ?(该环境下若有应用关联将被拒绝)`)&&c("envs/del",{id:o}).then(()=>{_("已删除"),h()}).catch(s=>m(s?.message??"失败"))}return R(h),(o,s)=>(u(),r("div",null,[n(t("div",null,[t("div",Y,[s[19]||(s[19]=t("div",null,[t("h2",{class:"text-lg font-semibold text-slate-800"},"环境节点(部署服务器)"),t("p",{class:"text-sm text-slate-400 mt-1"},"部署服务器节点(如 上海 / 日本 / 新加坡):远端 IP、SSH 登录账号与私钥、私有镜像仓库、区域共享基础设施。应用管理里「部署到目标环境」从这里选择、两边对应;下一期即可从页面直接更新服务/部署应用。密钥加密存储,不回显明文。")],-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:s[0]||(s[0]=e=>U())},"+ 新增节点")]),t("div",J,[t("div",Q,[t("table",W,[s[22]||(s[22]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"名称"),t("th",null,"区域码"),t("th",null,"SSH 目标"),t("th",null,"镜像仓库"),t("th",null,"启用"),t("th",null,"操作")])],-1)),t("tbody",null,[k.value?(u(),r("tr",X,[...s[20]||(s[20]=[t("td",{colspan:"7",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):v.value.length?B("",!0):(u(),r("tr",Z,[...s[21]||(s[21]=[t("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无环境",-1)])])),(u(!0),r(H,null,I(v.value,e=>(u(),r("tr",{key:e.id},[t("td",tt,i(e.id),1),t("td",st,i(e.name||""),1),t("td",null,i(e.code||""),1),t("td",et,i(N(e)),1),t("td",lt,i($(e)),1),t("td",null,[e.enabled?(u(),r("span",ot,"是")):(u(),r("span",nt,"否"))]),t("td",null,[t("div",at,[t("button",{class:"btn btn-ghost btn-xs",onClick:M=>U(e)},"编辑",8,dt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:M=>F(e.id)},"删除",8,it)])])]))),128))])])])])],512),[[V,x.value==="list"]]),n(t("div",null,[t("div",rt,[t("button",{class:"btn btn-ghost btn-sm",onClick:s[1]||(s[1]=e=>S())},"← 返回"),t("h2",ut,i(g.value?"编辑节点":"新增节点"),1)]),t("div",pt,[t("form",{onSubmit:z(j,["prevent"])},[t("div",mt,[t("div",bt,[s[23]||(s[23]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"名称 *")],-1)),n(t("input",{"onUpdate:modelValue":s[2]||(s[2]=e=>l.name=e),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 上海生产"},null,512),[[a,l.name]])]),t("div",ft,[s[24]||(s[24]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"区域码")],-1)),n(t("input",{"onUpdate:modelValue":s[3]||(s[3]=e=>l.code=e),type:"text",class:"input input-bordered w-full",list:"env-code-list",placeholder:"shanghai / japan / singapore"},null,512),[[a,l.code]]),s[25]||(s[25]=t("datalist",{id:"env-code-list"},[t("option",{value:"shanghai"}),t("option",{value:"japan"}),t("option",{value:"singapore"})],-1))])]),s[41]||(s[41]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"SSH 部署目标",-1)),t("div",ct,[t("div",xt,[s[26]||(s[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 主机")],-1)),n(t("input",{"onUpdate:modelValue":s[4]||(s[4]=e=>l.ssh_host=e),type:"text",class:"input input-bordered w-full",placeholder:"139.224.212.237",onInput:p},null,544),[[a,l.ssh_host]])]),t("div",vt,[s[27]||(s[27]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"端口")],-1)),n(t("input",{"onUpdate:modelValue":s[5]||(s[5]=e=>l.ssh_port=e),type:"number",class:"input input-bordered w-full",placeholder:"22",onInput:p},null,544),[[a,l.ssh_port,void 0,{number:!0}]])])]),t("div",gt,[s[28]||(s[28]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 用户")],-1)),n(t("input",{"onUpdate:modelValue":s[6]||(s[6]=e=>l.ssh_user=e),type:"text",class:"input input-bordered w-full",placeholder:"root",onInput:p},null,544),[[a,l.ssh_user]])]),t("div",yt,[s[29]||(s[29]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 私钥 (PEM)")],-1)),n(t("textarea",{"onUpdate:modelValue":s[7]||(s[7]=e=>l.ssh_private_key=e),class:"textarea textarea-bordered w-full font-mono text-xs h-28",placeholder:"-----BEGIN OPENSSH PRIVATE KEY-----",onInput:p},null,544),[[a,l.ssh_private_key]]),s[30]||(s[30]=t("span",{class:"text-xs text-slate-400 mt-1"},"加密存储;编辑时显示 [encrypted] 表示不改,如需更换直接粘贴新私钥。",-1))]),s[42]||(s[42]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"私有镜像仓库 + Docker 网络",-1)),t("div",_t,[t("div",kt,[s[31]||(s[31]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库地址")],-1)),n(t("input",{"onUpdate:modelValue":s[8]||(s[8]=e=>l.registry=e),type:"text",class:"input input-bordered w-full",placeholder:"docker-registry.ideapsound.com"},null,512),[[a,l.registry]])]),t("div",wt,[s[32]||(s[32]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Docker 网络")],-1)),n(t("input",{"onUpdate:modelValue":s[9]||(s[9]=e=>l.docker_network=e),type:"text",class:"input input-bordered w-full",placeholder:"1panel-network"},null,512),[[a,l.docker_network]])]),t("div",ht,[s[33]||(s[33]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库账号")],-1)),n(t("input",{"onUpdate:modelValue":s[10]||(s[10]=e=>l.registry_user=e),type:"text",class:"input input-bordered w-full",autocomplete:"off"},null,512),[[a,l.registry_user]])]),t("div",St,[s[34]||(s[34]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库密码")],-1)),n(t("input",{"onUpdate:modelValue":s[11]||(s[11]=e=>l.registry_pass=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.registry_pass]])])]),s[43]||(s[43]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"节点共享集群服务",-1)),s[44]||(s[44]=t("p",{class:"text-xs text-slate-400 -mt-2 mb-2"},"该服务器上各应用共用的地址。各应用自己的部署目录、业务库 DSN、镜像、redis 库号等,在「应用管理 → 部署到目标环境」里按应用填。",-1)),t("div",Vt,[t("div",Ct,[s[35]||(s[35]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"ETCD")],-1)),n(t("input",{"onUpdate:modelValue":s[12]||(s[12]=e=>l.etcd_servers=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"etcd:2379",onInput:p},null,544),[[a,l.etcd_servers]])]),t("div",Ut,[s[36]||(s[36]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"NATS")],-1)),n(t("input",{"onUpdate:modelValue":s[13]||(s[13]=e=>l.nats_url=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"nats://nats:4222",onInput:p},null,544),[[a,l.nats_url]])])]),t("div",Ht,[t("div",It,[s[37]||(s[37]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 地址")],-1)),n(t("input",{"onUpdate:modelValue":s[14]||(s[14]=e=>l.redis_addr=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"redis:6379",onInput:p},null,544),[[a,l.redis_addr]])]),t("div",Et,[s[38]||(s[38]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 密码")],-1)),n(t("input",{"onUpdate:modelValue":s[15]||(s[15]=e=>l.redis_pwd=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.redis_pwd]])])]),t("div",Tt,[s[39]||(s[39]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"备注")],-1)),n(t("input",{"onUpdate:modelValue":s[16]||(s[16]=e=>l.remark=e),type:"text",class:"input input-bordered w-full"},null,512),[[a,l.remark]])]),t("div",Dt,[t("label",Nt,[n(t("input",{"onUpdate:modelValue":s[17]||(s[17]=e=>l.enabled=e),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[L,l.enabled]]),s[40]||(s[40]=t("span",{class:"text-sm"},"启用",-1))])]),n(t("div",$t,[(u(!0),r(H,null,I(D.value,e=>(u(),r("div",{key:e.key,class:T(e.ok?"text-green-700":"text-red-600")},[t("span",{class:T(e.ok?"text-green-600":"text-red-500")},i(e.ok?"✓":"✗"),3),q(" "+i(e.label)+":"+i(e.msg),1)],2))),128))],512),[[V,d.show]]),t("div",At,[t("button",{type:"button",class:"btn btn-ghost",onClick:s[18]||(s[18]=e=>S())},"取消"),t("button",{type:"button",class:"btn btn-outline",disabled:y.value,onClick:A},i(y.value?"测试中...":"测试连接"),9,jt),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:!f.value},"保存",8,Ft)]),s[45]||(s[45]=t("p",{class:"text-xs text-slate-400 mt-2"},"需先「测试连接」(SSH 握手成功即可保存;基础设施逐项仅作提示)。",-1))],32)])],512),[[V,x.value==="form"]])]))}});export{zt as default}; +import{g as P,C as R,c as r,q as n,H as V,a as t,l as B,F as H,r as I,t as i,p as z,v as a,x as L,y as b,z as E,A as O,o as u,n as T,d as q}from"./DSy_gLdM.js";import{u as G}from"./NtXZuCUg.js";import{u as K}from"./EeX3zgoF.js";const Y={class:"flex items-center justify-between mb-5"},J={class:"bg-white rounded-xl shadow-sm border border-slate-100"},Q={class:"overflow-x-auto"},W={class:"table table-zebra text-sm"},X={key:0},Z={key:1},tt={class:"font-mono"},st={class:"font-medium"},et={class:"font-mono text-xs text-slate-500"},lt={class:"text-xs text-slate-500"},ot={key:0,class:"text-green-600"},nt={key:1,class:"text-slate-400"},at={class:"flex gap-1"},dt=["onClick"],it=["onClick"],rt={class:"flex items-center gap-3 mb-5"},ut={class:"text-lg font-semibold text-slate-800"},pt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-3xl"},mt={class:"grid grid-cols-2 gap-4"},bt={class:"form-control"},ft={class:"form-control"},ct={class:"grid grid-cols-3 gap-4"},xt={class:"form-control col-span-2"},vt={class:"form-control"},gt={class:"form-control mt-4"},yt={class:"form-control mt-4"},_t={class:"grid grid-cols-2 gap-4"},kt={class:"form-control"},wt={class:"form-control"},ht={class:"form-control"},St={class:"form-control"},Vt={class:"grid grid-cols-2 gap-4"},Ct={class:"form-control"},Ut={class:"form-control"},Ht={class:"grid grid-cols-2 gap-4 mt-4"},It={class:"form-control"},Et={class:"form-control"},Tt={class:"form-control mt-4"},Dt={class:"flex items-center gap-2 mt-4"},Nt={class:"flex items-center gap-2 cursor-pointer"},$t={class:"mt-4 text-sm space-y-0.5"},At={class:"flex gap-3 mt-6"},jt=["disabled"],Ft=["disabled"],zt=P({__name:"environments",setup(Mt){const{consoleApi:c}=G(),{success:_,error:m}=K(),x=b("list"),v=b([]),k=b(!1),g=b(!1),f=b(!1),y=b(!1),d=E({show:!1,ok:!1,ssh_ok:!1,ssh_msg:"",etcd_ok:!1,etcd_msg:"",redis_ok:!1,redis_msg:"",nats_ok:!1,nats_msg:""}),D=O(()=>[{key:"ssh",label:"SSH 部署机",ok:d.ssh_ok,msg:d.ssh_msg},{key:"etcd",label:"ETCD",ok:d.etcd_ok,msg:d.etcd_msg},{key:"redis",label:"Redis",ok:d.redis_ok,msg:d.redis_msg},{key:"nats",label:"NATS",ok:d.nats_ok,msg:d.nats_msg}]);function w(){return{id:0,name:"",code:"",remark:"",enabled:!0,ssh_host:"",ssh_port:22,ssh_user:"root",ssh_private_key:"",registry:"",registry_user:"",registry_pass:"",docker_network:"1panel-network",etcd_servers:"",redis_addr:"",redis_pwd:"",nats_url:""}}const l=E(w());function C(o){Object.assign(l,w(),o)}function N(o){return o.ssh_host?`${o.ssh_user||"root"}@${o.ssh_host}:${o.ssh_port||22}`:"-"}function $(o){return o.registry||"-"}async function h(){k.value=!0;try{const o=await c("envs/list",{});v.value=o??[]}catch(o){m(o?.message??"获取环境列表失败"),v.value=[]}finally{k.value=!1}}function p(){f.value=!1,d.show=!1}function S(){x.value="list",h()}function U(o){o?(g.value=!0,C(o)):(g.value=!1,C(w())),p(),x.value="form"}async function A(){if(!l.ssh_host.trim()){m("请先填 SSH 主机");return}y.value=!0;try{const o=await c("envs/test",{...l});Object.assign(d,o,{show:!0}),f.value=!!o.ok,f.value?_("SSH 握手成功,可以保存"):m("SSH 未通过,请检查主机/私钥/用户")}catch(o){m(o?.message??"测试失败")}finally{y.value=!1}}async function j(){if(!f.value){m("请先「测试连接」通过再保存");return}const o={...l};let s="envs/add";g.value&&l.id?(o.id=Number(l.id),s="envs/update"):delete o.id;try{await c(s,o),_("保存成功"),S()}catch(e){m(e?.message??"失败")}}function F(o){window.confirm(`删除环境 #${o} ?(该环境下若有应用关联将被拒绝)`)&&c("envs/del",{id:o}).then(()=>{_("已删除"),h()}).catch(s=>m(s?.message??"失败"))}return R(h),(o,s)=>(u(),r("div",null,[n(t("div",null,[t("div",Y,[s[19]||(s[19]=t("div",null,[t("h2",{class:"text-lg font-semibold text-slate-800"},"环境节点(部署服务器)"),t("p",{class:"text-sm text-slate-400 mt-1"},"部署服务器节点(如 上海 / 日本 / 新加坡):远端 IP、SSH 登录账号与私钥、私有镜像仓库、区域共享基础设施。应用管理里「部署到目标环境」从这里选择、两边对应;下一期即可从页面直接更新服务/部署应用。密钥加密存储,不回显明文。")],-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:s[0]||(s[0]=e=>U())},"+ 新增节点")]),t("div",J,[t("div",Q,[t("table",W,[s[22]||(s[22]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"名称"),t("th",null,"区域码"),t("th",null,"SSH 目标"),t("th",null,"镜像仓库"),t("th",null,"启用"),t("th",null,"操作")])],-1)),t("tbody",null,[k.value?(u(),r("tr",X,[...s[20]||(s[20]=[t("td",{colspan:"7",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):v.value.length?B("",!0):(u(),r("tr",Z,[...s[21]||(s[21]=[t("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无环境",-1)])])),(u(!0),r(H,null,I(v.value,e=>(u(),r("tr",{key:e.id},[t("td",tt,i(e.id),1),t("td",st,i(e.name||""),1),t("td",null,i(e.code||""),1),t("td",et,i(N(e)),1),t("td",lt,i($(e)),1),t("td",null,[e.enabled?(u(),r("span",ot,"是")):(u(),r("span",nt,"否"))]),t("td",null,[t("div",at,[t("button",{class:"btn btn-ghost btn-xs",onClick:M=>U(e)},"编辑",8,dt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:M=>F(e.id)},"删除",8,it)])])]))),128))])])])])],512),[[V,x.value==="list"]]),n(t("div",null,[t("div",rt,[t("button",{class:"btn btn-ghost btn-sm",onClick:s[1]||(s[1]=e=>S())},"← 返回"),t("h2",ut,i(g.value?"编辑节点":"新增节点"),1)]),t("div",pt,[t("form",{onSubmit:z(j,["prevent"])},[t("div",mt,[t("div",bt,[s[23]||(s[23]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"名称 *")],-1)),n(t("input",{"onUpdate:modelValue":s[2]||(s[2]=e=>l.name=e),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 上海生产"},null,512),[[a,l.name]])]),t("div",ft,[s[24]||(s[24]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"区域码")],-1)),n(t("input",{"onUpdate:modelValue":s[3]||(s[3]=e=>l.code=e),type:"text",class:"input input-bordered w-full",list:"env-code-list",placeholder:"shanghai / japan / singapore"},null,512),[[a,l.code]]),s[25]||(s[25]=t("datalist",{id:"env-code-list"},[t("option",{value:"shanghai"}),t("option",{value:"japan"}),t("option",{value:"singapore"})],-1))])]),s[41]||(s[41]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"SSH 部署目标",-1)),t("div",ct,[t("div",xt,[s[26]||(s[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 主机")],-1)),n(t("input",{"onUpdate:modelValue":s[4]||(s[4]=e=>l.ssh_host=e),type:"text",class:"input input-bordered w-full",placeholder:"139.224.212.237",onInput:p},null,544),[[a,l.ssh_host]])]),t("div",vt,[s[27]||(s[27]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"端口")],-1)),n(t("input",{"onUpdate:modelValue":s[5]||(s[5]=e=>l.ssh_port=e),type:"number",class:"input input-bordered w-full",placeholder:"22",onInput:p},null,544),[[a,l.ssh_port,void 0,{number:!0}]])])]),t("div",gt,[s[28]||(s[28]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 用户")],-1)),n(t("input",{"onUpdate:modelValue":s[6]||(s[6]=e=>l.ssh_user=e),type:"text",class:"input input-bordered w-full",placeholder:"root",onInput:p},null,544),[[a,l.ssh_user]])]),t("div",yt,[s[29]||(s[29]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"SSH 私钥 (PEM)")],-1)),n(t("textarea",{"onUpdate:modelValue":s[7]||(s[7]=e=>l.ssh_private_key=e),class:"textarea textarea-bordered w-full font-mono text-xs h-28",placeholder:"-----BEGIN OPENSSH PRIVATE KEY-----",onInput:p},null,544),[[a,l.ssh_private_key]]),s[30]||(s[30]=t("span",{class:"text-xs text-slate-400 mt-1"},"加密存储;编辑时显示 [encrypted] 表示不改,如需更换直接粘贴新私钥。",-1))]),s[42]||(s[42]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"私有镜像仓库 + Docker 网络",-1)),t("div",_t,[t("div",kt,[s[31]||(s[31]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库地址")],-1)),n(t("input",{"onUpdate:modelValue":s[8]||(s[8]=e=>l.registry=e),type:"text",class:"input input-bordered w-full",placeholder:"docker-registry.ideapsound.com"},null,512),[[a,l.registry]])]),t("div",wt,[s[32]||(s[32]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Docker 网络")],-1)),n(t("input",{"onUpdate:modelValue":s[9]||(s[9]=e=>l.docker_network=e),type:"text",class:"input input-bordered w-full",placeholder:"1panel-network"},null,512),[[a,l.docker_network]])]),t("div",ht,[s[33]||(s[33]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库账号")],-1)),n(t("input",{"onUpdate:modelValue":s[10]||(s[10]=e=>l.registry_user=e),type:"text",class:"input input-bordered w-full",autocomplete:"off"},null,512),[[a,l.registry_user]])]),t("div",St,[s[34]||(s[34]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"仓库密码")],-1)),n(t("input",{"onUpdate:modelValue":s[11]||(s[11]=e=>l.registry_pass=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.registry_pass]])])]),s[43]||(s[43]=t("div",{class:"divider text-xs text-slate-400 mt-6"},"节点共享集群服务",-1)),s[44]||(s[44]=t("p",{class:"text-xs text-slate-400 -mt-2 mb-2"},"该服务器上各应用共用的地址。各应用自己的部署目录、业务库 DSN、镜像、redis 库号等,在「应用管理 → 部署到目标环境」里按应用填。",-1)),t("div",Vt,[t("div",Ct,[s[35]||(s[35]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"ETCD")],-1)),n(t("input",{"onUpdate:modelValue":s[12]||(s[12]=e=>l.etcd_servers=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"etcd:2379",onInput:p},null,544),[[a,l.etcd_servers]])]),t("div",Ut,[s[36]||(s[36]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"NATS")],-1)),n(t("input",{"onUpdate:modelValue":s[13]||(s[13]=e=>l.nats_url=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"nats://nats:4222",onInput:p},null,544),[[a,l.nats_url]])])]),t("div",Ht,[t("div",It,[s[37]||(s[37]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 地址")],-1)),n(t("input",{"onUpdate:modelValue":s[14]||(s[14]=e=>l.redis_addr=e),type:"text",class:"input input-bordered w-full font-mono text-xs",placeholder:"redis:6379",onInput:p},null,544),[[a,l.redis_addr]])]),t("div",Et,[s[38]||(s[38]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"Redis 密码")],-1)),n(t("input",{"onUpdate:modelValue":s[15]||(s[15]=e=>l.redis_pwd=e),type:"password",class:"input input-bordered w-full",autocomplete:"new-password",placeholder:"[encrypted]"},null,512),[[a,l.redis_pwd]])])]),t("div",Tt,[s[39]||(s[39]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"备注")],-1)),n(t("input",{"onUpdate:modelValue":s[16]||(s[16]=e=>l.remark=e),type:"text",class:"input input-bordered w-full"},null,512),[[a,l.remark]])]),t("div",Dt,[t("label",Nt,[n(t("input",{"onUpdate:modelValue":s[17]||(s[17]=e=>l.enabled=e),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[L,l.enabled]]),s[40]||(s[40]=t("span",{class:"text-sm"},"启用",-1))])]),n(t("div",$t,[(u(!0),r(H,null,I(D.value,e=>(u(),r("div",{key:e.key,class:T(e.ok?"text-green-700":"text-red-600")},[t("span",{class:T(e.ok?"text-green-600":"text-red-500")},i(e.ok?"✓":"✗"),3),q(" "+i(e.label)+":"+i(e.msg),1)],2))),128))],512),[[V,d.show]]),t("div",At,[t("button",{type:"button",class:"btn btn-ghost",onClick:s[18]||(s[18]=e=>S())},"取消"),t("button",{type:"button",class:"btn btn-outline",disabled:y.value,onClick:A},i(y.value?"测试中...":"测试连接"),9,jt),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:!f.value},"保存",8,Ft)]),s[45]||(s[45]=t("p",{class:"text-xs text-slate-400 mt-2"},"需先「测试连接」(SSH 握手成功即可保存;基础设施逐项仅作提示)。",-1))],32)])],512),[[V,x.value==="form"]])]))}});export{zt as default}; diff --git a/apps/admin/.output/public/_nuxt/BZjLILU0.js b/apps/admin/.output/public/_nuxt/B9UHsPCY.js similarity index 99% rename from apps/admin/.output/public/_nuxt/BZjLILU0.js rename to apps/admin/.output/public/_nuxt/B9UHsPCY.js index c873d59b..3a8c0758 100644 --- a/apps/admin/.output/public/_nuxt/BZjLILU0.js +++ b/apps/admin/.output/public/_nuxt/B9UHsPCY.js @@ -1 +1 @@ -import{g as $t,C as Lt,c as n,a as e,t as o,q as c,s as ut,F as y,r as x,v,p as Ut,m as J,l as g,d as T,y as d,z as Vt,A,o as i,n as Nt,x as dt,_ as At}from"./DMxDLVSv.js";import{u as St}from"./CCZrj3X-.js";import{u as Mt}from"./B-sqZCu-.js";import{l as K,A as Ot}from"./DD3V9C6_.js";const Tt={key:0},Ft={class:"flex flex-wrap items-start justify-between gap-3 mb-5"},Bt={class:"panel p-3 mb-5"},Et={class:"flex flex-wrap items-center gap-2"},Pt=["value"],Dt=["value"],It={class:"ml-auto text-xs text-slate-400"},zt={key:0,class:"py-16 text-center"},Rt={key:1,class:"panel py-16 text-center text-slate-400 text-sm"},qt={key:2,class:"tpl-grid"},Gt=["onClick"],Wt={class:"tc-top"},Yt={class:"tc-ico"},jt=["src"],Ht={key:1},Jt={class:"min-w-0 flex-1"},Kt=["title"],Qt=["title"],Xt={class:"tc-desc"},Zt={class:"tc-tags"},te={key:0,class:"chip chip-type"},ee={class:"tc-foot"},le={class:"chip chip-lang"},se={key:0,class:"chip chip-warn"},ae={key:1},ne={class:"flex flex-wrap items-center gap-3 mb-4"},oe={class:"min-w-0"},ie={class:"text-lg font-semibold text-slate-800 truncate"},ue={class:"text-xs text-slate-400 font-mono"},de={class:"ml-auto flex items-center gap-2"},re={class:"panel p-3 mb-4"},pe={class:"flex items-center gap-2 flex-wrap"},ce=["title","onClick"],me={class:"lp-name"},ve={class:"panel p-6"},ge={key:0,class:"py-16 text-center"},be={class:"flex items-center gap-2 mb-4 pb-3 border-b border-slate-100"},fe={class:"badge badge-outline"},ye={class:"text-sm text-slate-500"},xe={key:0,class:"chip chip-primary"},_e={class:"text-xs text-slate-300 font-mono ml-2"},ke={class:"ml-auto flex gap-2"},we={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},he={class:"form-control"},Ce={class:"form-control"},$e={id:"ttypelist"},Le=["value"],Ue={class:"form-control"},Ve={class:"form-control"},Ne={class:"form-control mt-4"},Ae={class:"form-control mt-4"},Se={class:"form-control mt-4"},Me={class:"flex gap-3 mt-6"},Oe=["disabled"],Te=["disabled"],Fe={key:2,class:"modal modal-open"},Be={class:"modal-box max-w-2xl"},Ee={class:"text-xs text-slate-400 mb-4"},Pe={class:"font-mono"},De={class:"mb-4"},Ie={class:"flex flex-wrap gap-x-5 gap-y-2"},ze=["value"],Re={key:0,class:"chip chip-warn"},qe={class:"flex items-center gap-2 mb-2"},Ge={class:"text-xs text-slate-400"},We={class:"lang-picker"},Ye=["value"],je={class:"lo-code"},He={class:"lo-name"},Je={class:"modal-action"},Ke=["disabled"],Qe={key:3,class:"modal modal-open"},Xe={class:"modal-box max-w-lg"},Ze={class:"font-bold text-base mb-1"},tl={class:"text-xs text-slate-400 mb-4"},el={class:"font-mono"},ll={class:"form-control"},sl={id:"addlanglist"},al=["value"],nl={key:0,class:"text-xs text-rose-600 mt-1"},ol={class:"modal-action"},il=["disabled"],ul={key:4,class:"modal modal-open"},dl={class:"modal-box max-w-lg"},rl={class:"form-control"},pl={class:"form-control mt-3"},cl={class:"form-control mt-3"},ml={key:0,class:"text-xs text-rose-600 mt-2 block"},vl={class:"modal-action"},gl=["disabled"],S="zh-CN",bl=$t({__name:"meettemplates",setup(fl){const st=[{key:"ttype",label:"类型 ttype"},{key:"tags",label:"标签 tags"},{key:"icon",label:"图标 icon"},{key:"title",label:"标题 title",translated:!0},{key:"description",label:"描述 description",translated:!0},{key:"outline",label:"大纲 outline",translated:!0},{key:"template",label:"模板内容 template",translated:!0}],{webApi:_}=St(),{success:C,error:k}=Mt(),F=d("list"),$=d([]),Q=d(!1),X=d(!1),p=d(!1),B=d(""),E=d(""),Z=d(""),r=d(null),m=d(""),w=new Map,a=Vt({id:0,title:"",tid:"",language:"",ttype:"",tags:"",icon:"",description:"",outline:"",template:""}),P=d(!1),M=d([]),b=d([]),D=d(!1),I=d(""),L=d(""),z=d(!1),R=d(""),q=d(""),G=d(S),h=d("");function rt(s){return(s||"").split(",").map(t=>t.trim()).filter(Boolean)}function pt(s){return/^https?:\/\//i.test(s||"")}function U(s){return s===S}function at(s){const t=(s||"").indexOf("-");return t>0?s.slice(0,t):"其他"}function ct(s){return(s.primary.title||s.tid||"?").trim().slice(0,1).toUpperCase()}const V=A(()=>{const s=new Map;$.value.forEach(l=>{const u=l.tid||"";s.has(u)||s.set(u,[]),s.get(u).push(l)});const t=[];return s.forEach((l,u)=>{const f=l.slice().sort((O,it)=>U(O.language)!==U(it.language)?U(O.language)?-1:1:(O.language||"")<(it.language||"")?-1:1),N=f.find(O=>U(O.language));t.push({tid:u,primary:N||f[0],hasPrimary:!!N,langs:f})}),t.sort((l,u)=>l.tidArray.from(new Set(V.value.map(s=>at(s.tid)))).sort()),nt=A(()=>Array.from(new Set($.value.map(s=>s.ttype).filter(Boolean))).sort()),tt=A(()=>{const s=Z.value.trim().toLowerCase();return V.value.filter(t=>B.value&&at(t.tid)!==B.value||E.value&&t.primary.ttype!==E.value?!1:s?`${t.tid} ${t.primary.title} ${t.primary.description}`.toLowerCase().includes(s):!0)}),W=A(()=>(r.value?.langs??[]).map(s=>s.language).filter(s=>s&&s!==m.value)),vt=A(()=>{const s=new Set((r.value?.langs??[]).map(t=>t.language));return Ot.filter(t=>!s.has(t.code))});function et(s){a.id=s.id||0,a.title=s.title||"",a.tid=s.tid||"",a.language=s.language||"",a.ttype=s.ttype||"",a.tags=s.tags||"",a.icon=s.icon||"",a.description=s.description||"",a.outline=s.outline||"",a.template=s.template||""}async function Y(){Q.value=!0;try{const s=await _("getmeettemplates",{});$.value=s?.templates??[]}catch(s){k(s?.message??"加载失败"),$.value=[]}finally{Q.value=!1}}function lt(){F.value="list",r.value=null,m.value="",Y()}function ot(s){r.value=s,F.value="detail",j(s.primary.language)}async function j(s){const t=r.value?.langs.find(u=>u.language===s);if(!t)return;m.value=s,et(t);const l=w.get(t.id);if(l){et(l);return}X.value=!0;try{const u=await _("getmeettemplate",{id:t.id});u&&(w.set(t.id,u),m.value===s&&et(u))}catch(u){k(u?.message??"加载详情失败")}finally{X.value=!1}}function gt(){w.delete(a.id),j(m.value)}async function bt(){p.value=!0;try{await _("updatemeettemplate",{id:Number(a.id),title:a.title.trim(),tid:a.tid.trim(),language:a.language.trim(),ttype:a.ttype.trim(),tags:a.tags.trim(),icon:a.icon.trim(),description:a.description.trim(),outline:a.outline,template:a.template}),w.delete(a.id),C("已保存"),await H()}catch(s){k(s?.message??"保存失败")}finally{p.value=!1}}async function H(s){const t=r.value?.tid,l=s||m.value;if(await Y(),!t)return;const u=V.value.find(N=>N.tid===t);if(!u){lt();return}r.value=u;const f=u.langs.find(N=>N.language===l)?l:u.primary.language;await j(f)}function ft(){M.value=st.filter(s=>!("translated"in s&&s.translated)).map(s=>s.key),b.value=W.value.slice(),P.value=!0}async function yt(){p.value=!0;try{const s=await _("syncmeettemplate",{src_id:Number(a.id),fields:M.value,languages:b.value});P.value=!1,w.clear(),C(`已同步 ${s?.updated??0} 个语言版本`),await H()}catch(s){k(s?.message??"同步失败")}finally{p.value=!1}}function xt(){I.value="",L.value="",D.value=!0}async function _t(){const s=I.value.trim();if(L.value="",!s){L.value="请填写语言码";return}if(r.value?.langs.some(t=>t.language===s)){L.value=`该 tid 下已存在 ${s} 版本`;return}p.value=!0;try{await _("addmeettemplate",{title:a.title.trim(),tid:a.tid.trim(),language:s,ttype:a.ttype.trim(),tags:a.tags.trim(),icon:a.icon.trim(),description:a.description.trim(),outline:a.outline,template:a.template}),D.value=!1,C(`已创建 ${s} 版本`),await H(s)}catch(t){k(t?.message??"创建失败")}finally{p.value=!1}}function kt(){R.value="",q.value="",G.value=S,h.value="",z.value=!0}async function wt(){const s=R.value.trim(),t=q.value.trim(),l=G.value.trim();if(h.value="",!s||!t){h.value="tid 与标题均必填";return}if(V.value.some(u=>u.tid===s)){h.value=`tid「${s}」已存在,请到列表中打开它再「添加语言」`;return}p.value=!0;try{await _("addmeettemplate",{tid:s,title:t,language:l}),z.value=!1,C("已创建"),await Y();const u=V.value.find(f=>f.tid===s);u&&ot(u)}catch(u){h.value=u?.message??"创建失败"}finally{p.value=!1}}async function ht(){if(r.value){if(r.value.langs.length<=1){k("这是最后一个语言版本,请用「删除整组」");return}if(window.confirm(`确定删除「${r.value.tid}」的 ${m.value} 版本吗?`)){p.value=!0;try{await _("delmeettemplate",{ids:[Number(a.id)]}),w.delete(a.id),C("已删除"),await H(S)}catch(s){k(s?.message??"删除失败")}finally{p.value=!1}}}}async function Ct(){const s=r.value;if(s&&window.confirm(`确定删除「${s.tid}」的全部 ${s.langs.length} 个语言版本吗?此操作不可恢复。`)){p.value=!0;try{await _("delmeettemplate",{ids:s.langs.map(t=>Number(t.id))}),w.clear(),C("已删除整组"),lt()}catch(t){k(t?.message??"删除失败")}finally{p.value=!1}}}return Lt(Y),(s,t)=>(i(),n("div",null,[F.value==="list"?(i(),n("div",Tt,[e("div",Ft,[e("div",null,[t[32]||(t[32]=e("h2",{class:"text-lg font-semibold text-slate-800"},"会议模板",-1)),e("p",{class:"text-xs text-slate-400 mt-1"}," 会议纪要公共模板(source=public),所有应用共享。同一 tid 下每种语言一份,卡面展示 "+o(S)+" 版本。修改后各服务约 10 分钟内自动同步。 ")]),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=l=>kt())},"+ 新增模板")]),e("div",Bt,[e("div",Et,[c(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>B.value=l),class:"select select-bordered select-sm w-40"},[t[33]||(t[33]=e("option",{value:""},"全部分类",-1)),(i(!0),n(y,null,x(mt.value,l=>(i(),n("option",{key:l,value:l},o(l),9,Pt))),128))],512),[[ut,B.value]]),c(e("select",{"onUpdate:modelValue":t[2]||(t[2]=l=>E.value=l),class:"select select-bordered select-sm w-40"},[t[34]||(t[34]=e("option",{value:""},"全部类型",-1)),(i(!0),n(y,null,x(nt.value,l=>(i(),n("option",{key:l,value:l},o(l),9,Dt))),128))],512),[[ut,E.value]]),c(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>Z.value=l),class:"input input-bordered input-sm w-56",placeholder:"搜索标题 / tid / 描述"},null,512),[[v,Z.value]]),e("span",It,o(V.value.length)+" 个模板 · "+o($.value.length)+" 个语言版本 · 命中 "+o(tt.value.length),1)])]),Q.value?(i(),n("div",zt,[...t[35]||(t[35]=[e("span",{class:"loading loading-spinner loading-md"},null,-1)])])):tt.value.length?(i(),n("div",qt,[(i(!0),n(y,null,x(tt.value,l=>(i(),n("div",{key:l.tid,class:"tpl-card",onClick:u=>ot(l)},[e("div",Wt,[e("div",Yt,[pt(l.primary.icon)?(i(),n("img",{key:0,src:l.primary.icon,alt:""},null,8,jt)):(i(),n("span",Ht,o(ct(l)),1))]),e("div",Jt,[e("div",{class:"tc-title",title:l.primary.title},o(l.primary.title||"(未命名)"),9,Kt),e("div",{class:"tc-tid",title:l.tid},o(l.tid||"无 tid"),9,Qt)])]),e("div",Xt,o(l.primary.description||"(无描述)"),1),e("div",Zt,[l.primary.ttype?(i(),n("span",te,o(l.primary.ttype),1)):g("",!0),(i(!0),n(y,null,x(rt(l.primary.tags),(u,f)=>(i(),n("span",{key:f,class:"chip"},o(u),1))),128))]),e("div",ee,[e("span",le,o(l.langs.length)+" 种语言",1),l.hasPrimary?g("",!0):(i(),n("span",se,"缺 "+o(S)+",按 "+o(l.primary.language)+" 展示",1)),t[36]||(t[36]=e("span",{class:"ml-auto tc-go"},"查看 →",-1))])],8,Gt))),128))])):(i(),n("div",Rt,o($.value.length?"当前筛选下没有匹配的模板":"暂无模板,点击右上角「新增模板」创建"),1))])):F.value==="detail"&&r.value?(i(),n("div",ae,[e("div",ne,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[4]||(t[4]=l=>lt())},"← 返回列表"),e("div",oe,[e("h2",ie,o(a.title||r.value.tid),1),e("div",ue,o(r.value.tid)+" · "+o(r.value.langs.length)+" 种语言",1)]),e("div",de,[e("button",{class:"btn btn-sm",onClick:t[5]||(t[5]=l=>ft())},"同步到其他语言"),e("button",{class:"btn btn-sm",onClick:t[6]||(t[6]=l=>xt())},"+ 添加语言"),e("button",{class:"btn btn-ghost btn-sm text-red-500",onClick:t[7]||(t[7]=l=>Ct())},"删除整组")])]),e("div",re,[e("div",pe,[t[37]||(t[37]=e("span",{class:"text-xs text-slate-400 shrink-0"},"语言版本",-1)),(i(!0),n(y,null,x(r.value.langs,l=>(i(),n("button",{key:l.language,class:Nt(["lang-pill",{on:l.language===m.value,primary:U(l.language)}]),title:J(K)(l.language),onClick:u=>j(l.language)},[T(o(l.language)+" ",1),e("span",me,o(J(K)(l.language)),1)],10,ce))),128))])]),e("div",ve,[X.value?(i(),n("div",ge,[...t[38]||(t[38]=[e("span",{class:"loading loading-spinner loading-md"},null,-1)])])):(i(),n("form",{key:1,onSubmit:t[17]||(t[17]=Ut(l=>bt(),["prevent"]))},[e("div",be,[e("span",fe,o(m.value),1),e("span",ye,o(J(K)(m.value)),1),U(m.value)?(i(),n("span",xe,"主语言")):g("",!0),e("span",_e,"id "+o(a.id),1),e("div",ke,[e("button",{type:"button",class:"btn btn-ghost btn-xs text-red-500",onClick:t[8]||(t[8]=l=>ht())}," 删除此语言版本 ")])]),e("div",we,[e("div",he,[t[39]||(t[39]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"标题 *")],-1)),c(e("input",{"onUpdate:modelValue":t[9]||(t[9]=l=>a.title=l),type:"text",class:"input input-bordered w-full",required:""},null,512),[[v,a.title]])]),e("div",Ce,[t[40]||(t[40]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"类型 (ttype)")],-1)),c(e("input",{"onUpdate:modelValue":t[10]||(t[10]=l=>a.ttype=l),type:"text",class:"input input-bordered w-full",list:"ttypelist"},null,512),[[v,a.ttype]]),e("datalist",$e,[(i(!0),n(y,null,x(nt.value,l=>(i(),n("option",{key:l,value:l},null,8,Le))),128))])]),e("div",Ue,[t[41]||(t[41]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"标签 (tags)")],-1)),c(e("input",{"onUpdate:modelValue":t[11]||(t[11]=l=>a.tags=l),type:"text",class:"input input-bordered w-full",placeholder:"逗号分隔"},null,512),[[v,a.tags]])]),e("div",Ve,[t[42]||(t[42]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"图标 (icon)")],-1)),c(e("input",{"onUpdate:modelValue":t[12]||(t[12]=l=>a.icon=l),type:"text",class:"input input-bordered w-full",placeholder:"图标 URL 或名称"},null,512),[[v,a.icon]])])]),e("div",Ne,[t[43]||(t[43]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),c(e("input",{"onUpdate:modelValue":t[13]||(t[13]=l=>a.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[v,a.description]])]),e("div",Ae,[t[44]||(t[44]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"大纲 (outline)")],-1)),c(e("textarea",{"onUpdate:modelValue":t[14]||(t[14]=l=>a.outline=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"5"},null,512),[[v,a.outline]])]),e("div",Se,[t[45]||(t[45]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"模板内容 (template)")],-1)),c(e("textarea",{"onUpdate:modelValue":t[15]||(t[15]=l=>a.template=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"16"},null,512),[[v,a.template]])]),e("div",Me,[e("button",{type:"submit",class:"btn btn-primary text-white",disabled:p.value},"保存当前语言",8,Oe),e("button",{type:"button",class:"btn btn-ghost",disabled:p.value,onClick:t[16]||(t[16]=l=>gt())},"放弃修改",8,Te)])],32))])])):g("",!0),P.value?(i(),n("div",Fe,[e("div",Be,[t[50]||(t[50]=e("h3",{class:"font-bold text-base mb-1"},"同步到其他语言",-1)),e("p",Ee,[t[46]||(t[46]=T(" 以 ",-1)),e("span",Pe,o(m.value),1),t[47]||(t[47]=T(" 版本为源,把勾选字段覆盖写入所选语言版本。 标题/描述/大纲/模板属译文,覆盖后目标语言的译文会丢失,请谨慎勾选。 ",-1))]),e("div",De,[t[48]||(t[48]=e("div",{class:"text-sm font-medium text-slate-600 mb-2"},"同步哪些字段",-1)),e("div",Ie,[(i(),n(y,null,x(st,l=>e("label",{key:l.key,class:"flex items-center gap-2 text-sm cursor-pointer"},[c(e("input",{"onUpdate:modelValue":t[18]||(t[18]=u=>M.value=u),type:"checkbox",value:l.key,class:"checkbox checkbox-sm checkbox-primary"},null,8,ze),[[dt,M.value]]),e("span",null,o(l.label),1),l.translated?(i(),n("span",Re,"译文")):g("",!0)])),64))])]),e("div",null,[e("div",qe,[t[49]||(t[49]=e("span",{class:"text-sm font-medium text-slate-600"},"同步到哪些语言",-1)),e("span",Ge,"已选 "+o(b.value.length)+" / "+o(W.value.length),1),e("button",{type:"button",class:"btn btn-ghost btn-xs ml-auto",onClick:t[19]||(t[19]=l=>b.value=W.value.slice())},"全选"),e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[20]||(t[20]=l=>b.value=[])},"清空")]),e("div",We,[(i(!0),n(y,null,x(W.value,l=>(i(),n("label",{key:l,class:"lang-opt"},[c(e("input",{"onUpdate:modelValue":t[21]||(t[21]=u=>b.value=u),type:"checkbox",value:l,class:"checkbox checkbox-xs checkbox-primary"},null,8,Ye),[[dt,b.value]]),e("span",je,o(l),1),e("span",He,o(J(K)(l)),1)]))),128))])]),e("div",Je,[e("button",{class:"btn btn-ghost",onClick:t[22]||(t[22]=l=>P.value=!1)},"取消"),e("button",{class:"btn btn-primary text-white",disabled:p.value||!M.value.length||!b.value.length,onClick:t[23]||(t[23]=l=>yt())}," 同步到 "+o(b.value.length)+" 个语言 ",9,Ke)])])])):g("",!0),D.value?(i(),n("div",Qe,[e("div",Xe,[e("h3",Ze,"为「"+o(r.value?.tid)+"」添加语言版本",1),e("p",tl,[t[51]||(t[51]=T(" 新版本以当前 ",-1)),e("span",el,o(m.value),1),t[52]||(t[52]=T(" 版本的内容为初稿,创建后再逐项译成目标语言。 ",-1))]),e("div",ll,[t[53]||(t[53]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"语言码 *")],-1)),c(e("input",{"onUpdate:modelValue":t[24]||(t[24]=l=>I.value=l),class:"input input-bordered w-full",list:"addlanglist",placeholder:"BCP-47,如 en-US"},null,512),[[v,I.value]]),e("datalist",sl,[(i(!0),n(y,null,x(vt.value,l=>(i(),n("option",{key:l.code,value:l.code},o(l.name),9,al))),128))]),L.value?(i(),n("span",nl,o(L.value),1)):g("",!0)]),e("div",ol,[e("button",{class:"btn btn-ghost",onClick:t[25]||(t[25]=l=>D.value=!1)},"取消"),e("button",{class:"btn btn-primary text-white",disabled:p.value,onClick:t[26]||(t[26]=l=>_t())},"创建",8,il)])])])):g("",!0),z.value?(i(),n("div",ul,[e("div",dl,[t[57]||(t[57]=e("h3",{class:"font-bold text-base mb-1"},"新增模板",-1)),t[58]||(t[58]=e("p",{class:"text-xs text-slate-400 mb-4"}," 先建出主语言版本,创建后在详情页补齐内容,再用「添加语言」扩展其他语言。 ",-1)),e("div",rl,[t[54]||(t[54]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"模板标识 tid *")],-1)),c(e("input",{"onUpdate:modelValue":t[27]||(t[27]=l=>R.value=l),class:"input input-bordered w-full",placeholder:"如 Meeting-WeeklyMeeting"},null,512),[[v,R.value]])]),e("div",pl,[t[55]||(t[55]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"标题 *")],-1)),c(e("input",{"onUpdate:modelValue":t[28]||(t[28]=l=>q.value=l),class:"input input-bordered w-full"},null,512),[[v,q.value]])]),e("div",cl,[t[56]||(t[56]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"语言")],-1)),c(e("input",{"onUpdate:modelValue":t[29]||(t[29]=l=>G.value=l),class:"input input-bordered w-full",list:"addlanglist"},null,512),[[v,G.value]])]),h.value?(i(),n("span",ml,o(h.value),1)):g("",!0),e("div",vl,[e("button",{class:"btn btn-ghost",onClick:t[30]||(t[30]=l=>z.value=!1)},"取消"),e("button",{class:"btn btn-primary text-white",disabled:p.value,onClick:t[31]||(t[31]=l=>wt())},"创建",8,gl)])])])):g("",!0)]))}}),wl=At(bl,[["__scopeId","data-v-5eb39361"]]);export{wl as default}; +import{g as $t,C as Lt,c as n,a as e,t as o,q as c,s as ut,F as y,r as x,v,p as Ut,m as J,l as g,d as T,y as d,z as Vt,A,o as i,n as Nt,x as dt,_ as At}from"./DSy_gLdM.js";import{u as St}from"./NtXZuCUg.js";import{u as Mt}from"./EeX3zgoF.js";import{l as K,A as Ot}from"./DD3V9C6_.js";const Tt={key:0},Ft={class:"flex flex-wrap items-start justify-between gap-3 mb-5"},Bt={class:"panel p-3 mb-5"},Et={class:"flex flex-wrap items-center gap-2"},Pt=["value"],Dt=["value"],It={class:"ml-auto text-xs text-slate-400"},zt={key:0,class:"py-16 text-center"},Rt={key:1,class:"panel py-16 text-center text-slate-400 text-sm"},qt={key:2,class:"tpl-grid"},Gt=["onClick"],Wt={class:"tc-top"},Yt={class:"tc-ico"},jt=["src"],Ht={key:1},Jt={class:"min-w-0 flex-1"},Kt=["title"],Qt=["title"],Xt={class:"tc-desc"},Zt={class:"tc-tags"},te={key:0,class:"chip chip-type"},ee={class:"tc-foot"},le={class:"chip chip-lang"},se={key:0,class:"chip chip-warn"},ae={key:1},ne={class:"flex flex-wrap items-center gap-3 mb-4"},oe={class:"min-w-0"},ie={class:"text-lg font-semibold text-slate-800 truncate"},ue={class:"text-xs text-slate-400 font-mono"},de={class:"ml-auto flex items-center gap-2"},re={class:"panel p-3 mb-4"},pe={class:"flex items-center gap-2 flex-wrap"},ce=["title","onClick"],me={class:"lp-name"},ve={class:"panel p-6"},ge={key:0,class:"py-16 text-center"},be={class:"flex items-center gap-2 mb-4 pb-3 border-b border-slate-100"},fe={class:"badge badge-outline"},ye={class:"text-sm text-slate-500"},xe={key:0,class:"chip chip-primary"},_e={class:"text-xs text-slate-300 font-mono ml-2"},ke={class:"ml-auto flex gap-2"},we={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},he={class:"form-control"},Ce={class:"form-control"},$e={id:"ttypelist"},Le=["value"],Ue={class:"form-control"},Ve={class:"form-control"},Ne={class:"form-control mt-4"},Ae={class:"form-control mt-4"},Se={class:"form-control mt-4"},Me={class:"flex gap-3 mt-6"},Oe=["disabled"],Te=["disabled"],Fe={key:2,class:"modal modal-open"},Be={class:"modal-box max-w-2xl"},Ee={class:"text-xs text-slate-400 mb-4"},Pe={class:"font-mono"},De={class:"mb-4"},Ie={class:"flex flex-wrap gap-x-5 gap-y-2"},ze=["value"],Re={key:0,class:"chip chip-warn"},qe={class:"flex items-center gap-2 mb-2"},Ge={class:"text-xs text-slate-400"},We={class:"lang-picker"},Ye=["value"],je={class:"lo-code"},He={class:"lo-name"},Je={class:"modal-action"},Ke=["disabled"],Qe={key:3,class:"modal modal-open"},Xe={class:"modal-box max-w-lg"},Ze={class:"font-bold text-base mb-1"},tl={class:"text-xs text-slate-400 mb-4"},el={class:"font-mono"},ll={class:"form-control"},sl={id:"addlanglist"},al=["value"],nl={key:0,class:"text-xs text-rose-600 mt-1"},ol={class:"modal-action"},il=["disabled"],ul={key:4,class:"modal modal-open"},dl={class:"modal-box max-w-lg"},rl={class:"form-control"},pl={class:"form-control mt-3"},cl={class:"form-control mt-3"},ml={key:0,class:"text-xs text-rose-600 mt-2 block"},vl={class:"modal-action"},gl=["disabled"],S="zh-CN",bl=$t({__name:"meettemplates",setup(fl){const st=[{key:"ttype",label:"类型 ttype"},{key:"tags",label:"标签 tags"},{key:"icon",label:"图标 icon"},{key:"title",label:"标题 title",translated:!0},{key:"description",label:"描述 description",translated:!0},{key:"outline",label:"大纲 outline",translated:!0},{key:"template",label:"模板内容 template",translated:!0}],{webApi:_}=St(),{success:C,error:k}=Mt(),F=d("list"),$=d([]),Q=d(!1),X=d(!1),p=d(!1),B=d(""),E=d(""),Z=d(""),r=d(null),m=d(""),w=new Map,a=Vt({id:0,title:"",tid:"",language:"",ttype:"",tags:"",icon:"",description:"",outline:"",template:""}),P=d(!1),M=d([]),b=d([]),D=d(!1),I=d(""),L=d(""),z=d(!1),R=d(""),q=d(""),G=d(S),h=d("");function rt(s){return(s||"").split(",").map(t=>t.trim()).filter(Boolean)}function pt(s){return/^https?:\/\//i.test(s||"")}function U(s){return s===S}function at(s){const t=(s||"").indexOf("-");return t>0?s.slice(0,t):"其他"}function ct(s){return(s.primary.title||s.tid||"?").trim().slice(0,1).toUpperCase()}const V=A(()=>{const s=new Map;$.value.forEach(l=>{const u=l.tid||"";s.has(u)||s.set(u,[]),s.get(u).push(l)});const t=[];return s.forEach((l,u)=>{const f=l.slice().sort((O,it)=>U(O.language)!==U(it.language)?U(O.language)?-1:1:(O.language||"")<(it.language||"")?-1:1),N=f.find(O=>U(O.language));t.push({tid:u,primary:N||f[0],hasPrimary:!!N,langs:f})}),t.sort((l,u)=>l.tidArray.from(new Set(V.value.map(s=>at(s.tid)))).sort()),nt=A(()=>Array.from(new Set($.value.map(s=>s.ttype).filter(Boolean))).sort()),tt=A(()=>{const s=Z.value.trim().toLowerCase();return V.value.filter(t=>B.value&&at(t.tid)!==B.value||E.value&&t.primary.ttype!==E.value?!1:s?`${t.tid} ${t.primary.title} ${t.primary.description}`.toLowerCase().includes(s):!0)}),W=A(()=>(r.value?.langs??[]).map(s=>s.language).filter(s=>s&&s!==m.value)),vt=A(()=>{const s=new Set((r.value?.langs??[]).map(t=>t.language));return Ot.filter(t=>!s.has(t.code))});function et(s){a.id=s.id||0,a.title=s.title||"",a.tid=s.tid||"",a.language=s.language||"",a.ttype=s.ttype||"",a.tags=s.tags||"",a.icon=s.icon||"",a.description=s.description||"",a.outline=s.outline||"",a.template=s.template||""}async function Y(){Q.value=!0;try{const s=await _("getmeettemplates",{});$.value=s?.templates??[]}catch(s){k(s?.message??"加载失败"),$.value=[]}finally{Q.value=!1}}function lt(){F.value="list",r.value=null,m.value="",Y()}function ot(s){r.value=s,F.value="detail",j(s.primary.language)}async function j(s){const t=r.value?.langs.find(u=>u.language===s);if(!t)return;m.value=s,et(t);const l=w.get(t.id);if(l){et(l);return}X.value=!0;try{const u=await _("getmeettemplate",{id:t.id});u&&(w.set(t.id,u),m.value===s&&et(u))}catch(u){k(u?.message??"加载详情失败")}finally{X.value=!1}}function gt(){w.delete(a.id),j(m.value)}async function bt(){p.value=!0;try{await _("updatemeettemplate",{id:Number(a.id),title:a.title.trim(),tid:a.tid.trim(),language:a.language.trim(),ttype:a.ttype.trim(),tags:a.tags.trim(),icon:a.icon.trim(),description:a.description.trim(),outline:a.outline,template:a.template}),w.delete(a.id),C("已保存"),await H()}catch(s){k(s?.message??"保存失败")}finally{p.value=!1}}async function H(s){const t=r.value?.tid,l=s||m.value;if(await Y(),!t)return;const u=V.value.find(N=>N.tid===t);if(!u){lt();return}r.value=u;const f=u.langs.find(N=>N.language===l)?l:u.primary.language;await j(f)}function ft(){M.value=st.filter(s=>!("translated"in s&&s.translated)).map(s=>s.key),b.value=W.value.slice(),P.value=!0}async function yt(){p.value=!0;try{const s=await _("syncmeettemplate",{src_id:Number(a.id),fields:M.value,languages:b.value});P.value=!1,w.clear(),C(`已同步 ${s?.updated??0} 个语言版本`),await H()}catch(s){k(s?.message??"同步失败")}finally{p.value=!1}}function xt(){I.value="",L.value="",D.value=!0}async function _t(){const s=I.value.trim();if(L.value="",!s){L.value="请填写语言码";return}if(r.value?.langs.some(t=>t.language===s)){L.value=`该 tid 下已存在 ${s} 版本`;return}p.value=!0;try{await _("addmeettemplate",{title:a.title.trim(),tid:a.tid.trim(),language:s,ttype:a.ttype.trim(),tags:a.tags.trim(),icon:a.icon.trim(),description:a.description.trim(),outline:a.outline,template:a.template}),D.value=!1,C(`已创建 ${s} 版本`),await H(s)}catch(t){k(t?.message??"创建失败")}finally{p.value=!1}}function kt(){R.value="",q.value="",G.value=S,h.value="",z.value=!0}async function wt(){const s=R.value.trim(),t=q.value.trim(),l=G.value.trim();if(h.value="",!s||!t){h.value="tid 与标题均必填";return}if(V.value.some(u=>u.tid===s)){h.value=`tid「${s}」已存在,请到列表中打开它再「添加语言」`;return}p.value=!0;try{await _("addmeettemplate",{tid:s,title:t,language:l}),z.value=!1,C("已创建"),await Y();const u=V.value.find(f=>f.tid===s);u&&ot(u)}catch(u){h.value=u?.message??"创建失败"}finally{p.value=!1}}async function ht(){if(r.value){if(r.value.langs.length<=1){k("这是最后一个语言版本,请用「删除整组」");return}if(window.confirm(`确定删除「${r.value.tid}」的 ${m.value} 版本吗?`)){p.value=!0;try{await _("delmeettemplate",{ids:[Number(a.id)]}),w.delete(a.id),C("已删除"),await H(S)}catch(s){k(s?.message??"删除失败")}finally{p.value=!1}}}}async function Ct(){const s=r.value;if(s&&window.confirm(`确定删除「${s.tid}」的全部 ${s.langs.length} 个语言版本吗?此操作不可恢复。`)){p.value=!0;try{await _("delmeettemplate",{ids:s.langs.map(t=>Number(t.id))}),w.clear(),C("已删除整组"),lt()}catch(t){k(t?.message??"删除失败")}finally{p.value=!1}}}return Lt(Y),(s,t)=>(i(),n("div",null,[F.value==="list"?(i(),n("div",Tt,[e("div",Ft,[e("div",null,[t[32]||(t[32]=e("h2",{class:"text-lg font-semibold text-slate-800"},"会议模板",-1)),e("p",{class:"text-xs text-slate-400 mt-1"}," 会议纪要公共模板(source=public),所有应用共享。同一 tid 下每种语言一份,卡面展示 "+o(S)+" 版本。修改后各服务约 10 分钟内自动同步。 ")]),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=l=>kt())},"+ 新增模板")]),e("div",Bt,[e("div",Et,[c(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>B.value=l),class:"select select-bordered select-sm w-40"},[t[33]||(t[33]=e("option",{value:""},"全部分类",-1)),(i(!0),n(y,null,x(mt.value,l=>(i(),n("option",{key:l,value:l},o(l),9,Pt))),128))],512),[[ut,B.value]]),c(e("select",{"onUpdate:modelValue":t[2]||(t[2]=l=>E.value=l),class:"select select-bordered select-sm w-40"},[t[34]||(t[34]=e("option",{value:""},"全部类型",-1)),(i(!0),n(y,null,x(nt.value,l=>(i(),n("option",{key:l,value:l},o(l),9,Dt))),128))],512),[[ut,E.value]]),c(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>Z.value=l),class:"input input-bordered input-sm w-56",placeholder:"搜索标题 / tid / 描述"},null,512),[[v,Z.value]]),e("span",It,o(V.value.length)+" 个模板 · "+o($.value.length)+" 个语言版本 · 命中 "+o(tt.value.length),1)])]),Q.value?(i(),n("div",zt,[...t[35]||(t[35]=[e("span",{class:"loading loading-spinner loading-md"},null,-1)])])):tt.value.length?(i(),n("div",qt,[(i(!0),n(y,null,x(tt.value,l=>(i(),n("div",{key:l.tid,class:"tpl-card",onClick:u=>ot(l)},[e("div",Wt,[e("div",Yt,[pt(l.primary.icon)?(i(),n("img",{key:0,src:l.primary.icon,alt:""},null,8,jt)):(i(),n("span",Ht,o(ct(l)),1))]),e("div",Jt,[e("div",{class:"tc-title",title:l.primary.title},o(l.primary.title||"(未命名)"),9,Kt),e("div",{class:"tc-tid",title:l.tid},o(l.tid||"无 tid"),9,Qt)])]),e("div",Xt,o(l.primary.description||"(无描述)"),1),e("div",Zt,[l.primary.ttype?(i(),n("span",te,o(l.primary.ttype),1)):g("",!0),(i(!0),n(y,null,x(rt(l.primary.tags),(u,f)=>(i(),n("span",{key:f,class:"chip"},o(u),1))),128))]),e("div",ee,[e("span",le,o(l.langs.length)+" 种语言",1),l.hasPrimary?g("",!0):(i(),n("span",se,"缺 "+o(S)+",按 "+o(l.primary.language)+" 展示",1)),t[36]||(t[36]=e("span",{class:"ml-auto tc-go"},"查看 →",-1))])],8,Gt))),128))])):(i(),n("div",Rt,o($.value.length?"当前筛选下没有匹配的模板":"暂无模板,点击右上角「新增模板」创建"),1))])):F.value==="detail"&&r.value?(i(),n("div",ae,[e("div",ne,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[4]||(t[4]=l=>lt())},"← 返回列表"),e("div",oe,[e("h2",ie,o(a.title||r.value.tid),1),e("div",ue,o(r.value.tid)+" · "+o(r.value.langs.length)+" 种语言",1)]),e("div",de,[e("button",{class:"btn btn-sm",onClick:t[5]||(t[5]=l=>ft())},"同步到其他语言"),e("button",{class:"btn btn-sm",onClick:t[6]||(t[6]=l=>xt())},"+ 添加语言"),e("button",{class:"btn btn-ghost btn-sm text-red-500",onClick:t[7]||(t[7]=l=>Ct())},"删除整组")])]),e("div",re,[e("div",pe,[t[37]||(t[37]=e("span",{class:"text-xs text-slate-400 shrink-0"},"语言版本",-1)),(i(!0),n(y,null,x(r.value.langs,l=>(i(),n("button",{key:l.language,class:Nt(["lang-pill",{on:l.language===m.value,primary:U(l.language)}]),title:J(K)(l.language),onClick:u=>j(l.language)},[T(o(l.language)+" ",1),e("span",me,o(J(K)(l.language)),1)],10,ce))),128))])]),e("div",ve,[X.value?(i(),n("div",ge,[...t[38]||(t[38]=[e("span",{class:"loading loading-spinner loading-md"},null,-1)])])):(i(),n("form",{key:1,onSubmit:t[17]||(t[17]=Ut(l=>bt(),["prevent"]))},[e("div",be,[e("span",fe,o(m.value),1),e("span",ye,o(J(K)(m.value)),1),U(m.value)?(i(),n("span",xe,"主语言")):g("",!0),e("span",_e,"id "+o(a.id),1),e("div",ke,[e("button",{type:"button",class:"btn btn-ghost btn-xs text-red-500",onClick:t[8]||(t[8]=l=>ht())}," 删除此语言版本 ")])]),e("div",we,[e("div",he,[t[39]||(t[39]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"标题 *")],-1)),c(e("input",{"onUpdate:modelValue":t[9]||(t[9]=l=>a.title=l),type:"text",class:"input input-bordered w-full",required:""},null,512),[[v,a.title]])]),e("div",Ce,[t[40]||(t[40]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"类型 (ttype)")],-1)),c(e("input",{"onUpdate:modelValue":t[10]||(t[10]=l=>a.ttype=l),type:"text",class:"input input-bordered w-full",list:"ttypelist"},null,512),[[v,a.ttype]]),e("datalist",$e,[(i(!0),n(y,null,x(nt.value,l=>(i(),n("option",{key:l,value:l},null,8,Le))),128))])]),e("div",Ue,[t[41]||(t[41]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"标签 (tags)")],-1)),c(e("input",{"onUpdate:modelValue":t[11]||(t[11]=l=>a.tags=l),type:"text",class:"input input-bordered w-full",placeholder:"逗号分隔"},null,512),[[v,a.tags]])]),e("div",Ve,[t[42]||(t[42]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"图标 (icon)")],-1)),c(e("input",{"onUpdate:modelValue":t[12]||(t[12]=l=>a.icon=l),type:"text",class:"input input-bordered w-full",placeholder:"图标 URL 或名称"},null,512),[[v,a.icon]])])]),e("div",Ne,[t[43]||(t[43]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),c(e("input",{"onUpdate:modelValue":t[13]||(t[13]=l=>a.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[v,a.description]])]),e("div",Ae,[t[44]||(t[44]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"大纲 (outline)")],-1)),c(e("textarea",{"onUpdate:modelValue":t[14]||(t[14]=l=>a.outline=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"5"},null,512),[[v,a.outline]])]),e("div",Se,[t[45]||(t[45]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"模板内容 (template)")],-1)),c(e("textarea",{"onUpdate:modelValue":t[15]||(t[15]=l=>a.template=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"16"},null,512),[[v,a.template]])]),e("div",Me,[e("button",{type:"submit",class:"btn btn-primary text-white",disabled:p.value},"保存当前语言",8,Oe),e("button",{type:"button",class:"btn btn-ghost",disabled:p.value,onClick:t[16]||(t[16]=l=>gt())},"放弃修改",8,Te)])],32))])])):g("",!0),P.value?(i(),n("div",Fe,[e("div",Be,[t[50]||(t[50]=e("h3",{class:"font-bold text-base mb-1"},"同步到其他语言",-1)),e("p",Ee,[t[46]||(t[46]=T(" 以 ",-1)),e("span",Pe,o(m.value),1),t[47]||(t[47]=T(" 版本为源,把勾选字段覆盖写入所选语言版本。 标题/描述/大纲/模板属译文,覆盖后目标语言的译文会丢失,请谨慎勾选。 ",-1))]),e("div",De,[t[48]||(t[48]=e("div",{class:"text-sm font-medium text-slate-600 mb-2"},"同步哪些字段",-1)),e("div",Ie,[(i(),n(y,null,x(st,l=>e("label",{key:l.key,class:"flex items-center gap-2 text-sm cursor-pointer"},[c(e("input",{"onUpdate:modelValue":t[18]||(t[18]=u=>M.value=u),type:"checkbox",value:l.key,class:"checkbox checkbox-sm checkbox-primary"},null,8,ze),[[dt,M.value]]),e("span",null,o(l.label),1),l.translated?(i(),n("span",Re,"译文")):g("",!0)])),64))])]),e("div",null,[e("div",qe,[t[49]||(t[49]=e("span",{class:"text-sm font-medium text-slate-600"},"同步到哪些语言",-1)),e("span",Ge,"已选 "+o(b.value.length)+" / "+o(W.value.length),1),e("button",{type:"button",class:"btn btn-ghost btn-xs ml-auto",onClick:t[19]||(t[19]=l=>b.value=W.value.slice())},"全选"),e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[20]||(t[20]=l=>b.value=[])},"清空")]),e("div",We,[(i(!0),n(y,null,x(W.value,l=>(i(),n("label",{key:l,class:"lang-opt"},[c(e("input",{"onUpdate:modelValue":t[21]||(t[21]=u=>b.value=u),type:"checkbox",value:l,class:"checkbox checkbox-xs checkbox-primary"},null,8,Ye),[[dt,b.value]]),e("span",je,o(l),1),e("span",He,o(J(K)(l)),1)]))),128))])]),e("div",Je,[e("button",{class:"btn btn-ghost",onClick:t[22]||(t[22]=l=>P.value=!1)},"取消"),e("button",{class:"btn btn-primary text-white",disabled:p.value||!M.value.length||!b.value.length,onClick:t[23]||(t[23]=l=>yt())}," 同步到 "+o(b.value.length)+" 个语言 ",9,Ke)])])])):g("",!0),D.value?(i(),n("div",Qe,[e("div",Xe,[e("h3",Ze,"为「"+o(r.value?.tid)+"」添加语言版本",1),e("p",tl,[t[51]||(t[51]=T(" 新版本以当前 ",-1)),e("span",el,o(m.value),1),t[52]||(t[52]=T(" 版本的内容为初稿,创建后再逐项译成目标语言。 ",-1))]),e("div",ll,[t[53]||(t[53]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"语言码 *")],-1)),c(e("input",{"onUpdate:modelValue":t[24]||(t[24]=l=>I.value=l),class:"input input-bordered w-full",list:"addlanglist",placeholder:"BCP-47,如 en-US"},null,512),[[v,I.value]]),e("datalist",sl,[(i(!0),n(y,null,x(vt.value,l=>(i(),n("option",{key:l.code,value:l.code},o(l.name),9,al))),128))]),L.value?(i(),n("span",nl,o(L.value),1)):g("",!0)]),e("div",ol,[e("button",{class:"btn btn-ghost",onClick:t[25]||(t[25]=l=>D.value=!1)},"取消"),e("button",{class:"btn btn-primary text-white",disabled:p.value,onClick:t[26]||(t[26]=l=>_t())},"创建",8,il)])])])):g("",!0),z.value?(i(),n("div",ul,[e("div",dl,[t[57]||(t[57]=e("h3",{class:"font-bold text-base mb-1"},"新增模板",-1)),t[58]||(t[58]=e("p",{class:"text-xs text-slate-400 mb-4"}," 先建出主语言版本,创建后在详情页补齐内容,再用「添加语言」扩展其他语言。 ",-1)),e("div",rl,[t[54]||(t[54]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"模板标识 tid *")],-1)),c(e("input",{"onUpdate:modelValue":t[27]||(t[27]=l=>R.value=l),class:"input input-bordered w-full",placeholder:"如 Meeting-WeeklyMeeting"},null,512),[[v,R.value]])]),e("div",pl,[t[55]||(t[55]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"标题 *")],-1)),c(e("input",{"onUpdate:modelValue":t[28]||(t[28]=l=>q.value=l),class:"input input-bordered w-full"},null,512),[[v,q.value]])]),e("div",cl,[t[56]||(t[56]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"语言")],-1)),c(e("input",{"onUpdate:modelValue":t[29]||(t[29]=l=>G.value=l),class:"input input-bordered w-full",list:"addlanglist"},null,512),[[v,G.value]])]),h.value?(i(),n("span",ml,o(h.value),1)):g("",!0),e("div",vl,[e("button",{class:"btn btn-ghost",onClick:t[30]||(t[30]=l=>z.value=!1)},"取消"),e("button",{class:"btn btn-primary text-white",disabled:p.value,onClick:t[31]||(t[31]=l=>wt())},"创建",8,gl)])])])):g("",!0)]))}}),wl=At(bl,[["__scopeId","data-v-5eb39361"]]);export{wl as default}; diff --git a/apps/admin/.output/public/_nuxt/BIbETX06.js b/apps/admin/.output/public/_nuxt/BAkLwAvM.js similarity index 99% rename from apps/admin/.output/public/_nuxt/BIbETX06.js rename to apps/admin/.output/public/_nuxt/BAkLwAvM.js index 55639fcb..b95532af 100644 --- a/apps/admin/.output/public/_nuxt/BIbETX06.js +++ b/apps/admin/.output/public/_nuxt/BAkLwAvM.js @@ -1 +1 @@ -import{g as pt,G as ct,C as bt,c as o,q as u,H as w,a as e,l as A,F as x,r as f,t as r,v as _,s as O,m as L,J as z,K as mt,M as xt,d as b,y as m,A as tt,z as q,o as a,n as vt,x as P,_ as ft}from"./DMxDLVSv.js";import{u as yt}from"./CCZrj3X-.js";import{u as gt}from"./B-sqZCu-.js";import{R as kt}from"./7m3DvxFn.js";const wt={class:"flex items-center justify-between mb-4"},_t={class:"bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden"},ht={class:"table table-sm"},Ct={key:0},Vt={key:1},St={class:"font-mono"},Ut={class:"font-medium"},Nt={key:0,class:"text-green-600 text-xs"},It={key:1,class:"text-slate-400 text-xs"},$t={key:0,class:"text-xs text-slate-500"},Et={key:1,class:"text-xs text-slate-300"},Mt={key:0,class:"text-xs text-slate-500"},At={key:1,class:"text-xs text-slate-300"},Ot={key:2,class:"text-xs text-slate-300"},Lt={key:3,class:"text-[11px] text-emerald-600 mt-0.5"},Pt={class:"text-xs text-slate-500"},Tt={class:"flex gap-1 justify-end"},jt=["onClick"],Dt=["onClick"],Rt=["onClick"],Bt=["onClick"],Gt={class:"flex items-center gap-3 mb-5"},Ft={class:"text-lg font-semibold text-slate-800"},zt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},qt={class:"grid grid-cols-2 gap-3"},Ht=["disabled"],Jt={class:"col-span-2"},Kt={class:"mt-4 border-t border-slate-100 pt-4"},Qt={class:"flex items-center justify-between mb-1"},Wt={class:"flex gap-1"},Xt={class:"text-xs text-slate-500 mb-1.5"},Yt={key:0,class:"text-amber-500 ml-1"},Zt={class:"flex flex-wrap gap-2"},te=["value"],ee={class:"mt-4 border-t border-slate-100 pt-4"},se={class:"grid grid-cols-2 gap-3"},le=["value"],ne=["disabled"],oe={value:""},ae=["value"],ie={class:"mt-4 border-t border-slate-100 pt-4"},de={class:"mb-3"},re={class:"flex flex-wrap gap-2"},ue=["value"],pe={key:1,class:"text-xs text-slate-300"},ce={class:"mb-3"},be={class:"flex flex-wrap gap-2"},me=["value"],xe={class:"max-h-56 overflow-y-auto pr-1 border border-slate-100 rounded-lg p-2"},ve={key:0,class:"text-xs text-slate-300"},fe={key:1,class:"text-xs text-slate-300"},ye={class:"text-[11px] font-semibold text-slate-500 mb-1 sticky top-0 bg-white py-0.5"},ge={class:"flex flex-wrap gap-2"},ke=["value"],we={class:"flex gap-3 justify-end mt-6"},_e=["disabled"],he={class:"modal-box max-w-md"},Ce={class:"text-xs text-slate-400 mb-3"},Ve={class:"font-medium text-slate-600"},Se={class:"text-emerald-600"},Ue={class:"grid grid-cols-3 gap-3"},Ne={class:"modal-action"},Ie=pt({__name:"accounts",setup($e){const{webApi:T,consoleApi:g}=yt(),{success:V,error:y,warn:et}=gt(),st={1:"超管",2:"管理员",3:"品牌商",4:"运营",5:"渠道商"},lt={1:"badge-error",2:"badge-primary",3:"badge-warning",4:"badge-info",5:"badge-accent"},S=m("list"),U=m([]),j=m([]),H=tt(()=>[...new Set(j.value.map(l=>l.app_name||l.name).filter(Boolean))].sort()),D=m(!1),N=m(!1),k=m(0),n=q({username:"",password:"",identity:2,enabled:"1",remark:"",brandid:0,channelid:""}),J=m([]),R=tt(()=>n.brandid?J.value.filter(l=>l.brandid===n.brandid):[]),i=q({access:[],apps:[],regions:[],products:[]}),K=m([]),h=m([]),B=m(!1);function v(l){return(l||"").split(",").map(t=>t.trim()).filter(t=>t)}function I(l){return l.join(",")}function Q(l){const t=[];return l.apps&&t.push("应用:"+v(l.apps).length),l.regions&&t.push("区域:"+v(l.regions).length),l.products&&t.push("产品:"+v(l.products).length),l.access&&t.push("页面:"+v(l.access).length),t}async function $(){D.value=!0;try{try{j.value=await g("apps/list",{})??[]}catch{j.value=[]}const l=await g("accounts/list",{});U.value=l??[]}catch(l){y(l?.message??"获取账号列表失败"),U.value=[]}finally{D.value=!1}}async function nt(){B.value=!0,h.value=[];try{const[l,t,s]=await Promise.all([T("getbrands",{}),T("getproducts",{}),T("getchannels",{status:-1})]),d=l?.brands??[];K.value=d,J.value=s?.channels??[];const C=t?.products??[],Z={};d.forEach(c=>{Z[c.id]=c.brand||"品牌商#"+c.id});const E={};C.forEach(c=>{const M=String(c.brandid||0);(E[M]=E[M]||[]).push(c)});const ut=Object.keys(E).sort((c,M)=>(parseInt(c)||0)-(parseInt(M)||0));h.value=ut.map(c=>({fid:c,label:Z[c]||(parseInt(c)?"品牌商#"+c:"未分组"),products:E[c]??[]}))}catch{h.value=[]}finally{B.value=!1}}function W(l){k.value=l?l.id:0,n.username=l&&l.username||"",n.password="",n.identity=l?l.identity:2,n.enabled=l&&!l.enabled?"0":"1",n.remark=l&&l.remark||"",n.brandid=l&&Number(l.brandid)||0,n.channelid=l&&l.channelid||"",i.access=v(l?.access),n.identity===2&&!i.access.length&&(i.access=z.slice()),i.apps=v(l?.apps),i.regions=v(l?.regions),i.products=v(l?.products),nt(),S.value="form"}ct(()=>n.identity,l=>{l===2&&i.access.length===0&&(i.access=z.slice())});function G(){S.value="list",$()}async function ot(){const l=n.identity,t={identity:l,enabled:n.enabled==="1",remark:n.remark.trim(),access:"",apps:"",regions:"",products:""};if(l!==1&&(t.access=I(i.access)),(l===3||l===4)&&(t.apps=I(i.apps),t.regions=I(i.regions),t.products=I(i.products)),t.brandid=0,t.channelid="",l===3||l===5){if(!n.brandid){y("请选择所属品牌商");return}if(t.brandid=Number(n.brandid),l===5){if(!n.channelid){y("请选择所属渠道商");return}t.channelid=n.channelid}}N.value=!0;try{if(k.value)t.id=k.value,await g("accounts/update",t);else{if(t.username=n.username.trim(),t.password=n.password,!t.username||!t.password){y("用户名和密码必填"),N.value=!1;return}await g("accounts/add",t)}V("已保存"),G()}catch(s){y(s?.message??"保存失败")}finally{N.value=!1}}async function at(l,t){const s=window.prompt("为账号【"+t+"】设置新密码:");if(s)try{await g("accounts/resetpwd",{id:l,password:s}),V("密码已重置")}catch(d){y(d?.message??"失败")}}function it(l,t){window.confirm("确认删除账号【"+t+"】?该操作不可恢复。")&&g("accounts/del",{id:l}).then(()=>{V("已删除"),$()}).catch(s=>y(s?.message??"失败"))}const F=m(null),X=m(0),p=q({name:"",cur:"",vipday:0,trademin:0,meetmin:0});function dt(l){X.value=l.id,p.name=l.username||"#"+l.id,p.cur="VIP"+(l.balance_vipday||0)+"天 · 翻译"+(l.balance_trademin||0)+"分 · 会议"+(l.balance_meetmin||0)+"分",p.vipday=0,p.trademin=0,p.meetmin=0,F.value?.showModal()}function Y(){F.value?.close()}async function rt(){const l=Number(p.vipday)||0,t=Number(p.trademin)||0,s=Number(p.meetmin)||0;if(!l&&!t&&!s){et("请至少填写一项");return}try{await g("accounts/topup",{account_id:X.value,vipday:l,trademin:t,meetmin:s}),V("余额已更新"),Y(),$()}catch(d){y(d?.message??"操作失败")}}return bt($),(l,t)=>(a(),o("div",null,[u(e("div",null,[e("div",wt,[t[24]||(t[24]=e("div",null,[e("h2",{class:"text-lg font-bold text-slate-700"},"后台账号"),e("p",{class:"text-xs text-slate-400 mt-0.5"},"超管 / 管理员 / 代理 / 运营。代理·运营可绑定应用·区域·产品,登录后仪表盘按绑定限制。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=s=>W())},"+ 新建账号")]),e("div",_t,[e("table",ht,[t[27]||(t[27]=e("thead",null,[e("tr",{class:"text-slate-500"},[e("th",null,"ID"),e("th",null,"用户名"),e("th",null,"角色"),e("th",null,"状态"),e("th",null,"绑定作用域"),e("th",null,"备注"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[D.value?(a(),o("tr",Ct,[...t[25]||(t[25]=[e("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"加载中...",-1)])])):U.value.length?A("",!0):(a(),o("tr",Vt,[...t[26]||(t[26]=[e("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无账号(引导超管不在此列)",-1)])])),(a(!0),o(x,null,f(U.value,s=>(a(),o("tr",{key:s.id},[e("td",St,r(s.id),1),e("td",Ut,r(s.username||""),1),e("td",null,[e("span",{class:vt(["badge badge-sm",lt[s.identity]||""])},r(st[s.identity]||s.identity),3)]),e("td",null,[s.enabled?(a(),o("span",Nt,"启用")):(a(),o("span",It,"停用"))]),e("td",null,[s.identity===3||s.identity===4?(a(),o(x,{key:0},[Q(s).length?(a(),o("span",$t,r(Q(s).join(" · ")),1)):(a(),o("span",Et,"未绑定(不限)"))],64)):s.identity===2?(a(),o(x,{key:1},[s.access?(a(),o("span",Mt,"菜单:"+r(v(s.access).length),1)):(a(),o("span",At,"默认(除SaaS/系统管理)"))],64)):(a(),o("span",Ot,"全部权限")),s.identity===3?(a(),o("div",Lt," 余额 VIP"+r(s.balance_vipday||0)+"天 · 翻译"+r(s.balance_trademin||0)+"分 · 会议"+r(s.balance_meetmin||0)+"分 ",1)):A("",!0)]),e("td",Pt,r(s.remark||""),1),e("td",null,[e("div",Tt,[s.identity===3?(a(),o("button",{key:0,class:"btn btn-ghost btn-xs text-emerald-600",onClick:d=>dt(s)},"充值",8,jt)):A("",!0),e("button",{class:"btn btn-ghost btn-xs",onClick:d=>W(s)},"编辑",8,Dt),e("button",{class:"btn btn-ghost btn-xs text-amber-600",onClick:d=>at(s.id,s.username)},"改密",8,Rt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:d=>it(s.id,s.username)},"删除",8,Bt)])])]))),128))])])])],512),[[w,S.value==="list"]]),u(e("div",null,[e("div",Gt,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[1]||(t[1]=s=>G())},"← 返回列表"),e("h2",Ft,r(k.value?"编辑账号 #"+k.value:"新建账号"),1)]),e("div",zt,[e("div",qt,[e("div",null,[t[28]||(t[28]=e("label",{class:"text-xs text-slate-500"},"用户名",-1)),u(e("input",{"onUpdate:modelValue":t[2]||(t[2]=s=>n.username=s),disabled:!!k.value,class:"input input-bordered input-sm w-full",placeholder:"登录用户名"},null,8,Ht),[[_,n.username]])]),u(e("div",null,[t[29]||(t[29]=e("label",{class:"text-xs text-slate-500"},"密码",-1)),u(e("input",{"onUpdate:modelValue":t[3]||(t[3]=s=>n.password=s),type:"password",class:"input input-bordered input-sm w-full",placeholder:"登录密码"},null,512),[[_,n.password]])],512),[[w,!k.value]]),e("div",null,[t[31]||(t[31]=e("label",{class:"text-xs text-slate-500"},"角色",-1)),u(e("select",{"onUpdate:modelValue":t[4]||(t[4]=s=>n.identity=s),class:"select select-bordered select-sm w-full"},[...t[30]||(t[30]=[e("option",{value:2},"管理员(默认除 SaaS/系统管理外全部)",-1),e("option",{value:3},"品牌商(绑定品牌商,见名下全部渠道商)",-1),e("option",{value:5},"渠道商(绑定单个渠道商,只见自己数据)",-1),e("option",{value:4},"运营(内部,按绑定限制)",-1),e("option",{value:1},"超管(全部权限)",-1)])],512),[[O,n.identity,void 0,{number:!0}]])]),e("div",null,[t[33]||(t[33]=e("label",{class:"text-xs text-slate-500"},"状态",-1)),u(e("select",{"onUpdate:modelValue":t[5]||(t[5]=s=>n.enabled=s),class:"select select-bordered select-sm w-full"},[...t[32]||(t[32]=[e("option",{value:"1"},"启用",-1),e("option",{value:"0"},"停用",-1)])],512),[[O,n.enabled]])]),e("div",Jt,[t[34]||(t[34]=e("label",{class:"text-xs text-slate-500"},"备注",-1)),u(e("input",{"onUpdate:modelValue":t[6]||(t[6]=s=>n.remark=s),class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[_,n.remark]])])]),u(e("div",Kt,[e("div",Qt,[t[35]||(t[35]=e("div",{class:"text-sm font-semibold text-slate-600"},"菜单权限",-1)),e("div",Wt,[e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[7]||(t[7]=s=>i.access=L(z).slice())},"管理员默认"),e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[8]||(t[8]=s=>i.access=L(mt).slice())},"全选"),e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[9]||(t[9]=s=>i.access=[])},"清空")])]),t[36]||(t[36]=e("p",{class:"text-xs text-slate-400 mb-3"},"管理员默认开放除「SaaS 管理 / 系统管理」以外的全部菜单(权限留空时按默认生效);代理/运营需显式勾选。",-1)),(a(!0),o(x,null,f(L(xt),s=>(a(),o("div",{key:s.label,class:"mb-2.5"},[e("div",Xt,[b(r(s.label),1),s.restricted?(a(),o("span",Yt,"(管理员默认不开放)")):A("",!0)]),e("div",Zt,[(a(!0),o(x,null,f(s.items,d=>(a(),o("label",{key:d.id,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[10]||(t[10]=C=>i.access=C),type:"checkbox",value:d.id},null,8,te),[[P,i.access]]),b(r(d.label),1)]))),128))])]))),128))],512),[[w,n.identity!==1]]),u(e("div",ee,[t[40]||(t[40]=e("div",{class:"text-sm font-semibold text-slate-600 mb-2"},[b(" 归属绑定 "),e("span",{class:"text-xs text-slate-400 font-normal"},"(品牌商账号只绑品牌商;渠道商账号两者都要绑)")],-1)),e("div",se,[e("div",null,[t[38]||(t[38]=e("label",{class:"text-xs text-slate-500"},"所属品牌商 *",-1)),u(e("select",{"onUpdate:modelValue":t[11]||(t[11]=s=>n.brandid=s),class:"select select-bordered select-sm w-full",onChange:t[12]||(t[12]=s=>n.channelid="")},[t[37]||(t[37]=e("option",{value:0},"请选择品牌商",-1)),(a(!0),o(x,null,f(K.value,s=>(a(),o("option",{key:s.id,value:s.id},r(s.brand),9,le))),128))],544),[[O,n.brandid,void 0,{number:!0}]])]),u(e("div",null,[t[39]||(t[39]=e("label",{class:"text-xs text-slate-500"},"所属渠道商 *",-1)),u(e("select",{"onUpdate:modelValue":t[13]||(t[13]=s=>n.channelid=s),class:"select select-bordered select-sm w-full",disabled:!R.value.length},[e("option",oe,r(n.brandid?R.value.length?"请选择渠道商":"该品牌商暂无渠道商":"请先选择品牌商"),1),(a(!0),o(x,null,f(R.value,s=>(a(),o("option",{key:s.id,value:s.id},r(s.name)+" ("+r(s.id)+")",9,ae))),128))],8,ne),[[O,n.channelid]])],512),[[w,n.identity===5]])]),t[41]||(t[41]=e("p",{class:"text-xs text-slate-400 mt-2"}," 数据隔离由后端强制:品牌商账号只能看到本品牌商及其名下渠道商的数据,渠道商账号只能看到自己渠道的数据。 ",-1))],512),[[w,n.identity===3||n.identity===5]]),u(e("div",ie,[t[45]||(t[45]=e("div",{class:"text-sm font-semibold text-slate-600 mb-2"},[b("作用域绑定 "),e("span",{class:"text-xs text-slate-400 font-normal"},"(代理/运营生效;限制仪表盘数据范围)")],-1)),e("div",de,[t[42]||(t[42]=e("div",{class:"text-xs text-slate-500 mb-1.5"},[b("绑定应用 "),e("span",{class:"text-slate-300"},"(仪表盘只显示这些应用数据;不勾=不限)")],-1)),e("div",re,[H.value.length?(a(!0),o(x,{key:0},f(H.value,s=>(a(),o("label",{key:s,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[14]||(t[14]=d=>i.apps=d),type:"checkbox",value:s},null,8,ue),[[P,i.apps]]),b(r(s),1)]))),128)):(a(),o("span",pe,"无注册应用"))])]),e("div",ce,[t[43]||(t[43]=e("div",{class:"text-xs text-slate-500 mb-1.5"},[b("绑定区域 "),e("span",{class:"text-slate-300"},"(不勾=不限)")],-1)),e("div",be,[(a(!0),o(x,null,f(L(kt),s=>(a(),o("label",{key:s.value,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[15]||(t[15]=d=>i.regions=d),type:"checkbox",value:s.value},null,8,me),[[P,i.regions]]),b(r(s.label),1)]))),128))])]),e("div",null,[t[44]||(t[44]=e("div",{class:"text-xs text-slate-500 mb-1.5"},[b("绑定产品 "),e("span",{class:"text-slate-300"},"(按厂家分组;仪表盘只显示这些产品数据;不勾=不限)")],-1)),e("div",xe,[B.value?(a(),o("span",ve,"加载产品中...")):h.value.length?(a(!0),o(x,{key:2},f(h.value,s=>(a(),o("div",{key:s.fid,class:"mb-2 last:mb-0"},[e("div",ye,"🏭 "+r(s.label),1),e("div",ge,[(a(!0),o(x,null,f(s.products,d=>(a(),o("label",{key:d.id,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[16]||(t[16]=C=>i.products=C),type:"checkbox",value:String(d.id)},null,8,ke),[[P,i.products]]),b(r((d.devicename||"产品")+" #"+d.id),1)]))),128))])]))),128)):(a(),o("span",fe,"无产品"))])])],512),[[w,n.identity===3||n.identity===4]]),e("div",we,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[17]||(t[17]=s=>G())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",disabled:N.value,onClick:t[18]||(t[18]=s=>ot())},"保存",8,_e)])])],512),[[w,S.value==="form"]]),e("dialog",{ref_key:"topupModal",ref:F,class:"modal"},[e("div",he,[t[51]||(t[51]=e("h3",{class:"font-bold text-lg mb-1"},"充值 / 调整资源点",-1)),e("p",Ce,[t[46]||(t[46]=b("代理:",-1)),e("span",Ve,r(p.name),1),t[47]||(t[47]=b("。填增量(可填负数下调),当前余额:",-1)),e("span",Se,r(p.cur),1)]),e("div",Ue,[e("div",null,[t[48]||(t[48]=e("label",{class:"text-xs text-slate-500"},"VIP天数",-1)),u(e("input",{"onUpdate:modelValue":t[19]||(t[19]=s=>p.vipday=s),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.vipday,void 0,{number:!0}]])]),e("div",null,[t[49]||(t[49]=e("label",{class:"text-xs text-slate-500"},"翻译分钟",-1)),u(e("input",{"onUpdate:modelValue":t[20]||(t[20]=s=>p.trademin=s),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.trademin,void 0,{number:!0}]])]),e("div",null,[t[50]||(t[50]=e("label",{class:"text-xs text-slate-500"},"会议分钟",-1)),u(e("input",{"onUpdate:modelValue":t[21]||(t[21]=s=>p.meetmin=s),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.meetmin,void 0,{number:!0}]])])]),e("div",Ne,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[22]||(t[22]=s=>Y())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[23]||(t[23]=s=>rt())},"确认")])]),t[52]||(t[52]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}}),Le=ft(Ie,[["__scopeId","data-v-b47e60f8"]]);export{Le as default}; +import{g as pt,G as ct,C as bt,c as o,q as u,H as w,a as e,l as A,F as x,r as f,t as r,v as _,s as O,m as L,J as z,K as mt,M as xt,d as b,y as m,A as tt,z as q,o as a,n as vt,x as P,_ as ft}from"./DSy_gLdM.js";import{u as yt}from"./NtXZuCUg.js";import{u as gt}from"./EeX3zgoF.js";import{R as kt}from"./7m3DvxFn.js";const wt={class:"flex items-center justify-between mb-4"},_t={class:"bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden"},ht={class:"table table-sm"},Ct={key:0},Vt={key:1},St={class:"font-mono"},Ut={class:"font-medium"},Nt={key:0,class:"text-green-600 text-xs"},It={key:1,class:"text-slate-400 text-xs"},$t={key:0,class:"text-xs text-slate-500"},Et={key:1,class:"text-xs text-slate-300"},Mt={key:0,class:"text-xs text-slate-500"},At={key:1,class:"text-xs text-slate-300"},Ot={key:2,class:"text-xs text-slate-300"},Lt={key:3,class:"text-[11px] text-emerald-600 mt-0.5"},Pt={class:"text-xs text-slate-500"},Tt={class:"flex gap-1 justify-end"},jt=["onClick"],Dt=["onClick"],Rt=["onClick"],Bt=["onClick"],Gt={class:"flex items-center gap-3 mb-5"},Ft={class:"text-lg font-semibold text-slate-800"},zt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},qt={class:"grid grid-cols-2 gap-3"},Ht=["disabled"],Jt={class:"col-span-2"},Kt={class:"mt-4 border-t border-slate-100 pt-4"},Qt={class:"flex items-center justify-between mb-1"},Wt={class:"flex gap-1"},Xt={class:"text-xs text-slate-500 mb-1.5"},Yt={key:0,class:"text-amber-500 ml-1"},Zt={class:"flex flex-wrap gap-2"},te=["value"],ee={class:"mt-4 border-t border-slate-100 pt-4"},se={class:"grid grid-cols-2 gap-3"},le=["value"],ne=["disabled"],oe={value:""},ae=["value"],ie={class:"mt-4 border-t border-slate-100 pt-4"},de={class:"mb-3"},re={class:"flex flex-wrap gap-2"},ue=["value"],pe={key:1,class:"text-xs text-slate-300"},ce={class:"mb-3"},be={class:"flex flex-wrap gap-2"},me=["value"],xe={class:"max-h-56 overflow-y-auto pr-1 border border-slate-100 rounded-lg p-2"},ve={key:0,class:"text-xs text-slate-300"},fe={key:1,class:"text-xs text-slate-300"},ye={class:"text-[11px] font-semibold text-slate-500 mb-1 sticky top-0 bg-white py-0.5"},ge={class:"flex flex-wrap gap-2"},ke=["value"],we={class:"flex gap-3 justify-end mt-6"},_e=["disabled"],he={class:"modal-box max-w-md"},Ce={class:"text-xs text-slate-400 mb-3"},Ve={class:"font-medium text-slate-600"},Se={class:"text-emerald-600"},Ue={class:"grid grid-cols-3 gap-3"},Ne={class:"modal-action"},Ie=pt({__name:"accounts",setup($e){const{webApi:T,consoleApi:g}=yt(),{success:V,error:y,warn:et}=gt(),st={1:"超管",2:"管理员",3:"品牌商",4:"运营",5:"渠道商"},lt={1:"badge-error",2:"badge-primary",3:"badge-warning",4:"badge-info",5:"badge-accent"},S=m("list"),U=m([]),j=m([]),H=tt(()=>[...new Set(j.value.map(l=>l.app_name||l.name).filter(Boolean))].sort()),D=m(!1),N=m(!1),k=m(0),n=q({username:"",password:"",identity:2,enabled:"1",remark:"",brandid:0,channelid:""}),J=m([]),R=tt(()=>n.brandid?J.value.filter(l=>l.brandid===n.brandid):[]),i=q({access:[],apps:[],regions:[],products:[]}),K=m([]),h=m([]),B=m(!1);function v(l){return(l||"").split(",").map(t=>t.trim()).filter(t=>t)}function I(l){return l.join(",")}function Q(l){const t=[];return l.apps&&t.push("应用:"+v(l.apps).length),l.regions&&t.push("区域:"+v(l.regions).length),l.products&&t.push("产品:"+v(l.products).length),l.access&&t.push("页面:"+v(l.access).length),t}async function $(){D.value=!0;try{try{j.value=await g("apps/list",{})??[]}catch{j.value=[]}const l=await g("accounts/list",{});U.value=l??[]}catch(l){y(l?.message??"获取账号列表失败"),U.value=[]}finally{D.value=!1}}async function nt(){B.value=!0,h.value=[];try{const[l,t,s]=await Promise.all([T("getbrands",{}),T("getproducts",{}),T("getchannels",{status:-1})]),d=l?.brands??[];K.value=d,J.value=s?.channels??[];const C=t?.products??[],Z={};d.forEach(c=>{Z[c.id]=c.brand||"品牌商#"+c.id});const E={};C.forEach(c=>{const M=String(c.brandid||0);(E[M]=E[M]||[]).push(c)});const ut=Object.keys(E).sort((c,M)=>(parseInt(c)||0)-(parseInt(M)||0));h.value=ut.map(c=>({fid:c,label:Z[c]||(parseInt(c)?"品牌商#"+c:"未分组"),products:E[c]??[]}))}catch{h.value=[]}finally{B.value=!1}}function W(l){k.value=l?l.id:0,n.username=l&&l.username||"",n.password="",n.identity=l?l.identity:2,n.enabled=l&&!l.enabled?"0":"1",n.remark=l&&l.remark||"",n.brandid=l&&Number(l.brandid)||0,n.channelid=l&&l.channelid||"",i.access=v(l?.access),n.identity===2&&!i.access.length&&(i.access=z.slice()),i.apps=v(l?.apps),i.regions=v(l?.regions),i.products=v(l?.products),nt(),S.value="form"}ct(()=>n.identity,l=>{l===2&&i.access.length===0&&(i.access=z.slice())});function G(){S.value="list",$()}async function ot(){const l=n.identity,t={identity:l,enabled:n.enabled==="1",remark:n.remark.trim(),access:"",apps:"",regions:"",products:""};if(l!==1&&(t.access=I(i.access)),(l===3||l===4)&&(t.apps=I(i.apps),t.regions=I(i.regions),t.products=I(i.products)),t.brandid=0,t.channelid="",l===3||l===5){if(!n.brandid){y("请选择所属品牌商");return}if(t.brandid=Number(n.brandid),l===5){if(!n.channelid){y("请选择所属渠道商");return}t.channelid=n.channelid}}N.value=!0;try{if(k.value)t.id=k.value,await g("accounts/update",t);else{if(t.username=n.username.trim(),t.password=n.password,!t.username||!t.password){y("用户名和密码必填"),N.value=!1;return}await g("accounts/add",t)}V("已保存"),G()}catch(s){y(s?.message??"保存失败")}finally{N.value=!1}}async function at(l,t){const s=window.prompt("为账号【"+t+"】设置新密码:");if(s)try{await g("accounts/resetpwd",{id:l,password:s}),V("密码已重置")}catch(d){y(d?.message??"失败")}}function it(l,t){window.confirm("确认删除账号【"+t+"】?该操作不可恢复。")&&g("accounts/del",{id:l}).then(()=>{V("已删除"),$()}).catch(s=>y(s?.message??"失败"))}const F=m(null),X=m(0),p=q({name:"",cur:"",vipday:0,trademin:0,meetmin:0});function dt(l){X.value=l.id,p.name=l.username||"#"+l.id,p.cur="VIP"+(l.balance_vipday||0)+"天 · 翻译"+(l.balance_trademin||0)+"分 · 会议"+(l.balance_meetmin||0)+"分",p.vipday=0,p.trademin=0,p.meetmin=0,F.value?.showModal()}function Y(){F.value?.close()}async function rt(){const l=Number(p.vipday)||0,t=Number(p.trademin)||0,s=Number(p.meetmin)||0;if(!l&&!t&&!s){et("请至少填写一项");return}try{await g("accounts/topup",{account_id:X.value,vipday:l,trademin:t,meetmin:s}),V("余额已更新"),Y(),$()}catch(d){y(d?.message??"操作失败")}}return bt($),(l,t)=>(a(),o("div",null,[u(e("div",null,[e("div",wt,[t[24]||(t[24]=e("div",null,[e("h2",{class:"text-lg font-bold text-slate-700"},"后台账号"),e("p",{class:"text-xs text-slate-400 mt-0.5"},"超管 / 管理员 / 代理 / 运营。代理·运营可绑定应用·区域·产品,登录后仪表盘按绑定限制。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[0]||(t[0]=s=>W())},"+ 新建账号")]),e("div",_t,[e("table",ht,[t[27]||(t[27]=e("thead",null,[e("tr",{class:"text-slate-500"},[e("th",null,"ID"),e("th",null,"用户名"),e("th",null,"角色"),e("th",null,"状态"),e("th",null,"绑定作用域"),e("th",null,"备注"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[D.value?(a(),o("tr",Ct,[...t[25]||(t[25]=[e("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"加载中...",-1)])])):U.value.length?A("",!0):(a(),o("tr",Vt,[...t[26]||(t[26]=[e("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无账号(引导超管不在此列)",-1)])])),(a(!0),o(x,null,f(U.value,s=>(a(),o("tr",{key:s.id},[e("td",St,r(s.id),1),e("td",Ut,r(s.username||""),1),e("td",null,[e("span",{class:vt(["badge badge-sm",lt[s.identity]||""])},r(st[s.identity]||s.identity),3)]),e("td",null,[s.enabled?(a(),o("span",Nt,"启用")):(a(),o("span",It,"停用"))]),e("td",null,[s.identity===3||s.identity===4?(a(),o(x,{key:0},[Q(s).length?(a(),o("span",$t,r(Q(s).join(" · ")),1)):(a(),o("span",Et,"未绑定(不限)"))],64)):s.identity===2?(a(),o(x,{key:1},[s.access?(a(),o("span",Mt,"菜单:"+r(v(s.access).length),1)):(a(),o("span",At,"默认(除SaaS/系统管理)"))],64)):(a(),o("span",Ot,"全部权限")),s.identity===3?(a(),o("div",Lt," 余额 VIP"+r(s.balance_vipday||0)+"天 · 翻译"+r(s.balance_trademin||0)+"分 · 会议"+r(s.balance_meetmin||0)+"分 ",1)):A("",!0)]),e("td",Pt,r(s.remark||""),1),e("td",null,[e("div",Tt,[s.identity===3?(a(),o("button",{key:0,class:"btn btn-ghost btn-xs text-emerald-600",onClick:d=>dt(s)},"充值",8,jt)):A("",!0),e("button",{class:"btn btn-ghost btn-xs",onClick:d=>W(s)},"编辑",8,Dt),e("button",{class:"btn btn-ghost btn-xs text-amber-600",onClick:d=>at(s.id,s.username)},"改密",8,Rt),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:d=>it(s.id,s.username)},"删除",8,Bt)])])]))),128))])])])],512),[[w,S.value==="list"]]),u(e("div",null,[e("div",Gt,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[1]||(t[1]=s=>G())},"← 返回列表"),e("h2",Ft,r(k.value?"编辑账号 #"+k.value:"新建账号"),1)]),e("div",zt,[e("div",qt,[e("div",null,[t[28]||(t[28]=e("label",{class:"text-xs text-slate-500"},"用户名",-1)),u(e("input",{"onUpdate:modelValue":t[2]||(t[2]=s=>n.username=s),disabled:!!k.value,class:"input input-bordered input-sm w-full",placeholder:"登录用户名"},null,8,Ht),[[_,n.username]])]),u(e("div",null,[t[29]||(t[29]=e("label",{class:"text-xs text-slate-500"},"密码",-1)),u(e("input",{"onUpdate:modelValue":t[3]||(t[3]=s=>n.password=s),type:"password",class:"input input-bordered input-sm w-full",placeholder:"登录密码"},null,512),[[_,n.password]])],512),[[w,!k.value]]),e("div",null,[t[31]||(t[31]=e("label",{class:"text-xs text-slate-500"},"角色",-1)),u(e("select",{"onUpdate:modelValue":t[4]||(t[4]=s=>n.identity=s),class:"select select-bordered select-sm w-full"},[...t[30]||(t[30]=[e("option",{value:2},"管理员(默认除 SaaS/系统管理外全部)",-1),e("option",{value:3},"品牌商(绑定品牌商,见名下全部渠道商)",-1),e("option",{value:5},"渠道商(绑定单个渠道商,只见自己数据)",-1),e("option",{value:4},"运营(内部,按绑定限制)",-1),e("option",{value:1},"超管(全部权限)",-1)])],512),[[O,n.identity,void 0,{number:!0}]])]),e("div",null,[t[33]||(t[33]=e("label",{class:"text-xs text-slate-500"},"状态",-1)),u(e("select",{"onUpdate:modelValue":t[5]||(t[5]=s=>n.enabled=s),class:"select select-bordered select-sm w-full"},[...t[32]||(t[32]=[e("option",{value:"1"},"启用",-1),e("option",{value:"0"},"停用",-1)])],512),[[O,n.enabled]])]),e("div",Jt,[t[34]||(t[34]=e("label",{class:"text-xs text-slate-500"},"备注",-1)),u(e("input",{"onUpdate:modelValue":t[6]||(t[6]=s=>n.remark=s),class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[_,n.remark]])])]),u(e("div",Kt,[e("div",Qt,[t[35]||(t[35]=e("div",{class:"text-sm font-semibold text-slate-600"},"菜单权限",-1)),e("div",Wt,[e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[7]||(t[7]=s=>i.access=L(z).slice())},"管理员默认"),e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[8]||(t[8]=s=>i.access=L(mt).slice())},"全选"),e("button",{type:"button",class:"btn btn-ghost btn-xs",onClick:t[9]||(t[9]=s=>i.access=[])},"清空")])]),t[36]||(t[36]=e("p",{class:"text-xs text-slate-400 mb-3"},"管理员默认开放除「SaaS 管理 / 系统管理」以外的全部菜单(权限留空时按默认生效);代理/运营需显式勾选。",-1)),(a(!0),o(x,null,f(L(xt),s=>(a(),o("div",{key:s.label,class:"mb-2.5"},[e("div",Xt,[b(r(s.label),1),s.restricted?(a(),o("span",Yt,"(管理员默认不开放)")):A("",!0)]),e("div",Zt,[(a(!0),o(x,null,f(s.items,d=>(a(),o("label",{key:d.id,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[10]||(t[10]=C=>i.access=C),type:"checkbox",value:d.id},null,8,te),[[P,i.access]]),b(r(d.label),1)]))),128))])]))),128))],512),[[w,n.identity!==1]]),u(e("div",ee,[t[40]||(t[40]=e("div",{class:"text-sm font-semibold text-slate-600 mb-2"},[b(" 归属绑定 "),e("span",{class:"text-xs text-slate-400 font-normal"},"(品牌商账号只绑品牌商;渠道商账号两者都要绑)")],-1)),e("div",se,[e("div",null,[t[38]||(t[38]=e("label",{class:"text-xs text-slate-500"},"所属品牌商 *",-1)),u(e("select",{"onUpdate:modelValue":t[11]||(t[11]=s=>n.brandid=s),class:"select select-bordered select-sm w-full",onChange:t[12]||(t[12]=s=>n.channelid="")},[t[37]||(t[37]=e("option",{value:0},"请选择品牌商",-1)),(a(!0),o(x,null,f(K.value,s=>(a(),o("option",{key:s.id,value:s.id},r(s.brand),9,le))),128))],544),[[O,n.brandid,void 0,{number:!0}]])]),u(e("div",null,[t[39]||(t[39]=e("label",{class:"text-xs text-slate-500"},"所属渠道商 *",-1)),u(e("select",{"onUpdate:modelValue":t[13]||(t[13]=s=>n.channelid=s),class:"select select-bordered select-sm w-full",disabled:!R.value.length},[e("option",oe,r(n.brandid?R.value.length?"请选择渠道商":"该品牌商暂无渠道商":"请先选择品牌商"),1),(a(!0),o(x,null,f(R.value,s=>(a(),o("option",{key:s.id,value:s.id},r(s.name)+" ("+r(s.id)+")",9,ae))),128))],8,ne),[[O,n.channelid]])],512),[[w,n.identity===5]])]),t[41]||(t[41]=e("p",{class:"text-xs text-slate-400 mt-2"}," 数据隔离由后端强制:品牌商账号只能看到本品牌商及其名下渠道商的数据,渠道商账号只能看到自己渠道的数据。 ",-1))],512),[[w,n.identity===3||n.identity===5]]),u(e("div",ie,[t[45]||(t[45]=e("div",{class:"text-sm font-semibold text-slate-600 mb-2"},[b("作用域绑定 "),e("span",{class:"text-xs text-slate-400 font-normal"},"(代理/运营生效;限制仪表盘数据范围)")],-1)),e("div",de,[t[42]||(t[42]=e("div",{class:"text-xs text-slate-500 mb-1.5"},[b("绑定应用 "),e("span",{class:"text-slate-300"},"(仪表盘只显示这些应用数据;不勾=不限)")],-1)),e("div",re,[H.value.length?(a(!0),o(x,{key:0},f(H.value,s=>(a(),o("label",{key:s,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[14]||(t[14]=d=>i.apps=d),type:"checkbox",value:s},null,8,ue),[[P,i.apps]]),b(r(s),1)]))),128)):(a(),o("span",pe,"无注册应用"))])]),e("div",ce,[t[43]||(t[43]=e("div",{class:"text-xs text-slate-500 mb-1.5"},[b("绑定区域 "),e("span",{class:"text-slate-300"},"(不勾=不限)")],-1)),e("div",be,[(a(!0),o(x,null,f(L(kt),s=>(a(),o("label",{key:s.value,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[15]||(t[15]=d=>i.regions=d),type:"checkbox",value:s.value},null,8,me),[[P,i.regions]]),b(r(s.label),1)]))),128))])]),e("div",null,[t[44]||(t[44]=e("div",{class:"text-xs text-slate-500 mb-1.5"},[b("绑定产品 "),e("span",{class:"text-slate-300"},"(按厂家分组;仪表盘只显示这些产品数据;不勾=不限)")],-1)),e("div",xe,[B.value?(a(),o("span",ve,"加载产品中...")):h.value.length?(a(!0),o(x,{key:2},f(h.value,s=>(a(),o("div",{key:s.fid,class:"mb-2 last:mb-0"},[e("div",ye,"🏭 "+r(s.label),1),e("div",ge,[(a(!0),o(x,null,f(s.products,d=>(a(),o("label",{key:d.id,class:"chk"},[u(e("input",{"onUpdate:modelValue":t[16]||(t[16]=C=>i.products=C),type:"checkbox",value:String(d.id)},null,8,ke),[[P,i.products]]),b(r((d.devicename||"产品")+" #"+d.id),1)]))),128))])]))),128)):(a(),o("span",fe,"无产品"))])])],512),[[w,n.identity===3||n.identity===4]]),e("div",we,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[17]||(t[17]=s=>G())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",disabled:N.value,onClick:t[18]||(t[18]=s=>ot())},"保存",8,_e)])])],512),[[w,S.value==="form"]]),e("dialog",{ref_key:"topupModal",ref:F,class:"modal"},[e("div",he,[t[51]||(t[51]=e("h3",{class:"font-bold text-lg mb-1"},"充值 / 调整资源点",-1)),e("p",Ce,[t[46]||(t[46]=b("代理:",-1)),e("span",Ve,r(p.name),1),t[47]||(t[47]=b("。填增量(可填负数下调),当前余额:",-1)),e("span",Se,r(p.cur),1)]),e("div",Ue,[e("div",null,[t[48]||(t[48]=e("label",{class:"text-xs text-slate-500"},"VIP天数",-1)),u(e("input",{"onUpdate:modelValue":t[19]||(t[19]=s=>p.vipday=s),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.vipday,void 0,{number:!0}]])]),e("div",null,[t[49]||(t[49]=e("label",{class:"text-xs text-slate-500"},"翻译分钟",-1)),u(e("input",{"onUpdate:modelValue":t[20]||(t[20]=s=>p.trademin=s),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.trademin,void 0,{number:!0}]])]),e("div",null,[t[50]||(t[50]=e("label",{class:"text-xs text-slate-500"},"会议分钟",-1)),u(e("input",{"onUpdate:modelValue":t[21]||(t[21]=s=>p.meetmin=s),type:"number",class:"input input-bordered input-sm w-full"},null,512),[[_,p.meetmin,void 0,{number:!0}]])])]),e("div",Ne,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[22]||(t[22]=s=>Y())},"取消"),e("button",{class:"btn btn-primary btn-sm text-white",onClick:t[23]||(t[23]=s=>rt())},"确认")])]),t[52]||(t[52]=e("form",{method:"dialog",class:"modal-backdrop"},[e("button",null,"close")],-1))],512)]))}}),Le=ft(Ie,[["__scopeId","data-v-b47e60f8"]]);export{Le as default}; diff --git a/apps/admin/.output/public/_nuxt/BDDumZok.js b/apps/admin/.output/public/_nuxt/BDDumZok.js new file mode 100644 index 00000000..506904e6 --- /dev/null +++ b/apps/admin/.output/public/_nuxt/BDDumZok.js @@ -0,0 +1 @@ +import{g as ce,k as pe,C as ve,c as o,a as s,q as d,s as H,F as p,r as v,l as c,d as w,H as me,t as r,v as x,x as N,p as be,y as b,z as fe,A as z,o as i,L as Q,n as O,_ as xe}from"./DSy_gLdM.js";import{u as ye}from"./NtXZuCUg.js";import{u as ge}from"./EeX3zgoF.js";const ke={class:"flex items-center justify-between mb-5 flex-wrap gap-3"},_e={class:"flex items-center gap-3"},he=["value"],we={key:0,class:"pay-warn"},Ce={class:"flex items-start gap-2"},Ve={class:"flex-1"},Ae={class:"text-xs mt-1"},Ue={key:1,class:"scope-tip"},Se={class:"flex items-center gap-2 mb-3"},Pe={class:"text-xs text-slate-400"},Ne={class:"ch-grid"},Oe=["onClick"],je={class:"flex items-start justify-between gap-2"},Le={class:"min-w-0"},Me={class:"font-semibold text-sm text-slate-800"},Ee={class:"text-[11px] text-slate-400 mt-0.5"},Ie={class:"ver-row"},Be={class:"ver-box"},Te={class:"ver-val"},$e={class:"ver-box"},He={key:0,class:"ver-box"},ze={class:"ver-val review"},Fe={class:"flex flex-wrap items-center gap-1.5 mt-2"},Ge={key:0,class:"flag flag-warn"},Re={key:1,class:"flag"},qe={key:2,class:"flag"},De={key:3,class:"flag flag-off"},We={key:0,class:"flex flex-wrap items-center gap-1.5 mt-2"},Ye=["title"],Je={key:1,class:"text-[11px] text-slate-400 mt-2 truncate"},Ke=["onClick"],Qe={class:"text-sm text-slate-400"},Xe={class:"ch-overlay"},Ze={class:"ch-box"},es={class:"flex items-center justify-between mb-4"},ss={class:"flex items-center gap-3"},ts={class:"text-base font-semibold text-slate-800"},ls={class:"scope-chip"},ns={class:"ed-section"},as={class:"grid grid-cols-2 gap-3"},os=["disabled"],is=["label"],rs=["value"],ds=["value"],us={class:"mt-3"},cs={class:"ed-section"},ps={class:"grid grid-cols-3 gap-3"},vs={class:"flex items-center gap-2 text-sm cursor-pointer mt-3"},ms={key:0,class:"ed-warn"},bs={class:"mt-3"},fs={class:"mt-3"},xs={class:"ed-section"},ys={class:"flex flex-col gap-2"},gs={class:"flex items-center gap-2 text-sm cursor-pointer"},ks={class:"flex items-center gap-2 text-sm cursor-pointer"},_s={class:"ed-section"},hs={class:"pay-grid"},ws=["checked","onChange"],Cs={key:0,class:"pay-miss"},Vs={class:"ed-tip"},As={key:1},Us={class:"ed-footer"},Ss={class:"flex items-center gap-2 text-sm cursor-pointer"},Ps={class:"flex gap-2"},Ns=["disabled"],Os=ce({__name:"channels",setup(js){const X={1:"华为",2:"小米",3:"OPPO",4:"VIVO",5:"荣耀",100:"官方包",101:"App Store",102:"Google Play"};function y(l){return X[l]??"渠道"+l}const F=[{label:"中国厂商",icon:"📱",color:"#0369a1",bg:"#dbeafe",channels:[1,2,3,4,5]},{label:"全球商店",icon:"🌍",color:"#c2410c",bg:"#fff7ed",channels:[101,102]},{label:"官方渠道",icon:"🏠",color:"#059669",bg:"#dcfce7",channels:[100]}],j=[{v:0,label:"草稿(不下发)",color:"#64748b",bg:"#f1f5f9"},{v:1,label:"已上架",color:"#059669",bg:"#dcfce7"},{v:2,label:"审核中",color:"#b45309",bg:"#fef9c3"},{v:3,label:"已下架",color:"#be123c",bg:"#ffe4e6"}];function Z(l){return j.find(e=>e.v===l)?.label??"未知"}function ee(l){const e=j.find(t=>t.v===l);return e?{background:e.bg,color:e.color}:{}}const L=[{key:"wxpay",label:"微信支付",module:"wechatpay"},{key:"alipay",label:"支付宝",module:"alipay"},{key:"paypal",label:"PayPal",module:"paypal"},{key:"apple",label:"Apple 内购",module:"appleiap"},{key:"google",label:"Google 内购",module:"googleiap"}];function G(l){return L.find(e=>e.key===l)?.label??l}const{webApi:C,consoleApi:se}=ye(),{success:R,error:f}=ge(),te=pe(),u=b(""),M=b([]),g=b([]),E=b([]),V=b(!1),A=b(!1),k=b(!1),I=b(!1);function B(){return{row_id:0,app_name:"",channel:0,version:"",min_version:"",force_update:!1,changelog:"",address:"",review_version:"",status:1,description:"",tourists:!1,allowskipdevicebinding:!1,paychannels:"",enable:!0}}const n=fe(B()),le=z(()=>F.map(l=>({...l,items:g.value.filter(e=>l.channels.includes(e.channel)).sort((e,t)=>e.channel-t.channel),missing:l.channels.filter(e=>!g.value.some(t=>t.channel===e))})));function _(l){return(l.paychannels||"").split(",").map(e=>e.trim()).filter(Boolean)}function h(l){if(!V.value)return!1;const e=L.find(t=>t.key===l)?.module;return!!e&&!E.value.includes(e)}const q=z(()=>{if(!V.value)return[];const l={};for(const e of g.value)if(e.enable)for(const t of _(e))h(t)&&(l[t]=l[t]||[]).push(y(e.channel));return Object.keys(l).map(e=>({key:e,label:G(e),channels:l[e]}))}),U=z(()=>n.force_update&&!n.min_version.trim()?"开启强制更新时必须填「最低支持版本」,否则挡不住任何人":n.min_version.trim()&&n.version.trim()&&ne(n.min_version,n.version)>0?"「最低支持版本」高于「当前线上版本」,会把所有线上用户判定为需强更却无更高版本可更":"");function ne(l,e){const t=l.trim().split("."),a=e.trim().split("."),m=Math.max(t.length,a.length);for(let P=0;Pe.name).filter(Boolean)}catch{M.value=[]}}async function T(){try{const l=await C("getchannelapps",{app_name:u.value});g.value=l?.items??[]}catch(l){f(l?.message??"加载失败"),g.value=[]}}async function oe(){try{const l=await C("getchannelpaystatus",{app_name:u.value});E.value=l?.configured??[],V.value=!!l?.checked}catch{E.value=[],V.value=!1}}async function D(){await Promise.all([T(),oe()])}function W(l){Object.assign(n,B()),typeof l=="number"&&(n.channel=l),k.value=!1,A.value=!0}function ie(l){Object.assign(n,B(),l),k.value=!0,A.value=!0}function S(){A.value=!1}function $(l){return _(n).includes(l)}function re(l){const e=_(n),t=e.indexOf(l);t>=0?e.splice(t,1):e.push(l),n.paychannels=e.join(",")}async function de(){if(!n.channel){f("请选择分发渠道");return}if(U.value){f(U.value);return}I.value=!0;try{await C("savechannelapp",{...n,app_name:u.value}),R("保存成功"),S(),await T()}catch(l){f(l?.message??"保存失败")}finally{I.value=!1}}function ue(){window.confirm(`确定删除「${y(n.channel)}」这个渠道的配置吗?`)&&C("delchannelapp",{app_name:u.value,channel:n.channel}).then(()=>{R("已删除"),S(),T()}).catch(l=>f(l?.message??"删除失败"))}function Y(){if(!u.value){f("请先在上方选择一个应用");return}te.push(`/apps/${encodeURIComponent(u.value)}?tab=modules`)}return ve(async()=>{await ae(),await D()}),(l,e)=>(i(),o("div",null,[s("div",ke,[e[15]||(e[15]=s("div",null,[s("h2",{class:"text-lg font-semibold text-slate-800"},"渠道分发"),s("p",{class:"text-xs text-slate-400 mt-1"}," 管理各应用在各分发渠道上的版本、强制更新与能力开关。支付渠道在这里控制「开放哪几种支付入口」,商户凭据在应用的业务功能配置里填。 ")],-1)),s("div",_e,[e[14]||(e[14]=s("span",{class:"text-sm text-slate-500"},"应用",-1)),d(s("select",{"onUpdate:modelValue":e[0]||(e[0]=t=>u.value=t),class:"select select-bordered select-sm",onChange:D},[e[13]||(e[13]=s("option",{value:""},"全局默认(所有应用兜底)",-1)),(i(!0),o(p,null,v(M.value,t=>(i(),o("option",{key:t,value:t},r(t),9,he))),128))],544),[[H,u.value]]),s("button",{class:"btn btn-primary btn-sm text-white",onClick:W},"+ 添加渠道")])]),q.value.length?(i(),o("div",we,[s("div",Ce,[e[17]||(e[17]=s("span",null,"⚠",-1)),s("div",Ve,[e[16]||(e[16]=s("div",{class:"text-sm font-semibold"},"以下支付方式已在渠道里开放,但商户凭据还没配:",-1)),s("div",Ae,[(i(!0),o(p,null,v(q.value,t=>(i(),o("span",{key:t.key,class:"warn-pill"},r(t.label)+"("+r(t.channels.join("、"))+")",1))),128))])]),s("button",{class:"btn btn-xs btn-ghost",onClick:Y},"去配置 →")])])):c("",!0),u.value?c("",!0):(i(),o("div",Ue,[...e[18]||(e[18]=[w(" 当前是",-1),s("b",null,"全局默认",-1),w("作用域:这里配的渠道对所有应用生效,应用自己配了同渠道则以应用的为准。 ",-1)])])),(i(!0),o(p,null,v(le.value,t=>(i(),o("div",{key:t.label,class:"mb-6"},[s("div",Se,[s("span",{class:"group-tag",style:Q({background:t.bg,color:t.color})},r(t.icon)+" "+r(t.label),5),s("span",Pe,r(t.items.length)+" / "+r(t.channels.length)+" 已配置",1)]),s("div",Ne,[(i(!0),o(p,null,v(t.items,a=>(i(),o("div",{key:a.channel,class:O(["ch-card",{off:!a.enable}]),onClick:m=>ie(a)},[s("div",je,[s("div",Le,[s("div",Me,r(y(a.channel)),1),s("div",Ee,"渠道号 "+r(a.channel),1)]),s("span",{class:"status-badge",style:Q(ee(a.status))},r(Z(a.status)),5)]),s("div",Ie,[s("div",Be,[e[19]||(e[19]=s("span",{class:"ver-label"},"线上版本",-1)),s("span",Te,r(a.version||"—"),1)]),s("div",$e,[e[20]||(e[20]=s("span",{class:"ver-label"},"最低支持",-1)),s("span",{class:O(["ver-val",{warn:a.force_update}])},r(a.min_version||"—"),3)]),a.review_version?(i(),o("div",He,[e[21]||(e[21]=s("span",{class:"ver-label"},"审核中",-1)),s("span",ze,r(a.review_version),1)])):c("",!0)]),s("div",Fe,[a.force_update?(i(),o("span",Ge,"强制更新")):c("",!0),a.tourists?(i(),o("span",Re,"游客登录")):c("",!0),a.allowskipdevicebinding?(i(),o("span",qe,"可跳过绑定")):c("",!0),a.enable?c("",!0):(i(),o("span",De,"已停用"))]),_(a).length?(i(),o("div",We,[(i(!0),o(p,null,v(_(a),m=>(i(),o("span",{key:m,class:O(["pay-pill",{missing:h(m)}]),title:h(m)?"该支付方式的商户凭据尚未配置":""},r(G(m))+r(h(m)?" ⚠":""),11,Ye))),128))])):c("",!0),a.address?(i(),o("div",Je,r(a.address),1)):c("",!0)],10,Oe))),128)),(i(!0),o(p,null,v(t.missing,a=>(i(),o("div",{key:"m"+a,class:"ch-card ch-empty",onClick:m=>W(a)},[s("div",Qe,r(y(a)),1),e[22]||(e[22]=s("div",{class:"text-[11px] text-slate-300 mt-1"},"未配置 · 点击添加",-1))],8,Ke))),128))])]))),128)),d(s("div",Xe,[s("div",Ze,[s("div",es,[s("div",ss,[s("h3",ts,r(k.value?"编辑渠道":"添加渠道"),1),s("span",ls,r(u.value||"全局默认"),1)]),s("button",{class:"btn btn-ghost btn-xs",onClick:S},"✕ 关闭")]),s("section",ns,[e[27]||(e[27]=s("div",{class:"ed-section-title"},"渠道",-1)),s("div",as,[s("div",null,[e[24]||(e[24]=s("span",{class:"ed-label"},[w("分发渠道 "),s("i",{class:"req"},"*")],-1)),d(s("select",{"onUpdate:modelValue":e[1]||(e[1]=t=>n.channel=t),disabled:k.value,class:"select select-bordered select-sm w-full"},[e[23]||(e[23]=s("option",{value:0,disabled:""},"请选择渠道",-1)),(i(),o(p,null,v(F,t=>s("optgroup",{key:t.label,label:t.label},[(i(!0),o(p,null,v(t.channels,a=>(i(),o("option",{key:a,value:a},r(y(a))+"("+r(a)+")",9,rs))),128))],8,is)),64))],8,os),[[H,n.channel,void 0,{number:!0}]])]),s("div",null,[e[25]||(e[25]=s("span",{class:"ed-label"},"上架状态",-1)),d(s("select",{"onUpdate:modelValue":e[2]||(e[2]=t=>n.status=t),class:"select select-bordered select-sm w-full"},[(i(),o(p,null,v(j,t=>s("option",{key:t.v,value:t.v},r(t.label),9,ds)),64))],512),[[H,n.status,void 0,{number:!0}]])])]),s("div",us,[e[26]||(e[26]=s("span",{class:"ed-label"},"描述",-1)),d(s("input",{"onUpdate:modelValue":e[3]||(e[3]=t=>n.description=t),class:"input input-bordered input-sm w-full",placeholder:"这个渠道包的说明"},null,512),[[x,n.description]])])]),s("section",cs,[e[35]||(e[35]=s("div",{class:"ed-section-title"},"版本",-1)),s("div",ps,[s("div",null,[e[28]||(e[28]=s("span",{class:"ed-label"},"当前线上版本",-1)),d(s("input",{"onUpdate:modelValue":e[4]||(e[4]=t=>n.version=t),class:"input input-bordered input-sm w-full",placeholder:"如 1.4.2"},null,512),[[x,n.version]])]),s("div",null,[e[29]||(e[29]=s("span",{class:"ed-label"},"最低支持版本",-1)),d(s("input",{"onUpdate:modelValue":e[5]||(e[5]=t=>n.min_version=t),class:"input input-bordered input-sm w-full",placeholder:"低于它的客户端需更新"},null,512),[[x,n.min_version]])]),s("div",null,[e[30]||(e[30]=s("span",{class:"ed-label"},"审核中版本",-1)),d(s("input",{"onUpdate:modelValue":e[6]||(e[6]=t=>n.review_version=t),class:"input input-bordered input-sm w-full",placeholder:"过审后清空"},null,512),[[x,n.review_version]])])]),s("label",vs,[d(s("input",{"onUpdate:modelValue":e[7]||(e[7]=t=>n.force_update=t),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[N,n.force_update]]),e[31]||(e[31]=s("span",null,"强制更新",-1)),e[32]||(e[32]=s("span",{class:"text-xs text-slate-400"},"低于「最低支持版本」的客户端必须更新才能继续使用",-1))]),U.value?(i(),o("p",ms,"⚠ "+r(U.value),1)):c("",!0),s("div",bs,[e[33]||(e[33]=s("span",{class:"ed-label"},"下载地址",-1)),d(s("input",{"onUpdate:modelValue":e[8]||(e[8]=t=>n.address=t),class:"input input-bordered input-sm w-full",placeholder:"应用商店链接或 apk 直链"},null,512),[[x,n.address]])]),s("div",fs,[e[34]||(e[34]=s("span",{class:"ed-label"},"更新日志",-1)),d(s("textarea",{"onUpdate:modelValue":e[9]||(e[9]=t=>n.changelog=t),class:"textarea textarea-bordered w-full text-xs",rows:"3",placeholder:"本次更新内容,会下发给客户端展示"},null,512),[[x,n.changelog]])])]),s("section",xs,[e[38]||(e[38]=s("div",{class:"ed-section-title"},"能力开关",-1)),s("div",ys,[s("label",gs,[d(s("input",{"onUpdate:modelValue":e[10]||(e[10]=t=>n.tourists=t),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[N,n.tourists]]),e[36]||(e[36]=s("span",null,"允许游客登录",-1))]),s("label",ks,[d(s("input",{"onUpdate:modelValue":e[11]||(e[11]=t=>n.allowskipdevicebinding=t),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[N,n.allowskipdevicebinding]]),e[37]||(e[37]=s("span",null,"允许跳过设备绑定",-1))])])]),s("section",_s,[e[41]||(e[41]=s("div",{class:"ed-section-title"},"支付渠道",-1)),s("div",hs,[(i(),o(p,null,v(L,t=>s("label",{key:t.key,class:O(["pay-item",{checked:$(t.key)}])},[s("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary",checked:$(t.key),onChange:a=>re(t.key)},null,40,ws),s("span",null,r(t.label),1),$(t.key)&&h(t.key)?(i(),o("span",Cs,"未配凭据")):c("",!0)],2)),64))]),s("p",Vs,[e[39]||(e[39]=w(" 这里只决定「这个渠道开放哪几种支付入口」;商户号、密钥等凭据在 ",-1)),u.value?(i(),o("a",{key:0,class:"link",onClick:be(Y,["prevent"])},"应用「"+r(u.value)+"」→ 业务功能配置 → 支付",1)):(i(),o("span",As,"各应用的「业务功能配置 → 支付」")),e[40]||(e[40]=w(" 里填。 ",-1))])]),s("div",Us,[s("label",Ss,[d(s("input",{"onUpdate:modelValue":e[12]||(e[12]=t=>n.enable=t),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[N,n.enable]]),e[42]||(e[42]=s("span",null,"启用",-1)),e[43]||(e[43]=s("span",{class:"text-xs text-slate-400"},"停用后该渠道配置不下发客户端",-1))]),s("div",Ps,[k.value?(i(),o("button",{key:0,class:"btn btn-ghost btn-sm text-error mr-auto",onClick:ue},"删除")):c("",!0),s("button",{class:"btn btn-ghost btn-sm",onClick:S},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",disabled:I.value,onClick:de},"保存",8,Ns)])])])],512),[[me,A.value]])]))}}),Is=xe(Os,[["__scopeId","data-v-66a7d845"]]);export{Is as default}; diff --git a/apps/admin/.output/public/_nuxt/Bj3tUDmW.js b/apps/admin/.output/public/_nuxt/BFjsaYIf.js similarity index 98% rename from apps/admin/.output/public/_nuxt/Bj3tUDmW.js rename to apps/admin/.output/public/_nuxt/BFjsaYIf.js index edb34579..11766a43 100644 --- a/apps/admin/.output/public/_nuxt/Bj3tUDmW.js +++ b/apps/admin/.output/public/_nuxt/BFjsaYIf.js @@ -1 +1 @@ -import{_ as Y}from"./DiAHNWP8.js";import{g as Z,j as G,C as J,c as a,q as d,H as L,a as t,m as y,l as r,F as g,r as T,s as B,O as W,v as x,d as M,t as c,p as tt,x as et,b as st,A as lt,y as v,z as P,o,n as nt}from"./DMxDLVSv.js";import{u as at}from"./CCZrj3X-.js";import{u as ot}from"./B-sqZCu-.js";const rt={class:"flex items-center justify-between mb-5"},it={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4 mb-4"},dt={class:"flex flex-wrap items-end gap-3"},ut={key:0,class:"form-control"},ct=["value"],mt={class:"form-control"},bt={class:"form-control"},pt={class:"bg-white rounded-xl shadow-sm border border-slate-100"},xt={class:"overflow-x-auto"},ft={class:"table table-zebra"},vt={key:0},kt={key:1},yt={class:"font-mono text-sm font-semibold"},gt={class:"font-medium"},wt={key:0,class:"badge badge-sm badge-primary badge-outline ml-1"},_t={class:"badge badge-ghost badge-sm"},Ct={class:"text-sm"},At={class:"text-sm text-slate-500"},Ut={key:0},$t={key:1,class:"text-xs text-slate-400"},Vt={key:2,class:"text-slate-300"},ht={key:0,class:"text-xs text-slate-400 mt-1"},St={class:"text-sm text-slate-500"},Nt={class:"flex flex-wrap gap-1"},Dt=["onClick"],Tt=["onClick"],Bt=["onClick"],Mt=["onClick"],Ft=["onClick"],Lt={class:"text-xs text-slate-400 mt-3"},Pt={class:"flex items-center gap-3 mb-5"},Rt={class:"text-lg font-semibold text-slate-800"},Et={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},qt={key:0,class:"form-control mb-4"},zt=["value"],It={class:"form-control mb-4"},Kt={key:1,class:"form-control mb-4"},jt=["disabled"],Ht=["value"],Ot={key:0,class:"label-text-alt text-slate-400 mt-1"},Qt={class:"form-control mb-4"},Xt=["disabled"],Yt={class:"form-control mb-4"},Zt={class:"form-control mb-4"},Gt={class:"form-control mb-6"},Jt={key:2,class:"form-control mb-6 border-t border-slate-100 pt-4"},Wt={class:"flex items-center gap-2 cursor-pointer"},te={key:0,class:"grid grid-cols-2 gap-3 mt-3"},ee={class:"col-span-2"},se={key:0,class:"col-span-2 text-xs text-amber-600"},le={class:"flex gap-3"},ne=["disabled"],ae={key:3,class:"text-xs text-amber-600 mt-3"},ce=Z({__name:"dealers",setup(oe){const{webApi:w}=at(),{success:A,error:_}=ot(),f=G(),C=lt(()=>f.isAdmin),V=v(null),U=v("list"),$=v([]),k=v([]),h=v(!1),S=v(!1),m=v(!1),u=P({brandid:0,status:-1,keyword:""}),l=P({id:"",name:"",brandid:0,sharepct:0,contact:"",contactmails:"",remark:"",createAccount:!1,accountUsername:"",accountPassword:"",accountRemark:""}),R={0:"待审核",1:"启用",2:"停用",3:"驳回"},E={0:"badge-warning",1:"badge-success",2:"badge-ghost",3:"badge-error"};function q(n){return R[n]??String(n)}function z(n){return E[n]??"badge-ghost"}function I(n){return((Number(n)||0)/100).toFixed(2)+"%"}function K(n){const e=k.value.find(i=>i.id===n);return e?e.brand:n?"品牌商#"+Number(n).toString(16).toUpperCase():"-"}function j(n){if(!n)return"-";const e=new Date(n*1e3),i=s=>("0"+s).slice(-2);return`${e.getFullYear()}-${i(e.getMonth()+1)}-${i(e.getDate())} ${i(e.getHours())}:${i(e.getMinutes())}`}async function H(){try{const n=await w("getbrands",{});k.value=n?.brands??[]}catch{k.value=[]}}async function b(){h.value=!0;try{k.value.length||await H();const n=await w("getchannels",{brandid:Number(u.brandid)||0,status:Number(u.status),keyword:u.keyword.trim()});$.value=n?.channels??[]}catch(n){_(n?.message??"获取渠道商列表失败"),$.value=[]}finally{h.value=!1}}function O(){u.brandid=0,u.status=-1,u.keyword="",b()}function N(){U.value="list",b()}function F(n){n?(m.value=!0,l.id=n.id,l.name=n.name||"",l.brandid=n.brandid||0,l.sharepct=(Number(n.sharerate)||0)/100,l.contact=n.contact||"",l.contactmails=n.contactmails||"",l.remark=n.remark||""):(m.value=!1,l.id="",l.name="",l.brandid=Number(u.brandid)||0,l.sharepct=0,l.contact="",l.contactmails="",l.remark=""),l.createAccount=!1,l.accountUsername="",l.accountPassword="",l.accountRemark="",U.value="form"}async function Q(){if(!l.brandid&&!f.isBrandAccount){_("请选择所属品牌商");return}S.value=!0;try{const n={name:l.name.trim(),brandid:Number(l.brandid)||0,sharerate:Math.round((Number(l.sharepct)||0)*100),contact:l.contact,contactmails:l.contactmails,remark:l.remark};m.value&&(n.id=l.id);const e={channel:n};!m.value&&l.createAccount&&(e.create_account=!0,e.account_username=l.accountUsername.trim(),e.account_password=l.accountPassword,e.account_remark=l.accountRemark.trim());const i=await w(m.value?"updatechannel":"addchannel",e);m.value?A("保存成功"):(A(C.value?"新增成功":"已提交,等待审核"),i?.account&&(V.value={title:`渠道账号「${i.account}」已创建`,username:i.account,password:i.account_password??"",mailTo:i.mail_to??"",mailError:i.mail_error??""})),N()}catch(n){_(n?.message??"保存失败")}finally{S.value=!1}}async function D(n,e){const i={1:n.status===0?"通过":"启用",2:"停用",3:"驳回"};let s="";if(e===3){const p=window.prompt(`驳回渠道商 "${n.name}" 的原因:`,"");if(p===null)return;s=p}else if(!window.confirm(`确定${i[e]}渠道商 "${n.name}" 吗?`))return;try{await w("auditchannel",{id:n.id,status:e,auditremark:s}),A(i[e]+"成功"),b()}catch(p){_(p?.message??"操作失败")}}function X(n){window.confirm(`确定删除渠道商 "${n.name}" 吗?已有生产批次的渠道商不能删除。`)&&w("delchannel",{id:n.id}).then(()=>{A("删除成功"),b()}).catch(e=>_(e?.message??"删除失败"))}return J(b),(n,e)=>{const i=Y;return o(),a("div",null,[d(t("div",null,[t("div",rt,[e[17]||(e[17]=t("h2",{class:"text-lg font-semibold text-slate-800"},"渠道商列表",-1)),y(f).isDealer?r("",!0):(o(),a("button",{key:0,class:"btn btn-primary btn-sm text-white",onClick:e[0]||(e[0]=s=>F())},"+ 新增渠道商"))]),t("div",it,[t("div",dt,[!y(f).isBrandAccount&&!y(f).isDealer?(o(),a("div",ut,[e[19]||(e[19]=t("label",{class:"label py-1"},[t("span",{class:"label-text text-xs text-slate-500"},"品牌商")],-1)),d(t("select",{"onUpdate:modelValue":e[1]||(e[1]=s=>u.brandid=s),class:"select select-bordered select-sm w-48",onChange:b},[e[18]||(e[18]=t("option",{value:0},"全部品牌商",-1)),(o(!0),a(g,null,T(k.value,s=>(o(),a("option",{key:s.id,value:s.id},c(s.brand),9,ct))),128))],544),[[B,u.brandid,void 0,{number:!0}]])])):r("",!0),t("div",mt,[e[21]||(e[21]=t("label",{class:"label py-1"},[t("span",{class:"label-text text-xs text-slate-500"},"状态")],-1)),d(t("select",{"onUpdate:modelValue":e[2]||(e[2]=s=>u.status=s),class:"select select-bordered select-sm w-36",onChange:b},[...e[20]||(e[20]=[t("option",{value:-1},"全部状态",-1),t("option",{value:0},"待审核",-1),t("option",{value:1},"启用",-1),t("option",{value:2},"停用",-1),t("option",{value:3},"驳回",-1)])],544),[[B,u.status,void 0,{number:!0}]])]),t("div",bt,[e[22]||(e[22]=t("label",{class:"label py-1"},[t("span",{class:"label-text text-xs text-slate-500"},"搜索")],-1)),d(t("input",{"onUpdate:modelValue":e[3]||(e[3]=s=>u.keyword=s),type:"text",class:"input input-bordered input-sm w-52",placeholder:"名称 / 渠道商ID",onKeydown:W(b,["enter"])},null,544),[[x,u.keyword]])]),t("button",{class:"btn btn-sm btn-primary text-white",onClick:b},"查询"),t("button",{class:"btn btn-sm btn-ghost",onClick:O},"重置")])]),t("div",pt,[t("div",xt,[t("table",ft,[e[25]||(e[25]=t("thead",null,[t("tr",null,[t("th",null,"渠道商ID"),t("th",null,"名称"),t("th",null,"所属品牌商"),t("th",null,"分成比例"),t("th",null,"联系方式"),t("th",null,"状态"),t("th",null,"创建时间"),t("th",null,"操作")])],-1)),t("tbody",null,[h.value?(o(),a("tr",vt,[...e[23]||(e[23]=[t("td",{colspan:"8",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):$.value.length?r("",!0):(o(),a("tr",kt,[...e[24]||(e[24]=[t("td",{colspan:"8",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(o(!0),a(g,null,T($.value,s=>(o(),a("tr",{key:s.id},[t("td",yt,c(s.id),1),t("td",gt,[M(c(s.name)+" ",1),s.official?(o(),a("span",wt,"官方")):r("",!0)]),t("td",null,[t("span",_t,c(K(s.brandid)),1)]),t("td",Ct,c(I(s.sharerate)),1),t("td",At,[s.contact?(o(),a("div",Ut,c(s.contact),1)):r("",!0),s.contactmails?(o(),a("div",$t,c(s.contactmails),1)):r("",!0),!s.contact&&!s.contactmails?(o(),a("span",Vt,"-")):r("",!0)]),t("td",null,[t("span",{class:nt(["badge badge-sm",z(s.status)])},c(q(s.status)),3),s.status===3&&s.auditremark?(o(),a("div",ht,c(s.auditremark),1)):r("",!0)]),t("td",St,c(j(s.createtime)),1),t("td",null,[t("div",Nt,[t("button",{class:"btn btn-ghost btn-xs",onClick:p=>F(s)},"编辑",8,Dt),C.value?(o(),a(g,{key:0},[s.status!==1?(o(),a("button",{key:0,class:"btn btn-ghost btn-xs text-emerald-600",onClick:p=>D(s,1)},c(s.status===0?"通过":"启用"),9,Tt)):r("",!0),s.status===1?(o(),a("button",{key:1,class:"btn btn-ghost btn-xs text-amber-600",onClick:p=>D(s,2)},"停用",8,Bt)):r("",!0),s.status===0?(o(),a("button",{key:2,class:"btn btn-ghost btn-xs text-red-500",onClick:p=>D(s,3)},"驳回",8,Mt)):r("",!0)],64)):r("",!0),!y(f).isDealer&&!s.official?(o(),a("button",{key:1,class:"btn btn-ghost btn-xs text-red-500",onClick:p=>X(s)},"删除",8,Ft)):r("",!0)])])]))),128))])])])]),t("p",Lt,[y(f).isBrandAccount?(o(),a(g,{key:0},[M(" 这里只显示贵品牌商名下的渠道商。新增后为「待审核」,需平台审核通过(状态=启用)才能用于生产授权码;分成比例由平台设置。 ")],64)):(o(),a(g,{key:1},[M(" 渠道商新增后需超管/管理员审核通过(状态=启用)才能用于生产授权码;已有生产批次的渠道商不能删除,只能停用。 标「官方」的是品牌自营渠道,随品牌商自动创建、直接启用、不可删除。 ")],64))])],512),[[L,U.value==="list"]]),d(t("div",null,[t("div",Pt,[t("button",{class:"btn btn-ghost btn-sm",onClick:e[4]||(e[4]=s=>N())},"← 返回列表"),t("h2",Rt,c(m.value?"编辑渠道商":"新增渠道商"),1)]),t("div",Et,[t("form",{onSubmit:tt(Q,["prevent"])},[m.value?(o(),a("div",qt,[e[26]||(e[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"渠道商ID")],-1)),t("input",{value:l.id,type:"text",class:"input input-bordered w-full font-mono",disabled:""},null,8,zt),e[27]||(e[27]=t("span",{class:"label-text-alt text-slate-400 mt-1"},"短码由系统生成,创建后不可修改",-1))])):r("",!0),t("div",It,[e[28]||(e[28]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"渠道商名称 *")],-1)),d(t("input",{"onUpdate:modelValue":e[5]||(e[5]=s=>l.name=s),type:"text",class:"input input-bordered w-full",required:""},null,512),[[x,l.name]])]),y(f).isBrandAccount?r("",!0):(o(),a("div",Kt,[e[30]||(e[30]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"所属品牌商 *")],-1)),d(t("select",{"onUpdate:modelValue":e[6]||(e[6]=s=>l.brandid=s),class:"select select-bordered w-full",disabled:m.value,required:""},[e[29]||(e[29]=t("option",{value:0},"请选择品牌商",-1)),(o(!0),a(g,null,T(k.value,s=>(o(),a("option",{key:s.id,value:s.id},c(s.brand),9,Ht))),128))],8,jt),[[B,l.brandid,void 0,{number:!0}]]),m.value?(o(),a("span",Ot,"归属品牌商创建后不可修改")):r("",!0)])),t("div",Qt,[e[31]||(e[31]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"分成比例(%)")],-1)),d(t("input",{"onUpdate:modelValue":e[7]||(e[7]=s=>l.sharepct=s),type:"number",step:"0.01",min:"0",max:"100",class:"input input-bordered w-full",disabled:!C.value},null,8,Xt),[[x,l.sharepct,void 0,{number:!0}]]),e[32]||(e[32]=t("span",{class:"label-text-alt text-slate-400 mt-1"}," 从所属品牌商的分成里再切;仅超管/管理员可设置。 ",-1))]),t("div",Yt,[e[33]||(e[33]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系人 / 电话")],-1)),d(t("input",{"onUpdate:modelValue":e[8]||(e[8]=s=>l.contact=s),type:"text",class:"input input-bordered w-full"},null,512),[[x,l.contact]])]),t("div",Zt,[e[34]||(e[34]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系邮箱")],-1)),d(t("input",{"onUpdate:modelValue":e[9]||(e[9]=s=>l.contactmails=s),type:"text",class:"input input-bordered w-full",placeholder:"多个邮箱用逗号分隔"},null,512),[[x,l.contactmails]])]),t("div",Gt,[e[35]||(e[35]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"备注")],-1)),d(t("textarea",{"onUpdate:modelValue":e[10]||(e[10]=s=>l.remark=s),class:"textarea textarea-bordered w-full",rows:"3"},null,512),[[x,l.remark]])]),!m.value&&C.value?(o(),a("div",Jt,[t("label",Wt,[d(t("input",{"onUpdate:modelValue":e[11]||(e[11]=s=>l.createAccount=s),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[et,l.createAccount]]),e[36]||(e[36]=t("span",{class:"label-text font-medium"},"同时创建渠道账号",-1))]),e[40]||(e[40]=t("span",{class:"label-text-alt text-slate-400 mt-1"}," 建一个绑定本渠道商的「渠道商」角色登录账号,只能看到自己渠道的数据与结算单。 用户名/密码留空则自动生成,创建后凭据会邮件发给上面填的联系邮箱。 ",-1)),l.createAccount?(o(),a("div",te,[t("div",null,[e[37]||(e[37]=t("label",{class:"text-xs text-slate-500"},"登录用户名",-1)),d(t("input",{"onUpdate:modelValue":e[12]||(e[12]=s=>l.accountUsername=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"留空自动生成,如 Channel-K7QM3ZTX",autocomplete:"off"},null,512),[[x,l.accountUsername]])]),t("div",null,[e[38]||(e[38]=t("label",{class:"text-xs text-slate-500"},"登录密码",-1)),d(t("input",{"onUpdate:modelValue":e[13]||(e[13]=s=>l.accountPassword=s),type:"text",class:"input input-bordered input-sm w-full font-mono",placeholder:"留空自动生成 12 位随机密码",autocomplete:"off"},null,512),[[x,l.accountPassword]])]),t("div",ee,[e[39]||(e[39]=t("label",{class:"text-xs text-slate-500"},"备注",-1)),d(t("input",{"onUpdate:modelValue":e[14]||(e[14]=s=>l.accountRemark=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[x,l.accountRemark]])]),l.contactmails.trim()?r("",!0):(o(),a("p",se," 没填联系邮箱,凭据将无法邮件送达,只会在创建后弹窗显示一次。 "))])):r("",!0)])):r("",!0),t("div",le,[t("button",{type:"button",class:"btn btn-ghost",onClick:e[15]||(e[15]=s=>N())},"取消"),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:S.value},"保存",8,ne)]),!m.value&&!C.value?(o(),a("p",ae," 提交后为「待审核」状态,须超管/管理员通过后才能用于生产。 ")):r("",!0)],32)])],512),[[L,U.value==="form"]]),st(i,{info:V.value,onClose:e[16]||(e[16]=s=>V.value=null)},null,8,["info"])])}}});export{ce as default}; +import{_ as Y}from"./DVest5s8.js";import{g as Z,j as G,C as J,c as a,q as d,H as L,a as t,m as y,l as r,F as g,r as T,s as B,O as W,v as x,d as M,t as c,p as tt,x as et,b as st,A as lt,y as v,z as P,o,n as nt}from"./DSy_gLdM.js";import{u as at}from"./NtXZuCUg.js";import{u as ot}from"./EeX3zgoF.js";const rt={class:"flex items-center justify-between mb-5"},it={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4 mb-4"},dt={class:"flex flex-wrap items-end gap-3"},ut={key:0,class:"form-control"},ct=["value"],mt={class:"form-control"},bt={class:"form-control"},pt={class:"bg-white rounded-xl shadow-sm border border-slate-100"},xt={class:"overflow-x-auto"},ft={class:"table table-zebra"},vt={key:0},kt={key:1},yt={class:"font-mono text-sm font-semibold"},gt={class:"font-medium"},wt={key:0,class:"badge badge-sm badge-primary badge-outline ml-1"},_t={class:"badge badge-ghost badge-sm"},Ct={class:"text-sm"},At={class:"text-sm text-slate-500"},Ut={key:0},$t={key:1,class:"text-xs text-slate-400"},Vt={key:2,class:"text-slate-300"},ht={key:0,class:"text-xs text-slate-400 mt-1"},St={class:"text-sm text-slate-500"},Nt={class:"flex flex-wrap gap-1"},Dt=["onClick"],Tt=["onClick"],Bt=["onClick"],Mt=["onClick"],Ft=["onClick"],Lt={class:"text-xs text-slate-400 mt-3"},Pt={class:"flex items-center gap-3 mb-5"},Rt={class:"text-lg font-semibold text-slate-800"},Et={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},qt={key:0,class:"form-control mb-4"},zt=["value"],It={class:"form-control mb-4"},Kt={key:1,class:"form-control mb-4"},jt=["disabled"],Ht=["value"],Ot={key:0,class:"label-text-alt text-slate-400 mt-1"},Qt={class:"form-control mb-4"},Xt=["disabled"],Yt={class:"form-control mb-4"},Zt={class:"form-control mb-4"},Gt={class:"form-control mb-6"},Jt={key:2,class:"form-control mb-6 border-t border-slate-100 pt-4"},Wt={class:"flex items-center gap-2 cursor-pointer"},te={key:0,class:"grid grid-cols-2 gap-3 mt-3"},ee={class:"col-span-2"},se={key:0,class:"col-span-2 text-xs text-amber-600"},le={class:"flex gap-3"},ne=["disabled"],ae={key:3,class:"text-xs text-amber-600 mt-3"},ce=Z({__name:"dealers",setup(oe){const{webApi:w}=at(),{success:A,error:_}=ot(),f=G(),C=lt(()=>f.isAdmin),V=v(null),U=v("list"),$=v([]),k=v([]),h=v(!1),S=v(!1),m=v(!1),u=P({brandid:0,status:-1,keyword:""}),l=P({id:"",name:"",brandid:0,sharepct:0,contact:"",contactmails:"",remark:"",createAccount:!1,accountUsername:"",accountPassword:"",accountRemark:""}),R={0:"待审核",1:"启用",2:"停用",3:"驳回"},E={0:"badge-warning",1:"badge-success",2:"badge-ghost",3:"badge-error"};function q(n){return R[n]??String(n)}function z(n){return E[n]??"badge-ghost"}function I(n){return((Number(n)||0)/100).toFixed(2)+"%"}function K(n){const e=k.value.find(i=>i.id===n);return e?e.brand:n?"品牌商#"+Number(n).toString(16).toUpperCase():"-"}function j(n){if(!n)return"-";const e=new Date(n*1e3),i=s=>("0"+s).slice(-2);return`${e.getFullYear()}-${i(e.getMonth()+1)}-${i(e.getDate())} ${i(e.getHours())}:${i(e.getMinutes())}`}async function H(){try{const n=await w("getbrands",{});k.value=n?.brands??[]}catch{k.value=[]}}async function b(){h.value=!0;try{k.value.length||await H();const n=await w("getchannels",{brandid:Number(u.brandid)||0,status:Number(u.status),keyword:u.keyword.trim()});$.value=n?.channels??[]}catch(n){_(n?.message??"获取渠道商列表失败"),$.value=[]}finally{h.value=!1}}function O(){u.brandid=0,u.status=-1,u.keyword="",b()}function N(){U.value="list",b()}function F(n){n?(m.value=!0,l.id=n.id,l.name=n.name||"",l.brandid=n.brandid||0,l.sharepct=(Number(n.sharerate)||0)/100,l.contact=n.contact||"",l.contactmails=n.contactmails||"",l.remark=n.remark||""):(m.value=!1,l.id="",l.name="",l.brandid=Number(u.brandid)||0,l.sharepct=0,l.contact="",l.contactmails="",l.remark=""),l.createAccount=!1,l.accountUsername="",l.accountPassword="",l.accountRemark="",U.value="form"}async function Q(){if(!l.brandid&&!f.isBrandAccount){_("请选择所属品牌商");return}S.value=!0;try{const n={name:l.name.trim(),brandid:Number(l.brandid)||0,sharerate:Math.round((Number(l.sharepct)||0)*100),contact:l.contact,contactmails:l.contactmails,remark:l.remark};m.value&&(n.id=l.id);const e={channel:n};!m.value&&l.createAccount&&(e.create_account=!0,e.account_username=l.accountUsername.trim(),e.account_password=l.accountPassword,e.account_remark=l.accountRemark.trim());const i=await w(m.value?"updatechannel":"addchannel",e);m.value?A("保存成功"):(A(C.value?"新增成功":"已提交,等待审核"),i?.account&&(V.value={title:`渠道账号「${i.account}」已创建`,username:i.account,password:i.account_password??"",mailTo:i.mail_to??"",mailError:i.mail_error??""})),N()}catch(n){_(n?.message??"保存失败")}finally{S.value=!1}}async function D(n,e){const i={1:n.status===0?"通过":"启用",2:"停用",3:"驳回"};let s="";if(e===3){const p=window.prompt(`驳回渠道商 "${n.name}" 的原因:`,"");if(p===null)return;s=p}else if(!window.confirm(`确定${i[e]}渠道商 "${n.name}" 吗?`))return;try{await w("auditchannel",{id:n.id,status:e,auditremark:s}),A(i[e]+"成功"),b()}catch(p){_(p?.message??"操作失败")}}function X(n){window.confirm(`确定删除渠道商 "${n.name}" 吗?已有生产批次的渠道商不能删除。`)&&w("delchannel",{id:n.id}).then(()=>{A("删除成功"),b()}).catch(e=>_(e?.message??"删除失败"))}return J(b),(n,e)=>{const i=Y;return o(),a("div",null,[d(t("div",null,[t("div",rt,[e[17]||(e[17]=t("h2",{class:"text-lg font-semibold text-slate-800"},"渠道商列表",-1)),y(f).isDealer?r("",!0):(o(),a("button",{key:0,class:"btn btn-primary btn-sm text-white",onClick:e[0]||(e[0]=s=>F())},"+ 新增渠道商"))]),t("div",it,[t("div",dt,[!y(f).isBrandAccount&&!y(f).isDealer?(o(),a("div",ut,[e[19]||(e[19]=t("label",{class:"label py-1"},[t("span",{class:"label-text text-xs text-slate-500"},"品牌商")],-1)),d(t("select",{"onUpdate:modelValue":e[1]||(e[1]=s=>u.brandid=s),class:"select select-bordered select-sm w-48",onChange:b},[e[18]||(e[18]=t("option",{value:0},"全部品牌商",-1)),(o(!0),a(g,null,T(k.value,s=>(o(),a("option",{key:s.id,value:s.id},c(s.brand),9,ct))),128))],544),[[B,u.brandid,void 0,{number:!0}]])])):r("",!0),t("div",mt,[e[21]||(e[21]=t("label",{class:"label py-1"},[t("span",{class:"label-text text-xs text-slate-500"},"状态")],-1)),d(t("select",{"onUpdate:modelValue":e[2]||(e[2]=s=>u.status=s),class:"select select-bordered select-sm w-36",onChange:b},[...e[20]||(e[20]=[t("option",{value:-1},"全部状态",-1),t("option",{value:0},"待审核",-1),t("option",{value:1},"启用",-1),t("option",{value:2},"停用",-1),t("option",{value:3},"驳回",-1)])],544),[[B,u.status,void 0,{number:!0}]])]),t("div",bt,[e[22]||(e[22]=t("label",{class:"label py-1"},[t("span",{class:"label-text text-xs text-slate-500"},"搜索")],-1)),d(t("input",{"onUpdate:modelValue":e[3]||(e[3]=s=>u.keyword=s),type:"text",class:"input input-bordered input-sm w-52",placeholder:"名称 / 渠道商ID",onKeydown:W(b,["enter"])},null,544),[[x,u.keyword]])]),t("button",{class:"btn btn-sm btn-primary text-white",onClick:b},"查询"),t("button",{class:"btn btn-sm btn-ghost",onClick:O},"重置")])]),t("div",pt,[t("div",xt,[t("table",ft,[e[25]||(e[25]=t("thead",null,[t("tr",null,[t("th",null,"渠道商ID"),t("th",null,"名称"),t("th",null,"所属品牌商"),t("th",null,"分成比例"),t("th",null,"联系方式"),t("th",null,"状态"),t("th",null,"创建时间"),t("th",null,"操作")])],-1)),t("tbody",null,[h.value?(o(),a("tr",vt,[...e[23]||(e[23]=[t("td",{colspan:"8",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):$.value.length?r("",!0):(o(),a("tr",kt,[...e[24]||(e[24]=[t("td",{colspan:"8",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(o(!0),a(g,null,T($.value,s=>(o(),a("tr",{key:s.id},[t("td",yt,c(s.id),1),t("td",gt,[M(c(s.name)+" ",1),s.official?(o(),a("span",wt,"官方")):r("",!0)]),t("td",null,[t("span",_t,c(K(s.brandid)),1)]),t("td",Ct,c(I(s.sharerate)),1),t("td",At,[s.contact?(o(),a("div",Ut,c(s.contact),1)):r("",!0),s.contactmails?(o(),a("div",$t,c(s.contactmails),1)):r("",!0),!s.contact&&!s.contactmails?(o(),a("span",Vt,"-")):r("",!0)]),t("td",null,[t("span",{class:nt(["badge badge-sm",z(s.status)])},c(q(s.status)),3),s.status===3&&s.auditremark?(o(),a("div",ht,c(s.auditremark),1)):r("",!0)]),t("td",St,c(j(s.createtime)),1),t("td",null,[t("div",Nt,[t("button",{class:"btn btn-ghost btn-xs",onClick:p=>F(s)},"编辑",8,Dt),C.value?(o(),a(g,{key:0},[s.status!==1?(o(),a("button",{key:0,class:"btn btn-ghost btn-xs text-emerald-600",onClick:p=>D(s,1)},c(s.status===0?"通过":"启用"),9,Tt)):r("",!0),s.status===1?(o(),a("button",{key:1,class:"btn btn-ghost btn-xs text-amber-600",onClick:p=>D(s,2)},"停用",8,Bt)):r("",!0),s.status===0?(o(),a("button",{key:2,class:"btn btn-ghost btn-xs text-red-500",onClick:p=>D(s,3)},"驳回",8,Mt)):r("",!0)],64)):r("",!0),!y(f).isDealer&&!s.official?(o(),a("button",{key:1,class:"btn btn-ghost btn-xs text-red-500",onClick:p=>X(s)},"删除",8,Ft)):r("",!0)])])]))),128))])])])]),t("p",Lt,[y(f).isBrandAccount?(o(),a(g,{key:0},[M(" 这里只显示贵品牌商名下的渠道商。新增后为「待审核」,需平台审核通过(状态=启用)才能用于生产授权码;分成比例由平台设置。 ")],64)):(o(),a(g,{key:1},[M(" 渠道商新增后需超管/管理员审核通过(状态=启用)才能用于生产授权码;已有生产批次的渠道商不能删除,只能停用。 标「官方」的是品牌自营渠道,随品牌商自动创建、直接启用、不可删除。 ")],64))])],512),[[L,U.value==="list"]]),d(t("div",null,[t("div",Pt,[t("button",{class:"btn btn-ghost btn-sm",onClick:e[4]||(e[4]=s=>N())},"← 返回列表"),t("h2",Rt,c(m.value?"编辑渠道商":"新增渠道商"),1)]),t("div",Et,[t("form",{onSubmit:tt(Q,["prevent"])},[m.value?(o(),a("div",qt,[e[26]||(e[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"渠道商ID")],-1)),t("input",{value:l.id,type:"text",class:"input input-bordered w-full font-mono",disabled:""},null,8,zt),e[27]||(e[27]=t("span",{class:"label-text-alt text-slate-400 mt-1"},"短码由系统生成,创建后不可修改",-1))])):r("",!0),t("div",It,[e[28]||(e[28]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"渠道商名称 *")],-1)),d(t("input",{"onUpdate:modelValue":e[5]||(e[5]=s=>l.name=s),type:"text",class:"input input-bordered w-full",required:""},null,512),[[x,l.name]])]),y(f).isBrandAccount?r("",!0):(o(),a("div",Kt,[e[30]||(e[30]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"所属品牌商 *")],-1)),d(t("select",{"onUpdate:modelValue":e[6]||(e[6]=s=>l.brandid=s),class:"select select-bordered w-full",disabled:m.value,required:""},[e[29]||(e[29]=t("option",{value:0},"请选择品牌商",-1)),(o(!0),a(g,null,T(k.value,s=>(o(),a("option",{key:s.id,value:s.id},c(s.brand),9,Ht))),128))],8,jt),[[B,l.brandid,void 0,{number:!0}]]),m.value?(o(),a("span",Ot,"归属品牌商创建后不可修改")):r("",!0)])),t("div",Qt,[e[31]||(e[31]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"分成比例(%)")],-1)),d(t("input",{"onUpdate:modelValue":e[7]||(e[7]=s=>l.sharepct=s),type:"number",step:"0.01",min:"0",max:"100",class:"input input-bordered w-full",disabled:!C.value},null,8,Xt),[[x,l.sharepct,void 0,{number:!0}]]),e[32]||(e[32]=t("span",{class:"label-text-alt text-slate-400 mt-1"}," 从所属品牌商的分成里再切;仅超管/管理员可设置。 ",-1))]),t("div",Yt,[e[33]||(e[33]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系人 / 电话")],-1)),d(t("input",{"onUpdate:modelValue":e[8]||(e[8]=s=>l.contact=s),type:"text",class:"input input-bordered w-full"},null,512),[[x,l.contact]])]),t("div",Zt,[e[34]||(e[34]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系邮箱")],-1)),d(t("input",{"onUpdate:modelValue":e[9]||(e[9]=s=>l.contactmails=s),type:"text",class:"input input-bordered w-full",placeholder:"多个邮箱用逗号分隔"},null,512),[[x,l.contactmails]])]),t("div",Gt,[e[35]||(e[35]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"备注")],-1)),d(t("textarea",{"onUpdate:modelValue":e[10]||(e[10]=s=>l.remark=s),class:"textarea textarea-bordered w-full",rows:"3"},null,512),[[x,l.remark]])]),!m.value&&C.value?(o(),a("div",Jt,[t("label",Wt,[d(t("input",{"onUpdate:modelValue":e[11]||(e[11]=s=>l.createAccount=s),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[et,l.createAccount]]),e[36]||(e[36]=t("span",{class:"label-text font-medium"},"同时创建渠道账号",-1))]),e[40]||(e[40]=t("span",{class:"label-text-alt text-slate-400 mt-1"}," 建一个绑定本渠道商的「渠道商」角色登录账号,只能看到自己渠道的数据与结算单。 用户名/密码留空则自动生成,创建后凭据会邮件发给上面填的联系邮箱。 ",-1)),l.createAccount?(o(),a("div",te,[t("div",null,[e[37]||(e[37]=t("label",{class:"text-xs text-slate-500"},"登录用户名",-1)),d(t("input",{"onUpdate:modelValue":e[12]||(e[12]=s=>l.accountUsername=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"留空自动生成,如 Channel-K7QM3ZTX",autocomplete:"off"},null,512),[[x,l.accountUsername]])]),t("div",null,[e[38]||(e[38]=t("label",{class:"text-xs text-slate-500"},"登录密码",-1)),d(t("input",{"onUpdate:modelValue":e[13]||(e[13]=s=>l.accountPassword=s),type:"text",class:"input input-bordered input-sm w-full font-mono",placeholder:"留空自动生成 12 位随机密码",autocomplete:"off"},null,512),[[x,l.accountPassword]])]),t("div",ee,[e[39]||(e[39]=t("label",{class:"text-xs text-slate-500"},"备注",-1)),d(t("input",{"onUpdate:modelValue":e[14]||(e[14]=s=>l.accountRemark=s),type:"text",class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[x,l.accountRemark]])]),l.contactmails.trim()?r("",!0):(o(),a("p",se," 没填联系邮箱,凭据将无法邮件送达,只会在创建后弹窗显示一次。 "))])):r("",!0)])):r("",!0),t("div",le,[t("button",{type:"button",class:"btn btn-ghost",onClick:e[15]||(e[15]=s=>N())},"取消"),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:S.value},"保存",8,ne)]),!m.value&&!C.value?(o(),a("p",ae," 提交后为「待审核」状态,须超管/管理员通过后才能用于生产。 ")):r("",!0)],32)])],512),[[L,U.value==="form"]]),st(i,{info:V.value,onClose:e[16]||(e[16]=s=>V.value=null)},null,8,["info"])])}}});export{ce as default}; diff --git a/apps/admin/.output/public/_nuxt/DOqVQ2Td.js b/apps/admin/.output/public/_nuxt/BKXYxnNU.js similarity index 95% rename from apps/admin/.output/public/_nuxt/DOqVQ2Td.js rename to apps/admin/.output/public/_nuxt/BKXYxnNU.js index 47ede3f9..4b96dc40 100644 --- a/apps/admin/.output/public/_nuxt/DOqVQ2Td.js +++ b/apps/admin/.output/public/_nuxt/BKXYxnNU.js @@ -1 +1 @@ -import{g as h,j as x,k as w,C as y,c as r,a as e,t as d,l as b,p as _,q as v,v as f,n as k,z as M,y as u,o as p,_ as z}from"./DMxDLVSv.js";const A={class:"login-bg flex items-center justify-center px-4"},B={class:"login-card"},C={class:"text-center"},S={style:{"font-size":"22px","font-weight":"700",color:"#0F172A",margin:"0 0 4px"}},T={key:0,class:"login-error show"},V={style:{width:"16px",height:"16px","flex-shrink":"0"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},j={style:{"margin-bottom":"16px"}},q={style:{"margin-bottom":"24px"}},D=h({__name:"index",setup(L){const a=x(),c=w(),o=M({account:"",password:""}),l=u(!1),n=u(""),m=u("Admin");y(async()=>{if(a.restore(),a.token){c.push("/dashboard");return}try{const t=(await $fetch("/web/api/api_getsiteinfo",{method:"POST",body:{}}))?.data?.sitename;t&&(m.value=t+" Admin",a.setSiteTitle(t))}catch{}});async function g(){l.value=!0,n.value="";try{const s=await $fetch("/web/api/api_login",{method:"POST",body:{account:o.account,password:o.password}});s.code===0&&s.data?(a.setLoginData(s.data),c.push("/dashboard")):n.value=s.msg||"登录失败"}catch{n.value="网络错误,请检查连接"}finally{l.value=!1}}return(s,t)=>(p(),r("div",A,[e("div",B,[e("div",C,[t[2]||(t[2]=e("div",{class:"logo-icon"},[e("svg",{class:"h-7 w-7 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})])],-1)),e("h1",S,d(m.value),1),t[3]||(t[3]=e("p",{style:{"font-size":"13px",color:"#94A3B8",margin:"0 0 32px"}},"管理控制台",-1))]),n.value?(p(),r("div",T,[(p(),r("svg",V,[...t[4]||(t[4]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"},null,-1)])])),e("span",null,d(n.value),1)])):b("",!0),e("form",{onSubmit:_(g,["prevent"])},[e("div",j,[t[5]||(t[5]=e("label",{class:"login-label"},"账号",-1)),v(e("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>o.account=i),type:"text",class:"login-input",placeholder:"请输入管理员账号",autocomplete:"username",required:""},null,512),[[f,o.account]])]),e("div",q,[t[6]||(t[6]=e("label",{class:"login-label"},"密码",-1)),v(e("input",{"onUpdate:modelValue":t[1]||(t[1]=i=>o.password=i),type:"password",class:"login-input",placeholder:"请输入密码",autocomplete:"current-password",required:""},null,512),[[f,o.password]])]),e("button",{type:"submit",class:k(["login-btn",{loading:l.value}])},d(l.value?"登录中...":"登 录"),3)],32),t[7]||(t[7]=e("p",{style:{"text-align":"center","font-size":"11px",color:"#94A3B8","margin-top":"24px"}}," © 2025 Admin Console · v1.0.1 ",-1))])]))}}),O=z(D,[["__scopeId","data-v-4f88fb34"]]);export{O as default}; +import{g as h,j as x,k as w,C as y,c as r,a as e,t as d,l as b,p as _,q as v,v as f,n as k,z as M,y as u,o as p,_ as z}from"./DSy_gLdM.js";const A={class:"login-bg flex items-center justify-center px-4"},B={class:"login-card"},C={class:"text-center"},S={style:{"font-size":"22px","font-weight":"700",color:"#0F172A",margin:"0 0 4px"}},T={key:0,class:"login-error show"},V={style:{width:"16px",height:"16px","flex-shrink":"0"},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},j={style:{"margin-bottom":"16px"}},q={style:{"margin-bottom":"24px"}},D=h({__name:"index",setup(L){const a=x(),c=w(),o=M({account:"",password:""}),l=u(!1),n=u(""),m=u("Admin");y(async()=>{if(a.restore(),a.token){c.push("/dashboard");return}try{const t=(await $fetch("/web/api/api_getsiteinfo",{method:"POST",body:{}}))?.data?.sitename;t&&(m.value=t+" Admin",a.setSiteTitle(t))}catch{}});async function g(){l.value=!0,n.value="";try{const s=await $fetch("/web/api/api_login",{method:"POST",body:{account:o.account,password:o.password}});s.code===0&&s.data?(a.setLoginData(s.data),c.push("/dashboard")):n.value=s.msg||"登录失败"}catch{n.value="网络错误,请检查连接"}finally{l.value=!1}}return(s,t)=>(p(),r("div",A,[e("div",B,[e("div",C,[t[2]||(t[2]=e("div",{class:"logo-icon"},[e("svg",{class:"h-7 w-7 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})])],-1)),e("h1",S,d(m.value),1),t[3]||(t[3]=e("p",{style:{"font-size":"13px",color:"#94A3B8",margin:"0 0 32px"}},"管理控制台",-1))]),n.value?(p(),r("div",T,[(p(),r("svg",V,[...t[4]||(t[4]=[e("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"},null,-1)])])),e("span",null,d(n.value),1)])):b("",!0),e("form",{onSubmit:_(g,["prevent"])},[e("div",j,[t[5]||(t[5]=e("label",{class:"login-label"},"账号",-1)),v(e("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>o.account=i),type:"text",class:"login-input",placeholder:"请输入管理员账号",autocomplete:"username",required:""},null,512),[[f,o.account]])]),e("div",q,[t[6]||(t[6]=e("label",{class:"login-label"},"密码",-1)),v(e("input",{"onUpdate:modelValue":t[1]||(t[1]=i=>o.password=i),type:"password",class:"login-input",placeholder:"请输入密码",autocomplete:"current-password",required:""},null,512),[[f,o.password]])]),e("button",{type:"submit",class:k(["login-btn",{loading:l.value}])},d(l.value?"登录中...":"登 录"),3)],32),t[7]||(t[7]=e("p",{style:{"text-align":"center","font-size":"11px",color:"#94A3B8","margin-top":"24px"}}," © 2025 Admin Console · v1.0.1 ",-1))])]))}}),O=z(D,[["__scopeId","data-v-4f88fb34"]]);export{O as default}; diff --git a/apps/admin/.output/public/_nuxt/SCeBFRND.js b/apps/admin/.output/public/_nuxt/BSO50kj0.js similarity index 98% rename from apps/admin/.output/public/_nuxt/SCeBFRND.js rename to apps/admin/.output/public/_nuxt/BSO50kj0.js index f25c3bff..e11d00be 100644 --- a/apps/admin/.output/public/_nuxt/SCeBFRND.js +++ b/apps/admin/.output/public/_nuxt/BSO50kj0.js @@ -1 +1 @@ -import{g as q,C as G,c as o,a as t,t as l,q as E,s as K,N as j,v as H,F as m,r as f,l as v,y as d,A as w,o as n,n as h,L as C,d as J,_ as Q}from"./DMxDLVSv.js";import{u as W}from"./CCZrj3X-.js";import{u as X}from"./B-sqZCu-.js";import{h as R,S as B,P as M,R as Y,C as Z,p as tt,a as et}from"./PN667bHc.js";const st={class:"panel p-4 mb-5"},at={class:"flex flex-wrap items-center gap-3"},lt={class:"flex items-center gap-2 mr-2"},ot={class:"text-xs text-slate-400"},nt={class:"ml-auto flex items-center gap-2"},rt=["disabled"],it=["disabled"],ct={class:"grid grid-cols-2 md:grid-cols-5 gap-3 mt-4"},ut=["onClick"],dt={class:"sum-lbl"},pt={class:"panel"},vt={class:"panel-head"},_t={class:"text-xs text-slate-400"},mt={class:"overflow-x-auto"},ft={class:"table w-full"},bt={key:0,class:"streak"},kt={class:"font-semibold text-slate-700"},xt={class:"text-xs text-slate-400 font-mono"},yt={key:0},gt={class:"chip chip-scope"},wt={key:0,class:"chip chip-region"},ht={key:1,class:"chip"},Ct={key:0,class:"text-xs text-slate-300"},$t=["title"],Lt={class:"reason-cell"},Tt={key:0,class:"issue-list"},At={class:"text-right text-xs text-slate-400"},St={class:"text-xs text-slate-400"},Et=["disabled","onClick"],Rt={key:0},Bt={colspan:"9",class:"text-center text-slate-400 py-8"},Mt=q({__name:"svcinspect",setup(Nt){const{webApi:b}=W(),p=X(),k=d([]),u=d({total:0,ok:0,warn:0,error:0,skip:0}),$=d(0),i=d(!1),c=d(""),x=d(""),N=w(()=>R($.value)),V=w(()=>[{key:"error",label:"不可用",value:u.value.error,ico:"🚨",color:"#be123c",bg:"#ffe4e6"},{key:"warn",label:"有隐患",value:u.value.warn,ico:"⚠️",color:"#b45309",bg:"#fef3c7"},{key:"ok",label:"正常",value:u.value.ok,ico:"✅",color:"#047857",bg:"#d1fae5"},{key:"skip",label:"已停用",value:u.value.skip,ico:"⏸️",color:"#64748b",bg:"#f1f5f9"},{key:"",label:"巡检配置总数",value:u.value.total,ico:"📋",color:"#334155",bg:"#e2e8f0"}]),y=w(()=>{const s=x.value.trim().toLowerCase();return k.value.filter(a=>c.value&&a.status!==c.value?!1:s?`${a.name} ${a.svc_id} ${a.provider} ${a.app_name}`.toLowerCase().includes(s):!0)});function O(s){return`${s.app_name}/${s.svc_id}/${s.region}`}function g(s){return B[s]||B.skip}function L(s){return M[s]||M.none}function D(s){return Y[s]||`区域 ${s}`}function I(s){return Z[s]||`类别 ${s}`}function T(s){return tt(s)}function A(s){return et(s)}function U(s){return R(s)}function S(s){const a=(s.config_issues||[]).map(r=>r.replace("[致命] ","")),e=A(s);return a.filter(r=>r!==e&&!e.includes(r))}async function _(){try{const s=await b("getsvchealth",{});k.value=s.items||[],u.value=s.summary||{total:0,ok:0,warn:0,error:0,skip:0},$.value=s.last_run||0}catch(s){p.error(s?.message||"加载巡检结果失败")}}async function z(){i.value=!0;try{const s=await b("runsvcinspect",{});p.success(`巡检完成,已检查 ${s.count} 份配置`),await _()}catch(s){p.error(s?.message||"巡检失败")}finally{i.value=!1}}async function F(s){i.value=!0;try{await b("runsvcinspect",{app_name:s.app_name,svc_id:s.svc_id}),p.success(`已重新检测:${s.name||s.svc_id}`),await _()}catch(a){p.error(a?.message||"检测失败")}finally{i.value=!1}}return G(_),(s,a)=>(n(),o("div",null,[t("div",st,[t("div",at,[t("div",lt,[a[2]||(a[2]=t("h2",{class:"text-base font-bold text-slate-800"},"服务巡检",-1)),t("span",ot," 定时校验第三方服务配置并探测可用性 · 最近巡检 "+l(N.value),1)]),t("div",nt,[E(t("select",{"onUpdate:modelValue":a[0]||(a[0]=e=>c.value=e),class:"select select-bordered select-sm w-32"},[...a[3]||(a[3]=[j('',5)])],512),[[K,c.value]]),E(t("input",{"onUpdate:modelValue":a[1]||(a[1]=e=>x.value=e),class:"input input-bordered input-sm w-44",placeholder:"搜索服务名/ID/服务商"},null,512),[[H,x.value]]),t("button",{class:"btn btn-sm",disabled:i.value,onClick:_},"刷新",8,rt),t("button",{class:"btn btn-primary btn-sm text-white",disabled:i.value,onClick:z},l(i.value?"巡检中…":"立即巡检"),9,it)])]),t("div",ct,[(n(!0),o(m,null,f(V.value,e=>(n(),o("div",{key:e.key,class:h(["sum-card",{on:c.value===e.key}]),onClick:r=>c.value=c.value===e.key?"":e.key},[t("span",{class:"sum-ico",style:C({background:e.bg,color:e.color})},l(e.ico),5),t("div",null,[t("div",dt,l(e.label),1),t("div",{class:"sum-val",style:C({color:e.color})},l(e.value),5)])],10,ut))),128))])]),t("div",pt,[t("div",vt,[a[4]||(a[4]=t("span",{class:"font-semibold text-slate-700 text-sm"},"巡检明细",-1)),t("span",_t,"共 "+l(y.value.length)+" 份配置",1),a[5]||(a[5]=t("span",{class:"ml-auto text-xs text-slate-400"}," 一个服务在不同区域可能配着不同凭据,故按「服务 × 区域」分别巡检 ",-1))]),t("div",mt,[t("table",ft,[a[6]||(a[6]=t("thead",null,[t("tr",null,[t("th",null,"状态"),t("th",null,"服务"),t("th",null,"作用域 / 区域"),t("th",null,"类别"),t("th",null,"探测方式"),t("th",null,"巡检结论"),t("th",{class:"text-right"},"耗时"),t("th",null,"检查时间"),t("th")])],-1)),t("tbody",null,[(n(!0),o(m,null,f(y.value,e=>(n(),o("tr",{key:O(e)},[t("td",null,[t("span",{class:"st-badge",style:C({background:g(e.status).bg,color:g(e.status).color})},l(g(e.status).label),5),e.fail_streak>1?(n(),o("div",bt,"连续 "+l(e.fail_streak)+" 次",1)):v("",!0)]),t("td",null,[t("div",kt,l(e.name||e.svc_id),1),t("div",xt,[J(l(e.svc_id),1),e.provider?(n(),o("span",yt," · "+l(e.provider),1)):v("",!0)])]),t("td",null,[t("span",gt,l(e.app_name||"全局默认"),1),e.region?(n(),o("span",wt,l(D(e.region)),1)):(n(),o("span",ht,"默认配置"))]),t("td",null,[(n(!0),o(m,null,f(T(e.categories),r=>(n(),o("span",{key:r,class:"chip"},l(I(r)),1))),128)),T(e.categories).length?v("",!0):(n(),o("span",Ct,"—"))]),t("td",null,[t("span",{class:h(["chip","pk-"+e.probe_kind]),title:L(e.probe_kind).hint},l(L(e.probe_kind).label),11,$t)]),t("td",Lt,[t("div",{class:h(e.status==="error"?"text-rose-600":"text-slate-500")},l(A(e)||"—"),3),S(e).length?(n(),o("div",Tt,[(n(!0),o(m,null,f(S(e),(r,P)=>(n(),o("div",{key:P,class:"issue"},"· "+l(r),1))),128))])):v("",!0)]),t("td",At,l(e.probe_kind==="none"?"—":e.latency_ms+" ms"),1),t("td",St,l(U(e.checked_at)),1),t("td",null,[t("button",{class:"btn btn-xs",disabled:i.value,onClick:r=>F(e)},"重测",8,Et)])]))),128)),y.value.length?v("",!0):(n(),o("tr",Rt,[t("td",Bt,l(k.value.length?"当前筛选下没有匹配的记录":"暂无巡检记录,点击右上角「立即巡检」执行一次"),1)]))])])])])]))}}),Ut=Q(Mt,[["__scopeId","data-v-a9764f3a"]]);export{Ut as default}; +import{g as q,C as G,c as o,a as t,t as l,q as E,s as K,N as j,v as H,F as m,r as f,l as v,y as d,A as w,o as n,n as h,L as C,d as J,_ as Q}from"./DSy_gLdM.js";import{u as W}from"./NtXZuCUg.js";import{u as X}from"./EeX3zgoF.js";import{h as R,S as B,P as M,R as Y,C as Z,p as tt,a as et}from"./PN667bHc.js";const st={class:"panel p-4 mb-5"},at={class:"flex flex-wrap items-center gap-3"},lt={class:"flex items-center gap-2 mr-2"},ot={class:"text-xs text-slate-400"},nt={class:"ml-auto flex items-center gap-2"},rt=["disabled"],it=["disabled"],ct={class:"grid grid-cols-2 md:grid-cols-5 gap-3 mt-4"},ut=["onClick"],dt={class:"sum-lbl"},pt={class:"panel"},vt={class:"panel-head"},_t={class:"text-xs text-slate-400"},mt={class:"overflow-x-auto"},ft={class:"table w-full"},bt={key:0,class:"streak"},kt={class:"font-semibold text-slate-700"},xt={class:"text-xs text-slate-400 font-mono"},yt={key:0},gt={class:"chip chip-scope"},wt={key:0,class:"chip chip-region"},ht={key:1,class:"chip"},Ct={key:0,class:"text-xs text-slate-300"},$t=["title"],Lt={class:"reason-cell"},Tt={key:0,class:"issue-list"},At={class:"text-right text-xs text-slate-400"},St={class:"text-xs text-slate-400"},Et=["disabled","onClick"],Rt={key:0},Bt={colspan:"9",class:"text-center text-slate-400 py-8"},Mt=q({__name:"svcinspect",setup(Nt){const{webApi:b}=W(),p=X(),k=d([]),u=d({total:0,ok:0,warn:0,error:0,skip:0}),$=d(0),i=d(!1),c=d(""),x=d(""),N=w(()=>R($.value)),V=w(()=>[{key:"error",label:"不可用",value:u.value.error,ico:"🚨",color:"#be123c",bg:"#ffe4e6"},{key:"warn",label:"有隐患",value:u.value.warn,ico:"⚠️",color:"#b45309",bg:"#fef3c7"},{key:"ok",label:"正常",value:u.value.ok,ico:"✅",color:"#047857",bg:"#d1fae5"},{key:"skip",label:"已停用",value:u.value.skip,ico:"⏸️",color:"#64748b",bg:"#f1f5f9"},{key:"",label:"巡检配置总数",value:u.value.total,ico:"📋",color:"#334155",bg:"#e2e8f0"}]),y=w(()=>{const s=x.value.trim().toLowerCase();return k.value.filter(a=>c.value&&a.status!==c.value?!1:s?`${a.name} ${a.svc_id} ${a.provider} ${a.app_name}`.toLowerCase().includes(s):!0)});function O(s){return`${s.app_name}/${s.svc_id}/${s.region}`}function g(s){return B[s]||B.skip}function L(s){return M[s]||M.none}function D(s){return Y[s]||`区域 ${s}`}function I(s){return Z[s]||`类别 ${s}`}function T(s){return tt(s)}function A(s){return et(s)}function U(s){return R(s)}function S(s){const a=(s.config_issues||[]).map(r=>r.replace("[致命] ","")),e=A(s);return a.filter(r=>r!==e&&!e.includes(r))}async function _(){try{const s=await b("getsvchealth",{});k.value=s.items||[],u.value=s.summary||{total:0,ok:0,warn:0,error:0,skip:0},$.value=s.last_run||0}catch(s){p.error(s?.message||"加载巡检结果失败")}}async function z(){i.value=!0;try{const s=await b("runsvcinspect",{});p.success(`巡检完成,已检查 ${s.count} 份配置`),await _()}catch(s){p.error(s?.message||"巡检失败")}finally{i.value=!1}}async function F(s){i.value=!0;try{await b("runsvcinspect",{app_name:s.app_name,svc_id:s.svc_id}),p.success(`已重新检测:${s.name||s.svc_id}`),await _()}catch(a){p.error(a?.message||"检测失败")}finally{i.value=!1}}return G(_),(s,a)=>(n(),o("div",null,[t("div",st,[t("div",at,[t("div",lt,[a[2]||(a[2]=t("h2",{class:"text-base font-bold text-slate-800"},"服务巡检",-1)),t("span",ot," 定时校验第三方服务配置并探测可用性 · 最近巡检 "+l(N.value),1)]),t("div",nt,[E(t("select",{"onUpdate:modelValue":a[0]||(a[0]=e=>c.value=e),class:"select select-bordered select-sm w-32"},[...a[3]||(a[3]=[j('',5)])],512),[[K,c.value]]),E(t("input",{"onUpdate:modelValue":a[1]||(a[1]=e=>x.value=e),class:"input input-bordered input-sm w-44",placeholder:"搜索服务名/ID/服务商"},null,512),[[H,x.value]]),t("button",{class:"btn btn-sm",disabled:i.value,onClick:_},"刷新",8,rt),t("button",{class:"btn btn-primary btn-sm text-white",disabled:i.value,onClick:z},l(i.value?"巡检中…":"立即巡检"),9,it)])]),t("div",ct,[(n(!0),o(m,null,f(V.value,e=>(n(),o("div",{key:e.key,class:h(["sum-card",{on:c.value===e.key}]),onClick:r=>c.value=c.value===e.key?"":e.key},[t("span",{class:"sum-ico",style:C({background:e.bg,color:e.color})},l(e.ico),5),t("div",null,[t("div",dt,l(e.label),1),t("div",{class:"sum-val",style:C({color:e.color})},l(e.value),5)])],10,ut))),128))])]),t("div",pt,[t("div",vt,[a[4]||(a[4]=t("span",{class:"font-semibold text-slate-700 text-sm"},"巡检明细",-1)),t("span",_t,"共 "+l(y.value.length)+" 份配置",1),a[5]||(a[5]=t("span",{class:"ml-auto text-xs text-slate-400"}," 一个服务在不同区域可能配着不同凭据,故按「服务 × 区域」分别巡检 ",-1))]),t("div",mt,[t("table",ft,[a[6]||(a[6]=t("thead",null,[t("tr",null,[t("th",null,"状态"),t("th",null,"服务"),t("th",null,"作用域 / 区域"),t("th",null,"类别"),t("th",null,"探测方式"),t("th",null,"巡检结论"),t("th",{class:"text-right"},"耗时"),t("th",null,"检查时间"),t("th")])],-1)),t("tbody",null,[(n(!0),o(m,null,f(y.value,e=>(n(),o("tr",{key:O(e)},[t("td",null,[t("span",{class:"st-badge",style:C({background:g(e.status).bg,color:g(e.status).color})},l(g(e.status).label),5),e.fail_streak>1?(n(),o("div",bt,"连续 "+l(e.fail_streak)+" 次",1)):v("",!0)]),t("td",null,[t("div",kt,l(e.name||e.svc_id),1),t("div",xt,[J(l(e.svc_id),1),e.provider?(n(),o("span",yt," · "+l(e.provider),1)):v("",!0)])]),t("td",null,[t("span",gt,l(e.app_name||"全局默认"),1),e.region?(n(),o("span",wt,l(D(e.region)),1)):(n(),o("span",ht,"默认配置"))]),t("td",null,[(n(!0),o(m,null,f(T(e.categories),r=>(n(),o("span",{key:r,class:"chip"},l(I(r)),1))),128)),T(e.categories).length?v("",!0):(n(),o("span",Ct,"—"))]),t("td",null,[t("span",{class:h(["chip","pk-"+e.probe_kind]),title:L(e.probe_kind).hint},l(L(e.probe_kind).label),11,$t)]),t("td",Lt,[t("div",{class:h(e.status==="error"?"text-rose-600":"text-slate-500")},l(A(e)||"—"),3),S(e).length?(n(),o("div",Tt,[(n(!0),o(m,null,f(S(e),(r,P)=>(n(),o("div",{key:P,class:"issue"},"· "+l(r),1))),128))])):v("",!0)]),t("td",At,l(e.probe_kind==="none"?"—":e.latency_ms+" ms"),1),t("td",St,l(U(e.checked_at)),1),t("td",null,[t("button",{class:"btn btn-xs",disabled:i.value,onClick:r=>F(e)},"重测",8,Et)])]))),128)),y.value.length?v("",!0):(n(),o("tr",Rt,[t("td",Bt,l(k.value.length?"当前筛选下没有匹配的记录":"暂无巡检记录,点击右上角「立即巡检」执行一次"),1)]))])])])])]))}}),Ut=Q(Mt,[["__scopeId","data-v-a9764f3a"]]);export{Ut as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/ByX5RcOZ.js b/apps/admin/.output/public/_nuxt/BZKwWPxz.js similarity index 98% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/ByX5RcOZ.js rename to apps/admin/.output/public/_nuxt/BZKwWPxz.js index 2902edf0..3311b2d1 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/ByX5RcOZ.js +++ b/apps/admin/.output/public/_nuxt/BZKwWPxz.js @@ -1 +1 @@ -import{g as I,C as J,c as a,q as p,H as j,a as e,F as g,r as h,s as q,v as y,t as d,l as K,p as Q,y as r,z as W,A as w,o as i}from"./DMxDLVSv.js";import{u as X}from"./CCZrj3X-.js";import{u as Y}from"./B-sqZCu-.js";import{r as Z}from"./7m3DvxFn.js";const ee={class:"flex items-center justify-between mb-5"},te=["disabled"],se={class:"flex items-center gap-3 mb-4 flex-wrap"},le=["value"],oe=["disabled"],ne=["value"],ae={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 text-center text-slate-400 py-16"},ie={class:"text-sm"},ue={key:1,class:"bg-white rounded-xl shadow-sm border border-slate-100"},de={class:"overflow-x-auto"},re={class:"table"},pe={key:0},me={key:1},ve={class:"bg-slate-100/80"},ce={colspan:"4",class:"py-2"},be={class:"font-semibold text-slate-600 text-sm"},fe={class:"text-xs text-slate-400 ml-2"},xe={class:"font-mono text-sm font-medium"},ge=["title"],ye={class:"text-sm text-slate-400"},we={class:"text-right"},_e={class:"inline-flex gap-1"},ke=["onClick"],he=["onClick"],Ce={class:"flex items-center gap-3 mb-5"},$e={class:"text-lg font-semibold text-slate-800"},Ae={class:"text-xs text-slate-400"},Ve={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Le={class:"form-control mb-4"},Ne={class:"form-control mb-4"},Se={class:"form-control mb-4"},Ue={class:"form-control mb-6"},De={class:"flex gap-3"},Be=["disabled"],Oe=I({__name:"appconfig",setup(Me){const{consoleApi:v}=X(),{success:U,error:c}=Y(),_=r("list"),b=r([]),C=r([]),m=r(""),u=r(0),f=r([]),$=r(!1),A=r(!1),k=r(!1),V=r(""),o=W({id:0,group:"",key:"",value:"",description:""}),L=w(()=>[...new Set(b.value.map(s=>s.app_name||s.name).filter(Boolean))].sort()),D=w(()=>b.value.filter(s=>(s.app_name||s.name)===m.value));function B(s){const t=C.value.find(S=>S.id===s.env_id),l=t?t.name||t.code:s.env_id?`环境#${s.env_id}`:"未关联环境",n=s.status==="pending"?"(待部署)":"";return s.region?`${l} · ${Z(s.region)}${n}`:`${l}${n}`}const O=w(()=>{const s=b.value.find(t=>t.id===u.value);return s?`${s.app_name||s.name} · ${B(s)}`:""}),M=w(()=>{const s=V.value.trim().toLowerCase();return s?f.value.filter(t=>((t.group||"")+(t.key||"")).toLowerCase().includes(s)):f.value}),R=w(()=>{const s={};return M.value.forEach(l=>{const n=l.group||"";(s[n]=s[n]||[]).push(l)}),Object.keys(s).sort((l,n)=>l===""?-1:n===""?1:l({key:l,label:l||"未分组",items:s[l]}))});async function T(){try{const[s,t]=await Promise.all([v("apps/list",{}),v("envs/list",{})]);b.value=s??[],C.value=t??[],!m.value&&L.value.length&&(m.value=L.value[0],E(),await x())}catch(s){c(s?.message??"获取应用列表失败"),b.value=[],C.value=[]}}function E(){const s=D.value,t=s.find(l=>l.status!=="pending")??s[0];u.value=t?.id??0}function z(){E(),x()}async function x(){if(!u.value){f.value=[];return}$.value=!0;try{const s=await v("appcfg/list",{app_id:u.value});f.value=s?.items??[]}catch(s){c(s?.message??"获取配置失败"),f.value=[]}finally{$.value=!1}}function H(){x()}function N(){_.value="list",x()}function F(s){s?(k.value=!0,o.id=s.id||0,o.group=s.group||"",o.key=s.key||"",o.value=s.value||"",o.description=s.description||""):(k.value=!1,o.id=0,o.group="",o.key="",o.value="",o.description=""),_.value="form"}async function P(){if(!u.value){c("请先选择应用和部署环境");return}A.value=!0;try{const s={app_id:u.value,group:o.group.trim(),key:o.key.trim(),value:o.value,description:o.description.trim()};k.value?(s.id=Number(o.id),await v("appcfg/update",s)):await v("appcfg/add",s),U("保存成功"),N()}catch(s){c(s?.message??"保存失败")}finally{A.value=!1}}function G(s){window.confirm("确定删除该配置项吗?")&&v("appcfg/del",{app_id:u.value,ids:[s.id]}).then(()=>{U("删除成功"),x()}).catch(t=>c(t?.message??"删除失败"))}return J(T),(s,t)=>(i(),a("div",null,[p(e("div",null,[e("div",ee,[t[10]||(t[10]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"应用环境配置"),e("p",{class:"text-xs text-slate-400 mt-1"},"应用自有的 key/value 配置(音乐、OSS 等),直接读写所选应用的业务库。结构同「全局环境配置」但不分区域。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",disabled:!u.value,onClick:t[0]||(t[0]=l=>F())},"+ 新增配置",8,te)]),e("div",se,[t[13]||(t[13]=e("span",{class:"text-sm text-slate-500"},"应用",-1)),p(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>m.value=l),class:"select select-bordered select-sm min-w-40",onChange:z},[t[11]||(t[11]=e("option",{value:"",disabled:""},"请选择应用",-1)),(i(!0),a(g,null,h(L.value,l=>(i(),a("option",{key:l,value:l},d(l),9,le))),128))],544),[[q,m.value]]),t[14]||(t[14]=e("span",{class:"text-sm text-slate-500"},"部署环境",-1)),p(e("select",{"onUpdate:modelValue":t[2]||(t[2]=l=>u.value=l),class:"select select-bordered select-sm min-w-48",disabled:!m.value,onChange:H},[t[12]||(t[12]=e("option",{value:0,disabled:""},"请选择环境",-1)),(i(!0),a(g,null,h(D.value,l=>(i(),a("option",{key:l.id,value:l.id},d(B(l)),9,ne))),128))],40,oe),[[q,u.value,void 0,{number:!0}]]),p(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>V.value=l),class:"input input-bordered input-sm w-48",placeholder:"按分组/键搜索"},null,512),[[y,V.value]])]),u.value?(i(),a("div",ue,[e("div",de,[e("table",re,[t[18]||(t[18]=e("thead",null,[e("tr",null,[e("th",null,"键"),e("th",null,"值"),e("th",null,"描述"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[$.value?(i(),a("tr",pe,[...t[16]||(t[16]=[e("td",{colspan:"4",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):M.value.length?K("",!0):(i(),a("tr",me,[...t[17]||(t[17]=[e("td",{colspan:"4",class:"text-center text-slate-400 py-8"},"暂无配置",-1)])])),(i(!0),a(g,null,h(R.value,l=>(i(),a(g,{key:l.key},[e("tr",ve,[e("td",ce,[e("span",be,"▸ "+d(l.label),1),e("span",fe,d(l.items.length)+" 项",1)])]),(i(!0),a(g,null,h(l.items,n=>(i(),a("tr",{key:n.id,class:"hover"},[e("td",xe,d(n.key||""),1),e("td",{class:"text-sm text-slate-500 max-w-xs truncate",title:n.value||""},d(n.value||""),9,ge),e("td",ye,d(n.description||""),1),e("td",we,[e("div",_e,[e("button",{class:"btn btn-ghost btn-xs",onClick:S=>F(n)},"编辑",8,ke),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:S=>G(n)},"删除",8,he)])])]))),128))],64))),128))])])])])):(i(),a("div",ae,[t[15]||(t[15]=e("div",{class:"text-4xl mb-2"},"🗂️",-1)),e("p",ie,d(m.value?"该应用还没有部署环境,请先在「应用中心」为它部署一个环境":"请先在上方选择应用和部署环境"),1)]))],512),[[j,_.value==="list"]]),p(e("div",null,[e("div",Ce,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[4]||(t[4]=l=>N())},"← 返回列表"),e("h2",$e,d(k.value?"编辑配置":"新增配置"),1),e("span",Ae,"配置目标:"+d(O.value),1)]),e("div",Ve,[e("form",{onSubmit:Q(P,["prevent"])},[e("div",Le,[t[19]||(t[19]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"分组 (group)")],-1)),p(e("input",{"onUpdate:modelValue":t[5]||(t[5]=l=>o.group=l),type:"text",class:"input input-bordered w-full",placeholder:"如 music / oss / other"},null,512),[[y,o.group]])]),e("div",Ne,[t[20]||(t[20]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"键 (key) *")],-1)),p(e("input",{"onUpdate:modelValue":t[6]||(t[6]=l=>o.key=l),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 oss_access_key"},null,512),[[y,o.key]])]),e("div",Se,[t[21]||(t[21]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"值 (value)")],-1)),p(e("textarea",{"onUpdate:modelValue":t[7]||(t[7]=l=>o.value=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"3"},null,512),[[y,o.value]])]),e("div",Ue,[t[22]||(t[22]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),p(e("input",{"onUpdate:modelValue":t[8]||(t[8]=l=>o.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[y,o.description]])]),e("div",De,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[9]||(t[9]=l=>N())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:A.value},"保存",8,Be)])],32)])],512),[[j,_.value==="form"]])]))}});export{Oe as default}; +import{g as I,C as J,c as a,q as p,H as j,a as e,F as g,r as h,s as q,v as y,t as d,l as K,p as Q,y as r,z as W,A as w,o as i}from"./DSy_gLdM.js";import{u as X}from"./NtXZuCUg.js";import{u as Y}from"./EeX3zgoF.js";import{r as Z}from"./7m3DvxFn.js";const ee={class:"flex items-center justify-between mb-5"},te=["disabled"],se={class:"flex items-center gap-3 mb-4 flex-wrap"},le=["value"],oe=["disabled"],ne=["value"],ae={key:0,class:"bg-white rounded-xl shadow-sm border border-slate-100 text-center text-slate-400 py-16"},ie={class:"text-sm"},ue={key:1,class:"bg-white rounded-xl shadow-sm border border-slate-100"},de={class:"overflow-x-auto"},re={class:"table"},pe={key:0},me={key:1},ve={class:"bg-slate-100/80"},ce={colspan:"4",class:"py-2"},be={class:"font-semibold text-slate-600 text-sm"},fe={class:"text-xs text-slate-400 ml-2"},xe={class:"font-mono text-sm font-medium"},ge=["title"],ye={class:"text-sm text-slate-400"},we={class:"text-right"},_e={class:"inline-flex gap-1"},ke=["onClick"],he=["onClick"],Ce={class:"flex items-center gap-3 mb-5"},$e={class:"text-lg font-semibold text-slate-800"},Ae={class:"text-xs text-slate-400"},Ve={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Le={class:"form-control mb-4"},Ne={class:"form-control mb-4"},Se={class:"form-control mb-4"},Ue={class:"form-control mb-6"},De={class:"flex gap-3"},Be=["disabled"],Oe=I({__name:"appconfig",setup(Me){const{consoleApi:v}=X(),{success:U,error:c}=Y(),_=r("list"),b=r([]),C=r([]),m=r(""),u=r(0),f=r([]),$=r(!1),A=r(!1),k=r(!1),V=r(""),o=W({id:0,group:"",key:"",value:"",description:""}),L=w(()=>[...new Set(b.value.map(s=>s.app_name||s.name).filter(Boolean))].sort()),D=w(()=>b.value.filter(s=>(s.app_name||s.name)===m.value));function B(s){const t=C.value.find(S=>S.id===s.env_id),l=t?t.name||t.code:s.env_id?`环境#${s.env_id}`:"未关联环境",n=s.status==="pending"?"(待部署)":"";return s.region?`${l} · ${Z(s.region)}${n}`:`${l}${n}`}const O=w(()=>{const s=b.value.find(t=>t.id===u.value);return s?`${s.app_name||s.name} · ${B(s)}`:""}),M=w(()=>{const s=V.value.trim().toLowerCase();return s?f.value.filter(t=>((t.group||"")+(t.key||"")).toLowerCase().includes(s)):f.value}),R=w(()=>{const s={};return M.value.forEach(l=>{const n=l.group||"";(s[n]=s[n]||[]).push(l)}),Object.keys(s).sort((l,n)=>l===""?-1:n===""?1:l({key:l,label:l||"未分组",items:s[l]}))});async function T(){try{const[s,t]=await Promise.all([v("apps/list",{}),v("envs/list",{})]);b.value=s??[],C.value=t??[],!m.value&&L.value.length&&(m.value=L.value[0],E(),await x())}catch(s){c(s?.message??"获取应用列表失败"),b.value=[],C.value=[]}}function E(){const s=D.value,t=s.find(l=>l.status!=="pending")??s[0];u.value=t?.id??0}function z(){E(),x()}async function x(){if(!u.value){f.value=[];return}$.value=!0;try{const s=await v("appcfg/list",{app_id:u.value});f.value=s?.items??[]}catch(s){c(s?.message??"获取配置失败"),f.value=[]}finally{$.value=!1}}function H(){x()}function N(){_.value="list",x()}function F(s){s?(k.value=!0,o.id=s.id||0,o.group=s.group||"",o.key=s.key||"",o.value=s.value||"",o.description=s.description||""):(k.value=!1,o.id=0,o.group="",o.key="",o.value="",o.description=""),_.value="form"}async function P(){if(!u.value){c("请先选择应用和部署环境");return}A.value=!0;try{const s={app_id:u.value,group:o.group.trim(),key:o.key.trim(),value:o.value,description:o.description.trim()};k.value?(s.id=Number(o.id),await v("appcfg/update",s)):await v("appcfg/add",s),U("保存成功"),N()}catch(s){c(s?.message??"保存失败")}finally{A.value=!1}}function G(s){window.confirm("确定删除该配置项吗?")&&v("appcfg/del",{app_id:u.value,ids:[s.id]}).then(()=>{U("删除成功"),x()}).catch(t=>c(t?.message??"删除失败"))}return J(T),(s,t)=>(i(),a("div",null,[p(e("div",null,[e("div",ee,[t[10]||(t[10]=e("div",null,[e("h2",{class:"text-lg font-semibold text-slate-800"},"应用环境配置"),e("p",{class:"text-xs text-slate-400 mt-1"},"应用自有的 key/value 配置(音乐、OSS 等),直接读写所选应用的业务库。结构同「全局环境配置」但不分区域。")],-1)),e("button",{class:"btn btn-primary btn-sm text-white",disabled:!u.value,onClick:t[0]||(t[0]=l=>F())},"+ 新增配置",8,te)]),e("div",se,[t[13]||(t[13]=e("span",{class:"text-sm text-slate-500"},"应用",-1)),p(e("select",{"onUpdate:modelValue":t[1]||(t[1]=l=>m.value=l),class:"select select-bordered select-sm min-w-40",onChange:z},[t[11]||(t[11]=e("option",{value:"",disabled:""},"请选择应用",-1)),(i(!0),a(g,null,h(L.value,l=>(i(),a("option",{key:l,value:l},d(l),9,le))),128))],544),[[q,m.value]]),t[14]||(t[14]=e("span",{class:"text-sm text-slate-500"},"部署环境",-1)),p(e("select",{"onUpdate:modelValue":t[2]||(t[2]=l=>u.value=l),class:"select select-bordered select-sm min-w-48",disabled:!m.value,onChange:H},[t[12]||(t[12]=e("option",{value:0,disabled:""},"请选择环境",-1)),(i(!0),a(g,null,h(D.value,l=>(i(),a("option",{key:l.id,value:l.id},d(B(l)),9,ne))),128))],40,oe),[[q,u.value,void 0,{number:!0}]]),p(e("input",{"onUpdate:modelValue":t[3]||(t[3]=l=>V.value=l),class:"input input-bordered input-sm w-48",placeholder:"按分组/键搜索"},null,512),[[y,V.value]])]),u.value?(i(),a("div",ue,[e("div",de,[e("table",re,[t[18]||(t[18]=e("thead",null,[e("tr",null,[e("th",null,"键"),e("th",null,"值"),e("th",null,"描述"),e("th",{class:"text-right"},"操作")])],-1)),e("tbody",null,[$.value?(i(),a("tr",pe,[...t[16]||(t[16]=[e("td",{colspan:"4",class:"text-center py-8"},[e("span",{class:"loading loading-spinner loading-sm"})],-1)])])):M.value.length?K("",!0):(i(),a("tr",me,[...t[17]||(t[17]=[e("td",{colspan:"4",class:"text-center text-slate-400 py-8"},"暂无配置",-1)])])),(i(!0),a(g,null,h(R.value,l=>(i(),a(g,{key:l.key},[e("tr",ve,[e("td",ce,[e("span",be,"▸ "+d(l.label),1),e("span",fe,d(l.items.length)+" 项",1)])]),(i(!0),a(g,null,h(l.items,n=>(i(),a("tr",{key:n.id,class:"hover"},[e("td",xe,d(n.key||""),1),e("td",{class:"text-sm text-slate-500 max-w-xs truncate",title:n.value||""},d(n.value||""),9,ge),e("td",ye,d(n.description||""),1),e("td",we,[e("div",_e,[e("button",{class:"btn btn-ghost btn-xs",onClick:S=>F(n)},"编辑",8,ke),e("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:S=>G(n)},"删除",8,he)])])]))),128))],64))),128))])])])])):(i(),a("div",ae,[t[15]||(t[15]=e("div",{class:"text-4xl mb-2"},"🗂️",-1)),e("p",ie,d(m.value?"该应用还没有部署环境,请先在「应用中心」为它部署一个环境":"请先在上方选择应用和部署环境"),1)]))],512),[[j,_.value==="list"]]),p(e("div",null,[e("div",Ce,[e("button",{class:"btn btn-ghost btn-sm",onClick:t[4]||(t[4]=l=>N())},"← 返回列表"),e("h2",$e,d(k.value?"编辑配置":"新增配置"),1),e("span",Ae,"配置目标:"+d(O.value),1)]),e("div",Ve,[e("form",{onSubmit:Q(P,["prevent"])},[e("div",Le,[t[19]||(t[19]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"分组 (group)")],-1)),p(e("input",{"onUpdate:modelValue":t[5]||(t[5]=l=>o.group=l),type:"text",class:"input input-bordered w-full",placeholder:"如 music / oss / other"},null,512),[[y,o.group]])]),e("div",Ne,[t[20]||(t[20]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"键 (key) *")],-1)),p(e("input",{"onUpdate:modelValue":t[6]||(t[6]=l=>o.key=l),type:"text",class:"input input-bordered w-full",required:"",placeholder:"如 oss_access_key"},null,512),[[y,o.key]])]),e("div",Se,[t[21]||(t[21]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"值 (value)")],-1)),p(e("textarea",{"onUpdate:modelValue":t[7]||(t[7]=l=>o.value=l),class:"textarea textarea-bordered w-full font-mono text-sm",rows:"3"},null,512),[[y,o.value]])]),e("div",Ue,[t[22]||(t[22]=e("label",{class:"label"},[e("span",{class:"label-text font-medium"},"描述")],-1)),p(e("input",{"onUpdate:modelValue":t[8]||(t[8]=l=>o.description=l),type:"text",class:"input input-bordered w-full"},null,512),[[y,o.description]])]),e("div",De,[e("button",{type:"button",class:"btn btn-ghost",onClick:t[9]||(t[9]=l=>N())},"取消"),e("button",{type:"submit",class:"btn btn-primary text-white",disabled:A.value},"保存",8,Be)])],32)])],512),[[j,_.value==="form"]])]))}});export{Oe as default}; diff --git a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/8OwDPhJR.js b/apps/admin/.output/public/_nuxt/Bad2XFSd.js similarity index 99% rename from apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/8OwDPhJR.js rename to apps/admin/.output/public/_nuxt/Bad2XFSd.js index a5954875..6a4f9c5a 100644 --- a/apps/admin/node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/8OwDPhJR.js +++ b/apps/admin/.output/public/_nuxt/Bad2XFSd.js @@ -1 +1 @@ -import{g as Ee,C as Le,c as n,a as s,d,q as S,s as q,F as c,r as C,t as i,l as g,n as h,m as Oe,v as he,x as fe,y as m,z as ke,A as O,o as a,_ as De}from"./DMxDLVSv.js";import{u as Be}from"./CCZrj3X-.js";import{u as je}from"./B-sqZCu-.js";import{L as de}from"./DD3V9C6_.js";const Fe={class:"scopebar"},Ie={class:"flex items-center gap-2"},Te=["value"],ze=["value"],Ge={class:"text-[11px] text-slate-400"},He={key:0,class:"bg-white rounded-xl border border-slate-100 py-16 text-center"},Ke={class:"langsum-head"},Re={class:"langsum-formula"},Xe={key:0,class:"langsum-msg bad"},Pe={key:1,class:"langsum-msg bad"},We={key:2,class:"langsum-langs"},qe=["title"],Je={key:3,class:"langsum-msg"},Qe={key:0,class:"alert alert-warning py-2 text-sm mb-4"},Ye={class:"card"},Ze={class:"card-head"},es={class:"flex gap-2 shrink-0"},ss=["disabled"],ts=["disabled"],ls={class:"probe-bar"},ns=["value"],as={key:0,class:"probe-out"},is={key:1,class:"probe-out bad"},os={key:0,class:"py-10 text-center text-slate-400 text-sm"},ds={class:"min-w-0"},us={class:"svc-prov"},cs={class:"flex flex-wrap gap-1"},rs={key:0,class:"lang"},vs={key:1,class:"text-[11px] text-slate-400"},bs={class:"svc-cost"},_s={key:1,class:"text-slate-300"},ms=["checked","disabled","onChange"],gs={class:"svc-acts"},ps=["disabled","onClick"],hs=["disabled","onClick"],fs=["onClick"],ks=["onClick"],xs={class:"card mt-4"},ys={class:"card-head"},ws={class:"flex gap-2 shrink-0"},Cs=["disabled"],$s=["disabled"],Ns={key:0,class:"py-10 text-center text-slate-400 text-sm"},As={class:"min-w-0"},Vs={class:"svc-name"},Ss={class:"svc-prov"},Ms={class:"svc-cost"},Us={key:1,class:"text-slate-300"},Es=["checked","disabled","onChange"],Ls={class:"svc-acts"},Os=["disabled","onClick"],Ds=["disabled","onClick"],Bs=["onClick"],js=["onClick"],Fs={class:"card mt-4"},Is={class:"card-head"},Ts=["disabled"],zs={class:"mode-bar"},Gs={class:"flex items-center gap-2 cursor-pointer shrink-0"},Hs=["checked","disabled"],Ks={class:"mode-txt"},Rs={key:0,class:"py-10 text-center text-slate-400 text-sm"},Xs={class:"grid place-items-center"},Ps=["checked","disabled","onChange"],Ws={class:"min-w-0"},qs={class:"svc-name"},Js={key:0,title:"多媒体大模型,能识图"},Qs={key:1,class:"chip chip-app ml-1"},Ys={class:"svc-prov"},Zs={class:"svc-cost"},et={key:1,class:"text-slate-300"},st=["checked","disabled","title","onChange"],tt=["checked","disabled","onChange"],lt={class:"svc-acts"},nt=["onClick"],at=["onClick"],it={class:"modal-box max-w-md"},ot={class:"font-bold text-lg"},dt={class:"mt-4 space-y-3"},ut={class:"form-control"},ct=["value"],rt={key:0,class:"text-[11px] text-amber-600 mt-1"},vt={class:"form-control"},bt={class:"label py-1"},_t={class:"label-text text-sm font-medium"},mt={key:0,class:"flex gap-4"},gt={class:"flex items-center gap-2 cursor-pointer"},pt={class:"flex items-center gap-2 cursor-pointer"},ht={class:"modal-action"},ft=["disabled"],kt={class:"modal-box max-w-sm"},xt={class:"text-xs text-slate-400 mt-1"},yt={class:"modal-action"},wt=["disabled"],Ct=Ee({__name:"meetingsvc",setup($t){const{webApi:D,consoleApi:xe}=Be(),{success:J,error:M}=je(),ue=[{value:1,label:"中国"},{value:2,label:"美国"},{value:3,label:"东亚"},{value:4,label:"东南亚"},{value:5,label:"南亚"},{value:6,label:"中东"},{value:7,label:"欧洲"},{value:8,label:"俄罗斯"},{value:9,label:"非洲"},{value:10,label:"南美"},{value:11,label:"北美"},{value:12,label:"大洋洲"},{value:13,label:"巴西"},{value:14,label:"印度"}];function ye(l){return ue.find(e=>e.value===l)?.label??"区域"+l}const Q=m([]),$=m(""),N=m(0),B=m([]),I=m([]),Y=m({1:[8],2:[3],3:[5,9]}),U=m(!1),ce=m(!1),Z=m(!1),E=m(!1),r=m(!1),f=m("zh-CN"),T=m(null),z=m(null),k=m(1),v=ke({svc_id:"",cost_hint:0,is_default:!1,client_visible:!1}),y=ke({row_id:0,name:"",kind:1,cost_hint:0});function G(l){return l===1?"识别":l===2?"翻译":"总结"}function re(l){return l===1?"元/小时":l===2?"元/百万字符":"元/百万token"}function H(l){return de.find(e=>e.code===l)?.name??l}function ve(l,e){return(l||"").split(",").map(t=>Number(t.trim())).includes(e)}const K=O(()=>{const l=new Map;for(const e of I.value)l.set(e.id,e);return l});function w(l){return K.value.get(l)?.name??l}function ee(l){return K.value.get(l)?.provider??"?"}function L(l){return K.value.get(l)?.languages??""}function we(l){return ve(K.value.get(l)?.categories??"",9)}function b(l){return B.value.filter(e=>e.kind===l).sort((e,t)=>e.priority-t.priority)}function j(l){const e=Y.value[String(l)]??[],t=new Set(B.value.filter(o=>o.kind===l).map(o=>o.svc_id));return I.value.filter(o=>!t.has(o.id)&&o.categories.split(",").some(u=>e.includes(Number(u.trim()))))}function R(l,e){const t=L(l);return t?t.split(",").map(o=>o.trim()).includes(e):!0}const x=O(()=>b(1).find(l=>l.enabled&&R(l.svc_id,f.value))??null),A=O(()=>b(2).find(l=>l.enabled)??null);function Ce(l){return x.value?.row_id!==l.row_id&&(!l.enabled||!R(l.svc_id,f.value))}function $e(l){return x.value?.row_id===l.row_id?"ok":!l.enabled||!R(l.svc_id,f.value)?"no":""}function Ne(l){return x.value?.row_id===l.row_id?L(l.svc_id)?`✓ 当前源语言(${H(f.value)})由它承接`:"✓ 未限定语言,先落到它(实际支持由引擎判断)":l.enabled?R(l.svc_id,f.value)?"备用:前面都跳过时接手":`不支持 ${H(f.value)}(${f.value}),跳过 → 顺延下一个`:"已停用,跳过"}const _=O(()=>{const l=[],e=[];let t=0;for(const u of[1,2,3]){const V=b(u).filter(ie=>ie.enabled);if(!V.length){l.push(u);continue}const W=new Set;let ge=!1;for(const ie of V){const pe=L(ie.svc_id).split(",").map(oe=>oe.trim()).filter(Boolean);if(!pe.length){ge=!0;break}pe.forEach(oe=>W.add(oe))}ge?t++:e.push({kind:u,langs:[...W]})}if(!e.length)return{missing:l,unlimited:!0,langs:[],groups:e,unlimitedKinds:t};const o=e.reduce((u,V)=>u.filter(W=>V.langs.includes(W)),[...e[0].langs]).sort((u,V)=>be(u)-be(V));return{missing:l,unlimited:!1,langs:o,groups:e,unlimitedKinds:t}});function be(l){const e=de.findIndex(t=>t.code===l);return e<0?Number.MAX_SAFE_INTEGER:e}const Ae=O(()=>{const l=[];for(const e of[1,2,3]){if(_.value.missing.includes(e)){l.push(`${G(e)} 未配置`);continue}const t=_.value.groups.find(o=>o.kind===e);l.push(`${G(e)} ${t?t.langs.length+" 种":"全语种"}`)}return l.join(" ∩ ")}),X=O(()=>b(3).find(l=>l.is_default)??null),se=O(()=>b(3).filter(l=>l.enabled&&l.client_visible));async function Ve(){try{const l=await xe("products/list",{});Q.value=(l??[]).map(e=>e.name).filter(Boolean)}catch{Q.value=[]}}async function p(){Z.value=!0;try{const l=await D("getechoorch",{app_name:$.value,region:N.value});B.value=l?.items??[],I.value=l?.available??[],Y.value=l?.kind_cats??Y.value,U.value=!!l?.setting?.llm_client_choice,ce.value=(!!$.value||N.value!==0)&&(B.value.length>0||U.value)}catch(l){M(l?.message??"加载失败")}finally{Z.value=!1}}async function te(l){await D("saveechoorch",{app_name:$.value,region:N.value,orch:l})}function le(l){k.value=l,v.svc_id="",v.cost_hint=0,v.is_default=!1,v.client_visible=!1,T.value?.showModal()}async function Se(){if(v.svc_id){E.value=!0;try{const l=b(k.value),e=l.length?l[l.length-1].priority+10:10;await te({kind:k.value,svc_id:v.svc_id,priority:e,cost_hint:Number(v.cost_hint)||0,is_default:k.value===3?v.is_default:!1,client_visible:k.value===3?v.client_visible:!1,enabled:!0}),J("已添加"),T.value?.close(),await p()}catch(l){M(l?.message??"添加失败")}finally{E.value=!1}}}async function F(l,e){r.value=!0;try{await te({...l,...e}),await p()}catch(t){M(t?.message??"操作失败"),await p()}finally{r.value=!1}}async function ne(l){if(confirm(`从本段移除「${w(l.svc_id)}」?(不影响第三方服务配置里的服务本身)`))try{await D("delechoorch",{row_id:l.row_id}),J("已移除"),await p()}catch(e){M(e?.message??"移除失败")}}async function _e(l){r.value=!0;try{await D("reorderechoorch",{items:l.map((e,t)=>({row_id:e.row_id,priority:(t+1)*10}))}),await p()}catch(e){M(e?.message??"排序失败"),await p()}finally{r.value=!1}}function P(l,e,t){const o=[...b(l)],u=e+t;if(u<0||u>=o.length)return;const V=o[e];o[e]=o[u],o[u]=V,_e(o)}function me(l){const e=[...b(l)].sort((t,o)=>t.enabled!==o.enabled?t.enabled?-1:1:(t.cost_hint||Number.MAX_VALUE)-(o.cost_hint||Number.MAX_VALUE));_e(e)}function ae(l){y.row_id=l.row_id,y.name=w(l.svc_id),y.kind=l.kind,y.cost_hint=l.cost_hint,z.value?.showModal()}async function Me(){const l=B.value.find(e=>e.row_id===y.row_id);if(l){E.value=!0;try{await te({...l,cost_hint:Number(y.cost_hint)||0}),J("已保存"),z.value?.close(),await p()}catch(e){M(e?.message??"保存失败")}finally{E.value=!1}}}async function Ue(){r.value=!0;try{await D("saveechoorchsetting",{app_name:$.value,region:N.value,llm_client_choice:!U.value}),await p()}catch(l){M(l?.message??"保存失败"),await p()}finally{r.value=!1}}return Le(async()=>{await Ve(),await p()}),(l,e)=>(a(),n("div",null,[e[45]||(e[45]=s("div",{class:"flex items-start justify-between mb-4 flex-wrap gap-3"},[s("div",null,[s("h2",{class:"text-lg font-semibold text-slate-800"},"会议记录服务"),s("p",{class:"text-xs text-slate-400 mt-1 max-w-3xl"},[d(" 识别 / 翻译 / 总结三段,从"),s("b",null,"第三方服务配置"),d("里选已配好的服务来编排(不再单独填凭据)。 "),s("span",{class:"text-slate-500"},"先配「全局默认」作兜底,再按应用 / 区域覆盖"),d("——没配覆盖的应用自动继承全局默认。 ")])])],-1)),s("div",Fe,[s("div",Ie,[e[17]||(e[17]=s("span",{class:"text-xs text-slate-500 font-semibold"},"作用域",-1)),S(s("select",{"onUpdate:modelValue":e[0]||(e[0]=t=>$.value=t),class:"select select-bordered select-sm",onChange:p},[e[15]||(e[15]=s("option",{value:""},"全局默认(兜底)",-1)),(a(!0),n(c,null,C(Q.value,t=>(a(),n("option",{key:t,value:t},"应用:"+i(t),9,Te))),128))],544),[[q,$.value]]),S(s("select",{"onUpdate:modelValue":e[1]||(e[1]=t=>N.value=t),class:"select select-bordered select-sm",onChange:p},[e[16]||(e[16]=s("option",{value:0},"全区域",-1)),(a(),n(c,null,C(ue,t=>s("option",{key:t.value,value:t.value},i(t.label),9,ze)),64))],544),[[q,N.value,void 0,{number:!0}]])]),s("span",Ge,[d(i($.value?`正在编辑「${$.value}」`:"正在编辑全局默认")+i(N.value?` · ${ye(N.value)}`:" · 全区域")+" ",1),ce.value?(a(),n(c,{key:0},[d("(覆盖全局默认)")],64)):g("",!0)])]),Z.value?(a(),n("div",He,[...e[18]||(e[18]=[s("span",{class:"loading loading-spinner loading-sm"},null,-1)])])):(a(),n(c,{key:1},[s("div",{class:h(["langsum",{bad:!_.value.unlimited&&!_.value.langs.length,warn:_.value.missing.length}])},[s("div",Ke,[e[19]||(e[19]=s("span",{class:"langsum-title"},"当前配置支持的语言",-1)),_.value.unlimited?(a(),n("span",{key:0,class:h(["langsum-count",{off:_.value.missing.length}])},"未限定(各引擎自行判断)",2)):(a(),n("span",{key:1,class:h(["langsum-count",{off:_.value.missing.length}])},[d(i(_.value.langs.length)+" 种",1),_.value.missing.length?(a(),n(c,{key:0},[d("(链路未配全,尚不可用)")],64)):g("",!0)],2)),s("span",Re,i(Ae.value),1)]),_.value.missing.length?(a(),n("div",Xe," ⚠ "+i(_.value.missing.map(G).join("、"))+"段没有启用中的服务,整条链路走不通——先把这些段配上。 ",1)):!_.value.unlimited&&!_.value.langs.length?(a(),n("div",Pe," ⚠ 各段语言无交集,任何语种都走不完整条链路。放宽某一段的支持语言,或补一个覆盖面更广的服务。 ")):g("",!0),_.value.langs.length?(a(),n("div",We,[(a(!0),n(c,null,C(_.value.langs,t=>(a(),n("span",{key:t,class:"lang on",title:H(t)},i(t),9,qe))),128))])):_.value.unlimited&&!_.value.missing.length?(a(),n("div",Je," 各段都没限定支持语言(服务未填 languages 字段),实际能否处理由引擎判断。 ")):g("",!0)],2),I.value.length?g("",!0):(a(),n("div",Qe,[...e[20]||(e[20]=[s("span",null,[d(" 该作用域没有可选服务。先去"),s("b",null,"第三方服务配置"),d("添加「录音文件识别 / 机器翻译 / 文本或多媒体大模型」类的服务 (全局默认或该应用作用域),这里才能选。 ")],-1)])])),s("div",Ye,[s("div",Ze,[e[21]||(e[21]=s("div",null,[s("div",{class:"card-title"},"识别(录音文件转写)"),s("div",{class:"card-desc"},[d("按顺序找"),s("b",null,"第一个「已启用 + 支持源语言」"),d('的服务,不支持则跳到下一个。把便宜的排前面即"优先用性价比高的"。')])],-1)),s("div",es,[s("button",{class:"btn btn-xs",disabled:b(1).length<2||r.value,onClick:e[2]||(e[2]=t=>me(1))},"⇅ 按参考单价重排",8,ss),s("button",{class:"btn btn-primary btn-xs text-white",disabled:!j(1).length,onClick:e[3]||(e[3]=t=>le(1))},"+ 添加识别服务",8,ts)])]),s("div",ls,[e[22]||(e[22]=s("span",{class:"text-xs text-slate-500 font-semibold"},"选路预览",-1)),S(s("select",{"onUpdate:modelValue":e[4]||(e[4]=t=>f.value=t),class:"select select-bordered select-xs w-44 text-xs"},[(a(!0),n(c,null,C(Oe(de),t=>(a(),n("option",{key:t.code,value:t.code},i(t.code)+" · "+i(t.name),9,ns))),128))],512),[[q,f.value]]),x.value?(a(),n("span",as,[d("命中 "+i(w(x.value.svc_id)),1),x.value.cost_hint?(a(),n(c,{key:0},[d(" · ¥"+i(x.value.cost_hint)+"/时",1)],64)):g("",!0)])):(a(),n("span",is,"无可用服务 —— "+i(H(f.value))+" 会转写失败",1))]),b(1).length?g("",!0):(a(),n("div",os,"暂无识别服务,点右上「+ 添加识别服务」")),(a(!0),n(c,null,C(b(1),(t,o)=>(a(),n("div",{key:t.row_id,class:h(["svc asr",{hit:x.value&&x.value.row_id===t.row_id,off:!t.enabled}])},[s("div",{class:h(["svc-rank",{hit:x.value&&x.value.row_id===t.row_id}])},i(o+1),3),s("div",ds,[s("div",{class:h(["svc-name",{skip:Ce(t)}])},i(w(t.svc_id)),3),s("div",us,i(ee(t.svc_id))+" · "+i(t.svc_id),1)]),s("div",cs,[L(t.svc_id)?(a(),n(c,{key:0},[(a(!0),n(c,null,C(L(t.svc_id).split(",").slice(0,5),u=>(a(),n("span",{key:u,class:h(["lang",{on:u===f.value}])},i(u),3))),128)),L(t.svc_id).split(",").length>5?(a(),n("span",rs,"+"+i(L(t.svc_id).split(",").length-5),1)):g("",!0)],64)):(a(),n("span",vs,"未限定"))]),s("div",bs,[t.cost_hint?(a(),n(c,{key:0},[d("¥"+i(t.cost_hint),1),e[23]||(e[23]=s("small",null," /时",-1))],64)):(a(),n("span",_s,"—"))]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.enabled,disabled:r.value,onChange:u=>F(t,{enabled:!t.enabled})},null,40,ms)]),s("div",gs,[s("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>P(1,o,-1)},"↑",8,ps),s("button",{class:"arrow",disabled:o===b(1).length-1||r.value,"aria-label":"下移",onClick:u=>P(1,o,1)},"↓",8,hs),s("button",{class:"btn btn-ghost btn-xs",onClick:u=>ae(t)},"单价",8,fs),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ne(t)},"移除",8,ks)]),s("div",{class:h(["svc-why",$e(t)])},i(Ne(t)),3)],2))),128))]),s("div",xs,[s("div",ys,[e[24]||(e[24]=s("div",null,[s("div",{class:"card-title"},"翻译"),s("div",{class:"card-desc"},[d("按顺序取"),s("b",null,"第一个已启用"),d("的服务;调用失败自动回退下一个。")])],-1)),s("div",ws,[s("button",{class:"btn btn-xs",disabled:b(2).length<2||r.value,onClick:e[5]||(e[5]=t=>me(2))},"⇅ 按参考单价重排",8,Cs),s("button",{class:"btn btn-primary btn-xs text-white",disabled:!j(2).length,onClick:e[6]||(e[6]=t=>le(2))},"+ 添加翻译服务",8,$s)])]),b(2).length?g("",!0):(a(),n("div",Ns,"暂无翻译服务")),(a(!0),n(c,null,C(b(2),(t,o)=>(a(),n("div",{key:t.row_id,class:h(["svc mt",{hit:A.value&&A.value.row_id===t.row_id,off:!t.enabled}])},[s("div",{class:h(["svc-rank",{hit:A.value&&A.value.row_id===t.row_id}])},i(o+1),3),s("div",As,[s("div",Vs,i(w(t.svc_id)),1),s("div",Ss,i(ee(t.svc_id))+" · "+i(t.svc_id),1)]),s("div",Ms,[t.cost_hint?(a(),n(c,{key:0},[d("¥"+i(t.cost_hint),1),e[25]||(e[25]=s("small",null," /百万字符",-1))],64)):(a(),n("span",Us,"—"))]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.enabled,disabled:r.value,onChange:u=>F(t,{enabled:!t.enabled})},null,40,Es)]),s("div",Ls,[s("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>P(2,o,-1)},"↑",8,Os),s("button",{class:"arrow",disabled:o===b(2).length-1||r.value,"aria-label":"下移",onClick:u=>P(2,o,1)},"↓",8,Ds),s("button",{class:"btn btn-ghost btn-xs",onClick:u=>ae(t)},"单价",8,Bs),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ne(t)},"移除",8,js)]),s("div",{class:h(["svc-why",t.enabled?A.value&&A.value.row_id===t.row_id?"ok":"":"no"])},[t.enabled?A.value&&A.value.row_id===t.row_id?(a(),n(c,{key:1},[d("✓ 默认由它承接,失败顺延")],64)):(a(),n(c,{key:2},[d("备用:前面失败时接手")],64)):(a(),n(c,{key:0},[d("已停用,跳过")],64))],2)],2))),128))]),s("div",Fs,[s("div",Is,[e[26]||(e[26]=s("div",null,[s("div",{class:"card-title"},"总结(大模型)"),s("div",{class:"card-desc"},[d("后台指定默认模型,客户端可在允许范围内自选。带 🖼 的是"),s("b",null,"多媒体大模型"),d(",能识别会议里的图片。")])],-1)),s("button",{class:"btn btn-primary btn-xs text-white shrink-0",disabled:!j(3).length,onClick:e[7]||(e[7]=t=>le(3))},"+ 添加模型",8,Ts)]),s("div",zs,[s("label",Gs,[s("input",{type:"checkbox",class:"toggle toggle-primary toggle-sm",checked:U.value,disabled:r.value,onChange:Ue},null,40,Hs),e[27]||(e[27]=s("span",{class:"text-sm font-semibold text-slate-700"},"允许客户端指定模型",-1))]),s("p",Ks,[U.value?(a(),n(c,{key:0},[e[28]||(e[28]=d(" 前端能选 ",-1)),s("b",null,i(se.value.length),1),e[29]||(e[29]=d(" 个模型",-1)),se.value.length?(a(),n(c,{key:0},[d(":"+i(se.value.map(t=>w(t.svc_id)).join("、")),1)],64)):(a(),n(c,{key:1},[d("(一个都没勾「前端可见」,等同强制默认)")],64)),e[30]||(e[30]=d("。不传则用默认 ",-1)),s("b",null,i(X.value?w(X.value.svc_id):"—"),1),e[31]||(e[31]=d("。 ",-1))],64)):(a(),n(c,{key:1},[e[32]||(e[32]=d(" 前端不下发模型列表,一律走默认模型 ",-1)),s("b",null,i(X.value?w(X.value.svc_id):"—"),1),e[33]||(e[33]=d(";客户端传了也忽略。 ",-1))],64))])]),b(3).length?g("",!0):(a(),n("div",Rs,"暂无模型")),(a(!0),n(c,null,C(b(3),t=>(a(),n("div",{key:t.row_id,class:h(["svc llm",{isdefault:t.is_default,off:!t.enabled}])},[s("div",Xs,[s("input",{type:"radio",name:"llmdef",class:"radio radio-primary radio-xs",checked:t.is_default,disabled:!t.enabled||r.value,onChange:o=>F(t,{is_default:!0})},null,40,Ps)]),s("div",Ws,[s("div",qs,[d(i(w(t.svc_id))+" ",1),we(t.svc_id)?(a(),n("span",Js,"🖼")):g("",!0),t.is_default?(a(),n("span",Qs,"默认")):g("",!0)]),s("div",Ys,i(ee(t.svc_id))+" · "+i(t.svc_id),1)]),s("div",Zs,[t.cost_hint?(a(),n(c,{key:0},[d("¥"+i(t.cost_hint),1),e[34]||(e[34]=s("small",null," /百万token",-1))],64)):(a(),n("span",et,"—"))]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.client_visible,disabled:!U.value||!t.enabled||r.value,title:U.value?"":"先打开「允许客户端指定模型」",onChange:o=>F(t,{client_visible:!t.client_visible})},null,40,st)]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.enabled,disabled:r.value,onChange:o=>F(t,{enabled:!t.enabled})},null,40,tt)]),s("div",lt,[s("button",{class:"btn btn-ghost btn-xs",onClick:o=>ae(t)},"单价",8,nt),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:o=>ne(t)},"移除",8,at)])],2))),128)),e[35]||(e[35]=s("div",{class:"col-h llm-h"},[s("div"),s("div"),s("div",null,"参考单价"),s("div",null,"前端可见"),s("div",null,"启用"),s("div")],-1))])],64)),s("dialog",{ref_key:"addDlg",ref:T,class:"modal"},[s("div",it,[s("h3",ot,"添加"+i(G(k.value))+"服务",1),e[41]||(e[41]=s("p",{class:"text-xs text-slate-400 mt-1"},"从第三方服务配置里选一个已配好的服务加入本段编排。",-1)),s("div",dt,[s("div",ut,[e[37]||(e[37]=s("label",{class:"label py-1"},[s("span",{class:"label-text text-sm font-medium"},"服务")],-1)),S(s("select",{"onUpdate:modelValue":e[8]||(e[8]=t=>v.svc_id=t),class:"select select-bordered select-sm"},[e[36]||(e[36]=s("option",{value:""},"请选择服务…",-1)),(a(!0),n(c,null,C(j(k.value),t=>(a(),n("option",{key:t.id,value:t.id},i(t.name)+i(k.value===3&&ve(t.categories,9)?" 🖼":"")+"("+i(t.provider||t.id)+") ",9,ct))),128))],512),[[q,v.svc_id]]),j(k.value).length?g("",!0):(a(),n("span",rt,"没有可添加的服务了(都加过了,或服务池里没这类服务)。"))]),s("div",vt,[s("label",bt,[s("span",_t,"参考单价("+i(re(k.value))+",可空)",1)]),S(s("input",{"onUpdate:modelValue":e[9]||(e[9]=t=>v.cost_hint=t),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm font-mono text-xs",placeholder:"0"},null,512),[[he,v.cost_hint,void 0,{number:!0}]]),e[38]||(e[38]=s("span",{class:"text-[11px] text-slate-400 mt-1"},"仅用于排序/展示,填你的实付价。",-1))]),k.value===3?(a(),n("div",mt,[s("label",gt,[S(s("input",{"onUpdate:modelValue":e[10]||(e[10]=t=>v.is_default=t),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[fe,v.is_default]]),e[39]||(e[39]=s("span",{class:"text-sm"},"设为默认",-1))]),s("label",pt,[S(s("input",{"onUpdate:modelValue":e[11]||(e[11]=t=>v.client_visible=t),type:"checkbox",class:"toggle toggle-success toggle-sm"},null,512),[[fe,v.client_visible]]),e[40]||(e[40]=s("span",{class:"text-sm"},"前端可见",-1))])])):g("",!0)]),s("div",ht,[s("button",{class:"btn btn-ghost btn-sm",onClick:e[12]||(e[12]=t=>T.value?.close())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",disabled:!v.svc_id||E.value,onClick:Se},i(E.value?"添加中…":"添加"),9,ft)])]),e[42]||(e[42]=s("form",{method:"dialog",class:"modal-backdrop"},[s("button",null,"close")],-1))],512),s("dialog",{ref_key:"costDlg",ref:z,class:"modal"},[s("div",kt,[e[43]||(e[43]=s("h3",{class:"font-bold text-lg"},"参考单价",-1)),s("p",xt,i(y.name)+"("+i(re(y.kind))+")",1),S(s("input",{"onUpdate:modelValue":e[13]||(e[13]=t=>y.cost_hint=t),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm w-full font-mono text-xs mt-3",placeholder:"0"},null,512),[[he,y.cost_hint,void 0,{number:!0}]]),s("div",yt,[s("button",{class:"btn btn-ghost btn-sm",onClick:e[14]||(e[14]=t=>z.value?.close())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",disabled:E.value,onClick:Me},"保存",8,wt)])]),e[44]||(e[44]=s("form",{method:"dialog",class:"modal-backdrop"},[s("button",null,"close")],-1))],512)]))}}),Mt=De(Ct,[["__scopeId","data-v-512b8191"]]);export{Mt as default}; +import{g as Ee,C as Le,c as n,a as s,d,q as S,s as q,F as c,r as C,t as i,l as g,n as h,m as Oe,v as he,x as fe,y as m,z as ke,A as O,o as a,_ as De}from"./DSy_gLdM.js";import{u as Be}from"./NtXZuCUg.js";import{u as je}from"./EeX3zgoF.js";import{L as de}from"./DD3V9C6_.js";const Fe={class:"scopebar"},Ie={class:"flex items-center gap-2"},Te=["value"],ze=["value"],Ge={class:"text-[11px] text-slate-400"},He={key:0,class:"bg-white rounded-xl border border-slate-100 py-16 text-center"},Ke={class:"langsum-head"},Re={class:"langsum-formula"},Xe={key:0,class:"langsum-msg bad"},Pe={key:1,class:"langsum-msg bad"},We={key:2,class:"langsum-langs"},qe=["title"],Je={key:3,class:"langsum-msg"},Qe={key:0,class:"alert alert-warning py-2 text-sm mb-4"},Ye={class:"card"},Ze={class:"card-head"},es={class:"flex gap-2 shrink-0"},ss=["disabled"],ts=["disabled"],ls={class:"probe-bar"},ns=["value"],as={key:0,class:"probe-out"},is={key:1,class:"probe-out bad"},os={key:0,class:"py-10 text-center text-slate-400 text-sm"},ds={class:"min-w-0"},us={class:"svc-prov"},cs={class:"flex flex-wrap gap-1"},rs={key:0,class:"lang"},vs={key:1,class:"text-[11px] text-slate-400"},bs={class:"svc-cost"},_s={key:1,class:"text-slate-300"},ms=["checked","disabled","onChange"],gs={class:"svc-acts"},ps=["disabled","onClick"],hs=["disabled","onClick"],fs=["onClick"],ks=["onClick"],xs={class:"card mt-4"},ys={class:"card-head"},ws={class:"flex gap-2 shrink-0"},Cs=["disabled"],$s=["disabled"],Ns={key:0,class:"py-10 text-center text-slate-400 text-sm"},As={class:"min-w-0"},Vs={class:"svc-name"},Ss={class:"svc-prov"},Ms={class:"svc-cost"},Us={key:1,class:"text-slate-300"},Es=["checked","disabled","onChange"],Ls={class:"svc-acts"},Os=["disabled","onClick"],Ds=["disabled","onClick"],Bs=["onClick"],js=["onClick"],Fs={class:"card mt-4"},Is={class:"card-head"},Ts=["disabled"],zs={class:"mode-bar"},Gs={class:"flex items-center gap-2 cursor-pointer shrink-0"},Hs=["checked","disabled"],Ks={class:"mode-txt"},Rs={key:0,class:"py-10 text-center text-slate-400 text-sm"},Xs={class:"grid place-items-center"},Ps=["checked","disabled","onChange"],Ws={class:"min-w-0"},qs={class:"svc-name"},Js={key:0,title:"多媒体大模型,能识图"},Qs={key:1,class:"chip chip-app ml-1"},Ys={class:"svc-prov"},Zs={class:"svc-cost"},et={key:1,class:"text-slate-300"},st=["checked","disabled","title","onChange"],tt=["checked","disabled","onChange"],lt={class:"svc-acts"},nt=["onClick"],at=["onClick"],it={class:"modal-box max-w-md"},ot={class:"font-bold text-lg"},dt={class:"mt-4 space-y-3"},ut={class:"form-control"},ct=["value"],rt={key:0,class:"text-[11px] text-amber-600 mt-1"},vt={class:"form-control"},bt={class:"label py-1"},_t={class:"label-text text-sm font-medium"},mt={key:0,class:"flex gap-4"},gt={class:"flex items-center gap-2 cursor-pointer"},pt={class:"flex items-center gap-2 cursor-pointer"},ht={class:"modal-action"},ft=["disabled"],kt={class:"modal-box max-w-sm"},xt={class:"text-xs text-slate-400 mt-1"},yt={class:"modal-action"},wt=["disabled"],Ct=Ee({__name:"meetingsvc",setup($t){const{webApi:D,consoleApi:xe}=Be(),{success:J,error:M}=je(),ue=[{value:1,label:"中国"},{value:2,label:"美国"},{value:3,label:"东亚"},{value:4,label:"东南亚"},{value:5,label:"南亚"},{value:6,label:"中东"},{value:7,label:"欧洲"},{value:8,label:"俄罗斯"},{value:9,label:"非洲"},{value:10,label:"南美"},{value:11,label:"北美"},{value:12,label:"大洋洲"},{value:13,label:"巴西"},{value:14,label:"印度"}];function ye(l){return ue.find(e=>e.value===l)?.label??"区域"+l}const Q=m([]),$=m(""),N=m(0),B=m([]),I=m([]),Y=m({1:[8],2:[3],3:[5,9]}),U=m(!1),ce=m(!1),Z=m(!1),E=m(!1),r=m(!1),f=m("zh-CN"),T=m(null),z=m(null),k=m(1),v=ke({svc_id:"",cost_hint:0,is_default:!1,client_visible:!1}),y=ke({row_id:0,name:"",kind:1,cost_hint:0});function G(l){return l===1?"识别":l===2?"翻译":"总结"}function re(l){return l===1?"元/小时":l===2?"元/百万字符":"元/百万token"}function H(l){return de.find(e=>e.code===l)?.name??l}function ve(l,e){return(l||"").split(",").map(t=>Number(t.trim())).includes(e)}const K=O(()=>{const l=new Map;for(const e of I.value)l.set(e.id,e);return l});function w(l){return K.value.get(l)?.name??l}function ee(l){return K.value.get(l)?.provider??"?"}function L(l){return K.value.get(l)?.languages??""}function we(l){return ve(K.value.get(l)?.categories??"",9)}function b(l){return B.value.filter(e=>e.kind===l).sort((e,t)=>e.priority-t.priority)}function j(l){const e=Y.value[String(l)]??[],t=new Set(B.value.filter(o=>o.kind===l).map(o=>o.svc_id));return I.value.filter(o=>!t.has(o.id)&&o.categories.split(",").some(u=>e.includes(Number(u.trim()))))}function R(l,e){const t=L(l);return t?t.split(",").map(o=>o.trim()).includes(e):!0}const x=O(()=>b(1).find(l=>l.enabled&&R(l.svc_id,f.value))??null),A=O(()=>b(2).find(l=>l.enabled)??null);function Ce(l){return x.value?.row_id!==l.row_id&&(!l.enabled||!R(l.svc_id,f.value))}function $e(l){return x.value?.row_id===l.row_id?"ok":!l.enabled||!R(l.svc_id,f.value)?"no":""}function Ne(l){return x.value?.row_id===l.row_id?L(l.svc_id)?`✓ 当前源语言(${H(f.value)})由它承接`:"✓ 未限定语言,先落到它(实际支持由引擎判断)":l.enabled?R(l.svc_id,f.value)?"备用:前面都跳过时接手":`不支持 ${H(f.value)}(${f.value}),跳过 → 顺延下一个`:"已停用,跳过"}const _=O(()=>{const l=[],e=[];let t=0;for(const u of[1,2,3]){const V=b(u).filter(ie=>ie.enabled);if(!V.length){l.push(u);continue}const W=new Set;let ge=!1;for(const ie of V){const pe=L(ie.svc_id).split(",").map(oe=>oe.trim()).filter(Boolean);if(!pe.length){ge=!0;break}pe.forEach(oe=>W.add(oe))}ge?t++:e.push({kind:u,langs:[...W]})}if(!e.length)return{missing:l,unlimited:!0,langs:[],groups:e,unlimitedKinds:t};const o=e.reduce((u,V)=>u.filter(W=>V.langs.includes(W)),[...e[0].langs]).sort((u,V)=>be(u)-be(V));return{missing:l,unlimited:!1,langs:o,groups:e,unlimitedKinds:t}});function be(l){const e=de.findIndex(t=>t.code===l);return e<0?Number.MAX_SAFE_INTEGER:e}const Ae=O(()=>{const l=[];for(const e of[1,2,3]){if(_.value.missing.includes(e)){l.push(`${G(e)} 未配置`);continue}const t=_.value.groups.find(o=>o.kind===e);l.push(`${G(e)} ${t?t.langs.length+" 种":"全语种"}`)}return l.join(" ∩ ")}),X=O(()=>b(3).find(l=>l.is_default)??null),se=O(()=>b(3).filter(l=>l.enabled&&l.client_visible));async function Ve(){try{const l=await xe("products/list",{});Q.value=(l??[]).map(e=>e.name).filter(Boolean)}catch{Q.value=[]}}async function p(){Z.value=!0;try{const l=await D("getechoorch",{app_name:$.value,region:N.value});B.value=l?.items??[],I.value=l?.available??[],Y.value=l?.kind_cats??Y.value,U.value=!!l?.setting?.llm_client_choice,ce.value=(!!$.value||N.value!==0)&&(B.value.length>0||U.value)}catch(l){M(l?.message??"加载失败")}finally{Z.value=!1}}async function te(l){await D("saveechoorch",{app_name:$.value,region:N.value,orch:l})}function le(l){k.value=l,v.svc_id="",v.cost_hint=0,v.is_default=!1,v.client_visible=!1,T.value?.showModal()}async function Se(){if(v.svc_id){E.value=!0;try{const l=b(k.value),e=l.length?l[l.length-1].priority+10:10;await te({kind:k.value,svc_id:v.svc_id,priority:e,cost_hint:Number(v.cost_hint)||0,is_default:k.value===3?v.is_default:!1,client_visible:k.value===3?v.client_visible:!1,enabled:!0}),J("已添加"),T.value?.close(),await p()}catch(l){M(l?.message??"添加失败")}finally{E.value=!1}}}async function F(l,e){r.value=!0;try{await te({...l,...e}),await p()}catch(t){M(t?.message??"操作失败"),await p()}finally{r.value=!1}}async function ne(l){if(confirm(`从本段移除「${w(l.svc_id)}」?(不影响第三方服务配置里的服务本身)`))try{await D("delechoorch",{row_id:l.row_id}),J("已移除"),await p()}catch(e){M(e?.message??"移除失败")}}async function _e(l){r.value=!0;try{await D("reorderechoorch",{items:l.map((e,t)=>({row_id:e.row_id,priority:(t+1)*10}))}),await p()}catch(e){M(e?.message??"排序失败"),await p()}finally{r.value=!1}}function P(l,e,t){const o=[...b(l)],u=e+t;if(u<0||u>=o.length)return;const V=o[e];o[e]=o[u],o[u]=V,_e(o)}function me(l){const e=[...b(l)].sort((t,o)=>t.enabled!==o.enabled?t.enabled?-1:1:(t.cost_hint||Number.MAX_VALUE)-(o.cost_hint||Number.MAX_VALUE));_e(e)}function ae(l){y.row_id=l.row_id,y.name=w(l.svc_id),y.kind=l.kind,y.cost_hint=l.cost_hint,z.value?.showModal()}async function Me(){const l=B.value.find(e=>e.row_id===y.row_id);if(l){E.value=!0;try{await te({...l,cost_hint:Number(y.cost_hint)||0}),J("已保存"),z.value?.close(),await p()}catch(e){M(e?.message??"保存失败")}finally{E.value=!1}}}async function Ue(){r.value=!0;try{await D("saveechoorchsetting",{app_name:$.value,region:N.value,llm_client_choice:!U.value}),await p()}catch(l){M(l?.message??"保存失败"),await p()}finally{r.value=!1}}return Le(async()=>{await Ve(),await p()}),(l,e)=>(a(),n("div",null,[e[45]||(e[45]=s("div",{class:"flex items-start justify-between mb-4 flex-wrap gap-3"},[s("div",null,[s("h2",{class:"text-lg font-semibold text-slate-800"},"会议记录服务"),s("p",{class:"text-xs text-slate-400 mt-1 max-w-3xl"},[d(" 识别 / 翻译 / 总结三段,从"),s("b",null,"第三方服务配置"),d("里选已配好的服务来编排(不再单独填凭据)。 "),s("span",{class:"text-slate-500"},"先配「全局默认」作兜底,再按应用 / 区域覆盖"),d("——没配覆盖的应用自动继承全局默认。 ")])])],-1)),s("div",Fe,[s("div",Ie,[e[17]||(e[17]=s("span",{class:"text-xs text-slate-500 font-semibold"},"作用域",-1)),S(s("select",{"onUpdate:modelValue":e[0]||(e[0]=t=>$.value=t),class:"select select-bordered select-sm",onChange:p},[e[15]||(e[15]=s("option",{value:""},"全局默认(兜底)",-1)),(a(!0),n(c,null,C(Q.value,t=>(a(),n("option",{key:t,value:t},"应用:"+i(t),9,Te))),128))],544),[[q,$.value]]),S(s("select",{"onUpdate:modelValue":e[1]||(e[1]=t=>N.value=t),class:"select select-bordered select-sm",onChange:p},[e[16]||(e[16]=s("option",{value:0},"全区域",-1)),(a(),n(c,null,C(ue,t=>s("option",{key:t.value,value:t.value},i(t.label),9,ze)),64))],544),[[q,N.value,void 0,{number:!0}]])]),s("span",Ge,[d(i($.value?`正在编辑「${$.value}」`:"正在编辑全局默认")+i(N.value?` · ${ye(N.value)}`:" · 全区域")+" ",1),ce.value?(a(),n(c,{key:0},[d("(覆盖全局默认)")],64)):g("",!0)])]),Z.value?(a(),n("div",He,[...e[18]||(e[18]=[s("span",{class:"loading loading-spinner loading-sm"},null,-1)])])):(a(),n(c,{key:1},[s("div",{class:h(["langsum",{bad:!_.value.unlimited&&!_.value.langs.length,warn:_.value.missing.length}])},[s("div",Ke,[e[19]||(e[19]=s("span",{class:"langsum-title"},"当前配置支持的语言",-1)),_.value.unlimited?(a(),n("span",{key:0,class:h(["langsum-count",{off:_.value.missing.length}])},"未限定(各引擎自行判断)",2)):(a(),n("span",{key:1,class:h(["langsum-count",{off:_.value.missing.length}])},[d(i(_.value.langs.length)+" 种",1),_.value.missing.length?(a(),n(c,{key:0},[d("(链路未配全,尚不可用)")],64)):g("",!0)],2)),s("span",Re,i(Ae.value),1)]),_.value.missing.length?(a(),n("div",Xe," ⚠ "+i(_.value.missing.map(G).join("、"))+"段没有启用中的服务,整条链路走不通——先把这些段配上。 ",1)):!_.value.unlimited&&!_.value.langs.length?(a(),n("div",Pe," ⚠ 各段语言无交集,任何语种都走不完整条链路。放宽某一段的支持语言,或补一个覆盖面更广的服务。 ")):g("",!0),_.value.langs.length?(a(),n("div",We,[(a(!0),n(c,null,C(_.value.langs,t=>(a(),n("span",{key:t,class:"lang on",title:H(t)},i(t),9,qe))),128))])):_.value.unlimited&&!_.value.missing.length?(a(),n("div",Je," 各段都没限定支持语言(服务未填 languages 字段),实际能否处理由引擎判断。 ")):g("",!0)],2),I.value.length?g("",!0):(a(),n("div",Qe,[...e[20]||(e[20]=[s("span",null,[d(" 该作用域没有可选服务。先去"),s("b",null,"第三方服务配置"),d("添加「录音文件识别 / 机器翻译 / 文本或多媒体大模型」类的服务 (全局默认或该应用作用域),这里才能选。 ")],-1)])])),s("div",Ye,[s("div",Ze,[e[21]||(e[21]=s("div",null,[s("div",{class:"card-title"},"识别(录音文件转写)"),s("div",{class:"card-desc"},[d("按顺序找"),s("b",null,"第一个「已启用 + 支持源语言」"),d('的服务,不支持则跳到下一个。把便宜的排前面即"优先用性价比高的"。')])],-1)),s("div",es,[s("button",{class:"btn btn-xs",disabled:b(1).length<2||r.value,onClick:e[2]||(e[2]=t=>me(1))},"⇅ 按参考单价重排",8,ss),s("button",{class:"btn btn-primary btn-xs text-white",disabled:!j(1).length,onClick:e[3]||(e[3]=t=>le(1))},"+ 添加识别服务",8,ts)])]),s("div",ls,[e[22]||(e[22]=s("span",{class:"text-xs text-slate-500 font-semibold"},"选路预览",-1)),S(s("select",{"onUpdate:modelValue":e[4]||(e[4]=t=>f.value=t),class:"select select-bordered select-xs w-44 text-xs"},[(a(!0),n(c,null,C(Oe(de),t=>(a(),n("option",{key:t.code,value:t.code},i(t.code)+" · "+i(t.name),9,ns))),128))],512),[[q,f.value]]),x.value?(a(),n("span",as,[d("命中 "+i(w(x.value.svc_id)),1),x.value.cost_hint?(a(),n(c,{key:0},[d(" · ¥"+i(x.value.cost_hint)+"/时",1)],64)):g("",!0)])):(a(),n("span",is,"无可用服务 —— "+i(H(f.value))+" 会转写失败",1))]),b(1).length?g("",!0):(a(),n("div",os,"暂无识别服务,点右上「+ 添加识别服务」")),(a(!0),n(c,null,C(b(1),(t,o)=>(a(),n("div",{key:t.row_id,class:h(["svc asr",{hit:x.value&&x.value.row_id===t.row_id,off:!t.enabled}])},[s("div",{class:h(["svc-rank",{hit:x.value&&x.value.row_id===t.row_id}])},i(o+1),3),s("div",ds,[s("div",{class:h(["svc-name",{skip:Ce(t)}])},i(w(t.svc_id)),3),s("div",us,i(ee(t.svc_id))+" · "+i(t.svc_id),1)]),s("div",cs,[L(t.svc_id)?(a(),n(c,{key:0},[(a(!0),n(c,null,C(L(t.svc_id).split(",").slice(0,5),u=>(a(),n("span",{key:u,class:h(["lang",{on:u===f.value}])},i(u),3))),128)),L(t.svc_id).split(",").length>5?(a(),n("span",rs,"+"+i(L(t.svc_id).split(",").length-5),1)):g("",!0)],64)):(a(),n("span",vs,"未限定"))]),s("div",bs,[t.cost_hint?(a(),n(c,{key:0},[d("¥"+i(t.cost_hint),1),e[23]||(e[23]=s("small",null," /时",-1))],64)):(a(),n("span",_s,"—"))]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.enabled,disabled:r.value,onChange:u=>F(t,{enabled:!t.enabled})},null,40,ms)]),s("div",gs,[s("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>P(1,o,-1)},"↑",8,ps),s("button",{class:"arrow",disabled:o===b(1).length-1||r.value,"aria-label":"下移",onClick:u=>P(1,o,1)},"↓",8,hs),s("button",{class:"btn btn-ghost btn-xs",onClick:u=>ae(t)},"单价",8,fs),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ne(t)},"移除",8,ks)]),s("div",{class:h(["svc-why",$e(t)])},i(Ne(t)),3)],2))),128))]),s("div",xs,[s("div",ys,[e[24]||(e[24]=s("div",null,[s("div",{class:"card-title"},"翻译"),s("div",{class:"card-desc"},[d("按顺序取"),s("b",null,"第一个已启用"),d("的服务;调用失败自动回退下一个。")])],-1)),s("div",ws,[s("button",{class:"btn btn-xs",disabled:b(2).length<2||r.value,onClick:e[5]||(e[5]=t=>me(2))},"⇅ 按参考单价重排",8,Cs),s("button",{class:"btn btn-primary btn-xs text-white",disabled:!j(2).length,onClick:e[6]||(e[6]=t=>le(2))},"+ 添加翻译服务",8,$s)])]),b(2).length?g("",!0):(a(),n("div",Ns,"暂无翻译服务")),(a(!0),n(c,null,C(b(2),(t,o)=>(a(),n("div",{key:t.row_id,class:h(["svc mt",{hit:A.value&&A.value.row_id===t.row_id,off:!t.enabled}])},[s("div",{class:h(["svc-rank",{hit:A.value&&A.value.row_id===t.row_id}])},i(o+1),3),s("div",As,[s("div",Vs,i(w(t.svc_id)),1),s("div",Ss,i(ee(t.svc_id))+" · "+i(t.svc_id),1)]),s("div",Ms,[t.cost_hint?(a(),n(c,{key:0},[d("¥"+i(t.cost_hint),1),e[25]||(e[25]=s("small",null," /百万字符",-1))],64)):(a(),n("span",Us,"—"))]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.enabled,disabled:r.value,onChange:u=>F(t,{enabled:!t.enabled})},null,40,Es)]),s("div",Ls,[s("button",{class:"arrow",disabled:o===0||r.value,"aria-label":"上移",onClick:u=>P(2,o,-1)},"↑",8,Os),s("button",{class:"arrow",disabled:o===b(2).length-1||r.value,"aria-label":"下移",onClick:u=>P(2,o,1)},"↓",8,Ds),s("button",{class:"btn btn-ghost btn-xs",onClick:u=>ae(t)},"单价",8,Bs),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:u=>ne(t)},"移除",8,js)]),s("div",{class:h(["svc-why",t.enabled?A.value&&A.value.row_id===t.row_id?"ok":"":"no"])},[t.enabled?A.value&&A.value.row_id===t.row_id?(a(),n(c,{key:1},[d("✓ 默认由它承接,失败顺延")],64)):(a(),n(c,{key:2},[d("备用:前面失败时接手")],64)):(a(),n(c,{key:0},[d("已停用,跳过")],64))],2)],2))),128))]),s("div",Fs,[s("div",Is,[e[26]||(e[26]=s("div",null,[s("div",{class:"card-title"},"总结(大模型)"),s("div",{class:"card-desc"},[d("后台指定默认模型,客户端可在允许范围内自选。带 🖼 的是"),s("b",null,"多媒体大模型"),d(",能识别会议里的图片。")])],-1)),s("button",{class:"btn btn-primary btn-xs text-white shrink-0",disabled:!j(3).length,onClick:e[7]||(e[7]=t=>le(3))},"+ 添加模型",8,Ts)]),s("div",zs,[s("label",Gs,[s("input",{type:"checkbox",class:"toggle toggle-primary toggle-sm",checked:U.value,disabled:r.value,onChange:Ue},null,40,Hs),e[27]||(e[27]=s("span",{class:"text-sm font-semibold text-slate-700"},"允许客户端指定模型",-1))]),s("p",Ks,[U.value?(a(),n(c,{key:0},[e[28]||(e[28]=d(" 前端能选 ",-1)),s("b",null,i(se.value.length),1),e[29]||(e[29]=d(" 个模型",-1)),se.value.length?(a(),n(c,{key:0},[d(":"+i(se.value.map(t=>w(t.svc_id)).join("、")),1)],64)):(a(),n(c,{key:1},[d("(一个都没勾「前端可见」,等同强制默认)")],64)),e[30]||(e[30]=d("。不传则用默认 ",-1)),s("b",null,i(X.value?w(X.value.svc_id):"—"),1),e[31]||(e[31]=d("。 ",-1))],64)):(a(),n(c,{key:1},[e[32]||(e[32]=d(" 前端不下发模型列表,一律走默认模型 ",-1)),s("b",null,i(X.value?w(X.value.svc_id):"—"),1),e[33]||(e[33]=d(";客户端传了也忽略。 ",-1))],64))])]),b(3).length?g("",!0):(a(),n("div",Rs,"暂无模型")),(a(!0),n(c,null,C(b(3),t=>(a(),n("div",{key:t.row_id,class:h(["svc llm",{isdefault:t.is_default,off:!t.enabled}])},[s("div",Xs,[s("input",{type:"radio",name:"llmdef",class:"radio radio-primary radio-xs",checked:t.is_default,disabled:!t.enabled||r.value,onChange:o=>F(t,{is_default:!0})},null,40,Ps)]),s("div",Ws,[s("div",qs,[d(i(w(t.svc_id))+" ",1),we(t.svc_id)?(a(),n("span",Js,"🖼")):g("",!0),t.is_default?(a(),n("span",Qs,"默认")):g("",!0)]),s("div",Ys,i(ee(t.svc_id))+" · "+i(t.svc_id),1)]),s("div",Zs,[t.cost_hint?(a(),n(c,{key:0},[d("¥"+i(t.cost_hint),1),e[34]||(e[34]=s("small",null," /百万token",-1))],64)):(a(),n("span",et,"—"))]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.client_visible,disabled:!U.value||!t.enabled||r.value,title:U.value?"":"先打开「允许客户端指定模型」",onChange:o=>F(t,{client_visible:!t.client_visible})},null,40,st)]),s("div",null,[s("input",{type:"checkbox",class:"toggle toggle-success toggle-sm",checked:t.enabled,disabled:r.value,onChange:o=>F(t,{enabled:!t.enabled})},null,40,tt)]),s("div",lt,[s("button",{class:"btn btn-ghost btn-xs",onClick:o=>ae(t)},"单价",8,nt),s("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:o=>ne(t)},"移除",8,at)])],2))),128)),e[35]||(e[35]=s("div",{class:"col-h llm-h"},[s("div"),s("div"),s("div",null,"参考单价"),s("div",null,"前端可见"),s("div",null,"启用"),s("div")],-1))])],64)),s("dialog",{ref_key:"addDlg",ref:T,class:"modal"},[s("div",it,[s("h3",ot,"添加"+i(G(k.value))+"服务",1),e[41]||(e[41]=s("p",{class:"text-xs text-slate-400 mt-1"},"从第三方服务配置里选一个已配好的服务加入本段编排。",-1)),s("div",dt,[s("div",ut,[e[37]||(e[37]=s("label",{class:"label py-1"},[s("span",{class:"label-text text-sm font-medium"},"服务")],-1)),S(s("select",{"onUpdate:modelValue":e[8]||(e[8]=t=>v.svc_id=t),class:"select select-bordered select-sm"},[e[36]||(e[36]=s("option",{value:""},"请选择服务…",-1)),(a(!0),n(c,null,C(j(k.value),t=>(a(),n("option",{key:t.id,value:t.id},i(t.name)+i(k.value===3&&ve(t.categories,9)?" 🖼":"")+"("+i(t.provider||t.id)+") ",9,ct))),128))],512),[[q,v.svc_id]]),j(k.value).length?g("",!0):(a(),n("span",rt,"没有可添加的服务了(都加过了,或服务池里没这类服务)。"))]),s("div",vt,[s("label",bt,[s("span",_t,"参考单价("+i(re(k.value))+",可空)",1)]),S(s("input",{"onUpdate:modelValue":e[9]||(e[9]=t=>v.cost_hint=t),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm font-mono text-xs",placeholder:"0"},null,512),[[he,v.cost_hint,void 0,{number:!0}]]),e[38]||(e[38]=s("span",{class:"text-[11px] text-slate-400 mt-1"},"仅用于排序/展示,填你的实付价。",-1))]),k.value===3?(a(),n("div",mt,[s("label",gt,[S(s("input",{"onUpdate:modelValue":e[10]||(e[10]=t=>v.is_default=t),type:"checkbox",class:"toggle toggle-primary toggle-sm"},null,512),[[fe,v.is_default]]),e[39]||(e[39]=s("span",{class:"text-sm"},"设为默认",-1))]),s("label",pt,[S(s("input",{"onUpdate:modelValue":e[11]||(e[11]=t=>v.client_visible=t),type:"checkbox",class:"toggle toggle-success toggle-sm"},null,512),[[fe,v.client_visible]]),e[40]||(e[40]=s("span",{class:"text-sm"},"前端可见",-1))])])):g("",!0)]),s("div",ht,[s("button",{class:"btn btn-ghost btn-sm",onClick:e[12]||(e[12]=t=>T.value?.close())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",disabled:!v.svc_id||E.value,onClick:Se},i(E.value?"添加中…":"添加"),9,ft)])]),e[42]||(e[42]=s("form",{method:"dialog",class:"modal-backdrop"},[s("button",null,"close")],-1))],512),s("dialog",{ref_key:"costDlg",ref:z,class:"modal"},[s("div",kt,[e[43]||(e[43]=s("h3",{class:"font-bold text-lg"},"参考单价",-1)),s("p",xt,i(y.name)+"("+i(re(y.kind))+")",1),S(s("input",{"onUpdate:modelValue":e[13]||(e[13]=t=>y.cost_hint=t),type:"number",step:"0.01",min:"0",class:"input input-bordered input-sm w-full font-mono text-xs mt-3",placeholder:"0"},null,512),[[he,y.cost_hint,void 0,{number:!0}]]),s("div",yt,[s("button",{class:"btn btn-ghost btn-sm",onClick:e[14]||(e[14]=t=>z.value?.close())},"取消"),s("button",{class:"btn btn-primary btn-sm text-white",disabled:E.value,onClick:Me},"保存",8,wt)])]),e[44]||(e[44]=s("form",{method:"dialog",class:"modal-backdrop"},[s("button",null,"close")],-1))],512)]))}}),Mt=De(Ct,[["__scopeId","data-v-512b8191"]]);export{Mt as default}; diff --git a/apps/admin/.output/public/_nuxt/DhTcVEsy.js b/apps/admin/.output/public/_nuxt/Bm2Gu08J.js similarity index 94% rename from apps/admin/.output/public/_nuxt/DhTcVEsy.js rename to apps/admin/.output/public/_nuxt/Bm2Gu08J.js index 0eb868df..5341b251 100644 --- a/apps/admin/.output/public/_nuxt/DhTcVEsy.js +++ b/apps/admin/.output/public/_nuxt/Bm2Gu08J.js @@ -1 +1 @@ -import{_ as s}from"./DBs5psLk.js";import{_ as a,o as i,c as u,a as t,t as n,b as c,w as l,d}from"./DMxDLVSv.js";import{u as f}from"./CYxZMiFx.js";const p={class:"antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide"},m={class:"max-w-520px text-center"},h=["textContent"],b=["textContent"],x=["textContent"],g={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},status:{type:Number,default:404},statusText:{type:String,default:"Page not found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(e){const r=e;return f({title:`${r.status} - ${r.statusText} | ${r.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{box-sizing:border-box;border-width:0;border-style:solid;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}h1,h2{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(k,_)=>{const o=s;return i(),u("div",p,[t("div",m,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:n(e.status)},null,8,h),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:n(e.statusText)},null,8,b),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:n(e.description)},null,8,x),t("div",g,[c(o,{to:"/",class:"font-medium hover:text-[#00DC82] text-sm underline underline-offset-3"},{default:l(()=>[d(n(e.backHome),1)]),_:1})])])])}}},z=a(y,[["__scopeId","data-v-52418c85"]]);export{z as default}; +import{_ as s}from"./32rNuZwS.js";import{_ as a,o as i,c as u,a as t,t as n,b as c,w as l,d}from"./DSy_gLdM.js";import{u as f}from"./obp34o1K.js";const p={class:"antialiased bg-white dark:bg-[#020420] dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-[#020420] tracking-wide"},m={class:"max-w-520px text-center"},h=["textContent"],b=["textContent"],x=["textContent"],g={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},status:{type:Number,default:404},statusText:{type:String,default:"Page not found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(e){const r=e;return f({title:`${r.status} - ${r.statusText} | ${r.appName}`,script:[{innerHTML:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)}).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{innerHTML:'*,:after,:before{box-sizing:border-box;border-width:0;border-style:solid;border-color:var(--un-default-border-color,#e5e7eb)}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}h1,h2{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}h1,h2,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(k,_)=>{const o=s;return i(),u("div",p,[t("div",m,[t("h1",{class:"font-semibold leading-none mb-4 sm:text-[110px] tabular-nums text-[80px]",textContent:n(e.status)},null,8,h),t("h2",{class:"font-semibold mb-2 sm:text-3xl text-2xl",textContent:n(e.statusText)},null,8,b),t("p",{class:"mb-4 px-2 text-[#64748B] text-md",textContent:n(e.description)},null,8,x),t("div",g,[c(o,{to:"/",class:"font-medium hover:text-[#00DC82] text-sm underline underline-offset-3"},{default:l(()=>[d(n(e.backHome),1)]),_:1})])])])}}},z=a(y,[["__scopeId","data-v-52418c85"]]);export{z as default}; diff --git a/apps/admin/.output/public/_nuxt/DWZBXvpA.js b/apps/admin/.output/public/_nuxt/Bp86Q8ON.js similarity index 98% rename from apps/admin/.output/public/_nuxt/DWZBXvpA.js rename to apps/admin/.output/public/_nuxt/Bp86Q8ON.js index 34dc7525..122e6885 100644 --- a/apps/admin/.output/public/_nuxt/DWZBXvpA.js +++ b/apps/admin/.output/public/_nuxt/Bp86Q8ON.js @@ -1 +1 @@ -import{_ as J}from"./DiAHNWP8.js";import{g as Q,j as W,C as X,c as a,q as r,H as R,a as t,l as v,F as y,r as _,t as i,p as S,v as m,s as Y,O as Z,m as tt,x as et,b as st,y as u,z as lt,A as j,o,d as nt}from"./DMxDLVSv.js";import{u as at}from"./CCZrj3X-.js";import{u as ot}from"./B-sqZCu-.js";const rt={class:"flex items-center justify-between mb-5"},it={class:"bg-white rounded-xl shadow-sm border border-slate-100"},dt={class:"overflow-x-auto"},ut={class:"table table-zebra"},ct={key:0},mt={key:1},pt={class:"font-mono text-sm"},bt={class:"font-medium"},vt={class:"badge badge-ghost badge-sm"},ft={class:"text-sm"},xt={class:"text-sm"},ht={key:1,class:"text-slate-300"},gt={class:"text-sm text-slate-500"},wt={class:"flex gap-1"},yt=["onClick"],_t=["onClick"],kt={class:"flex items-center gap-3 mb-5"},Ct={class:"text-lg font-semibold text-slate-800"},Nt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},At={class:"form-control mb-4"},Ut={class:"form-control mb-4"},Vt=["value"],Mt={class:"form-control mb-4"},$t={class:"form-control mb-4"},Bt={class:"form-control mb-6"},Pt={class:"space-y-2"},Lt={key:0,class:"text-xs text-slate-400"},Et={class:"badge badge-lg gap-1 bg-slate-100 border-slate-200"},Rt=["onClick"],St={class:"flex gap-2 mt-2"},jt=["onKeydown"],Dt={key:0,class:"form-control mb-6 border-t border-slate-100 pt-4"},Ft=["placeholder"],Tt={class:"label-text-alt text-slate-400 mt-1"},qt={key:1,class:"form-control mb-6 border-t border-slate-100 pt-4"},zt={class:"flex items-center gap-2 cursor-pointer"},It={key:0,class:"grid grid-cols-2 gap-3 mt-3"},Kt={class:"col-span-2"},Ot={key:0,class:"col-span-2 text-xs text-amber-600"},Ht={class:"flex gap-3"},Gt=["disabled"],Jt="358030594@qq.com",te=Q({__name:"factory",setup(Qt){const{webApi:x}=at(),{success:k,error:C,warn:D}=ot(),F=W(),h=u("list"),g=u([]),w=u([]),N=u(!1),A=u(!1),c=u(!1),d=u([]),f=u(""),s=lt({id:0,brand:"",providerid:0,description:"",sharepct:0,officialChannelName:"",createAccount:!1,accountUsername:"",accountPassword:"",accountRemark:""}),B=j(()=>(s.brand.trim()||"品牌")+"官方渠道"),T=j(()=>d.value.filter(l=>l.toLowerCase()!==Jt)),U=u(null);function q(l){return((Number(l)||0)/100).toFixed(2)+"%"}function z(l){return l?Number(l).toString(16).toUpperCase():""}function V(l){return(l||"").split(",").map(e=>e.trim()).filter(Boolean)}function I(l){if(!l)return"-";const e=w.value.find(p=>p.id===l);return e?e.name:"方案商#"+l}async function K(){try{const l=await x("getsolutionproviders",{});w.value=l?.providers??[]}catch{w.value=[]}}async function M(){N.value=!0;try{await K();const l=await x("getbrands",{});g.value=l?.brands??[]}catch(l){C(l?.message??"获取品牌商列表失败"),g.value=[]}finally{N.value=!1}}function $(){h.value="list",M()}function P(l){l?(c.value=!0,s.id=l.id,s.brand=l.brand||"",s.providerid=l.providerid||0,s.description=l.description||"",s.sharepct=(Number(l.sharerate)||0)/100,d.value=V(l.contactmails)):(c.value=!1,s.id=0,s.brand="",s.providerid=0,s.description="",s.sharepct=0,d.value=[]),s.officialChannelName="",s.createAccount=!1,s.accountUsername="",s.accountPassword="",s.accountRemark="",f.value="",h.value="form"}function L(){const l=f.value.trim();if(l){if(d.value.includes(l)){D("邮箱已存在");return}d.value.push(l),f.value=""}}function O(l){d.value.splice(l,1)}async function H(){A.value=!0;try{const l={brand:{brand:s.brand,providerid:Number(s.providerid)||0,description:s.description,sharerate:Math.round((Number(s.sharepct)||0)*100),contactmails:d.value.join(",")}};c.value?l.brand.id=Number(s.id):(l.official_channel_name=s.officialChannelName.trim(),l.create_account=s.createAccount,s.createAccount&&(l.account_username=s.accountUsername.trim(),l.account_password=s.accountPassword,l.account_remark=s.accountRemark.trim()));const e=await x(c.value?"updatebrand":"addbrand",l);if(c.value)k("保存成功");else{const p=["品牌商已创建"];e?.channel?.id&&p.push(`官方渠道「${e.channel.name}」(${e.channel.id})`),k(p.join(",")),e?.account&&(U.value={title:`品牌账号「${e.account}」已创建`,username:e.account,password:e.account_password??"",mailTo:e.mail_to??"",mailError:e.mail_error??""})}$()}catch(l){C(l?.message??"保存失败")}finally{A.value=!1}}function G(l){window.confirm(`确定删除品牌商 "${l.brand}" 吗?`)&&x("delbrand",{id:l.id}).then(()=>{k("删除成功"),M()}).catch(e=>C(e?.message??"删除失败"))}return X(M),(l,e)=>{const p=J;return o(),a("div",null,[r(t("div",null,[t("div",rt,[e[14]||(e[14]=t("h2",{class:"text-lg font-semibold text-slate-800"},"品牌商列表",-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:e[0]||(e[0]=n=>P())},"+ 新增品牌商")]),t("div",it,[t("div",dt,[t("table",ut,[e[17]||(e[17]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"品牌名称"),t("th",null,"归属方案商"),t("th",null,"分成比例"),t("th",null,"联系邮箱"),t("th",null,"产品"),t("th",null,"操作")])],-1)),t("tbody",null,[N.value?(o(),a("tr",ct,[...e[15]||(e[15]=[t("td",{colspan:"7",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):g.value.length?v("",!0):(o(),a("tr",mt,[...e[16]||(e[16]=[t("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(o(!0),a(y,null,_(g.value,n=>(o(),a("tr",{key:n.id},[t("td",pt,i(z(n.id)),1),t("td",bt,i(n.brand),1),t("td",null,[t("span",vt,i(I(n.providerid)),1)]),t("td",ft,i(q(n.sharerate)),1),t("td",xt,[V(n.contactmails).length?(o(!0),a(y,{key:0},_(V(n.contactmails),(b,E)=>(o(),a("span",{key:E,class:"badge badge-ghost badge-sm mr-1"},i(b),1))),128)):(o(),a("span",ht,"-"))]),t("td",gt,i(n.productlists||""),1),t("td",null,[t("div",wt,[t("button",{class:"btn btn-ghost btn-xs",onClick:b=>P(n)},"编辑",8,yt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:b=>G(n)},"删除",8,_t)])])]))),128))])])])])],512),[[R,h.value==="list"]]),r(t("div",null,[t("div",kt,[t("button",{class:"btn btn-ghost btn-sm",onClick:e[1]||(e[1]=n=>$())},"← 返回列表"),t("h2",Ct,i(c.value?"编辑品牌商":"新增品牌商"),1)]),t("div",Nt,[t("form",{onSubmit:S(H,["prevent"])},[t("div",At,[e[18]||(e[18]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"品牌名称 *")],-1)),r(t("input",{"onUpdate:modelValue":e[2]||(e[2]=n=>s.brand=n),type:"text",class:"input input-bordered w-full",required:""},null,512),[[m,s.brand]])]),t("div",Ut,[e[20]||(e[20]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"归属方案商")],-1)),r(t("select",{"onUpdate:modelValue":e[3]||(e[3]=n=>s.providerid=n),class:"select select-bordered w-full"},[e[19]||(e[19]=t("option",{value:0},"请选择方案商",-1)),(o(!0),a(y,null,_(w.value,n=>(o(),a("option",{key:n.id,value:n.id},i(n.name),9,Vt))),128))],512),[[Y,s.providerid,void 0,{number:!0}]])]),t("div",Mt,[e[21]||(e[21]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"分成比例(%)")],-1)),r(t("input",{"onUpdate:modelValue":e[4]||(e[4]=n=>s.sharepct=n),type:"number",step:"0.01",min:"0",max:"100",class:"input input-bordered w-full"},null,512),[[m,s.sharepct,void 0,{number:!0}]]),e[22]||(e[22]=t("span",{class:"label-text-alt text-slate-400 mt-1"},"平台从订单实付里分给该品牌商的总提成;其名下渠道商再从这份里切自己的比例。",-1))]),t("div",$t,[e[23]||(e[23]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"描述")],-1)),r(t("textarea",{"onUpdate:modelValue":e[5]||(e[5]=n=>s.description=n),class:"textarea textarea-bordered w-full",rows:"3"},null,512),[[m,s.description]])]),t("div",Bt,[e[25]||(e[25]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系邮箱")],-1)),t("div",Pt,[d.value.length?v("",!0):(o(),a("p",Lt,"暂无邮箱")),(o(!0),a(y,null,_(d.value,(n,b)=>(o(),a("div",{key:b,class:"flex items-center gap-2"},[t("span",Et,[e[24]||(e[24]=t("svg",{class:"h-3 w-3 text-slate-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})],-1)),nt(" "+i(n),1)]),t("button",{type:"button",class:"btn btn-ghost btn-xs text-red-400 hover:text-red-600",onClick:E=>O(b)},"×",8,Rt)]))),128))]),t("div",St,[r(t("input",{"onUpdate:modelValue":e[6]||(e[6]=n=>f.value=n),type:"email",class:"input input-bordered input-sm flex-1",placeholder:"输入邮箱地址",onKeydown:Z(S(L,["prevent"]),["enter"])},null,40,jt),[[m,f.value]]),t("button",{type:"button",class:"btn btn-outline btn-sm btn-primary",onClick:L},"添加")])]),c.value?v("",!0):(o(),a("div",Dt,[e[26]||(e[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"品牌官方渠道")],-1)),r(t("input",{"onUpdate:modelValue":e[7]||(e[7]=n=>s.officialChannelName=n),type:"text",class:"input input-bordered w-full",placeholder:B.value},null,8,Ft),[[m,s.officialChannelName]]),t("span",Tt," 新建品牌商时自动创建一条该品牌自己的渠道(直接启用、分成 0%、不创建渠道账号),用于品牌直销的授权码归属;留空则叫「"+i(B.value)+"」。 ",1)])),!c.value&&tt(F).isAdmin?(o(),a("div",qt,[t("label",zt,[r(t("input",{"onUpdate:modelValue":e[8]||(e[8]=n=>s.createAccount=n),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[et,s.createAccount]]),e[27]||(e[27]=t("span",{class:"label-text font-medium"},"同时创建品牌账号",-1))]),e[31]||(e[31]=t("span",{class:"label-text-alt text-slate-400 mt-1"}," 建一个绑定本品牌商的「品牌商」角色登录账号,可见本品牌及名下全部渠道商的数据。 用户名/密码留空则自动生成,创建后凭据会邮件发给上面填的品牌商联系邮箱。 ",-1)),s.createAccount?(o(),a("div",It,[t("div",null,[e[28]||(e[28]=t("label",{class:"text-xs text-slate-500"},"登录用户名",-1)),r(t("input",{"onUpdate:modelValue":e[9]||(e[9]=n=>s.accountUsername=n),type:"text",class:"input input-bordered input-sm w-full",placeholder:"留空自动生成,如 Brand-A001",autocomplete:"off"},null,512),[[m,s.accountUsername]])]),t("div",null,[e[29]||(e[29]=t("label",{class:"text-xs text-slate-500"},"登录密码",-1)),r(t("input",{"onUpdate:modelValue":e[10]||(e[10]=n=>s.accountPassword=n),type:"text",class:"input input-bordered input-sm w-full font-mono",placeholder:"留空自动生成 12 位随机密码",autocomplete:"off"},null,512),[[m,s.accountPassword]])]),t("div",Kt,[e[30]||(e[30]=t("label",{class:"text-xs text-slate-500"},"备注",-1)),r(t("input",{"onUpdate:modelValue":e[11]||(e[11]=n=>s.accountRemark=n),type:"text",class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[m,s.accountRemark]])]),T.value.length?v("",!0):(o(),a("p",Ot," 当前没有填品牌商自己的联系邮箱(平台默认邮箱不算),凭据将无法邮件送达,只会在创建后弹窗显示一次。 "))])):v("",!0)])):v("",!0),t("div",Ht,[t("button",{type:"button",class:"btn btn-ghost",onClick:e[12]||(e[12]=n=>$())},"取消"),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:A.value},"保存",8,Gt)])],32)])],512),[[R,h.value==="form"]]),st(p,{info:U.value,onClose:e[13]||(e[13]=n=>U.value=null)},null,8,["info"])])}}});export{te as default}; +import{_ as J}from"./DVest5s8.js";import{g as Q,j as W,C as X,c as a,q as r,H as R,a as t,l as v,F as y,r as _,t as i,p as S,v as m,s as Y,O as Z,m as tt,x as et,b as st,y as u,z as lt,A as j,o,d as nt}from"./DSy_gLdM.js";import{u as at}from"./NtXZuCUg.js";import{u as ot}from"./EeX3zgoF.js";const rt={class:"flex items-center justify-between mb-5"},it={class:"bg-white rounded-xl shadow-sm border border-slate-100"},dt={class:"overflow-x-auto"},ut={class:"table table-zebra"},ct={key:0},mt={key:1},pt={class:"font-mono text-sm"},bt={class:"font-medium"},vt={class:"badge badge-ghost badge-sm"},ft={class:"text-sm"},xt={class:"text-sm"},ht={key:1,class:"text-slate-300"},gt={class:"text-sm text-slate-500"},wt={class:"flex gap-1"},yt=["onClick"],_t=["onClick"],kt={class:"flex items-center gap-3 mb-5"},Ct={class:"text-lg font-semibold text-slate-800"},Nt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},At={class:"form-control mb-4"},Ut={class:"form-control mb-4"},Vt=["value"],Mt={class:"form-control mb-4"},$t={class:"form-control mb-4"},Bt={class:"form-control mb-6"},Pt={class:"space-y-2"},Lt={key:0,class:"text-xs text-slate-400"},Et={class:"badge badge-lg gap-1 bg-slate-100 border-slate-200"},Rt=["onClick"],St={class:"flex gap-2 mt-2"},jt=["onKeydown"],Dt={key:0,class:"form-control mb-6 border-t border-slate-100 pt-4"},Ft=["placeholder"],Tt={class:"label-text-alt text-slate-400 mt-1"},qt={key:1,class:"form-control mb-6 border-t border-slate-100 pt-4"},zt={class:"flex items-center gap-2 cursor-pointer"},It={key:0,class:"grid grid-cols-2 gap-3 mt-3"},Kt={class:"col-span-2"},Ot={key:0,class:"col-span-2 text-xs text-amber-600"},Ht={class:"flex gap-3"},Gt=["disabled"],Jt="358030594@qq.com",te=Q({__name:"factory",setup(Qt){const{webApi:x}=at(),{success:k,error:C,warn:D}=ot(),F=W(),h=u("list"),g=u([]),w=u([]),N=u(!1),A=u(!1),c=u(!1),d=u([]),f=u(""),s=lt({id:0,brand:"",providerid:0,description:"",sharepct:0,officialChannelName:"",createAccount:!1,accountUsername:"",accountPassword:"",accountRemark:""}),B=j(()=>(s.brand.trim()||"品牌")+"官方渠道"),T=j(()=>d.value.filter(l=>l.toLowerCase()!==Jt)),U=u(null);function q(l){return((Number(l)||0)/100).toFixed(2)+"%"}function z(l){return l?Number(l).toString(16).toUpperCase():""}function V(l){return(l||"").split(",").map(e=>e.trim()).filter(Boolean)}function I(l){if(!l)return"-";const e=w.value.find(p=>p.id===l);return e?e.name:"方案商#"+l}async function K(){try{const l=await x("getsolutionproviders",{});w.value=l?.providers??[]}catch{w.value=[]}}async function M(){N.value=!0;try{await K();const l=await x("getbrands",{});g.value=l?.brands??[]}catch(l){C(l?.message??"获取品牌商列表失败"),g.value=[]}finally{N.value=!1}}function $(){h.value="list",M()}function P(l){l?(c.value=!0,s.id=l.id,s.brand=l.brand||"",s.providerid=l.providerid||0,s.description=l.description||"",s.sharepct=(Number(l.sharerate)||0)/100,d.value=V(l.contactmails)):(c.value=!1,s.id=0,s.brand="",s.providerid=0,s.description="",s.sharepct=0,d.value=[]),s.officialChannelName="",s.createAccount=!1,s.accountUsername="",s.accountPassword="",s.accountRemark="",f.value="",h.value="form"}function L(){const l=f.value.trim();if(l){if(d.value.includes(l)){D("邮箱已存在");return}d.value.push(l),f.value=""}}function O(l){d.value.splice(l,1)}async function H(){A.value=!0;try{const l={brand:{brand:s.brand,providerid:Number(s.providerid)||0,description:s.description,sharerate:Math.round((Number(s.sharepct)||0)*100),contactmails:d.value.join(",")}};c.value?l.brand.id=Number(s.id):(l.official_channel_name=s.officialChannelName.trim(),l.create_account=s.createAccount,s.createAccount&&(l.account_username=s.accountUsername.trim(),l.account_password=s.accountPassword,l.account_remark=s.accountRemark.trim()));const e=await x(c.value?"updatebrand":"addbrand",l);if(c.value)k("保存成功");else{const p=["品牌商已创建"];e?.channel?.id&&p.push(`官方渠道「${e.channel.name}」(${e.channel.id})`),k(p.join(",")),e?.account&&(U.value={title:`品牌账号「${e.account}」已创建`,username:e.account,password:e.account_password??"",mailTo:e.mail_to??"",mailError:e.mail_error??""})}$()}catch(l){C(l?.message??"保存失败")}finally{A.value=!1}}function G(l){window.confirm(`确定删除品牌商 "${l.brand}" 吗?`)&&x("delbrand",{id:l.id}).then(()=>{k("删除成功"),M()}).catch(e=>C(e?.message??"删除失败"))}return X(M),(l,e)=>{const p=J;return o(),a("div",null,[r(t("div",null,[t("div",rt,[e[14]||(e[14]=t("h2",{class:"text-lg font-semibold text-slate-800"},"品牌商列表",-1)),t("button",{class:"btn btn-primary btn-sm text-white",onClick:e[0]||(e[0]=n=>P())},"+ 新增品牌商")]),t("div",it,[t("div",dt,[t("table",ut,[e[17]||(e[17]=t("thead",null,[t("tr",null,[t("th",null,"ID"),t("th",null,"品牌名称"),t("th",null,"归属方案商"),t("th",null,"分成比例"),t("th",null,"联系邮箱"),t("th",null,"产品"),t("th",null,"操作")])],-1)),t("tbody",null,[N.value?(o(),a("tr",ct,[...e[15]||(e[15]=[t("td",{colspan:"7",class:"text-center py-8"},[t("span",{class:"loading loading-spinner loading-sm"})],-1)])])):g.value.length?v("",!0):(o(),a("tr",mt,[...e[16]||(e[16]=[t("td",{colspan:"7",class:"text-center text-slate-400 py-8"},"暂无数据",-1)])])),(o(!0),a(y,null,_(g.value,n=>(o(),a("tr",{key:n.id},[t("td",pt,i(z(n.id)),1),t("td",bt,i(n.brand),1),t("td",null,[t("span",vt,i(I(n.providerid)),1)]),t("td",ft,i(q(n.sharerate)),1),t("td",xt,[V(n.contactmails).length?(o(!0),a(y,{key:0},_(V(n.contactmails),(b,E)=>(o(),a("span",{key:E,class:"badge badge-ghost badge-sm mr-1"},i(b),1))),128)):(o(),a("span",ht,"-"))]),t("td",gt,i(n.productlists||""),1),t("td",null,[t("div",wt,[t("button",{class:"btn btn-ghost btn-xs",onClick:b=>P(n)},"编辑",8,yt),t("button",{class:"btn btn-ghost btn-xs text-red-500",onClick:b=>G(n)},"删除",8,_t)])])]))),128))])])])])],512),[[R,h.value==="list"]]),r(t("div",null,[t("div",kt,[t("button",{class:"btn btn-ghost btn-sm",onClick:e[1]||(e[1]=n=>$())},"← 返回列表"),t("h2",Ct,i(c.value?"编辑品牌商":"新增品牌商"),1)]),t("div",Nt,[t("form",{onSubmit:S(H,["prevent"])},[t("div",At,[e[18]||(e[18]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"品牌名称 *")],-1)),r(t("input",{"onUpdate:modelValue":e[2]||(e[2]=n=>s.brand=n),type:"text",class:"input input-bordered w-full",required:""},null,512),[[m,s.brand]])]),t("div",Ut,[e[20]||(e[20]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"归属方案商")],-1)),r(t("select",{"onUpdate:modelValue":e[3]||(e[3]=n=>s.providerid=n),class:"select select-bordered w-full"},[e[19]||(e[19]=t("option",{value:0},"请选择方案商",-1)),(o(!0),a(y,null,_(w.value,n=>(o(),a("option",{key:n.id,value:n.id},i(n.name),9,Vt))),128))],512),[[Y,s.providerid,void 0,{number:!0}]])]),t("div",Mt,[e[21]||(e[21]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"分成比例(%)")],-1)),r(t("input",{"onUpdate:modelValue":e[4]||(e[4]=n=>s.sharepct=n),type:"number",step:"0.01",min:"0",max:"100",class:"input input-bordered w-full"},null,512),[[m,s.sharepct,void 0,{number:!0}]]),e[22]||(e[22]=t("span",{class:"label-text-alt text-slate-400 mt-1"},"平台从订单实付里分给该品牌商的总提成;其名下渠道商再从这份里切自己的比例。",-1))]),t("div",$t,[e[23]||(e[23]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"描述")],-1)),r(t("textarea",{"onUpdate:modelValue":e[5]||(e[5]=n=>s.description=n),class:"textarea textarea-bordered w-full",rows:"3"},null,512),[[m,s.description]])]),t("div",Bt,[e[25]||(e[25]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"联系邮箱")],-1)),t("div",Pt,[d.value.length?v("",!0):(o(),a("p",Lt,"暂无邮箱")),(o(!0),a(y,null,_(d.value,(n,b)=>(o(),a("div",{key:b,class:"flex items-center gap-2"},[t("span",Et,[e[24]||(e[24]=t("svg",{class:"h-3 w-3 text-slate-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})],-1)),nt(" "+i(n),1)]),t("button",{type:"button",class:"btn btn-ghost btn-xs text-red-400 hover:text-red-600",onClick:E=>O(b)},"×",8,Rt)]))),128))]),t("div",St,[r(t("input",{"onUpdate:modelValue":e[6]||(e[6]=n=>f.value=n),type:"email",class:"input input-bordered input-sm flex-1",placeholder:"输入邮箱地址",onKeydown:Z(S(L,["prevent"]),["enter"])},null,40,jt),[[m,f.value]]),t("button",{type:"button",class:"btn btn-outline btn-sm btn-primary",onClick:L},"添加")])]),c.value?v("",!0):(o(),a("div",Dt,[e[26]||(e[26]=t("label",{class:"label"},[t("span",{class:"label-text font-medium"},"品牌官方渠道")],-1)),r(t("input",{"onUpdate:modelValue":e[7]||(e[7]=n=>s.officialChannelName=n),type:"text",class:"input input-bordered w-full",placeholder:B.value},null,8,Ft),[[m,s.officialChannelName]]),t("span",Tt," 新建品牌商时自动创建一条该品牌自己的渠道(直接启用、分成 0%、不创建渠道账号),用于品牌直销的授权码归属;留空则叫「"+i(B.value)+"」。 ",1)])),!c.value&&tt(F).isAdmin?(o(),a("div",qt,[t("label",zt,[r(t("input",{"onUpdate:modelValue":e[8]||(e[8]=n=>s.createAccount=n),type:"checkbox",class:"checkbox checkbox-sm checkbox-primary"},null,512),[[et,s.createAccount]]),e[27]||(e[27]=t("span",{class:"label-text font-medium"},"同时创建品牌账号",-1))]),e[31]||(e[31]=t("span",{class:"label-text-alt text-slate-400 mt-1"}," 建一个绑定本品牌商的「品牌商」角色登录账号,可见本品牌及名下全部渠道商的数据。 用户名/密码留空则自动生成,创建后凭据会邮件发给上面填的品牌商联系邮箱。 ",-1)),s.createAccount?(o(),a("div",It,[t("div",null,[e[28]||(e[28]=t("label",{class:"text-xs text-slate-500"},"登录用户名",-1)),r(t("input",{"onUpdate:modelValue":e[9]||(e[9]=n=>s.accountUsername=n),type:"text",class:"input input-bordered input-sm w-full",placeholder:"留空自动生成,如 Brand-A001",autocomplete:"off"},null,512),[[m,s.accountUsername]])]),t("div",null,[e[29]||(e[29]=t("label",{class:"text-xs text-slate-500"},"登录密码",-1)),r(t("input",{"onUpdate:modelValue":e[10]||(e[10]=n=>s.accountPassword=n),type:"text",class:"input input-bordered input-sm w-full font-mono",placeholder:"留空自动生成 12 位随机密码",autocomplete:"off"},null,512),[[m,s.accountPassword]])]),t("div",Kt,[e[30]||(e[30]=t("label",{class:"text-xs text-slate-500"},"备注",-1)),r(t("input",{"onUpdate:modelValue":e[11]||(e[11]=n=>s.accountRemark=n),type:"text",class:"input input-bordered input-sm w-full",placeholder:"可选"},null,512),[[m,s.accountRemark]])]),T.value.length?v("",!0):(o(),a("p",Ot," 当前没有填品牌商自己的联系邮箱(平台默认邮箱不算),凭据将无法邮件送达,只会在创建后弹窗显示一次。 "))])):v("",!0)])):v("",!0),t("div",Ht,[t("button",{type:"button",class:"btn btn-ghost",onClick:e[12]||(e[12]=n=>$())},"取消"),t("button",{type:"submit",class:"btn btn-primary text-white",disabled:A.value},"保存",8,Gt)])],32)])],512),[[R,h.value==="form"]]),st(p,{info:U.value,onClose:e[13]||(e[13]=n=>U.value=null)},null,8,["info"])])}}});export{te as default}; diff --git a/apps/admin/.output/public/_nuxt/DckJLiId.js b/apps/admin/.output/public/_nuxt/Bs6lDwyi.js similarity index 99% rename from apps/admin/.output/public/_nuxt/DckJLiId.js rename to apps/admin/.output/public/_nuxt/Bs6lDwyi.js index 1b819bca..0e1163c0 100644 --- a/apps/admin/.output/public/_nuxt/DckJLiId.js +++ b/apps/admin/.output/public/_nuxt/Bs6lDwyi.js @@ -1 +1 @@ -import{g as W,C as X,c as r,a as t,q as a,s as Q,F,r as N,H as T,t as l,l as Z,p as tt,v as b,x as et,y as i,z as E,o as u}from"./DMxDLVSv.js";import{u as st}from"./CCZrj3X-.js";import{u as nt}from"./B-sqZCu-.js";const ot={class:"space-y-6"},lt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-4"},at={class:"flex items-end gap-3 flex-wrap"},dt={class:"form-control"},rt=["value"],it={class:"form-control"},ut=["disabled"],ct={class:"bg-white rounded-xl shadow-sm border border-slate-100"},mt={class:"overflow-x-auto"},bt={class:"table table-zebra"},pt={key:0},vt={key:1},ft={colspan:"9",class:"text-center text-slate-400 py-8"},xt={class:"font-mono text-base font-bold text-indigo-700"},gt={class:"text-sm"},wt={class:"text-sm"},ht={class:"text-sm text-slate-500"},yt={class:"text-sm"},kt={class:"text-sm"},_t={class:"text-sm"},Ct={key:0,class:"badge badge-success badge-sm text-white"},Vt={key:1,class:"badge badge-ghost badge-sm"},Mt={class:"flex gap-1"},Ut=["onClick"],Dt=["onClick"],Qt=["onClick"],Ft=["onClick"],Nt={class:"flex items-center gap-3 mb-5"},Tt={class:"text-lg font-semibold text-slate-800"},qt={class:"bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"},Lt={class:"form-control mb-4"},St=["value"],Et={class:"form-control mb-4"},$t={class:"grid grid-cols-3 gap-3 mb-4"},Bt={class:"form-control"},Rt={class:"form-control"},jt={class:"form-control"},It={class:"grid grid-cols-2 gap-3 mb-4"},zt={class:"form-control"},Ht={class:"form-control"},Pt={class:"form-control mb-6"},At={class:"label cursor-pointer justify-start gap-3"},Yt={class:"modal-box max-w-md"},Gt={class:"flex flex-col items-center gap-4"},Jt={class:"text-center"},Kt={class:"font-mono text-2xl font-bold text-indigo-700 tracking-widest"},Ot="https://cdn.jsdelivr.net/gh/davidshimjs/qrcodejs/qrcode.min.js",ee=W({__name:"code",setup(Wt){const{webApi:c}=st(),{success:g,error:p,warn:w}=nt(),h=i("list"),C=i(!1),v=i(!1),m=i(0),V=i(-1),y=i([]),M=i([]),k=i([]),U=E({}),o=E({code:"",productid:0,remark:"",bindrewardvpitime:0,bindrewardtranslate:0,bindrewardmeeting:0,maxuses:0,expire:"",disabled:!1});function $(n){return n?new Date(n*1e3).toLocaleString():"永久"}function B(n){if(!n)return"";const e=new Date(n*1e3),s=d=>d<10?"0"+d:""+d;return e.getFullYear()+"-"+s(e.getMonth()+1)+"-"+s(e.getDate())+"T"+s(e.getHours())+":"+s(e.getMinutes())}function R(n){return n?Math.floor(new Date(n).getTime()/1e3):0}function j(n){return U[n.brandid]||(n.brandid?"品牌商#"+n.brandid:"-")}function I(n){const e=k.value.find(s=>s.id===n.productid);return e?e.devicename||"#"+n.productid:n.productid?"#"+n.productid:"-"}function _(){h.value="list",f()}function z(){_()}async function f(){C.value=!0;try{const n=await c("getfactorypubliccodes",{brandid:m.value,status:V.value});y.value=n?.codes??[]}catch(n){p(n?.message??"获取公码列表失败"),y.value=[]}finally{C.value=!1}}function q(n){if(!m.value){w("请先选择品牌商");return}n?(v.value=!0,o.code=n.code,o.productid=n.productid||0,o.remark=n.remark||"",o.bindrewardvpitime=n.bindrewardvpitime||0,o.bindrewardtranslate=n.bindrewardtranslate||0,o.bindrewardmeeting=n.bindrewardmeeting||0,o.maxuses=n.maxuses||0,o.expire=B(n.expiretime),o.disabled=n.status===1):(v.value=!1,o.code="",o.productid=0,o.remark="",o.bindrewardvpitime=0,o.bindrewardtranslate=0,o.bindrewardmeeting=0,o.maxuses=0,o.expire="",o.disabled=!1),h.value="form"}async function H(){const n={productid:Number(o.productid)||0,remark:o.remark,maxuses:Number(o.maxuses)||0,expiretime:R(o.expire),bindrewardvpitime:Number(o.bindrewardvpitime)||0,bindrewardtranslate:Number(o.bindrewardtranslate)||0,bindrewardmeeting:Number(o.bindrewardmeeting)||0};try{if(v.value)n.code=o.code,n.status=o.disabled?1:0,await c("updatefactorypubliccode",n),g("保存成功");else{n.brandid=m.value;const e=await c("createfactorypubliccode",n);g("新公码已生成:"+(e?.code?.code||""))}_()}catch(e){p(e?.message??"保存失败")}}async function P(n){const e=n.status===0?1:0;try{await c("updatefactorypubliccode",{code:n.code,productid:n.productid||0,remark:n.remark||"",status:e,maxuses:n.maxuses||0,expiretime:n.expiretime||0,bindrewardvpitime:n.bindrewardvpitime||0,bindrewardtranslate:n.bindrewardtranslate||0,bindrewardmeeting:n.bindrewardmeeting||0}),g(e===1?"已停用":"已启用"),f()}catch(s){p(s?.message??"操作失败")}}function A(n){window.confirm(`确定删除公码 "${n}" 吗?删除后该码无法再被领取(已领取记录保留)`)&&c("delfactorypubliccode",{code:n}).then(()=>{g("删除成功"),f()}).catch(e=>p(e?.message??"删除失败"))}const L=i(null),D=i(null),x=i("");function Y(){return new Promise((n,e)=>{const s=window;if(s.QRCode){n(s.QRCode);return}const d=document.createElement("script");d.src=Ot,d.onload=()=>n(s.QRCode),d.onerror=()=>e(new Error("二维码库加载失败")),document.head.appendChild(d)})}async function G(n){x.value=n,L.value?.showModal();let e;try{e=await Y()}catch{p("二维码库加载失败");return}const s=D.value;!s||!e||(s.innerHTML="",new e(s,{text:n,width:240,height:240,colorDark:"#1E293B",colorLight:"#FFFFFF",correctLevel:e.CorrectLevel.H}))}function S(){const n=D.value;if(!n)return"";const e=n.querySelector("canvas");if(e)return e.toDataURL("image/png");const s=n.querySelector("img");return s?s.src:""}function J(){const n=S();if(!n){w("二维码尚未生成");return}const e=document.createElement("a");e.href=n,e.download="publiccode_"+x.value+".png",document.body.appendChild(e),e.click(),document.body.removeChild(e)}function K(){const n=S();if(!n){w("二维码尚未生成");return}const e=window.open("","_blank");if(!e){w("浏览器拦截了打印窗口");return}e.document.write(""+x.value+'

'+x.value+"

新用户扫码领取奖励

@@ -497,6 +662,11 @@ onMounted(async () => { .stage-tag { display: inline-block; font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 5px; color: #fff; vertical-align: middle; } .voice-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; } +.var-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; } +.mcp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; } +.mcp-item { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 7px 10px; border: 1.5px solid #e2e8f0; border-radius: 9px; font-size: 12.5px; color: #475569; cursor: pointer; transition: all .15s; } +.mcp-item:hover { border-color: #c7d2fe; background: #f8fafc; } +.mcp-item.on { border-color: #6366f1; background: #eef2ff; color: #4338ca; } .ed-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 14px; border-top: 1px solid #eef2f7; } diff --git a/apps/admin/app/pages/calltranslate.vue b/apps/admin/app/pages/calltranslate.vue index dd1dd0a1..e844736b 100644 --- a/apps/admin/app/pages/calltranslate.vue +++ b/apps/admin/app/pages/calltranslate.vue @@ -167,7 +167,7 @@ -
+

选路试算

用后端运行时同一套匹配逻辑,算一遍这个方向实际会走哪条规则。

diff --git a/apps/admin/app/pages/channels.vue b/apps/admin/app/pages/channels.vue index 1609c623..11ffe4c3 100644 --- a/apps/admin/app/pages/channels.vue +++ b/apps/admin/app/pages/channels.vue @@ -101,7 +101,7 @@
-
+
diff --git a/apps/admin/app/pages/serviceconfig.vue b/apps/admin/app/pages/serviceconfig.vue index 95d52775..b46b116b 100644 --- a/apps/admin/app/pages/serviceconfig.vue +++ b/apps/admin/app/pages/serviceconfig.vue @@ -18,6 +18,7 @@ +
@@ -31,13 +32,14 @@
-
+
+ ▾ {{ g.short }}

{{ g.label }}

{{ g.items.length }} 个服务
-
+
@@ -50,10 +52,14 @@

{{ s.description || '—' }}

-
+ +
{{ s.provider }} {{ (s.fields || []).length }} 字段 🔒{{ encCount(s) }} +
+
{{ regionChip(s).text }}
@@ -72,7 +78,7 @@
-