Files
mai-bot/dashboard/dist/assets/index-Bsbt9db6.js

6 lines
38 KiB
JavaScript

import{r as a,j as e}from"./router-zNjPR4CY.js";import{x as M,D as ee,i as se,j as te,k as ne,a5 as ce,L as m,E as de,l as ue,a3 as Y,B as f,I as X,S as ve,g as le,C as I,b as A,e as K,d as R,f as ge,A as Ie,n as Ae,o as Re,q as Be,r as ze,s as He,t as Ve,v as We}from"./index-CuOHsLf7.js";import{S as B,a as z,b as H,c as V,d as j}from"./select-DGqIoF9r.js";import{D as Ge,U as Ke}from"./uppy-S0BLpioz.js";import{B as T}from"./badge-CDs67obV.js";import{C as Z}from"./checkbox-DWiVrbnx.js";import{M as Xe}from"./markdown-renderer-CrKRiZ7X.js";import{T as Je}from"./textarea-8PIujbf-.js";import{as as Ce,g as je,b as fe,X as qe,e as oe,at as Ne,au as Qe,ai as Ye,av as Ze,v as be,ap as es,G as ss,y as ts,aq as ns,aw as rs,R as as}from"./icons-DTcdLw9j.js";import{S as is}from"./skeleton-CXI2IV_v.js";import"./misc-BwRzHX8c.js";import"./radix-C-ZuImoP.js";import"./utils-DjBw3JGv.js";import"./charts-C6WIfXk3.js";import"./markdown-6e5N06bH.js";const _="/api/webui/emoji";async function ls(s){const t=new URLSearchParams;s.page&&t.append("page",s.page.toString()),s.page_size&&t.append("page_size",s.page_size.toString()),s.search&&t.append("search",s.search),s.is_registered!==void 0&&t.append("is_registered",s.is_registered.toString()),s.is_banned!==void 0&&t.append("is_banned",s.is_banned.toString()),s.format&&t.append("format",s.format),s.sort_by&&t.append("sort_by",s.sort_by),s.sort_order&&t.append("sort_order",s.sort_order);const r=await M(`${_}/list?${t}`,{});if(!r.ok)throw new Error(`获取表情包列表失败: ${r.statusText}`);return r.json()}async function os(s,t){const r=await M(`${_}/${s}`,{method:"PATCH",body:JSON.stringify(t)});if(!r.ok)throw new Error(`更新表情包失败: ${r.statusText}`);return r.json()}async function cs(s){const t=await M(`${_}/${s}`,{method:"DELETE"});if(!t.ok)throw new Error(`删除表情包失败: ${t.statusText}`);return t.json()}async function ds(){const s=await M(`${_}/stats/summary`,{});if(!s.ok)throw new Error(`获取统计数据失败: ${s.statusText}`);return s.json()}async function us(s){const t=await M(`${_}/${s}/register`,{method:"POST"});if(!t.ok)throw new Error(`注册表情包失败: ${t.statusText}`);return t.json()}async function ms(s){const t=await M(`${_}/${s}/ban`,{method:"POST"});if(!t.ok)throw new Error(`封禁表情包失败: ${t.statusText}`);return t.json()}function hs(s,t=!1){return t?`${_}/${s}/thumbnail?original=true`:`${_}/${s}/thumbnail`}function ps(s){return`${_}/${s}/thumbnail?original=true`}async function xs(s){const t=await M(`${_}/batch/delete`,{method:"POST",body:JSON.stringify({emoji_ids:s})});if(!t.ok){const r=await t.json();throw new Error(r.detail||"批量删除失败")}return t.json()}function gs(){return`${_}/upload`}const js=["defaultChecked","defaultValue","suppressContentEditableWarning","suppressHydrationWarning","dangerouslySetInnerHTML","accessKey","className","contentEditable","contextMenu","dir","draggable","hidden","id","lang","placeholder","slot","spellCheck","style","tabIndex","title","translate","radioGroup","role","about","datatype","inlist","prefix","property","resource","typeof","vocab","autoCapitalize","autoCorrect","autoSave","color","itemProp","itemScope","itemType","itemID","itemRef","results","security","unselectable","inputMode","is","onCopy","onCopyCapture","onCut","onCutCapture","onPaste","onPasteCapture","onCompositionEnd","onCompositionEndCapture","onCompositionStart","onCompositionStartCapture","onCompositionUpdate","onCompositionUpdateCapture","onFocus","onFocusCapture","onBlur","onBlurCapture","onChange","onChangeCapture","onBeforeInput","onBeforeInputCapture","onInput","onInputCapture","onReset","onResetCapture","onSubmit","onSubmitCapture","onInvalid","onInvalidCapture","onLoad","onLoadCapture","onError","onErrorCapture","onKeyDown","onKeyDownCapture","onKeyPress","onKeyPressCapture","onKeyUp","onKeyUpCapture","onAbort","onAbortCapture","onCanPlay","onCanPlayCapture","onCanPlayThrough","onCanPlayThroughCapture","onDurationChange","onDurationChangeCapture","onEmptied","onEmptiedCapture","onEncrypted","onEncryptedCapture","onEnded","onEndedCapture","onLoadedData","onLoadedDataCapture","onLoadedMetadata","onLoadedMetadataCapture","onLoadStart","onLoadStartCapture","onPause","onPauseCapture","onPlay","onPlayCapture","onPlaying","onPlayingCapture","onProgress","onProgressCapture","onRateChange","onRateChangeCapture","onSeeked","onSeekedCapture","onSeeking","onSeekingCapture","onStalled","onStalledCapture","onSuspend","onSuspendCapture","onTimeUpdate","onTimeUpdateCapture","onVolumeChange","onVolumeChangeCapture","onWaiting","onWaitingCapture","onAuxClick","onAuxClickCapture","onClick","onClickCapture","onContextMenu","onContextMenuCapture","onDoubleClick","onDoubleClickCapture","onDrag","onDragCapture","onDragEnd","onDragEndCapture","onDragEnter","onDragEnterCapture","onDragExit","onDragExitCapture","onDragLeave","onDragLeaveCapture","onDragOver","onDragOverCapture","onDragStart","onDragStartCapture","onDrop","onDropCapture","onMouseDown","onMouseDownCapture","onMouseEnter","onMouseLeave","onMouseMove","onMouseMoveCapture","onMouseOut","onMouseOutCapture","onMouseOver","onMouseOverCapture","onMouseUp","onMouseUpCapture","onSelect","onSelectCapture","onTouchCancel","onTouchCancelCapture","onTouchEnd","onTouchEndCapture","onTouchMove","onTouchMoveCapture","onTouchStart","onTouchStartCapture","onPointerDown","onPointerDownCapture","onPointerMove","onPointerMoveCapture","onPointerUp","onPointerUpCapture","onPointerCancel","onPointerCancelCapture","onPointerEnter","onPointerEnterCapture","onPointerLeave","onPointerLeaveCapture","onPointerOver","onPointerOverCapture","onPointerOut","onPointerOutCapture","onGotPointerCapture","onGotPointerCaptureCapture","onLostPointerCapture","onLostPointerCaptureCapture","onScroll","onScrollCapture","onWheel","onWheelCapture","onAnimationStart","onAnimationStartCapture","onAnimationEnd","onAnimationEndCapture","onAnimationIteration","onAnimationIterationCapture","onTransitionEnd","onTransitionEndCapture"],fs=/^(aria-|data-)/,ye=s=>Object.fromEntries(Object.entries(s).filter(([t])=>fs.test(t)||js.includes(t)));function vs(s,t){const r=ye(s);return Object.keys(s).some(l=>!Object.hasOwn(r,l)&&s[l]!==t[l])}class Cs extends a.Component{container;plugin;componentDidMount(){this.installPlugin()}componentDidUpdate(t){if(t.uppy!==this.props.uppy)this.uninstallPlugin(t),this.installPlugin();else if(vs(this.props,t)){const{uppy:r,...l}={...this.props,target:this.container};this.plugin.setOptions(l)}}componentWillUnmount(){this.uninstallPlugin()}installPlugin(){const{uppy:t,...r}={id:"Dashboard",...this.props,inline:!0,target:this.container};t.use(Ge,r),this.plugin=t.getPlugin(r.id)}uninstallPlugin(t=this.props){const{uppy:r}=t;r.removePlugin(this.plugin)}render(){return a.createElement("div",{className:"uppy-Container",ref:t=>{this.container=t},...ye(this.props)})}}function Ns({children:s,className:t}){return e.jsx(Xe,{content:s,className:t})}function bs({emoji:s,open:t,onOpenChange:r}){if(!s)return null;const l=p=>p?new Date(p*1e3).toLocaleString("zh-CN"):"-";return e.jsx(ee,{open:t,onOpenChange:r,children:e.jsxs(se,{className:"max-w-2xl max-h-[90vh]",children:[e.jsx(te,{children:e.jsx(ne,{children:"表情包详情"})}),e.jsx(ce,{children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex justify-center",children:e.jsx("div",{className:"w-32 h-32 bg-muted rounded-lg flex items-center justify-center overflow-hidden",children:e.jsx("img",{src:ps(s.id),alt:s.description||"表情包",className:"w-full h-full object-cover",onError:p=>{const c=p.target;c.style.display="none";const h=c.parentElement;h&&(h.innerHTML='<svg class="h-16 w-16 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>')}})})}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"ID"}),e.jsx("div",{className:"mt-1 font-mono",children:s.id})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"格式"}),e.jsx("div",{className:"mt-1",children:e.jsx(T,{variant:"outline",children:s.format.toUpperCase()})})]})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"文件路径"}),e.jsx("div",{className:"mt-1 font-mono text-sm break-all bg-muted p-2 rounded",children:s.full_path})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"哈希值"}),e.jsx("div",{className:"mt-1 font-mono text-sm break-all bg-muted p-2 rounded",children:s.emoji_hash})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"描述"}),s.description?e.jsx("div",{className:"mt-1 rounded-lg border bg-muted/50 p-3",children:e.jsx(Ns,{className:"prose-sm",children:s.description})}):e.jsx("div",{className:"mt-1 text-sm text-muted-foreground",children:"-"})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"情绪"}),e.jsx("div",{className:"mt-1",children:s.emotion?e.jsx("span",{className:"text-sm",children:s.emotion}):e.jsx("span",{className:"text-sm text-muted-foreground",children:"-"})})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"状态"}),e.jsxs("div",{className:"mt-2 flex gap-2",children:[s.is_registered&&e.jsx(T,{variant:"default",className:"bg-green-600",children:"已注册"}),s.is_banned&&e.jsx(T,{variant:"destructive",children:"已封禁"}),!s.is_registered&&!s.is_banned&&e.jsx(T,{variant:"outline",children:"未注册"})]})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"使用次数"}),e.jsx("div",{className:"mt-1 font-mono text-lg",children:s.usage_count})]})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"记录时间"}),e.jsx("div",{className:"mt-1 text-sm",children:l(s.record_time)})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"注册时间"}),e.jsx("div",{className:"mt-1 text-sm",children:l(s.register_time)})]})]}),e.jsxs("div",{children:[e.jsx(m,{className:"text-muted-foreground",children:"最后使用"}),e.jsx("div",{className:"mt-1 text-sm",children:l(s.last_used_time)})]})]})})]})})}function ys({emoji:s,open:t,onOpenChange:r,onSuccess:l}){const[p,c]=a.useState(""),[h,x]=a.useState(!1),[w,N]=a.useState(!1),[S,k]=a.useState(!1),{toast:b}=de();a.useEffect(()=>{s&&(c(s.emotion||""),x(s.is_registered),N(s.is_banned))},[s]);const E=async()=>{if(s)try{k(!0);const d=p.split(/[,,]/).map(D=>D.trim()).filter(Boolean).join(",");await os(s.id,{emotion:d||void 0,is_registered:h,is_banned:w}),b({title:"成功",description:"表情包信息已更新"}),r(!1),l()}catch(d){const D=d instanceof Error?d.message:"保存失败";b({title:"错误",description:D,variant:"destructive"})}finally{k(!1)}};return s?e.jsx(ee,{open:t,onOpenChange:r,children:e.jsxs(se,{className:"max-w-2xl",confirmOnEnter:!0,children:[e.jsxs(te,{children:[e.jsx(ne,{children:"编辑表情包"}),e.jsx(ue,{children:"修改表情包的情绪和状态信息"})]}),e.jsx(ce,{children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(m,{children:"情绪"}),e.jsx(Je,{value:p,onChange:d=>c(d.target.value),placeholder:"输入情绪描述...",rows:2,className:"mt-1"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"输入情绪相关的文本描述"})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Z,{id:"is_registered",checked:h,onCheckedChange:d=>{d===!0?(x(!0),N(!1)):x(!1)}}),e.jsx(m,{htmlFor:"is_registered",className:"cursor-pointer",children:"已注册"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Z,{id:"is_banned",checked:w,onCheckedChange:d=>{d===!0?(N(!0),x(!1)):N(!1)}}),e.jsx(m,{htmlFor:"is_banned",className:"cursor-pointer",children:"已封禁"})]})]})]})}),e.jsxs(Y,{children:[e.jsx(f,{variant:"outline",onClick:()=>r(!1),children:"取消"}),e.jsx(f,{"data-dialog-action":"confirm",onClick:E,disabled:S,children:S?"保存中...":"保存"})]})]})}):null}function ws({open:s,onOpenChange:t,onSuccess:r}){const[l,p]=a.useState("select"),[c,h]=a.useState([]),[x,w]=a.useState(null),[N,S]=a.useState(!1),{toast:k}=de(),b=a.useMemo(()=>new Ke({id:"emoji-uploader",autoProceed:!1,restrictions:{maxFileSize:10485760,allowedFileTypes:["image/jpeg","image/png","image/gif","image/webp"],maxNumberOfFiles:20},locale:{pluralize:()=>0,strings:{addMoreFiles:"添加更多文件",addingMoreFiles:"正在添加更多文件",allowedFileTypes:"允许的文件类型:%{types}",cancel:"取消",closeModal:"关闭",complete:"完成",connectedToInternet:"已连接到互联网",copyLink:"复制链接",copyLinkToClipboardFallback:"复制下方链接",copyLinkToClipboardSuccess:"链接已复制到剪贴板",dashboardTitle:"选择文件",dashboardWindowTitle:"文件选择窗口(按 ESC 关闭)",done:"完成",dropHereOr:"拖放文件到这里或 %{browse}",dropHint:"将文件拖放到此处",dropPasteFiles:"将文件拖放到这里或 %{browseFiles}",dropPasteFolders:"将文件拖放到这里或 %{browseFolders}",dropPasteBoth:"将文件拖放到这里,%{browseFiles} 或 %{browseFolders}",dropPasteImportFiles:"将文件拖放到这里,%{browseFiles} 或从以下位置导入:",dropPasteImportFolders:"将文件拖放到这里,%{browseFolders} 或从以下位置导入:",dropPasteImportBoth:"将文件拖放到这里,%{browseFiles},%{browseFolders} 或从以下位置导入:",editFile:"编辑文件",editing:"正在编辑 %{file}",emptyFolderAdded:"未从空文件夹添加文件",exceedsSize:"%{file} 超过了最大允许大小 %{size}",failedToUpload:"上传 %{file} 失败",fileSource:"文件来源:%{name}",filesUploadedOfTotal:{0:"已上传 %{complete} / %{smart_count} 个文件",1:"已上传 %{complete} / %{smart_count} 个文件"},filter:"筛选",finishEditingFile:"完成编辑文件",folderAdded:{0:"已从 %{folder} 添加 %{smart_count} 个文件",1:"已从 %{folder} 添加 %{smart_count} 个文件"},generatingThumbnails:"正在生成缩略图...",import:"导入",importFiles:"从以下位置导入文件:",importFrom:"从 %{name} 导入",loading:"加载中...",logOut:"登出",myDevice:"我的设备",noFilesFound:"这里没有文件或文件夹",noInternetConnection:"无网络连接",openFolderNamed:"打开文件夹 %{name}",pause:"暂停",pauseUpload:"暂停上传",paused:"已暂停",poweredBy:"技术支持:%{uppy}",processingXFiles:{0:"正在处理 %{smart_count} 个文件",1:"正在处理 %{smart_count} 个文件"},recording:"录制中",removeFile:"移除文件",resetFilter:"重置筛选",resume:"继续",resumeUpload:"继续上传",retry:"重试",retryUpload:"重试上传",save:"保存",saveChanges:"保存更改",selectFileNamed:"选择文件 %{name}",selectX:{0:"选择 %{smart_count}",1:"选择 %{smart_count}"},smile:"笑一个!",startRecording:"开始录制视频",stopRecording:"停止录制视频",takePicture:"拍照",timedOut:"上传已停滞 %{seconds} 秒,正在中止。",upload:"下一步",uploadComplete:"上传完成",uploadFailed:"上传失败",uploadPaused:"上传已暂停",uploadXFiles:{0:"下一步(%{smart_count} 个文件)",1:"下一步(%{smart_count} 个文件)"},uploadXNewFiles:{0:"下一步(+%{smart_count} 个文件)",1:"下一步(+%{smart_count} 个文件)"},uploading:"正在上传",uploadingXFiles:{0:"正在上传 %{smart_count} 个文件",1:"正在上传 %{smart_count} 个文件"},xFilesSelected:{0:"已选择 %{smart_count} 个文件",1:"已选择 %{smart_count} 个文件"},xMoreFilesAdded:{0:"又添加了 %{smart_count} 个文件",1:"又添加了 %{smart_count} 个文件"},xTimeLeft:"剩余 %{time}",youCanOnlyUploadFileTypes:"您只能上传:%{types}",youCanOnlyUploadX:{0:"您只能上传 %{smart_count} 个文件",1:"您只能上传 %{smart_count} 个文件"},youHaveToAtLeastSelectX:{0:"您至少需要选择 %{smart_count} 个文件",1:"您至少需要选择 %{smart_count} 个文件"},browseFiles:"浏览文件",browseFolders:"浏览文件夹",cancelUpload:"取消上传",addMore:"添加更多",back:"返回",editFileWithFilename:"编辑文件 %{file}"}}}),[]);a.useEffect(()=>{const o=()=>{const g=b.getFiles();if(g.length===0)return;const u=g.map(v=>({id:v.id,name:v.name,previewUrl:v.preview||URL.createObjectURL(v.data),emotion:"",description:"",isRegistered:!0,file:v.data}));h(u),g.length===1?(w(u[0].id),p("edit-single")):p("edit-multiple")};return b.on("upload",o),()=>{b.off("upload",o)}},[b]),a.useEffect(()=>{s||(b.cancelAll(),p("select"),h([]),w(null),S(!1))},[s,b]);const E=a.useCallback((o,g)=>{h(u=>u.map(v=>v.id===o?{...v,...g}:v))},[]),d=a.useCallback(o=>o.emotion.trim().length>0,[]),D=a.useMemo(()=>c.length>0&&c.every(d),[c,d]),i=a.useMemo(()=>c.find(o=>o.id===x)||null,[c,x]),C=a.useCallback(()=>{(l==="edit-single"||l==="edit-multiple")&&(p("select"),h([]),w(null))},[l]),L=a.useCallback(async()=>{if(!D){k({title:"请填写必填项",description:"每个表情包的情感标签都是必填的",variant:"destructive"});return}S(!0);let o=0,g=0;try{for(const u of c){const v=new FormData;v.append("file",u.file),v.append("emotion",u.emotion),v.append("description",u.description),v.append("is_registered",u.isRegistered.toString());try{(await M(gs(),{method:"POST",body:v})).ok?o++:g++}catch{g++}}g===0?(k({title:"上传成功",description:`成功上传 ${o} 个表情包`}),t(!1),r()):(k({title:"部分上传失败",description:`成功 ${o} 个,失败 ${g}`,variant:"destructive"}),r())}finally{S(!1)}},[D,c,k,t,r]),re=()=>e.jsx("div",{className:"space-y-4",children:e.jsx("div",{className:"border rounded-lg overflow-hidden w-full",children:e.jsx(Cs,{uppy:b,proudlyDisplayPoweredByUppy:!1,hideProgressDetails:!0,height:350,width:"100%",theme:"auto",note:"支持 JPG、PNG、GIF、WebP 格式,最多 20 个文件"})})}),W=()=>{const o=c[0];return o?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(f,{variant:"ghost",size:"sm",onClick:C,children:[e.jsx(je,{className:"h-4 w-4 mr-1"}),"返回"]}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"编辑表情包信息"})]}),e.jsxs("div",{className:"flex gap-6",children:[e.jsxs("div",{className:"shrink-0",children:[e.jsx("div",{className:"w-32 h-32 rounded-lg border overflow-hidden bg-muted flex items-center justify-center",children:e.jsx("img",{src:o.previewUrl,alt:o.name,className:"max-w-full max-h-full object-contain"})}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2 text-center truncate max-w-32",children:o.name})]}),e.jsxs("div",{className:"flex-1 space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"single-emotion",children:["情感标签 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(X,{id:"single-emotion",value:o.emotion,onChange:g=>E(o.id,{emotion:g.target.value}),placeholder:"多个标签用逗号分隔,如:开心,高兴",className:o.emotion.trim()?"":"border-destructive"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"用于情感匹配,多个标签用逗号分隔"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"single-description",children:"描述"}),e.jsx(X,{id:"single-description",value:o.description,onChange:g=>E(o.id,{description:g.target.value}),placeholder:"输入表情包描述..."})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Z,{id:"single-is-registered",checked:o.isRegistered,onCheckedChange:g=>E(o.id,{isRegistered:g===!0})}),e.jsx(m,{htmlFor:"single-is-registered",className:"cursor-pointer",children:"上传后立即注册(可被麦麦使用)"})]})]})]}),e.jsx(Y,{children:e.jsx(f,{onClick:L,disabled:!D||N,children:N?"上传中...":"上传"})})]}):null},ae=()=>{const o=c.filter(d).length,g=c.length;return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(f,{variant:"ghost",size:"sm",onClick:C,children:[e.jsx(je,{className:"h-4 w-4 mr-1"}),"返回"]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["编辑表情包信息(",o,"/",g," 已完成)"]})]}),e.jsx(T,{variant:D?"default":"secondary",children:D?e.jsxs(e.Fragment,{children:[e.jsx(fe,{className:"h-3 w-3 mr-1"}),"全部完成"]}):e.jsxs(e.Fragment,{children:[e.jsx(qe,{className:"h-3 w-3 mr-1"}),"未完成"]})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsx(ve,{className:"h-87.5 pr-2",children:e.jsx("div",{className:"space-y-2",children:c.map(u=>{const v=d(u),J=x===u.id;return e.jsxs("div",{onClick:()=>w(u.id),role:"button",tabIndex:0,onKeyDown:$=>{($.key==="Enter"||$.key===" ")&&($.preventDefault(),w(u.id))},className:`
flex items-center gap-3 p-3 rounded-lg border-2 cursor-pointer transition-all
${J?"ring-2 ring-primary":""}
${v?"border-green-500 bg-green-50 dark:bg-green-950/20":"border-border hover:border-muted-foreground/50"}
`,children:[e.jsx("div",{className:"flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded border bg-muted",children:e.jsx("img",{src:u.previewUrl,alt:u.name,className:"max-w-full max-h-full object-contain"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-medium truncate",children:u.name}),e.jsx("p",{className:"text-xs text-muted-foreground truncate",children:u.emotion||"未填写情感标签"})]}),v?e.jsx(oe,{className:"h-5 w-5 shrink-0 text-green-500"}):e.jsx("div",{className:"h-5 w-5 shrink-0 rounded-full border-2 border-muted-foreground/30"})]},u.id)})})}),e.jsx("div",{className:"border rounded-lg p-4",children:i?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-16 h-16 rounded border overflow-hidden bg-muted flex items-center justify-center",children:e.jsx("img",{src:i.previewUrl,alt:i.name,className:"max-w-full max-h-full object-contain"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-medium truncate",children:i.name}),d(i)&&e.jsxs(T,{variant:"outline",className:"text-green-600 border-green-600",children:[e.jsx(fe,{className:"h-3 w-3 mr-1"}),"已完成"]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"multi-emotion",children:["情感标签 ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(X,{id:"multi-emotion",value:i.emotion,onChange:u=>E(i.id,{emotion:u.target.value}),placeholder:"多个标签用逗号分隔,如:开心,高兴",className:i.emotion.trim()?"":"border-destructive"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"multi-description",children:"描述"}),e.jsx(X,{id:"multi-description",value:i.description,onChange:u=>E(i.id,{description:u.target.value}),placeholder:"输入表情包描述..."})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Z,{id:"multi-is-registered",checked:i.isRegistered,onCheckedChange:u=>E(i.id,{isRegistered:u===!0})}),e.jsx(m,{htmlFor:"multi-is-registered",className:"cursor-pointer text-sm",children:"上传后立即注册"})]})]}):e.jsx("div",{className:"h-full flex items-center justify-center text-muted-foreground",children:e.jsxs("div",{className:"text-center",children:[e.jsx(Ne,{className:"h-12 w-12 mx-auto mb-2 opacity-50"}),e.jsx("p",{children:"点击左侧卡片编辑"})]})})})]}),e.jsx(Y,{children:e.jsx(f,{onClick:L,disabled:!D||N,children:N?"上传中...":`上传全部 (${g})`})})]})};return e.jsx(ee,{open:s,onOpenChange:t,children:e.jsxs(se,{className:"max-w-3xl max-h-[90vh] overflow-hidden",confirmOnEnter:!0,children:[e.jsxs(te,{children:[e.jsxs(ne,{className:"flex items-center gap-2",children:[e.jsx(Ce,{className:"h-5 w-5"}),l==="select"&&"上传表情包 - 选择文件",l==="edit-single"&&"上传表情包 - 填写信息",l==="edit-multiple"&&"上传表情包 - 批量编辑"]}),e.jsxs(ue,{children:[l==="select"&&"支持 JPG、PNG、GIF、WebP 格式,单个文件最大 10MB,可同时上传多个文件",l==="edit-single"&&"请填写表情包的情感标签(必填)和描述",l==="edit-multiple"&&"点击左侧卡片编辑每个表情包的信息,情感标签为必填项"]})]}),e.jsxs(ce,{viewportClassName:"pr-1",children:[l==="select"&&re(),l==="edit-single"&&W(),l==="edit-multiple"&&ae()]})]})})}function Ss({src:s,alt:t="表情包",className:r,maxRetries:l=5,retryInterval:p=1500}){const[c,h]=a.useState("loading"),[x,w]=a.useState(0),[N,S]=a.useState(null),[k,b]=a.useState(s);s!==k&&(h("loading"),w(0),S(null),b(s));const E=a.useCallback(async()=>{try{const d=await fetch(s,{credentials:"include"});if(d.status===202){h("generating"),x<l?setTimeout(()=>{w(C=>C+1)},p):h("error");return}if(!d.ok){h("error");return}const D=await d.blob(),i=URL.createObjectURL(D);S(i),h("loaded")}catch(d){console.error("加载缩略图失败:",d),h("error")}},[s,x,l,p]);return a.useEffect(()=>{E()},[E]),a.useEffect(()=>()=>{N&&URL.revokeObjectURL(N)},[N]),c==="loading"||c==="generating"?e.jsx(is,{className:le("w-full h-full",r)}):c==="error"||!N?e.jsx("div",{className:le("w-full h-full flex items-center justify-center bg-muted",r),children:e.jsx(Ne,{className:"h-8 w-8 text-muted-foreground"})}):e.jsx("img",{src:N,alt:t,className:le("w-full h-full object-contain",r)})}function Ds({emojiList:s,total:t,page:r,pageSize:l,selectedIds:p,cardSize:c,jumpToPage:h,onPageChange:x,onJumpToPage:w,onJumpToPageChange:N,onToggleSelect:S,onEdit:k,onViewDetail:b,onRegister:E,onBan:d,onDelete:D}){return s.length===0?e.jsx("div",{className:"text-center py-12 text-muted-foreground",children:"暂无数据"}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:`grid gap-3 ${c==="small"?"grid-cols-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10":c==="medium"?"grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8":"grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"}`,children:s.map(i=>e.jsxs("div",{className:`group relative rounded-lg border bg-card overflow-hidden hover:ring-2 hover:ring-primary transition-all cursor-pointer ${p.has(i.id)?"ring-2 ring-primary bg-primary/5":""}`,role:"button",tabIndex:0,onClick:()=>S(i.id),onKeyDown:C=>{(C.key==="Enter"||C.key===" ")&&(C.preventDefault(),S(i.id))},children:[e.jsx("div",{className:`absolute top-1 left-1 z-10 transition-opacity ${p.has(i.id)?"opacity-100":"opacity-0 group-hover:opacity-100"}`,children:e.jsx("div",{className:`w-5 h-5 rounded-full border-2 flex items-center justify-center ${p.has(i.id)?"bg-primary border-primary text-primary-foreground":"bg-background/80 border-muted-foreground/50"}`,children:p.has(i.id)&&e.jsx(oe,{className:"h-3 w-3"})})}),e.jsxs("div",{className:"absolute top-1 right-1 z-10 flex flex-col gap-0.5",children:[i.is_registered&&e.jsx(T,{variant:"default",className:"bg-green-600 text-[10px] px-1 py-0",children:"已注册"}),i.is_banned&&e.jsx(T,{variant:"destructive",className:"text-[10px] px-1 py-0",children:"已封禁"})]}),e.jsx("div",{className:`aspect-square bg-muted flex items-center justify-center overflow-hidden ${c==="small"?"p-1":c==="medium"?"p-2":"p-3"}`,children:e.jsx(Ss,{src:hs(i.id),alt:"表情包"})}),e.jsxs("div",{className:`border-t bg-card ${c==="small"?"p-1":"p-2"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1 text-xs text-muted-foreground mb-1",children:[e.jsx(T,{variant:"outline",className:"text-[10px] px-1 py-0",children:i.format.toUpperCase()}),e.jsxs("span",{className:"font-mono",children:[i.usage_count,"次"]})]}),e.jsxs("div",{className:`flex gap-1 justify-center opacity-0 group-hover:opacity-100 transition-opacity ${c==="small"?"flex-wrap":""}`,children:[e.jsx(f,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:C=>{C.stopPropagation(),k(i)},title:"编辑",children:e.jsx(Qe,{className:"h-3 w-3"})}),e.jsx(f,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:C=>{C.stopPropagation(),b(i)},title:"详情",children:e.jsx(Ye,{className:"h-3 w-3"})}),!i.is_registered&&e.jsx(f,{variant:"ghost",size:"icon",className:"h-6 w-6 text-green-600 hover:text-green-700",onClick:C=>{C.stopPropagation(),E(i)},title:"注册",children:e.jsx(oe,{className:"h-3 w-3"})}),!i.is_banned&&e.jsx(f,{variant:"ghost",size:"icon",className:"h-6 w-6 text-orange-600 hover:text-orange-700",onClick:C=>{C.stopPropagation(),d(i)},title:"封禁",children:e.jsx(Ze,{className:"h-3 w-3"})}),e.jsx(f,{variant:"ghost",size:"icon",className:"h-6 w-6 text-red-600 hover:text-red-700",onClick:C=>{C.stopPropagation(),D(i)},title:"删除",children:e.jsx(be,{className:"h-3 w-3"})})]})]})]},i.id))}),t>0&&e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-4 mt-4",children:[e.jsxs("div",{className:"text-sm text-muted-foreground",children:["显示 ",(r-1)*l+1," 到"," ",Math.min(r*l,t)," 条,共 ",t," 条"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(f,{variant:"outline",size:"sm",onClick:()=>x(1),disabled:r===1,className:"hidden sm:flex",children:e.jsx(es,{className:"h-4 w-4"})}),e.jsxs(f,{variant:"outline",size:"sm",onClick:()=>x(Math.max(1,r-1)),disabled:r===1,children:[e.jsx(ss,{className:"h-4 w-4 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"上一页"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(X,{type:"number",value:h,onChange:i=>N(i.target.value),onKeyDown:i=>i.key==="Enter"&&w(),placeholder:r.toString(),className:"w-16 h-8 text-center",min:1,max:Math.ceil(t/l)}),e.jsx(f,{variant:"outline",size:"sm",onClick:w,disabled:!h,className:"h-8",children:"跳转"})]}),e.jsxs(f,{variant:"outline",size:"sm",onClick:()=>x(r+1),disabled:r>=Math.ceil(t/l),children:[e.jsx("span",{className:"hidden sm:inline",children:"下一页"}),e.jsx(ts,{className:"h-4 w-4 sm:ml-1"})]}),e.jsx(f,{variant:"outline",size:"sm",onClick:()=>x(Math.ceil(t/l)),disabled:r>=Math.ceil(t/l),className:"hidden sm:flex",children:e.jsx(ns,{className:"h-4 w-4"})})]})]})]})}function zs(){const[s,t]=a.useState([]),[r,l]=a.useState(null),[p,c]=a.useState(!1),[h,x]=a.useState(1),[w,N]=a.useState(0),[S,k]=a.useState(20),[b,E]=a.useState("registered"),[d,D]=a.useState("all"),[i,C]=a.useState("all"),[L,re]=a.useState("usage_count"),[W,ae]=a.useState("desc"),[o,g]=a.useState(null),[u,v]=a.useState(!1),[J,$]=a.useState(!1),[we,q]=a.useState(!1),[O,Q]=a.useState(new Set),[Se,ie]=a.useState(!1),[me,he]=a.useState(""),[pe,De]=a.useState("medium"),[Ee,xe]=a.useState(!1),{toast:P}=de(),F=a.useCallback(async()=>{try{c(!0);const n=await ls({page:h,page_size:S,is_registered:b==="all"?void 0:b==="registered",is_banned:d==="all"?void 0:d==="banned",format:i==="all"?void 0:i,sort_by:L,sort_order:W});t(n.data),N(n.total)}catch(n){const y=n instanceof Error?n.message:"加载表情包列表失败";P({title:"错误",description:y,variant:"destructive"})}finally{c(!1)}},[h,S,b,d,i,L,W,P]),U=async()=>{try{const n=await ds();l(n.data)}catch(n){console.error("加载统计数据失败:",n)}};a.useEffect(()=>{F()},[F]),a.useEffect(()=>{U()},[]);const ke=async n=>{g(n),v(!0)},Pe=n=>{g(n),$(!0)},_e=n=>{g(n),q(!0)},Fe=async()=>{if(o)try{await cs(o.id),P({title:"成功",description:"表情包已删除"}),q(!1),g(null),F(),U()}catch(n){const y=n instanceof Error?n.message:"删除失败";P({title:"错误",description:y,variant:"destructive"})}},Te=async n=>{try{await us(n.id),P({title:"成功",description:"表情包已注册"}),F(),U()}catch(y){const G=y instanceof Error?y.message:"注册失败";P({title:"错误",description:G,variant:"destructive"})}},Me=async n=>{try{await ms(n.id),P({title:"成功",description:"表情包已封禁"}),F(),U()}catch(y){const G=y instanceof Error?y.message:"封禁失败";P({title:"错误",description:G,variant:"destructive"})}},Oe=n=>{const y=new Set(O);y.has(n)?y.delete(n):y.add(n),Q(y)},Ue=async()=>{try{const n=await xs(Array.from(O));P({title:"批量删除完成",description:n.message}),Q(new Set),ie(!1),F(),U()}catch(n){P({title:"批量删除失败",description:n instanceof Error?n.message:"批量删除失败",variant:"destructive"})}},Le=()=>{const n=parseInt(me),y=Math.ceil(w/S);n>=1&&n<=y?(x(n),he("")):P({title:"无效的页码",description:`请输入1-${y}之间的页码`,variant:"destructive"})},$e=r?.formats?Object.keys(r.formats):[];return e.jsxs("div",{className:"h-[calc(100vh-4rem)] flex flex-col p-4 sm:p-6",children:[e.jsxs("div",{className:"mb-4 sm:mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold",children:"表情包"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"管理麦麦的表情包资源"})]}),e.jsxs(f,{onClick:()=>xe(!0),className:"gap-2",children:[e.jsx(Ce,{className:"h-4 w-4"}),"上传表情包"]})]}),e.jsx(ve,{className:"flex-1",children:e.jsxs("div",{className:"space-y-4 sm:space-y-6 pr-4",children:[r&&e.jsxs("div",{className:"grid gap-4 grid-cols-2 lg:grid-cols-4",children:[e.jsx(I,{children:e.jsxs(A,{className:"pb-2",children:[e.jsx(K,{children:"总数"}),e.jsx(R,{className:"text-2xl",children:r.total})]})}),e.jsx(I,{children:e.jsxs(A,{className:"pb-2",children:[e.jsx(K,{children:"已注册"}),e.jsx(R,{className:"text-2xl text-green-600",children:r.registered})]})}),e.jsx(I,{children:e.jsxs(A,{className:"pb-2",children:[e.jsx(K,{children:"已封禁"}),e.jsx(R,{className:"text-2xl text-red-600",children:r.banned})]})}),e.jsx(I,{children:e.jsxs(A,{className:"pb-2",children:[e.jsx(K,{children:"未注册"}),e.jsx(R,{className:"text-2xl text-gray-600",children:r.unregistered})]})})]}),e.jsxs(I,{children:[e.jsx(A,{children:e.jsxs(R,{className:"flex items-center gap-2",children:[e.jsx(rs,{className:"h-5 w-5"}),"筛选和排序"]})}),e.jsxs(ge,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{children:"排序方式"}),e.jsxs(B,{value:`${L}-${W}`,onValueChange:n=>{const[y,G]=n.split("-");re(y),ae(G),x(1)},children:[e.jsx(z,{children:e.jsx(H,{})}),e.jsxs(V,{children:[e.jsx(j,{value:"usage_count-desc",children:"使用次数 (多→少)"}),e.jsx(j,{value:"usage_count-asc",children:"使用次数 (少→多)"}),e.jsx(j,{value:"register_time-desc",children:"注册时间 (新→旧)"}),e.jsx(j,{value:"register_time-asc",children:"注册时间 (旧→新)"}),e.jsx(j,{value:"record_time-desc",children:"记录时间 (新→旧)"}),e.jsx(j,{value:"record_time-asc",children:"记录时间 (旧→新)"}),e.jsx(j,{value:"last_used_time-desc",children:"最后使用 (新→旧)"}),e.jsx(j,{value:"last_used_time-asc",children:"最后使用 (旧→新)"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{children:"注册状态"}),e.jsxs(B,{value:b,onValueChange:n=>{E(n),x(1)},children:[e.jsx(z,{children:e.jsx(H,{})}),e.jsxs(V,{children:[e.jsx(j,{value:"all",children:"全部"}),e.jsx(j,{value:"registered",children:"已注册"}),e.jsx(j,{value:"unregistered",children:"未注册"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{children:"封禁状态"}),e.jsxs(B,{value:d,onValueChange:n=>{D(n),x(1)},children:[e.jsx(z,{children:e.jsx(H,{})}),e.jsxs(V,{children:[e.jsx(j,{value:"all",children:"全部"}),e.jsx(j,{value:"banned",children:"已封禁"}),e.jsx(j,{value:"unbanned",children:"未封禁"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{children:"格式"}),e.jsxs(B,{value:i,onValueChange:n=>{C(n),x(1)},children:[e.jsx(z,{children:e.jsx(H,{})}),e.jsxs(V,{children:[e.jsx(j,{value:"all",children:"全部"}),$e.map(n=>e.jsxs(j,{value:n,children:[n.toUpperCase()," (",r?.formats[n],")"]},n))]})]})]})]}),e.jsxs("div",{className:"flex flex-col gap-3 border-t pt-4 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[O.size>0&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:["已选择 ",O.size," 个表情包"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(m,{className:"text-sm whitespace-nowrap",children:"卡片大小"}),e.jsxs(B,{value:pe,onValueChange:n=>De(n),children:[e.jsx(z,{className:"w-24",children:e.jsx(H,{})}),e.jsxs(V,{children:[e.jsx(j,{value:"small",children:"小"}),e.jsx(j,{value:"medium",children:"中"}),e.jsx(j,{value:"large",children:"大"})]})]})]}),e.jsxs(f,{variant:"outline",size:"sm",onClick:F,disabled:p,children:[e.jsx(as,{className:`h-4 w-4 mr-2 ${p?"animate-spin":""}`}),"刷新"]}),O.size>0&&e.jsxs(e.Fragment,{children:[e.jsx(f,{variant:"outline",size:"sm",onClick:()=>Q(new Set),children:"取消选择"}),e.jsxs(f,{variant:"destructive",size:"sm",onClick:()=>ie(!0),children:[e.jsx(be,{className:"h-4 w-4 mr-1"}),"批量删除"]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 sm:ml-auto",children:[e.jsx(m,{htmlFor:"emoji-page-size",className:"text-sm whitespace-nowrap",children:"每页显示"}),e.jsxs(B,{value:S.toString(),onValueChange:n=>{k(parseInt(n)),x(1),Q(new Set)},children:[e.jsx(z,{id:"emoji-page-size",className:"w-20",children:e.jsx(H,{})}),e.jsxs(V,{children:[e.jsx(j,{value:"20",children:"20"}),e.jsx(j,{value:"40",children:"40"}),e.jsx(j,{value:"60",children:"60"}),e.jsx(j,{value:"100",children:"100"})]})]})]})]})]})]}),e.jsxs(I,{children:[e.jsxs(A,{children:[e.jsx(R,{children:"表情包列表"}),e.jsxs(K,{children:["共 ",w," 个表情包,当前第 ",h," 页"]})]}),e.jsx(ge,{children:e.jsx(Ds,{emojiList:s,loading:p,total:w,page:h,pageSize:S,selectedIds:O,cardSize:pe,jumpToPage:me,onPageChange:x,onJumpToPage:Le,onJumpToPageChange:he,onToggleSelect:Oe,onEdit:Pe,onViewDetail:ke,onRegister:Te,onBan:Me,onDelete:_e})})]}),e.jsx(bs,{emoji:o,open:u,onOpenChange:v}),e.jsx(ys,{emoji:o,open:J,onOpenChange:$,onSuccess:()=>{F(),U()}}),e.jsx(ws,{open:Ee,onOpenChange:xe,onSuccess:()=>{F(),U()}})]})}),e.jsx(Ie,{open:Se,onOpenChange:ie,children:e.jsxs(Ae,{children:[e.jsxs(Re,{children:[e.jsx(Be,{children:"确认批量删除"}),e.jsxs(ze,{children:["你确定要删除选中的 ",O.size," ","个表情包吗?此操作不可撤销。"]})]}),e.jsxs(He,{children:[e.jsx(Ve,{children:"取消"}),e.jsx(We,{onClick:Ue,children:"确认删除"})]})]})}),e.jsx(ee,{open:we,onOpenChange:q,children:e.jsxs(se,{children:[e.jsxs(te,{children:[e.jsx(ne,{children:"确认删除"}),e.jsx(ue,{children:"确定要删除这个表情包吗?此操作无法撤销。"})]}),e.jsxs(Y,{children:[e.jsx(f,{variant:"outline",onClick:()=>q(!1),children:"取消"}),e.jsx(f,{variant:"destructive",onClick:Fe,children:"删除"})]})]})})]})}export{zs as EmojiManagementPage};