Files
YelayMaths/yelaymaths_admin/.next/static/chunks/app/(admin)/[resource]/page-11eaa5a84ee2c65d.js
T
2026-09-29 15:25:40 +08:00

1 line
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[920],{754:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>c});var n=a(1333),l=a(8166),r=a(4705),s=a(8312),i=a(2787);function o(e){let{config:t}=e,[a,l]=(0,r.useState)([]),[o,d]=(0,r.useState)(0),[c,m]=(0,r.useState)(1),[u,x]=(0,r.useState)(""),[p,h]=(0,r.useState)(!1),[b,y]=(0,r.useState)(""),[g,f]=(0,r.useState)(!1),[v,j]=(0,r.useState)(null),[N,w]=(0,r.useState)({}),[S,_]=(0,r.useState)(!1),k=t.fields.filter(e=>!e.hideInTable),C=(0,r.useCallback)((e,a)=>{h(!0),y(""),s.F.listResource(t.key,{page:e,pageSize:20,keyword:a}).then(e=>{l(e.items),d(e.total),m(e.page)}).catch(e=>y(e.message)).finally(()=>h(!1))},[t.key]);(0,r.useEffect)(()=>{x(""),C(1,"")},[t.key,C]);let T=Math.max(1,Math.ceil(o/20));return(0,n.jsxs)("div",{className:"space-y-4",children:[(0,n.jsx)(i.$T,{message:b}),(0,n.jsxs)(i.Zp,{title:"".concat(t.title,"(共 ").concat(o," 条)"),action:(0,n.jsxs)("div",{className:"flex gap-2",children:[(0,n.jsx)(i.pd,{value:u,onChange:x,placeholder:"搜索…"}),(0,n.jsx)(i.$n,{variant:"ghost",onClick:()=>C(1,u),children:"搜索"}),(0,n.jsx)(i.$n,{onClick:()=>{let e={};for(let r of t.fields){var a,n,l;e[r.name]="select"===r.type?String(null!=(l=null==(n=r.options)||null==(a=n[0])?void 0:a.value)?l:1):""}w(e),j(null),f(!0)},children:"新建"})]}),children:[(0,n.jsx)("p",{className:"mb-3 text-xs text-gray-500",children:t.description}),p?(0,n.jsx)("div",{className:"py-10 text-center text-sm text-gray-400",children:"加载中…"}):0===a.length?(0,n.jsx)(i.Sv,{}):(0,n.jsx)("div",{className:"overflow-x-auto",children:(0,n.jsxs)("table",{className:"w-full text-sm",children:[(0,n.jsx)("thead",{children:(0,n.jsxs)("tr",{className:"border-b border-gray-200 text-left text-xs text-gray-500",children:[(0,n.jsx)("th",{className:"px-2 py-2",children:"ID"}),k.map(e=>(0,n.jsx)("th",{className:"px-2 py-2",children:e.label},e.name)),(0,n.jsx)("th",{className:"px-2 py-2 text-right",children:"操作"})]})}),(0,n.jsx)("tbody",{children:a.map(e=>(0,n.jsxs)("tr",{className:"border-b border-gray-100 hover:bg-gray-50",children:[(0,n.jsx)("td",{className:"px-2 py-2 text-gray-400",children:String(e.id)}),k.map(t=>{let a=function(e,t){let a=t[e.name];if(null==a||""===a)return"—";if("select"===e.type&&e.options){let t=e.options.find(e=>e.value===Number(a));return t?t.label:String(a)}return"date"===e.type?String(a).slice(0,10):String(a)}(t,e);return(0,n.jsx)("td",{className:"max-w-[280px] truncate px-2 py-2",title:a,children:a},t.name)}),(0,n.jsxs)("td",{className:"whitespace-nowrap px-2 py-2 text-right",children:[(0,n.jsx)(i.$n,{variant:"ghost",onClick:()=>(e=>{let a={};for(let n of t.fields)a[n.name]=function(e,t){if(null==t)return"";if("date"===e.type){let e=new Date(String(t));return isNaN(e.getTime())?"":e.toISOString().slice(0,10)}return String(t)}(n,e[n.name]);w(a),j(e),f(!0)})(e),children:"编辑"})," ",(0,n.jsx)(i.$n,{variant:"danger",onClick:()=>{window.confirm("确定删除这条记录吗?此操作不可撤销。")&&(y(""),s.F.deleteResource(t.key,Number(e.id)).then(()=>C(c,u)).catch(e=>y(e.message)))},children:"删除"})]})]},String(e.id)))})]})}),(0,n.jsxs)("div",{className:"mt-4 flex items-center justify-between text-sm text-gray-500",children:[(0,n.jsxs)("span",{children:["第 ",c," / ",T," 页"]}),(0,n.jsxs)("div",{className:"flex gap-2",children:[(0,n.jsx)(i.$n,{variant:"ghost",disabled:c<=1,onClick:()=>C(c-1,u),children:"上一页"}),(0,n.jsx)(i.$n,{variant:"ghost",disabled:c>=T,onClick:()=>C(c+1,u),children:"下一页"})]})]})]}),(0,n.jsx)(i.aF,{open:g,title:"".concat(v?"编辑":"新建").concat(t.title),onClose:()=>f(!1),footer:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.$n,{variant:"ghost",onClick:()=>f(!1),children:"取消"}),(0,n.jsx)(i.$n,{onClick:()=>{let e=function(e,t){let a={};for(let n of e){let e=t[n.name];void 0!==e&&(""===e?a[n.name]="number"===n.type?0:null:"number"===n.type||"select"===n.type?a[n.name]=Number(e):a[n.name]=e)}return a}(t.fields.filter(e=>!(v&&e.immutable)),N);_(!0),y(""),(v?s.F.updateResource(t.key,Number(v.id),e):s.F.createResource(t.key,e)).then(()=>{f(!1),C(c,u)}).catch(e=>y(e.message)).finally(()=>_(!1))},disabled:S,children:S?"保存中…":"保存"})]}),children:(0,n.jsx)("div",{className:"space-y-3",children:t.fields.map(e=>{var t,a,l,r;let s=!!(v&&e.immutable);return(0,n.jsxs)("div",{children:[(0,n.jsxs)("label",{className:"mb-1 block text-sm text-gray-600",children:[e.label,e.immutable&&(0,n.jsx)("span",{className:"ml-2 text-xs text-orange-500",children:"创建后不可修改"})]}),"textarea"===e.type?(0,n.jsx)(i.TM,{value:null!=(t=N[e.name])?t:"",onChange:t=>w({...N,[e.name]:t})}):"select"===e.type?(0,n.jsx)(i.l6,{value:null!=(a=N[e.name])?a:"",onChange:t=>w({...N,[e.name]:t}),options:null!=(l=e.options)?l:[]}):(0,n.jsx)("div",{className:s?"pointer-events-none opacity-60":"",children:(0,n.jsx)(i.pd,{value:null!=(r=N[e.name])?r:"",onChange:t=>w({...N,[e.name]:t}),type:"number"===e.type?"number":"date"===e.type?"date":"text",placeholder:e.placeholder})}),e.hint&&(0,n.jsx)("p",{className:"mt-1 text-xs text-gray-400",children:e.hint})]},e.name)})})})]})}var d=a(4357);function c(){var e;let t=(0,l.useParams)(),a=null!=(e=null==t?void 0:t.resource)?e:"",r=(0,d.MW)(a);return r?(0,n.jsxs)("div",{className:"space-y-4",children:[(0,n.jsx)("h1",{className:"text-lg font-semibold text-gray-900",children:r.title}),(0,n.jsx)(o,{config:r})]}):(0,n.jsxs)("div",{className:"rounded-lg border border-gray-200 bg-white p-6 text-sm text-gray-500",children:["未知的资源类型:",a]})}},1910:(e,t,a)=>{"use strict";a.d(t,{L:()=>s,M3:()=>i,WG:()=>r,gf:()=>l});let n="yelay_admin_token";function l(){var e;return null!=(e=window.localStorage.getItem(n))?e:""}function r(e){window.localStorage.setItem(n,e)}function s(){window.localStorage.removeItem(n)}function i(){return""!==l()}},2787:(e,t,a)=>{"use strict";a.d(t,{$T:()=>c,$n:()=>l,Sv:()=>m,TM:()=>s,Zp:()=>o,aF:()=>d,l6:()=>i,pd:()=>r});var n=a(1333);function l(e){let{children:t,onClick:a,variant:l="primary",disabled:r,type:s="button"}=e;return(0,n.jsx)("button",{type:s,onClick:a,disabled:r,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"}[l]),children:t})}function r(e){let{value:t,onChange:a,placeholder:l,type:r="text"}=e;return(0,n.jsx)("input",{type:r,value:t,placeholder:l,onChange:e=>a(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 s(e){let{value:t,onChange:a}=e;return(0,n.jsx)("textarea",{value:t,rows:6,onChange:e=>a(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:a,options:l}=e;return(0,n.jsx)("select",{value:t,onChange:e=>a(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:l.map(e=>(0,n.jsx)("option",{value:String(e.value),children:e.label},e.value))})}function o(e){let{title:t,children:a,action:l}=e;return(0,n.jsxs)("section",{className:"rounded-lg border border-gray-200 bg-white p-5 shadow-sm",children:[(t||l)&&(0,n.jsxs)("header",{className:"mb-4 flex items-center justify-between",children:[t&&(0,n.jsx)("h2",{className:"text-base font-semibold text-gray-900",children:t}),l]}),a]})}function d(e){let{open:t,title:a,onClose:l,children:r,footer:s}=e;return t?(0,n.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:(0,n.jsxs)("div",{className:"max-h-[85vh] w-full max-w-2xl overflow-auto rounded-lg bg-white shadow-xl",children:[(0,n.jsxs)("header",{className:"flex items-center justify-between border-b border-gray-200 px-5 py-3",children:[(0,n.jsx)("h3",{className:"text-base font-semibold",children:a}),(0,n.jsx)("button",{onClick:l,className:"text-gray-400 hover:text-gray-600","aria-label":"关闭",children:"✕"})]}),(0,n.jsx)("div",{className:"px-5 py-4",children:r}),s&&(0,n.jsx)("footer",{className:"flex justify-end gap-2 border-t border-gray-200 px-5 py-3",children:s})]})}):null}function c(e){let{message:t,kind:a="error"}=e;return t?(0,n.jsx)("div",{className:"mb-3 rounded-md border px-3 py-2 text-sm ".concat("error"===a?"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,n.jsx)("div",{className:"py-10 text-center text-sm text-gray-400",children:t})}},4357:(e,t,a)=>{"use strict";a.d(t,{MW:()=>s,le:()=>r,u_:()=>i});let n={name:"status",label:"状态",type:"select",options:[{value:1,label:"启用"},{value:0,label:"停用"}]},l={name:"sort_order",label:"排序",type:"number",hideInTable:!0},r=[{key:"courses",title:"课程",description:"付费课程。注意 code 是视频目录名与封面名,创建后不可修改。",fields:[{name:"code",label:"课程标识",type:"text",immutable:!0,hint:"64 位哈希,对应视频目录"},{name:"title",label:"课程名称",type:"text"},{name:"intro",label:"课程介绍",type:"text"},{name:"price_fen",label:"价格(分)",type:"number"},{name:"cover_image",label:"封面文件",type:"text",hideInTable:!0},n,l]},{key:"lessons",title:"课时",description:"课程下的视频。chapter_id 与 play_id 参与视频路径拼接,改动会使旧地址失效。",filterByCourse:!0,fields:[{name:"course_id",label:"课程 ID",type:"number"},{name:"chapter_id",label:"章节 ID",type:"text"},{name:"play_id",label:"播放 ID",type:"text"},{name:"chapter_title",label:"章节名称",type:"text"},{name:"lesson_title",label:"视频名称",type:"text"},{name:"duration",label:"时长",type:"text"},{name:"published_at",label:"发布日期",type:"date"},l]},{key:"home-courses",title:"首页新课",description:"首页「新课上线」的长图页面。course_name 决定图片路径,不要改动。",fields:[{name:"course_name",label:"条目名称",type:"text",hint:"对应 Images/NewCourse/{名称}.png"},{name:"intro",label:"简介",type:"text"},{name:"course_id",label:"关联课程 ID",type:"number",hint:"留空则长图页不显示购买按钮"},{name:"content",label:"长图内容",type:"textarea",hideInTable:!0},{name:"published_at",label:"发布日期",type:"date",hideInTable:!0},n,l]},{key:"home-free-courses",title:"首页试听",description:"首页「自我学习」入口。course_name 决定图片路径。",fields:[{name:"series_no",label:"序号",type:"number",hint:"对应免费试听课的 series_no"},{name:"course_name",label:"条目名称",type:"text"},{name:"intro",label:"简介",type:"text"},n,l]},{key:"banners",title:"轮播图",description:"首页顶部轮播。filename 对应 Images/Banner/{文件名}。",fields:[{name:"filename",label:"图片文件名",type:"text"},n,l]},{key:"articles",title:"知识速通",description:"首页「知识速通」文章。legacy_page_id 对应缩略图 WebPages/{id}.png。",fields:[{name:"title",label:"标题",type:"text"},{name:"legacy_page_id",label:"图片编号",type:"text"},{name:"intro",label:"简介",type:"text"},{name:"publisher",label:"发布人",type:"text",hideInTable:!0},{name:"content",label:"正文",type:"textarea",hideInTable:!0},{name:"published_at",label:"发布日期",type:"date"},n,l]},{key:"products",title:"支付商品",description:"课程与微信虚拟支付道具的映射。微信道具 ID 与价格必须先在小程序后台创建。",fields:[{name:"course_id",label:"课程 ID",type:"number"},{name:"wx_product_id",label:"微信道具 ID",type:"text"},{name:"name",label:"商品名称",type:"text"},{name:"price_fen",label:"价格(分)",type:"text"},n]}],s=e=>r.find(t=>t.key===e),i={0:"待支付",1:"已支付",2:"已开通",3:"已退款",4:"已关闭"}},8166:(e,t,a)=>{"use strict";var n=a(8874);a.o(n,"useParams")&&a.d(t,{useParams:function(){return n.useParams}}),a.o(n,"usePathname")&&a.d(t,{usePathname:function(){return n.usePathname}}),a.o(n,"useRouter")&&a.d(t,{useRouter:function(){return n.useRouter}})},8312:(e,t,a)=>{"use strict";a.d(t,{F:()=>i});var n=a(1910);let l="http://127.0.0.1:3000".replace(/\/+$/,"");async function r(e){var t,a,r,s,i;let o,d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=(0,n.gf)(),m={"content-type":"application/json",...null!=(t=d.headers)?t:{}};c&&(m.Authorization="Bearer ".concat(c));try{o=await fetch("".concat(l).concat(e),{...d,headers:m})}catch(e){throw{code:-1,message:"无法连接服务端,请检查网络或接口地址"}}let u=null;try{u=await o.json()}catch(e){throw{code:-1,message:"服务端返回异常(HTTP ".concat(o.status,")")}}if(401===o.status)throw(0,n.L)(),window.location.pathname.startsWith("/login")||(window.location.href="/login"),{code:null!=(a=null==u?void 0:u.code)?a:2e3,message:null!=(r=null==u?void 0:u.message)?r:"登录已失效,请重新登录"};if(!u||0!==u.code)throw{code:null!=(s=null==u?void 0:u.code)?s:-1,message:null!=(i=null==u?void 0:u.message)?i:"请求失败"};return u.data}let s=e=>{let t=Object.entries(e).filter(e=>{let[,t]=e;return void 0!==t&&""!==t}).map(e=>{let[t,a]=e;return"".concat(encodeURIComponent(t),"=").concat(encodeURIComponent(String(a)))});return t.length?"?".concat(t.join("&")):""},i={base:l,request:r,login:(e,t)=>r("/admin/v1/auth/login",{method:"POST",body:JSON.stringify({username:e,password:t})}),bootstrap:(e,t)=>r("/admin/v1/auth/bootstrap",{method:"POST",body:JSON.stringify({username:e,password:t})}),stats:()=>r("/admin/v1/stats"),listUsers:(e,t,a)=>r("/admin/v1/users".concat(s({page:e,pageSize:t,keyword:a}))),updateUser:(e,t)=>r("/admin/v1/users/".concat(e),{method:"PATCH",body:JSON.stringify(t)}),listResource:(e,t)=>r("/admin/v1/data/".concat(e).concat(s(t))),createResource:(e,t)=>r("/admin/v1/data/".concat(e),{method:"POST",body:JSON.stringify(t)}),updateResource:(e,t,a)=>r("/admin/v1/data/".concat(e,"/").concat(t),{method:"PATCH",body:JSON.stringify(a)}),deleteResource:(e,t)=>r("/admin/v1/data/".concat(e,"/").concat(t),{method:"DELETE"}),listSettings:()=>r("/admin/v1/settings"),upsertSetting:(e,t,a)=>r("/admin/v1/settings",{method:"PUT",body:JSON.stringify({key:e,value:t,remark:a})}),listOrders:(e,t,a)=>r("/admin/v1/orders".concat(s({page:e,pageSize:t,status:a}))),refundOrder:(e,t)=>r("/admin/v1/orders/".concat(e,"/refund"),{method:"POST",body:JSON.stringify({reason:t})}),listEntitlements:e=>r("/admin/v1/entitlements".concat(s({userId:e}))),grantEntitlement:(e,t,a)=>r("/admin/v1/entitlements",{method:"POST",body:JSON.stringify({userId:e,courseId:t,note:a})}),revokeEntitlement:(e,t)=>r("/admin/v1/entitlements".concat(s({userId:e,courseId:t})),{method:"DELETE"})}},8630:(e,t,a)=>{Promise.resolve().then(a.bind(a,754))}},e=>{e.O(0,[964,857,358],()=>e(e.s=8630)),_N_E=e.O()}]);