(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[572],{1910:(e,t,s)=>{"use strict";s.d(t,{L:()=>r,M3:()=>i,WG:()=>l,gf:()=>n});let a="yelay_admin_token";function n(){var e;return null!=(e=window.localStorage.getItem(a))?e:""}function l(e){window.localStorage.setItem(a,e)}function r(){window.localStorage.removeItem(a)}function i(){return""!==n()}},2787:(e,t,s)=>{"use strict";s.d(t,{$T:()=>o,$n:()=>n,Sv:()=>m,TM:()=>r,Zp:()=>c,aF:()=>d,l6:()=>i,pd:()=>l});var a=s(1333);function n(e){let{children:t,onClick:s,variant:n="primary",disabled:l,type:r="button"}=e;return(0,a.jsx)("button",{type:r,onClick:s,disabled:l,className:"rounded-md px-3 py-1.5 text-sm font-medium transition disabled:cursor-not-allowed disabled:opacity-50 ".concat({primary:"bg-blue-600 text-white hover:bg-blue-700",ghost:"bg-white text-gray-700 border border-gray-300 hover:bg-gray-50",danger:"bg-red-600 text-white hover:bg-red-700"}[n]),children:t})}function l(e){let{value:t,onChange:s,placeholder:n,type:l="text"}=e;return(0,a.jsx)("input",{type:l,value:t,placeholder:n,onChange:e=>s(e.target.value),className:"w-full rounded-md border border-gray-300 px-3 py-1.5 text-sm outline-none focus:border-blue-500"})}function r(e){let{value:t,onChange:s}=e;return(0,a.jsx)("textarea",{value:t,rows:6,onChange:e=>s(e.target.value),className:"w-full rounded-md border border-gray-300 px-3 py-1.5 font-mono text-xs outline-none focus:border-blue-500"})}function i(e){let{value:t,onChange:s,options:n}=e;return(0,a.jsx)("select",{value:t,onChange:e=>s(e.target.value),className:"w-full rounded-md border border-gray-300 px-3 py-1.5 text-sm outline-none focus:border-blue-500",children:n.map(e=>(0,a.jsx)("option",{value:String(e.value),children:e.label},e.value))})}function c(e){let{title:t,children:s,action:n}=e;return(0,a.jsxs)("section",{className:"rounded-lg border border-gray-200 bg-white p-5 shadow-sm",children:[(t||n)&&(0,a.jsxs)("header",{className:"mb-4 flex items-center justify-between",children:[t&&(0,a.jsx)("h2",{className:"text-base font-semibold text-gray-900",children:t}),n]}),s]})}function d(e){let{open:t,title:s,onClose:n,children:l,footer:r}=e;return t?(0,a.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:(0,a.jsxs)("div",{className:"max-h-[85vh] w-full max-w-2xl overflow-auto rounded-lg bg-white shadow-xl",children:[(0,a.jsxs)("header",{className:"flex items-center justify-between border-b border-gray-200 px-5 py-3",children:[(0,a.jsx)("h3",{className:"text-base font-semibold",children:s}),(0,a.jsx)("button",{onClick:n,className:"text-gray-400 hover:text-gray-600","aria-label":"关闭",children:"✕"})]}),(0,a.jsx)("div",{className:"px-5 py-4",children:l}),r&&(0,a.jsx)("footer",{className:"flex justify-end gap-2 border-t border-gray-200 px-5 py-3",children:r})]})}):null}function o(e){let{message:t,kind:s="error"}=e;return t?(0,a.jsx)("div",{className:"mb-3 rounded-md border px-3 py-2 text-sm ".concat("error"===s?"bg-red-50 text-red-700 border-red-200":"bg-green-50 text-green-700 border-green-200"),children:t}):null}function m(e){let{text:t="暂无数据"}=e;return(0,a.jsx)("div",{className:"py-10 text-center text-sm text-gray-400",children:t})}},3308:(e,t,s)=>{Promise.resolve().then(s.bind(s,7249))},7249:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>c});var a=s(1333),n=s(4705),l=s(8312),r=s(2787);let i={1:"订单购买",2:"历史数据",3:"后台发放"};function c(){var e;let[t,s]=(0,n.useState)([]),[c,d]=(0,n.useState)(0),[o,m]=(0,n.useState)(1),[x,h]=(0,n.useState)(""),[u,g]=(0,n.useState)(""),[b,p]=(0,n.useState)(null),[y,j]=(0,n.useState)({nickname:"",headicon_id:"0",status:"1"}),[v,f]=(0,n.useState)([]),[N,w]=(0,n.useState)([]),[S,k]=(0,n.useState)(""),C=(0,n.useCallback)((e,t)=>{g(""),l.F.listUsers(e,20,t).then(e=>{s(e.items),d(e.total),m(e.page)}).catch(e=>g(e.message))},[]);(0,n.useEffect)(()=>{C(1,""),l.F.listResource("courses",{page:1,pageSize:100}).then(e=>f(e.items)).catch(()=>f([]))},[C]);let _=e=>{l.F.listEntitlements(e).then(e=>w(e)).catch(()=>w([]))},O=Math.max(1,Math.ceil(c/20));return(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsx)("h1",{className:"text-lg font-semibold text-gray-900",children:"用户"}),(0,a.jsx)(r.$T,{message:u}),(0,a.jsxs)(r.Zp,{title:"共 ".concat(c," 位用户"),action:(0,a.jsxs)("div",{className:"flex gap-2",children:[(0,a.jsx)(r.pd,{value:x,onChange:h,placeholder:"昵称或 openid…"}),(0,a.jsx)(r.$n,{variant:"ghost",onClick:()=>C(1,x),children:"搜索"})]}),children:[0===t.length?(0,a.jsx)(r.Sv,{}):(0,a.jsx)("div",{className:"overflow-x-auto",children:(0,a.jsxs)("table",{className:"w-full text-sm",children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{className:"border-b border-gray-200 text-left text-xs text-gray-500",children:[(0,a.jsx)("th",{className:"px-2 py-2",children:"ID"}),(0,a.jsx)("th",{className:"px-2 py-2",children:"昵称"}),(0,a.jsx)("th",{className:"px-2 py-2",children:"已购课程"}),(0,a.jsx)("th",{className:"px-2 py-2",children:"状态"}),(0,a.jsx)("th",{className:"px-2 py-2",children:"最后登录"}),(0,a.jsx)("th",{className:"px-2 py-2 text-right",children:"操作"})]})}),(0,a.jsx)("tbody",{children:t.map(e=>(0,a.jsxs)("tr",{className:"border-b border-gray-100 hover:bg-gray-50",children:[(0,a.jsx)("td",{className:"px-2 py-2 text-gray-400",children:e.id}),(0,a.jsx)("td",{className:"px-2 py-2",children:e.nickname||(0,a.jsx)("span",{className:"text-gray-400",children:"游客"})}),(0,a.jsx)("td",{className:"px-2 py-2",children:e.entitlement_count}),(0,a.jsx)("td",{className:"px-2 py-2",children:1===e.status?(0,a.jsx)("span",{className:"text-green-600",children:"正常"}):(0,a.jsx)("span",{className:"text-red-600",children:"封禁"})}),(0,a.jsx)("td",{className:"px-2 py-2 text-gray-500",children:e.last_login_at?String(e.last_login_at).slice(0,10):"—"}),(0,a.jsx)("td",{className:"px-2 py-2 text-right",children:(0,a.jsx)(r.$n,{variant:"ghost",onClick:()=>{var t;p(e),j({nickname:null!=(t=e.nickname)?t:"",headicon_id:String(e.headicon_id),status:String(e.status)}),k(""),_(e.id)},children:"编辑 / 权益"})})]},e.id))})]})}),(0,a.jsxs)("div",{className:"mt-4 flex items-center justify-between text-sm text-gray-500",children:[(0,a.jsxs)("span",{children:["第 ",o," / ",O," 页"]}),(0,a.jsxs)("div",{className:"flex gap-2",children:[(0,a.jsx)(r.$n,{variant:"ghost",disabled:o<=1,onClick:()=>C(o-1,x),children:"上一页"}),(0,a.jsx)(r.$n,{variant:"ghost",disabled:o>=O,onClick:()=>C(o+1,x),children:"下一页"})]})]})]}),(0,a.jsx)(r.aF,{open:null!==b,title:"用户 #".concat(null!=(e=null==b?void 0:b.id)?e:""),onClose:()=>p(null),footer:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(r.$n,{variant:"ghost",onClick:()=>p(null),children:"关闭"}),(0,a.jsx)(r.$n,{onClick:()=>{b&&(g(""),l.F.updateUser(b.id,{nickname:y.nickname,headicon_id:Number(y.headicon_id),status:Number(y.status)}).then(()=>{p(null),C(o,x)}).catch(e=>g(e.message)))},children:"保存"})]}),children:(0,a.jsxs)("div",{className:"space-y-5",children:[(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"mb-1 block text-sm text-gray-600",children:"昵称"}),(0,a.jsx)(r.pd,{value:y.nickname,onChange:e=>j({...y,nickname:e})})]}),(0,a.jsxs)("div",{className:"flex gap-3",children:[(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("label",{className:"mb-1 block text-sm text-gray-600",children:"头像序号"}),(0,a.jsx)(r.pd,{value:y.headicon_id,onChange:e=>j({...y,headicon_id:e}),type:"number"})]}),(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("label",{className:"mb-1 block text-sm text-gray-600",children:"账号状态"}),(0,a.jsx)(r.l6,{value:y.status,onChange:e=>j({...y,status:e}),options:[{value:1,label:"正常"},{value:0,label:"封禁"}]})]})]})]}),(0,a.jsxs)("div",{className:"border-t border-gray-200 pt-4",children:[(0,a.jsx)("h4",{className:"mb-2 text-sm font-medium text-gray-800",children:"课程权益"}),(0,a.jsx)("p",{className:"mb-2 text-xs text-gray-500",children:"这是原「口令码」的替代:有人拿旧码来找你时,在这里给他发对应的课程即可。"}),(0,a.jsxs)("div",{className:"flex gap-2",children:[(0,a.jsx)(r.l6,{value:S,onChange:k,options:[{value:0,label:"选择课程…"}].concat(v.map(e=>({value:e.id,label:"".concat(e.id," \xb7 ").concat(e.title)})))}),(0,a.jsx)(r.$n,{onClick:()=>{b&&S&&"0"!==S&&(g(""),l.F.grantEntitlement(b.id,Number(S),"后台发放").then(()=>{k(""),_(b.id),C(o,x)}).catch(e=>g(e.message)))},disabled:!S||"0"===S,children:"发放"})]}),(0,a.jsx)("table",{className:"mt-3 w-full text-sm",children:(0,a.jsxs)("tbody",{children:[N.map(e=>{var t;return(0,a.jsxs)("tr",{className:"border-b border-gray-100",children:[(0,a.jsx)("td",{className:"py-2",children:e.course_title}),(0,a.jsx)("td",{className:"py-2 text-xs text-gray-500",children:null!=(t=i[e.source])?t:e.source}),(0,a.jsx)("td",{className:"py-2 text-right",children:(0,a.jsx)(r.$n,{variant:"danger",onClick:()=>{var t;return t=e.course_id,void(b&&window.confirm("确定回收该课程权益吗?用户将失去访问权限。")&&(g(""),l.F.revokeEntitlement(b.id,t).then(()=>{_(b.id),C(o,x)}).catch(e=>g(e.message))))},children:"回收"})})]},e.id)}),0===N.length&&(0,a.jsx)("tr",{children:(0,a.jsx)("td",{colSpan:3,className:"py-4 text-center text-xs text-gray-400",children:"暂无权益"})})]})})]})]})})]})}},8312:(e,t,s)=>{"use strict";s.d(t,{F:()=>i});var a=s(1910);let n="http://127.0.0.1:3000".replace(/\/+$/,"");async function l(e){var t,s,l,r,i;let c,d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=(0,a.gf)(),m={"content-type":"application/json",...null!=(t=d.headers)?t:{}};o&&(m.Authorization="Bearer ".concat(o));try{c=await fetch("".concat(n).concat(e),{...d,headers:m})}catch(e){throw{code:-1,message:"无法连接服务端,请检查网络或接口地址"}}let x=null;try{x=await c.json()}catch(e){throw{code:-1,message:"服务端返回异常(HTTP ".concat(c.status,")")}}if(401===c.status)throw(0,a.L)(),window.location.pathname.startsWith("/login")||(window.location.href="/login"),{code:null!=(s=null==x?void 0:x.code)?s:2e3,message:null!=(l=null==x?void 0:x.message)?l:"登录已失效,请重新登录"};if(!x||0!==x.code)throw{code:null!=(r=null==x?void 0:x.code)?r:-1,message:null!=(i=null==x?void 0:x.message)?i:"请求失败"};return x.data}let r=e=>{let t=Object.entries(e).filter(e=>{let[,t]=e;return void 0!==t&&""!==t}).map(e=>{let[t,s]=e;return"".concat(encodeURIComponent(t),"=").concat(encodeURIComponent(String(s)))});return t.length?"?".concat(t.join("&")):""},i={base:n,request:l,login:(e,t)=>l("/admin/v1/auth/login",{method:"POST",body:JSON.stringify({username:e,password:t})}),bootstrap:(e,t)=>l("/admin/v1/auth/bootstrap",{method:"POST",body:JSON.stringify({username:e,password:t})}),stats:()=>l("/admin/v1/stats"),listUsers:(e,t,s)=>l("/admin/v1/users".concat(r({page:e,pageSize:t,keyword:s}))),updateUser:(e,t)=>l("/admin/v1/users/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),listResource:(e,t)=>l("/admin/v1/data/".concat(e).concat(r(t))),createResource:(e,t)=>l("/admin/v1/data/".concat(e),{method:"POST",body:JSON.stringify(t)}),updateResource:(e,t,s)=>l("/admin/v1/data/".concat(e,"/").concat(t),{method:"PATCH",body:JSON.stringify(s)}),deleteResource:(e,t)=>l("/admin/v1/data/".concat(e,"/").concat(t),{method:"DELETE"}),listSettings:()=>l("/admin/v1/settings"),upsertSetting:(e,t,s)=>l("/admin/v1/settings",{method:"PUT",body:JSON.stringify({key:e,value:t,remark:s})}),listOrders:(e,t,s)=>l("/admin/v1/orders".concat(r({page:e,pageSize:t,status:s}))),refundOrder:(e,t)=>l("/admin/v1/orders/".concat(e,"/refund"),{method:"POST",body:JSON.stringify({reason:t})}),listEntitlements:e=>l("/admin/v1/entitlements".concat(r({userId:e}))),grantEntitlement:(e,t,s)=>l("/admin/v1/entitlements",{method:"POST",body:JSON.stringify({userId:e,courseId:t,note:s})}),revokeEntitlement:(e,t)=>l("/admin/v1/entitlements".concat(r({userId:e,courseId:t})),{method:"DELETE"})}}},e=>{e.O(0,[964,857,358],()=>e(e.s=3308)),_N_E=e.O()}]);