Files
mai-bot/dashboard/dist/assets/plugin-detail-C98YfI36.js

2 lines
19 KiB
JavaScript

import{r,j as e,i as xe,x as ue}from"./router-zNjPR4CY.js";import{E as re,B as m,D as he,h as fe,i as pe,j as ge,k as je,l as Ne,a3 as ve,C as _,S as te,b as P,d as I,e as we,f as O,x as q}from"./index-CuOHsLf7.js";import{B as S}from"./badge-CDs67obV.js";import{e as ye,l as be,h as _e,j as Se,a as ke,g as Ce,i as Ee,b as Re,u as De,d as Pe,r as Ie}from"./plugin-stats-Bq_VsOhk.js";import{g as U,c as G,a as z}from"./installed-CHw5f9lL.js";import{M as $e}from"./markdown-renderer-CrKRiZ7X.js";import{T as Le}from"./textarea-8PIujbf-.js";import{aH as B,aX as k,a_ as K,a$ as ae,g as Q,L as $,W as ie,R as ne,v as Me,e as Te,a1 as Ae,a5 as Z,P as Fe,aB as Oe,J as Ue,b0 as Ge,ai as ze,am as Be}from"./icons-DTcdLw9j.js";import"./misc-BwRzHX8c.js";import"./radix-C-ZuImoP.js";import"./utils-DjBw3JGv.js";import"./unified-ws-CBnrIqHW.js";import"./markdown-6e5N06bH.js";function Ve({pluginId:u,compact:f=!1}){const[t,s]=r.useState(null),[V,C]=r.useState(!0),[l,L]=r.useState(0),[p,M]=r.useState(""),[j,N]=r.useState(!1),{toast:x}=re(),o=async()=>{C(!0);const a=await ye(u);a&&s(a),C(!1)};r.useEffect(()=>{o()},[u]);const H=async()=>{const a=await be(u);a.success?(x({title:"已点赞",description:"感谢你的支持!"}),o()):x({title:"点赞失败",description:a.error||"未知错误",variant:"destructive"})},E=async()=>{const a=await _e(u);a.success?(x({title:"已反馈",description:"感谢你的反馈!"}),o()):x({title:"操作失败",description:a.error||"未知错误",variant:"destructive"})},J=async()=>{if(l===0){x({title:"请选择评分",description:"至少选择 1 颗星",variant:"destructive"});return}const a=await Se(u,l,p||void 0);a.success?(x({title:"评分成功",description:"感谢你的评价!"}),N(!1),L(0),M(""),o()):x({title:"评分失败",description:a.error||"未知错误",variant:"destructive"})};return V?e.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(B,{className:"h-4 w-4"}),e.jsx("span",{children:"-"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(k,{className:"h-4 w-4"}),e.jsx("span",{children:"-"})]})]}):t?f?e.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",title:`下载量: ${t.downloads.toLocaleString()}`,children:[e.jsx(B,{className:"h-4 w-4"}),e.jsx("span",{children:t.downloads.toLocaleString()})]}),e.jsxs("div",{className:"flex items-center gap-1",title:`评分: ${t.rating.toFixed(1)} (${t.rating_count} 条评价)`,children:[e.jsx(k,{className:"h-4 w-4 fill-yellow-400 text-yellow-400"}),e.jsx("span",{children:t.rating.toFixed(1)})]}),e.jsxs("div",{className:"flex items-center gap-1",title:`点赞数: ${t.likes}`,children:[e.jsx(K,{className:"h-4 w-4"}),e.jsx("span",{children:t.likes})]})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(B,{className:"h-5 w-5 text-muted-foreground mb-1"}),e.jsx("span",{className:"text-2xl font-bold",children:t.downloads.toLocaleString()}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"下载量"})]}),e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(k,{className:"h-5 w-5 text-yellow-400 mb-1 fill-yellow-400"}),e.jsx("span",{className:"text-2xl font-bold",children:t.rating.toFixed(1)}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[t.rating_count," 条评价"]})]}),e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(K,{className:"h-5 w-5 text-green-500 mb-1"}),e.jsx("span",{className:"text-2xl font-bold",children:t.likes}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"点赞"})]}),e.jsxs("div",{className:"flex flex-col items-center p-3 rounded-lg border bg-card",children:[e.jsx(ae,{className:"h-5 w-5 text-red-500 mb-1"}),e.jsx("span",{className:"text-2xl font-bold",children:t.dislikes}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"点踩"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(m,{variant:"outline",size:"sm",onClick:H,children:[e.jsx(K,{className:"h-4 w-4 mr-1"}),"点赞"]}),e.jsxs(m,{variant:"outline",size:"sm",onClick:E,children:[e.jsx(ae,{className:"h-4 w-4 mr-1"}),"点踩"]}),e.jsxs(he,{open:j,onOpenChange:N,children:[e.jsx(fe,{asChild:!0,children:e.jsxs(m,{variant:"default",size:"sm",children:[e.jsx(k,{className:"h-4 w-4 mr-1"}),"评分"]})}),e.jsxs(pe,{children:[e.jsxs(ge,{children:[e.jsx(je,{children:"为插件评分"}),e.jsx(Ne,{children:"分享你的使用体验,帮助其他用户"})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx("div",{className:"flex gap-2",children:[1,2,3,4,5].map(a=>e.jsx("button",{onClick:()=>L(a),className:"focus:outline-none",children:e.jsx(k,{className:`h-8 w-8 transition-colors ${a<=l?"fill-yellow-400 text-yellow-400":"text-muted-foreground hover:text-yellow-300"}`})},a))}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[l===0&&"点击星星进行评分",l===1&&"很差",l===2&&"一般",l===3&&"还行",l===4&&"不错",l===5&&"非常好"]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"plugin-rating-comment",className:"text-sm font-medium mb-2 block",children:"评论(可选)"}),e.jsx(Le,{value:p,id:"plugin-rating-comment",onChange:a=>M(a.target.value),placeholder:"分享你的使用体验...",rows:4,maxLength:500}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-1 text-right",children:[p.length," / 500"]})]})]}),e.jsxs(ve,{children:[e.jsx(m,{variant:"outline",onClick:()=>N(!1),children:"取消"}),e.jsx(m,{onClick:J,disabled:l===0,children:"提交评分"})]})]})]})]}),t.recent_ratings&&t.recent_ratings.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("h4",{className:"text-sm font-semibold",children:"最近评价"}),e.jsx("div",{className:"space-y-3",children:t.recent_ratings.map((a,v)=>e.jsxs("div",{className:"p-3 rounded-lg border bg-muted/50",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("div",{className:"flex gap-1",children:[1,2,3,4,5].map(g=>e.jsx(k,{className:`h-3 w-3 ${g<=a.rating?"fill-yellow-400 text-yellow-400":"text-muted-foreground"}`},g))}),e.jsx("span",{className:"text-xs text-muted-foreground",children:new Date(a.created_at).toLocaleDateString()})]}),a.comment&&e.jsx("p",{className:"text-sm text-muted-foreground",children:a.comment})]},v))})]})]}):null}const He={"Group Management":"群组管理","Entertainment & Interaction":"娱乐互动","Utility Tools":"实用工具","Content Generation":"内容生成",Multimedia:"多媒体","External Integration":"外部集成","Data Analysis & Insights":"数据分析与洞察",Other:"其他"};function ns(){const u=xe(),f=ue({strict:!1}),{toast:t}=re(),[s,V]=r.useState(null),[C,l]=r.useState(""),[L,p]=r.useState(!0),[M,j]=r.useState(!0),[N,x]=r.useState(null),[o,H]=r.useState(null),[E,J]=r.useState(null),[a,v]=r.useState(!1),[g,T]=r.useState(),[w,y]=r.useState(!1);r.useEffect(()=>{(async()=>{if(!f.pluginId){x("缺少插件 ID"),p(!1);return}try{p(!0),x(null);const n=await q("/api/webui/plugins/fetch-raw",{method:"POST",body:JSON.stringify({owner:"Mai-with-u",repo:"plugin-repo",branch:"main",file_path:"plugin_details.json"})});if(!n.ok)throw new Error("获取插件列表失败");const c=await n.json();if(!c.success||!c.data)throw new Error(c.error||"获取插件列表失败");const R=JSON.parse(c.data).find(se=>(se.manifest?.id||se.id)===f.pluginId);if(!R)throw new Error("未找到该插件");const d=R.manifest||{},h=d.id||R.id,b=d.repository_url||d.urls?.repository,D=d.homepage_url||d.urls?.homepage,me={id:h,manifest:{...d,id:h,homepage_url:D,repository_url:b,default_locale:d.default_locale||d.i18n?.default_locale||"zh-CN",locales_path:d.locales_path||d.i18n?.locales_path},downloads:0,rating:0,review_count:0,installed:!1,published_at:new Date().toISOString(),updated_at:new Date().toISOString()};V(me);const[X,Y,F]=await Promise.all([ke(),Ce(),U()]);if(X.success?H(X.data):t({title:"Git 状态检查失败",description:X.error,variant:"destructive"}),Y.success?J(Y.data):t({title:"版本获取失败",description:Y.error,variant:"destructive"}),!F.success){t({title:"获取已安装插件失败",description:F.error,variant:"destructive"});return}v(G(h,F.data)),T(z(h,F.data))}catch(n){x(n instanceof Error?n.message:"加载失败")}finally{p(!1)}})()},[f.pluginId]),r.useEffect(()=>{(async()=>{if(!s?.manifest?.repository_url){j(!1);return}try{if(j(!0),a&&f.pluginId)try{const b=await q(`/api/webui/plugins/local-readme/${s.id}`);if(b.ok){const D=await b.json();if(D.success&&D.data){l(D.data),j(!1);return}}}catch(b){console.log("本地 README 获取失败,尝试远程获取:",b)}const n=s.manifest.repository_url.match(/github\.com\/([^/]+)\/([^/\s]+)/);if(!n){l("无法解析仓库地址");return}const[,c,A]=n,R=A.replace(/\.git$/,""),d=await q("/api/webui/plugins/fetch-raw",{method:"POST",body:JSON.stringify({owner:c,repo:R,branch:"main",file_path:"README.md"})});if(!d.ok)throw new Error("获取 README 失败");const h=await d.json();h.success&&h.data?l(h.data):l("该插件暂无 README 文档")}catch(n){console.error("加载 README 失败:",n),l("加载 README 失败")}finally{j(!1)}})()},[s,a,f.pluginId]);const ee=()=>!s||!a||!g?!1:g!==s.manifest.version,le=()=>!s||!E?!0:Ee(s.manifest.host_application.min_version,s.manifest.host_application.max_version,E),ce=async()=>{if(!(!s||!o?.installed))try{y(!0);const i=s.manifest.repository_url||s.manifest.urls?.repository||"",n=await Pe(s.id,i,"main");if(!n.success){t({title:"安装失败",description:n.error,variant:"destructive"});return}Ie(s.id).catch(A=>{console.warn("Failed to record download:",A)}),t({title:"安装成功",description:`${s.manifest.name} 已成功安装`});const c=await U();if(!c.success){t({title:"获取已安装插件失败",description:c.error,variant:"destructive"});return}v(G(s.id,c.data)),T(z(s.id,c.data))}catch(i){t({title:"安装失败",description:i instanceof Error?i.message:"未知错误",variant:"destructive"})}finally{y(!1)}},oe=async()=>{if(s)try{y(!0);const i=await De(s.id);if(!i.success){t({title:"卸载失败",description:i.error,variant:"destructive"});return}t({title:"卸载成功",description:`${s.manifest.name} 已成功卸载`});const n=await U();if(!n.success){t({title:"获取已安装插件失败",description:n.error,variant:"destructive"});return}v(G(s.id,n.data)),T(z(s.id,n.data))}catch(i){t({title:"卸载失败",description:i instanceof Error?i.message:"未知错误",variant:"destructive"})}finally{y(!1)}},de=async()=>{if(!(!s||!o?.installed))try{y(!0);const i=s.manifest.repository_url||s.manifest.urls?.repository||"",n=await Re(s.id,i,"main");if(!n.success){t({title:"更新失败",description:n.error,variant:"destructive"});return}t({title:"更新成功",description:`${s.manifest.name} 已从 ${n.data.old_version} 更新到 ${n.data.new_version}`});const c=await U();if(!c.success){t({title:"获取已安装插件失败",description:c.error,variant:"destructive"});return}v(G(s.id,c.data)),T(z(s.id,c.data))}catch(i){t({title:"更新失败",description:i instanceof Error?i.message:"未知错误",variant:"destructive"})}finally{y(!1)}};if(L)return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(m,{variant:"ghost",size:"icon",onClick:()=>u({to:"/plugins"}),children:e.jsx(Q,{className:"h-5 w-5"})}),e.jsx("div",{children:e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件详情"})})]}),e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx($,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-3 text-muted-foreground",children:"加载插件信息中..."})]})]});if(N||!s)return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(m,{variant:"ghost",size:"icon",onClick:()=>u({to:"/plugins"}),children:e.jsx(Q,{className:"h-5 w-5"})}),e.jsx("div",{children:e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件详情"})})]}),e.jsx(_,{className:"p-6",children:e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 text-center",children:[e.jsx(ie,{className:"h-12 w-12 text-destructive mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"加载失败"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:N}),e.jsx(m,{onClick:()=>u({to:"/plugins"}),children:"返回插件列表"})]})})]});const W=le();return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(m,{variant:"ghost",size:"icon",onClick:()=>u({to:"/plugins"}),className:"shrink-0",children:e.jsx(Q,{className:"h-5 w-5"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"插件详情"}),e.jsx("p",{className:"text-muted-foreground mt-1 sm:mt-2 text-sm sm:text-base",children:s.manifest.name})]})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:a?e.jsxs(e.Fragment,{children:[ee()?e.jsx(m,{disabled:!o?.installed||w,onClick:de,title:o?.installed?void 0:"Git 未安装",children:w?e.jsxs(e.Fragment,{children:[e.jsx($,{className:"h-4 w-4 mr-2 animate-spin"}),"更新中..."]}):e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"h-4 w-4 mr-2"}),"更新"]})}):null,e.jsx(m,{variant:"destructive",disabled:!o?.installed||w,onClick:oe,title:o?.installed?void 0:"Git 未安装",children:w?e.jsxs(e.Fragment,{children:[e.jsx($,{className:"h-4 w-4 mr-2 animate-spin"}),"卸载中..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Me,{className:"h-4 w-4 mr-2"}),"卸载"]})})]}):e.jsx(m,{disabled:!o?.installed||!W||w,onClick:ce,title:o?.installed?W?void 0:`不兼容当前版本 (需要 ${s.manifest.host_application.min_version}${s.manifest.host_application.max_version?` - ${s.manifest.host_application.max_version}`:"+"},当前 ${E?.version})`:"Git 未安装",children:w?e.jsxs(e.Fragment,{children:[e.jsx($,{className:"h-4 w-4 mr-2 animate-spin"}),"安装中..."]}):e.jsxs(e.Fragment,{children:[e.jsx(B,{className:"h-4 w-4 mr-2"}),"安装"]})})})]}),e.jsx(te,{className:"h-[calc(100vh-200px)] sm:h-[calc(100vh-220px)]",children:e.jsxs("div",{className:"space-y-6 pr-4",children:[e.jsx(_,{children:e.jsx(P,{children:e.jsx("div",{className:"flex items-start justify-between gap-4",children:e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsx(I,{className:"text-2xl",children:s.manifest.name}),e.jsxs(S,{variant:"secondary",className:"text-sm",children:["v",s.manifest.version]}),a&&e.jsxs(S,{variant:"default",className:"text-sm",children:[e.jsx(Te,{className:"h-3 w-3 mr-1"}),"已安装 ",g&&`(v${g})`]}),ee()&&e.jsxs(S,{variant:"outline",className:"text-sm border-orange-500 text-orange-500",children:[e.jsx(ne,{className:"h-3 w-3 mr-1"}),"可更新"]}),!W&&e.jsxs(S,{variant:"destructive",className:"text-sm",children:[e.jsx(ie,{className:"h-3 w-3 mr-1"}),"不兼容"]})]}),e.jsx(we,{className:"text-base",children:s.manifest.description})]})})})}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"lg:col-span-1 space-y-6",children:[e.jsxs(_,{children:[e.jsx(P,{children:e.jsx(I,{className:"text-lg",children:"统计信息"})}),e.jsx(O,{children:e.jsx(Ve,{pluginId:s.id})})]}),e.jsxs(_,{children:[e.jsx(P,{children:e.jsx(I,{className:"text-lg",children:"基本信息"})}),e.jsx(O,{className:"space-y-4",children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Ae,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"作者:"}),e.jsx("span",{className:"font-medium",children:s.manifest.author?.name||"Unknown"}),s.manifest.author?.url&&e.jsx("a",{href:s.manifest.author.url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:e.jsx(Z,{className:"h-3 w-3"})})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Fe,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"版本:"}),e.jsxs("span",{className:"font-medium",children:["v",s.manifest.version]})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Oe,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"许可证:"}),e.jsx("span",{className:"font-medium",children:s.manifest.license})]}),s.manifest.homepage_url&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Ue,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"主页:"}),e.jsxs("a",{href:s.manifest.homepage_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline flex items-center gap-1",children:["访问",e.jsx(Z,{className:"h-3 w-3"})]})]}),s.manifest.repository_url&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Ge,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"仓库:"}),e.jsxs("a",{href:s.manifest.repository_url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline flex items-center gap-1",children:["GitHub",e.jsx(Z,{className:"h-3 w-3"})]})]}),e.jsxs("div",{className:"pt-2 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm mb-2",children:[e.jsx(ze,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-muted-foreground",children:"支持版本:"})]}),e.jsxs("div",{className:"text-sm pl-6 font-medium",children:[s.manifest.host_application.min_version,s.manifest.host_application.max_version?` - ${s.manifest.host_application.max_version}`:" - 最新版本"]})]})]})})]}),(s.manifest.categories||s.manifest.keywords)&&e.jsxs(_,{children:[e.jsx(P,{children:e.jsx(I,{className:"text-lg",children:"分类与标签"})}),e.jsxs(O,{className:"space-y-4",children:[s.manifest.categories&&s.manifest.categories.length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"分类"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:s.manifest.categories.map(i=>e.jsx(S,{variant:"secondary",children:He[i]||i},i))})]}),s.manifest.keywords&&s.manifest.keywords.length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"标签"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:s.manifest.keywords.map(i=>e.jsxs(S,{variant:"outline",className:"text-xs",children:[e.jsx(Be,{className:"h-3 w-3 mr-1"}),i]},i))})]})]})]})]}),e.jsxs(_,{className:"lg:col-span-2",children:[e.jsx(P,{children:e.jsx(I,{className:"text-lg",children:"插件说明"})}),e.jsx(O,{children:e.jsx(te,{className:"h-[600px] pr-4",children:M?e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx($,{className:"h-6 w-6 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-3 text-sm text-muted-foreground",children:"加载说明文档中..."})]}):C?e.jsx($e,{content:C}):e.jsx("div",{className:"text-center text-muted-foreground py-12",children:"暂无说明文档"})})})]})]})]})})]})}export{ns as PluginDetailPage};