PageSourceSearch

https://www.daohang.info/assets/AdminNavigationList-tSaSLrsD.js

js daohang.info collected 2026-10-02 01:57:13 UTC 13,011 bytes, 6 lines download raw bytes

1import{c as ie,r as s,j as t,o as B,a8 as oe,G as A,a6 as ce,B as v,t as i}from"./main-C79EErcN.js";import{a as f}from"./admin-C19NR1ES.js";import{C as de}from"./circle-check-big-C8td3zir.js";import{B as ue}from"./ban-C_-zOhzo.js";import{E as me}from"./external-link-XNu2uw0U.js";import{E as xe}from"./eye-off-D6EfFNvg.js";import{E as G}from"./eye-C7qxGb8k.js";import{L as pe}from"./lock-BTSP16HQ.js";import{d as O}from"./dayjs.min-fuLfW2M_.js";import{r as he}from"./zh-cn-DZn7Atgq.js";import{P as fe}from"./PageLayout-CdIn63Zq.js";import{P as be}from"./PageHeader-9AEgnBf5.js";import{S as T}from"./StatusBadge-gli4Vau2.js";import{S as ge}from"./SearchInput-brnlrbwi.js";import{D as ve}from"./DataTable-tvLZLwKh.js";import{S}from"./StatsCard-C9hcibC4.js";import{C as K}from"./ConfirmModal-DElb-j6k.js";import"./vendor-B--z-fyW.js";import"./utils-BJmlP30g.js";import"./Card-Z4pXdS6k.js";import"./Loading-DWe7wAdL.js";import"./EmptyState-BqiDZ8_q.js";import"./box-C8vbe5k_.js";/**
2 * @license lucide-react v0.562.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const Ne=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"12",cy:"5",r:"1",key:"gxeob9"}],["circle",{cx:"12",cy:"19",r:"1",key:"lyex9k"}]],U=ie("ellipsis-vertical",Ne),we=({items:r,disabled:x,className:c=""})=>{const[N,b]=s.useState(!1),p=s.useRef(null);return s.useEffect(()=>{const a=h=>{p.current&&!p.current.contains(h.target)&&b(!1)};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[]),r.length===0?t.jsx("button",{disabled:!0,className:"p-2 text-slate-300 dark:text-slate-600 cursor-not-allowed",children:t.jsx(U,{className:"h-4 w-4"})}):t.jsxs("div",{className:`relative ${c}`,ref:p,children:[t.jsx("button",{onClick:()=>!x&&b(!N),disabled:x,className:`p-2 rounded-lg transition-colors ${x?"text-slate-300 dark:text-slate-600 cursor-not-allowed":"text-slate-500 hover:text-slate-700 hover:bg-slate-100 dark:text-slate-400 dark:hover:text-slate-200 dark:hover:bg-slate-700"}`,children:t.jsx(U,{className:"h-4 w-4"})}),N&&t.jsx("div",{className:"absolute right-0 top-full mt-1 w-40 bg-white dark:bg-slate-800 rounded-lg shadow-lg border border-slate-200 dark:border-slate-700 py-1 z-50",children:r.map((a,h)=>{const u=a.icon;return t.jsxs("button",{onClick:()=>{a.disabled||(a.onClick(),b(!1))},disabled:a.disabled,className:`w-full flex items-center gap-2 px-3 py-2 text-sm text-left transition-colors ${a.disabled?"text-slate-300 dark:text-slate-600 cursor-not-allowed":`text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700 ${a.className||""}`}`,children:[u&&t.jsx(u,{className:"h-4 w-4"}),a.label]},h)})})]})};O.extend(he);O.locale("zh-cn");const $=r=>r==null?"0":r>=1e6?`${(r/1e6).toFixed(1)}M`:r>=1e3?`${(r/1e3).toFixed(1)}K`:r.toString(),Ue=()=>{var R,z;const[r,x]=s.useState([]),[c,N]=s.useState(null),[b,p]=s.useState(!1),[a,h]=s.useState(""),[u,w]=s.useState("all"),[j,Y]=s.useState(""),[k,H]=s.useState("created_at"),[y,V]=s.useState("desc"),[o,d]=s.useState(1),[C]=s.useState(20),[L,q]=s.useState(0),[g,J]=s.useState(1),[I,n]=s.useState(null),[E,M]=s.useState({isOpen:!1,nav:null}),[D,P]=s.useState({isOpen:!1,nav:null}),m=s.useCallback(async()=>{p(!0);try{const e=await f.getNavigations({search:a||void 0,page:o,limit:C,status:u,is_public:j,sort_by:k,sort_order:y});x(e.data),e.meta&&(q(e.meta.total||0),J(e.meta.last_page||1),e.meta.summary&&N(e.meta.summary))}catch(e){console.error("获取导航列表失败",e),x([])}finally{p(!1)}},[a,o,C,u,j,k,y]);s.useEffect(()=>{m()},[m]),s.useEffect(()=>{d(1)},[a,u,j,k,y]);const Q=async e=>{M({isOpen:!0,nav:e})},W=async()=>{const e=E.nav;if(e){M({isOpen:!1,nav:null}),n(e.id);try{await f.banNavigation(e.id),i.success("导航已封禁"),m()}catch(l){console.error("封禁失败",l),i.error("封禁失败")}finally{n(null)}}},X=async e=>{n(e.id);try{await f.unbanNavigation(e.id),i.success("导航已解封"),m()}catch(l){console.error("解封失败",l),i.error("解封失败")}finally{n(null)}},Z=async e=>{n(e.id);try{await f.toggleNavigationPublic(e.id,!e.is_public),i.success(e.is_public?"已设为私有":"已设为公开"),m()}catch(l){console.error("切换状态失败",l),i.error("操作失败")}finally{n(null)}},ee=async e=>{n(e.id);try{await f.recoverNavigation(e.id),i.success("导航已恢复"),m()}catch(l){console.error("恢复失败",l),i.error("恢复失败")}finally{n(null)}},F=async e=>{P({isOpen:!0,nav:e})},te=async()=>{const e=D.nav;if(e){P({isOpen:!1,nav:null}),n(e.id);try{await f.deleteNavigation(e.id),i.success("导航已删除"),m()}catch(l){console.error("删除失败",l),i.error("删除失败")}finally{n(null)}}},se=e=>e.user_account&&e.slug?`/u/${e.user_account}/${e.slug}`:null,ae=s.useMemo(()=>[{header:"ID",accessor:"id",className:"whitespace-nowrap text-sm text-slate-500 dark:text-slate-400 w-16"},{header:"导航名称",cell:e=>{const l=se(e);return t.jsxs("div",{className:"min-w-[200px]",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("span",{className:"text-sm font-medium text-slate-900 dark:text-white",children:e.name}),e.is_password_protected&&t.jsx("span",{title:"密码保护",children:t.jsx(pe,{className:"h-3.5 w-3.5 text-blue-500"})}),l&&t.jsx("a",{href:l,target:"_blank",rel:"noopener noreferrer",className:"text-slate-400 hover:text-primary-500 transition-colors",onClick:_=>_.stopPropagation(),children:t.jsx(me,{className:"h-3.5 w-3.5"})})]}),t.jsxs("div",{className:"text-xs text-slate-500 dark:text-slate-400",children:["/",e.user_account,"/",e.slug]})]})},className:"whitespace-nowrap"},{header:"所有者",cell:e=>t.jsxs("div",{className:"text-sm",children:[t.jsx("div",{className:"text-slate-900 dark:text-white",children:e.user_nickname||e.user_account||"-"}),e.user_nickname&&e.user_account&&t.jsxs("div",{className:"text-xs text-slate-500 dark:text-slate-400",children:["@",e.user_account]})]}),className:"whitespace-nowrap"},{header:"状态",cell:e=>{const _={active:{color:"green",label:"正常"},banned:{color:"red",label:"封禁"},deleted:{color:"slate",label:"已删除"}}[e.status]||{color:"slate",label:e.status};return t.jsx(T,{color:_.color,children:_.label})},className:"whitespace-nowrap w-20"},{header:"可见性",cell:e=>t.jsxs("div",{className:"flex flex-wrap gap-1",children:[t.jsx(T,{color:e.is_public?"green":"amber",className:"text-[10px] py-0 px-1",children:e.is_public?"公开":"私有"}),e.is_password_protected&&t.jsx(T,{color:"blue",className:"text-[10px] py-0 px-1",children:"口令"})]}),className:"whitespace-nowrap w-24"},{header:"访问量",cell:e=>t.jsx("span",{className:"text-sm font-medium text-slate-700 dark:text-slate-300",title:e.views.toString(),children:$(e.views)}),className:"whitespace-nowrap text-center w-20",headerClassName:"text-center"},{header:"链接数",cell:e=>t.jsx("span",{className:"text-sm font-medium text-slate-700 dark:text-slate-300",children:$(e.link_count)}),className:"whitespace-nowrap text-center w-20",headerClassName:"text-center"},{header:"时间",cell:e=>t.jsxs("div",{className:"text-sm text-slate-500 dark:text-slate-400",children:[t.jsxs("div",{children:["更新: ",O(e.updated_at).format("YYYY-MM-DD")]}),t.jsxs("div",{className:"text-xs",children:["创建: ",O(e.created_at).format("YYYY-MM-DD")]})]}),className:"whitespace-nowrap"},{header:"操作",cell:e=>{const l=I===e.id;return t.jsx(we,{items:[...e.status==="active"?[{label:e.is_public?"设为私有":"设为公开",icon:e.is_public?xe:G,onClick:()=>Z(e)},{label:"封禁",icon:ue,onClick:()=>Q(e),className:"text-red-600 dark:text-red-400"},{label:"删除",icon:B,onClick:()=>F(e),className:"text-red-600 dark:text-red-400"}]:[],...e.status==="banned"?[{label:"解封",icon:de,onClick:()=>X(e),className:"text-green-600 dark:text-green-400"},{label:"删除",icon:B,onClick:()=>F(e),className:"text-red-600 dark:text-red-400"}]:[],...e.status==="deleted"?[{label:"恢复",icon:oe,onClick:()=>
6ee(e),className:"text-blue-600 dark:text-blue-400"}]:[]],disabled:l})},className:"text-right w-16",headerClassName:"text-right"}],[I]),le=[{value:"all",label:"全部状态"},{value:"active",label:"正常"},{value:"banned",label:"封禁"},{value:"deleted",label:"已删除"}],re=[{value:"",label:"全部"},{value:1,label:"公开"},{value:0,label:"私有"}],ne=[{value:"created_at",label:"创建时间"},{value:"updated_at",label:"更新时间"},{value:"views",label:"访问量"},{value:"link_count",label:"链接数"}];return t.jsxs(fe,{children:[t.jsx(be,{title:"导航管理",description:"查看和管理所有用户创建的导航站点。"}),c&&t.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 mb-6",children:[t.jsx(S,{title:"活跃站点",value:c.active_count,icon:A,iconColor:"green",onClick:()=>{w("active"),d(1)},className:"cursor-pointer hover:shadow-md transition-shadow"}),t.jsx(S,{title:"公开站点",value:c.public_count,icon:G,iconColor:"blue",onClick:()=>{Y(1),w("all"),d(1)},className:"cursor-pointer hover:shadow-md transition-shadow"}),t.jsx(S,{title:"总访问量",value:t.jsx("span",{title:c.total_views.toLocaleString(),children:$(c.total_views)}),icon:ce,iconColor:"purple"}),t.jsx(S,{title:"删除站点",value:c.deleted_count,icon:B,iconColor:"slate",onClick:()=>{w("deleted"),d(1)},className:"cursor-pointer hover:shadow-md transition-shadow"})]}),t.jsx(ve,{data:r,columns:ae,loading:b,emptyTitle:"没有找到导航",emptyDescription:"尝试调整筛选条件",emptyIcon:A,getRowKey:e=>e.id,toolbar:t.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[t.jsx(ge,{placeholder:"搜索导航名称或 Slug...",value:a,onChange:e=>h(e.target.value),onSearch:e=>h(e),className:"w-64"}),t.jsx("select",{value:u,onChange:e=>w(e.target.value),className:"px-3 py-2 text-sm border border-slate-200 dark:border-slate-700 rounded-lg bg-white dark:bg-slate-950 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",children:le.map(e=>t.jsx("option",{value:e.value,children:e.label},e.value))}),t.jsx("select",{value:j,onChange:e=>Y(e.target.value===""?"":Number(e.target.value)),className:"px-3 py-2 text-sm border border-slate-200 dark:border-slate-700 rounded-lg bg-white dark:bg-slate-950 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",children:re.map(e=>t.jsx("option",{value:e.value,children:e.label},String(e.value)))}),t.jsx("select",{value:k,onChange:e=>H(e.target.value),className:"px-3 py-2 text-sm border border-slate-200 dark:border-slate-700 rounded-lg bg-white dark:bg-slate-950 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",children:ne.map(e=>t.jsx("option",{value:e.value,children:e.label},e.value))}),t.jsx(v,{variant:"ghost",size:"sm",onClick:()=>V(e=>e==="asc"?"desc":"asc"),className:"px-2",children:y==="desc"?"↓ 降序":"↑ 升序"})]}),footer:L>0?t.jsxs("div",{className:"flex items-center justify-between px-4 py-3 bg-slate-50 dark:bg-slate-950/30",children:[t.jsxs("div",{className:"flex flex-1 justify-between sm:hidden",children:[t.jsx(v,{variant:"secondary",onClick:()=>d(e=>Math.max(1,e-1)),disabled:o===1,children:"上一页"}),t.jsx(v,{variant:"secondary",onClick:()=>d(e=>Math.min(g,e+1)),disabled:o>=g,children:"下一页"})]}),t.jsxs("div",{className:"hidden sm:flex sm:flex-1 sm:items-center sm:justify-between",children:[t.jsx("div",{children:t.jsxs("p",{className:"text-sm text-slate-700 dark:text-slate-300",children:["显示 ",t.jsx("span",{className:"font-medium",children:(o-1)*C+1})," 到"," ",t.jsx("span",{className:"font-medium",children:Math.min(o*C,L)})," 共"," ",t.jsx("span",{className:"font-medium",children:L})," 条"]})}),t.jsx("div",{children:t.jsxs("nav",{className:"isolate inline-flex -space-x-px rounded-md shadow-sm","aria-label":"Pagination",children:[t.jsx(v,{variant:"secondary",onClick:()=>d(e=>Math.max(1,e-1)),disabled:o===1,className:"rounded-l-md",children:"上一页"}),t.jsxs("span",{className:"relative inline-flex items-center px-4 py-2 text-sm font-semibold text-slate-900 dark:text-white ring-1 ring-inset ring-slate-300 dark:ring-slate-600",children:[o," / ",g]}),t.jsx(v,{variant:"secondary",onClick:()=>d(e=>Math.min(g,e+1)),disabled:o>=g,className:"rounded-r-md",children:"下一页"})]})})]})]}):void 0}),t.jsx(K,{isOpen:E.isOpen,onClose:()=>M({isOpen:!1,nav:null}),onConfirm:W,title:"确认封禁",message:`确定要封禁导航 "${((R=E.nav)==null?void 0:R.name)||""}" 吗?封禁后用户将无法访问和编辑该导航。`,confirmText:"封禁",cancelText:"取消",variant:"danger"}),t.jsx(K,{isOpen:D.isOpen,onClose:()=>P({isOpen:!1,nav:null}),onConfirm:te,title:"确认删除",message:`确定要删除导航 "${((z=D.nav)==null?void 0:z.name)||""}" 吗?此操作为软删除,用户将无法访问,但您仍可在后台筛选“已删除”状态来恢复它。`,confirmText:"删除",cancelText:"取消",variant:"danger"})]})};export{Ue as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.