Module Placeholder
游戏模块
这里先继续保留占位,后面你要接正式游戏模块时,直接在这块扩展就行。
import{s as Re,_ as H,u as Te,a as ie,b as X,r as u,c as A,w as ue,d as S,o as _,e as j,f as b,g as V,h as ce,i as e,j as M,t as h,k as c,l as a,m as D,n as de,T as pe,E as g,p as qe,q as Le,v as Ie,x as G,y as Me,z as se,A as te,B as J,C as ae,D as oe,F as le,G as ne,H as Ne}from"./index-B2CLdTeJ.js";function Ee(R){return Re({url:"/system/music/search",method:"get",params:{keyword:R}})}function re(R,T,w=!1){const d=new URLSearchParams;return d.set("url",R),d.set("name",T||"music-preview"),d.set("download",String(w)),`/prod-api/system/music/audio?${d.toString()}`}const Be={class:"console-modal"},Ae={class:"modal-head"},Oe={class:"field-shell"},De={class:"field-icon"},Ke={class:"field-shell"},Fe={class:"field-icon"},Je={class:"form-note"},je={key:0},ze={key:1},Ge={__name:"ConsoleLoginModal",props:{modelValue:{type:Boolean,default:!1},closable:{type:Boolean,default:!0}},emits:["update:modelValue","success","close"],setup(R,{emit:T}){const w=T,d=Te(),f=ie(),k=X(),v=u({username:"admin",password:"admin123",code:"",uuid:""}),y=u(!1),x=u(void 0),C=u(null),i=u(!1),N=A(()=>({username:[{required:!0,trigger:"blur",message:"请输入账号"}],password:[{required:!0,trigger:"blur",message:"请输入密码"}]})),q=A(()=>{var o;return((o=f.query)==null?void 0:o.registered)==="1"?"账号已创建成功,输入密码后可直接进入后台。":"输入账号和密码后直接进入后台管理。"});ue(()=>f.fullPath,()=>{var o,r,p;x.value=(o=f.query)==null?void 0:o.redirect,typeof((r=f.query)==null?void 0:r.username)=="string"&&f.query.username&&(v.value.username=f.query.username,v.value.password=""),((p=f.query)==null?void 0:p.registered)==="1"&&!i.value&&(g.success("注册成功,请登录系统"),i.value=!0)},{immediate:!0});function $(){w("update:modelValue",!1),w("close")}function U(){if(!C.value){g.error("登录表单未初始化");return}C.value.validate(async o=>{if(!o){g.warning("请输入账号和密码");return}y.value=!0;try{await d.login(v.value);const r=f.query||{},p=Object.keys(r).reduce((l,m)=>(["redirect","registered","username"].includes(m)||(l[m]=r[m]),l),{});if(await k.push({path:x.value||"/index",query:p}),k.currentRoute.value.path==="/login")throw new Error("登录后未能进入后台,请稍后重试");w("success"),w("update:modelValue",!1)}catch(r){g.error((r==null?void 0:r.message)||"登录失败,请重试"),console.error("登录失败:",r)}finally{y.value=!1}})}return(o,r)=>{const p=S("svg-icon"),l=S("el-input"),m=S("el-form-item"),P=S("router-link"),I=S("el-button"),O=S("el-form");return _(),j(pe,{name:"console-fade"},{default:b(()=>[R.modelValue?(_(),V("div",{key:0,class:"console-modal-mask",onClick:ce($,["self"])},[e("section",Be,[R.closable?(_(),V("button",{key:0,type:"button",class:"close-btn",onClick:$},"×")):M("",!0),e("header",Ae,[r[2]||(r[2]=e("p",{class:"head-tag"},"CONTROL ACCESS",-1)),r[3]||(r[3]=e("h2",null,"登录后台",-1)),e("p",null,h(q.value),1)]),c(O,{ref_key:"loginRef",ref:C,model:a(v),rules:N.value,class:"login-form"},{default:b(()=>[c(m,{prop:"username",class:"compact-item"},{default:b(()=>[e("div",Oe,[e("span",De,[c(p,{"icon-class":"user",class:"input-icon"})]),c(l,{modelValue:a(v).username,"onUpdate:modelValue":r[0]||(r[0]=E=>a(v).username=E),type:"text",autocomplete:"off",placeholder:"账号"},null,8,["modelValue"])])]),_:1}),c(m,{prop:"password",class:"compact-item"},{default:b(()=>[e("div",Ke,[e("span",Fe,[c(p,{"icon-class":"password",class:"input-icon"})]),c(l,{modelValue:a(v).password,"onUpdate:modelValue":r[1]||(r[1]=E=>a(v).password=E),type:"password",autocomplete:"off",placeholder:"密码","show-password":"",onKeyup:D(U,["enter"])},null,8,["modelValue"])])]),_:1}),e("div",Je,[r[5]||(r[5]=e("span",null,"当前登录不校验验证码。",-1)),c(P,{class:"action-link",to:"/register"},{default:b(()=>[...r[4]||(r[4]=[de("去注册",-1)])]),_:1})]),c(m,{class:"submit-row"},{default:b(()=>[c(I,{loading:a(y),type:"primary",class:"submit-btn",onClick:U},{default:b(()=>[a(y)?(_(),V("span",ze,"登录中...")):(_(),V("span",je,"进入后台"))]),_:1},8,["loading"])]),_:1})]),_:1},8,["model","rules"])])])):M("",!0)]),_:1})}}},He=H(Ge,[["__scopeId","data-v-7c5ed1a7"]]),Xe={class:"console-modal"},Qe={key:1,class:"success-panel"},We={class:"success-copy"},Ye={class:"field-shell"},Ze={class:"field-icon"},es={class:"field-shell"},ss={class:"field-icon"},ts={class:"field-shell"},as={class:"field-icon"},os={class:"captcha-shell"},ls={class:"field-shell"},ns={class:"field-icon"},rs=["src"],is={class:"form-note"},us={key:0},cs={key:1},ds={__name:"ConsoleRegisterModal",props:{modelValue:{type:Boolean,default:!1},closable:{type:Boolean,default:!0}},emits:["update:modelValue","success","close"],setup(R,{emit:T}){const w=T,d=X(),f=u(null),k=u(!1),v=u(!1),y=u(""),x=u(!1),C=u(""),i=u({username:"",password:"",confirmPassword:"",code:"",uuid:""}),q={username:[{required:!0,trigger:"blur",message:"请输入账号"},{min:2,max:20,trigger:"blur",message:"账号长度需在 2 到 20 个字符之间"}],password:[{required:!0,trigger:"blur",message:"请输入密码"},{min:5,max:20,trigger:"blur",message:"密码长度需在 5 到 20 个字符之间"},{pattern:/^[^<>"'|\\]+$/,trigger:"blur",message:"密码不能包含非法字符"}],confirmPassword:[{required:!0,trigger:"blur",message:"请再次输入密码"},{validator:(p,l,m)=>{if(i.value.password!==l){m(new Error("两次输入的密码不一致"));return}m()},trigger:"blur"}],code:[{required:!0,trigger:"change",message:"请输入验证码"}]};function $(){w("update:modelValue",!1),w("close")}function U(){if(!f.value){g.error("注册表单未初始化");return}f.value.validate(p=>{p&&(k.value=!0,Le({username:i.value.username,password:i.value.password,code:i.value.code,uuid:i.value.uuid}).then(()=>{C.value=i.value.username,x.value=!0}).catch(l=>{g.error((l==null?void 0:l.message)||"注册失败"),v.value&&r()}).finally(()=>{k.value=!1}))})}function o(){w("success"),w("update:modelValue",!1),x.value=!1,d.push({path:"/login",query:{username:C.value,registered:"1"}})}function r(){qe().then(p=>{v.value=(p==null?void 0:p.captchaEnabled)===void 0?!0:!!p.captchaEnabled,v.value?(y.value="data:image/gif;base64,"+(p.img||""),i.value.uuid=p.uuid||""):(i.value.code="",i.value.uuid="")}).catch(p=>{console.error("获取验证码失败:",p),v.value=!1,i.value.code="",i.value.uuid=""})}return r(),(p,l)=>{const m=S("svg-icon"),P=S("el-input"),I=S("el-form-item"),O=S("router-link"),E=S("el-button"),z=S("el-form");return _(),j(pe,{name:"console-fade"},{default:b(()=>[R.modelValue?(_(),V("div",{key:0,class:"console-modal-mask",onClick:ce($,["self"])},[e("section",Xe,[R.closable?(_(),V("button",{key:0,type:"button",class:"close-btn",onClick:$},"×")):M("",!0),l[8]||(l[8]=e("header",{class:"modal-head"},[e("p",{class:"head-tag"},"CREATE ACCOUNT"),e("h2",null,"创建账号"),e("p",null,"先完成基础注册,再返回登录进入后台。")],-1)),a(x)?(_(),V("div",Qe,[l[5]||(l[5]=e("div",{class:"success-badge"},"✓",-1)),e("div",We,[l[4]||(l[4]=e("p",{class:"success-title"},"注册成功",-1)),e("p",null,"账号 "+h(a(C))+" 已创建,现在可以直接登录。",1)]),e("button",{type:"button",class:"success-btn",onClick:o},"去登录")])):M("",!0),a(x)?M("",!0):(_(),j(z,{key:2,ref_key:"registerRef",ref:f,model:a(i),rules:q,class:"register-form"},{default:b(()=>[c(I,{prop:"username",class:"compact-item"},{default:b(()=>[e("div",Ye,[e("span",Ze,[c(m,{"icon-class":"user",class:"input-icon"})]),c(P,{modelValue:a(i).username,"onUpdate:modelValue":l[0]||(l[0]=L=>a(i).username=L),type:"text",autocomplete:"off",placeholder:"账号"},null,8,["modelValue"])])]),_:1}),c(I,{prop:"password",class:"compact-item"},{default:b(()=>[e("div",es,[e("span",ss,[c(m,{"icon-class":"password",class:"input-icon"})]),c(P,{modelValue:a(i).password,"onUpdate:modelValue":l[1]||(l[1]=L=>a(i).password=L),type:"password",autocomplete:"off",placeholder:"密码","show-password":""},null,8,["modelValue"])])]),_:1}),c(I,{prop:"confirmPassword",class:"compact-item"},{default:b(()=>[e("div",ts,[e("span",as,[c(m,{"icon-class":"password",class:"input-icon"})]),c(P,{modelValue:a(i).confirmPassword,"onUpdate:modelValue":l[2]||(l[2]=L=>a(i).confirmPassword=L),type:"password",autocomplete:"off",placeholder:"确认密码","show-password":"",onKeyup:D(U,["enter"])},null,8,["modelValue"])])]),_:1}),a(v)?(_(),j(I,{key:0,prop:"code",class:"compact-item"},{default:b(()=>[e("div",os,[e("div",ls,[e("span",ns,[c(m,{"icon-class":"validCode",class:"input-icon"})]),c(P,{modelValue:a(i).code,"onUpdate:modelValue":l[3]||(l[3]=L=>a(i).code=L),type:"text",autocomplete:"off",placeholder:"验证码",onKeyup:D(U,["enter"])},null,8,["modelValue"])]),e("img",{src:a(y),class:"captcha-img",onClick:r},null,8,rs)])]),_:1})):M("",!0),e("div",is,[l[7]||(l[7]=e("span",null,"仅提交后端稳定支持的最小注册参数。",-1)),c(O,{class:"action-link",to:"/login"},{default:b(()=>[...l[6]||(l[6]=[de("返回登录",-1)])]),_:1})]),c(I,{class:"submit-row"},{default:b(()=>[c(E,{loading:a(k),type:"primary",class:"submit-btn",onClick:U},{default:b(()=>[a(k)?(_(),V("span",cs,"提交中...")):(_(),V("span",us,"创建账号"))]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"]))])])):M("",!0)]),_:1})}}},ps=H(ds,[["__scopeId","data-v-a8005e9d"]]),ms={class:"console-shell"},fs={class:"console-frame"},vs={class:"stage"},gs={class:"topbar"},hs={class:"search-box"},_s={class:"top-actions"},ys={class:"profile-avatar"},bs={class:"profile-label"},ws={class:"board"},ks={class:"hero-card music-card"},Cs={class:"player-panel"},$s={class:"track-meta"},Vs={class:"music-search-row"},xs={class:"progress-line"},Ss={class:"playlist-actions"},Us={class:"player-controls"},Ps={class:"search-result-list"},Rs=["onClick"],Ts={class:"track-chip-title"},qs={class:"track-chip-meta"},Ls={key:0,class:"track-chip empty-state"},Is={class:"hero-actions"},Ms={class:"panel-card service-card"},Ns={class:"metric-value"},Es={class:"service-grid"},Bs=["onClick"],As={__name:"index",setup(R){const T=X(),w=ie(),d=u(null),f=u(""),k=u(""),v=u(!1),y=u([]),x=u(-1),C=u(!1),i=u(0),N=u(0),q=u(L("landing-music-favorites")),$=u(L("landing-music-playlists")),U=u(me("landing-music-downloaded")),o=Ie(z()),r=[{name:"CloudDrive",desc:"网盘管理",href:"/clouddrive/",external:!0},{name:"Jenkins",desc:"持续集成",href:"/jenkins/",external:!0},{name:"Nacos",desc:"注册配置",href:"/nacos/",external:!0},{name:"XXL-JOB",desc:"任务调度",href:"/xxl-job-admin/",external:!0},{name:"Seata",desc:"事务控制",href:"/seata/",external:!0},{name:"MinIO",desc:"文件对象",href:"/minio/",external:!0},{name:"ncm2mp3",desc:"音频转换",href:"/ncm2mp3/",external:!0}],p=A(()=>G()?"进入后台":"登录"),l=A(()=>G()?"A":"→"),m=u(!1),P=u(!1),I=A(()=>N.value?Math.min(100,i.value/N.value*100):0),O=A(()=>o.artwork?{backgroundImage:`url(${o.artwork})`,backgroundSize:"cover",backgroundPosition:"center"}:{}),E=A(()=>q.value.some(t=>t.id===o.id));function z(){return{id:0,title:"Neon Console",artist:"公开试听模式",album:"请输入歌名开始搜索",artwork:"",previewUrl:"",source:"Apple Music"}}function L(t){try{const s=localStorage.getItem(t);return s?JSON.parse(s):[]}catch{return[]}}function me(t){try{const s=sessionStorage.getItem(t);return s?JSON.parse(s):[]}catch{return[]}}function Q(t,s){localStorage.setItem(t,JSON.stringify(s))}function fe(t,s){sessionStorage.setItem(t,JSON.stringify(s))}function ve(t){o.id=t.id,o.title=t.title,o.artist=t.artist,o.album=t.album,o.artwork=t.artwork,o.previewUrl=t.previewUrl,o.source=t.source}function ge(){if(G()){T.push("/index");return}m.value=!0}function W(t){if(t.external){window.open(t.href,"_blank");return}T.push(t.href)}function he(){window.open("/clouddrive/","_blank")}async function K(){const t=k.value.trim()||f.value.trim();if(!(!t||v.value)){v.value=!0;try{const n=(await Ee(t)).data||[];if(y.value=n,!n.length){g.warning("没有找到可试听的音乐结果");return}F(n[0],0,!1),g.success(`找到 ${n.length} 首可试听歌曲`)}catch{g.error("音乐搜索暂时不可用")}finally{v.value=!1}}}function F(t,s,n){x.value=s,ve(t),i.value=0,N.value=0,d.value&&(d.value.src=re(t.previewUrl,`${t.artist}-${t.title}`,!1),d.value.load()),n&&Y()}async function Y(){if(!o.previewUrl){k.value.trim()||f.value.trim()?await K():g.info("先输入歌名或歌手再开始播放");return}if(d.value)try{await d.value.play(),C.value=!0,we(o)}catch{g.error("当前歌曲暂时无法播放")}}function _e(){d.value&&(d.value.pause(),C.value=!1)}function Z(){if(C.value){_e();return}Y()}function ye(){if(!y.value.length){g.info("先搜索歌曲,再使用上一曲");return}const t=x.value<=0?y.value.length-1:x.value-1;F(y.value[t],t,!0)}function be(){if(!y.value.length){g.info("先搜索歌曲,再使用下一曲");return}const t=x.value>=y.value.length-1?0:x.value+1;F(y.value[t],t,!0)}function we(t){if(!t.id||U.value.includes(t.id))return;U.value=[...U.value,t.id],fe("landing-music-downloaded",U.value);const s=document.createElement("a");s.href=re(t.previewUrl,`${t.artist}-${t.title}`,!0),s.target="_blank",s.rel="noreferrer",document.body.appendChild(s),s.click(),document.body.removeChild(s)}function ke(){if(!o.id){g.info("先选择一首歌");return}const t=q.value.some(s=>s.id===o.id);q.value=t?q.value.filter(s=>s.id!==o.id):[...q.value,{...o}],Q("landing-music-favorites",q.value),g.success(t?"已取消收藏":"已加入收藏")}function Ce(){if(!o.id){g.info("先选中一首歌再建歌单");return}const t=window.prompt("输入歌单名称",`我的歌单 ${$.value.length+1}`);if(!t||!t.trim())return;const s=t.trim(),n=$.value.find(B=>B.name===s);n?n.tracks.some(B=>B.id===o.id)||n.tracks.push({...o}):$.value=[...$.value,{name:s,tracks:[{...o}]}],Q("landing-music-playlists",$.value),g.success(`已保存到歌单:${s}`)}function $e(){if(!$.value.length){g.info("还没有本地歌单");return}const t=$.value.map(s=>`${s.name} · ${s.tracks.length} 首`).join(" | ");g.success(t)}function ee(){const t=f.value.trim();if(!t)return;const s=r.find(n=>n.name.toLowerCase().includes(t.toLowerCase()));if(s){W(s);return}k.value=t,K()}function Ve(){d.value&&(i.value=d.value.currentTime||0)}function xe(){d.value&&(N.value=d.value.duration||0)}function Se(){C.value=!1}function Ue(){w.path==="/login"&&T.push("/")}function Pe(){w.path==="/register"&&T.push("/")}return Me(()=>{d.value&&d.value.pause()}),ue(()=>w.path,t=>{m.value=t==="/login",P.value=t==="/register"},{immediate:!0}),(t,s)=>(_(),V("div",ms,[s[10]||(s[10]=e("div",{class:"ambient ambient-left"},null,-1)),s[11]||(s[11]=e("div",{class:"ambient ambient-right"},null,-1)),e("section",fs,[e("main",vs,[e("header",gs,[e("div",hs,[s[4]||(s[4]=e("span",{class:"search-icon"},"⌕",-1)),se(e("input",{"onUpdate:modelValue":s[0]||(s[0]=n=>J(f)?f.value=n:null),type:"text",placeholder:"ai搜索音乐、项目组件、控制台入口",onKeyup:D(ee,["enter"])},null,544),[[te,a(f)]]),e("button",{type:"button",class:"search-submit",onClick:ee},"ai搜索")]),e("div",_s,[e("button",{type:"button",class:"profile-chip",onClick:ge},[e("span",ys,h(l.value),1),e("span",bs,h(p.value),1)])])]),e("section",ws,[e("article",ks,[s[6]||(s[6]=ae('
Player Access
现在不用登录也能直接搜歌、试听和播放。播放时会自动把当前试听音频下载到本地, 收藏和歌单先保存在当前浏览器里。
Module Placeholder
这里先继续保留占位,后面你要接正式游戏模块时,直接在这块扩展就行。