vue-chat-kit 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vue-chat-kit.css +1 -0
- package/dist/vue-chat-kit.es.js +1880 -0
- package/dist/vue-chat-kit.umd.js +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(N,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("@element-plus/icons-vue"),require("dayjs"),require("element-plus")):typeof define=="function"&&define.amd?define(["exports","vue","@element-plus/icons-vue","dayjs","element-plus"],e):(N=typeof globalThis<"u"?globalThis:N||self,e(N.VueChatKit={},N.Vue,N.ElementPlusIconsVue,N.dayjs,N.ElementPlus))})(this,(function(N,e,_,de,I){"use strict";class _e{constructor(t,a={}){this.userId=t,this.wsUrl=a.wsUrl||"",this.socket=null,this.reconnectAttempts=0,this.maxReconnectAttempts=a.maxReconnectAttempts||5,this.reconnectDelay=a.reconnectDelay||3e3,this.handlers={message:[],open:[],close:[],error:[]},this.isConnecting=!1,this.manualClose=!1}connect(){if(!(this.isConnecting||this.isConnected())){this.isConnecting=!0,this.manualClose=!1;try{this.socket=new WebSocket(this.wsUrl),this.socket.onopen=()=>{console.log("[VueChatKit] WebSocket 连接成功"),this.isConnecting=!1,this.reconnectAttempts=0,this.emit("open")},this.socket.onmessage=t=>{try{const a=t.data;this.emit("message",a)}catch(a){console.error("[VueChatKit] WebSocket 消息解析失败",a)}},this.socket.onclose=t=>{console.log("[VueChatKit] WebSocket 连接关闭",t.code),this.isConnecting=!1,this.emit("close",t),!this.manualClose&&t.code!==1e3&&this.reconnect()},this.socket.onerror=t=>{console.error("[VueChatKit] WebSocket 连接错误",t),this.isConnecting=!1,this.emit("error",t)}}catch(t){console.error("[VueChatKit] WebSocket 创建连接失败",t),this.isConnecting=!1}}}send(t,a,l="text",V="",E="",B=0){if(this.isConnected()){const g=JSON.stringify({to:t,msg:a,type:l,fileUrl:V,fileName:E,fileSize:B});return this.socket.send(g),!0}return console.warn("[VueChatKit] WebSocket 连接未建立,无法发送消息"),!1}on(t,a){this.handlers[t]&&this.handlers[t].push(a)}off(t,a){if(this.handlers[t]){const l=this.handlers[t].indexOf(a);l>-1&&this.handlers[t].splice(l,1)}}emit(t,...a){this.handlers[t]&&this.handlers[t].forEach(l=>l(...a))}reconnect(){this.reconnectAttempts<this.maxReconnectAttempts?(this.reconnectAttempts++,console.log(`[VueChatKit] 尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`),setTimeout(()=>this.connect(),this.reconnectDelay)):console.error("[VueChatKit] 重连次数已达上限")}close(){this.manualClose=!0,this.socket&&(this.socket.close(),this.socket=null,this.handlers={message:[],open:[],close:[],error:[]})}isConnected(){return this.socket&&this.socket.readyState===WebSocket.OPEN}}class re extends Error{constructor(t,a,l,V){super(t),this.name="RequestError",this.status=a||0,this.code=l||0,this.data=V}}class Ne{constructor(t={}){this.baseUrl=t.baseUrl||"",this.timeout=t.timeout||1e4,this.headers=t.headers||{},this.requestInterceptors=[],this.responseInterceptors=[],this.addRequestInterceptor(a=>(a.body instanceof FormData||(a.headers={"Content-Type":"application/json",...a.headers}),a))}addRequestInterceptor(t){this.requestInterceptors.push(t)}addResponseInterceptor(t){this.responseInterceptors.push(t)}timeoutPromise(t){return new Promise((a,l)=>{setTimeout(()=>{l(new re("请求超时",408,408))},t)})}async request(t,a={}){const{method:l="GET",headers:V={},body:E,params:B}=a;let g=t.startsWith("http")?t:`${this.baseUrl}${t}`,y={method:l,headers:{...this.headers,...V},body:E,params:B};this.requestInterceptors.forEach(m=>{y=m(y)});const w={method:y.method,headers:y.headers,credentials:"include"};if(y.body&&l!=="GET"&&(y.body instanceof FormData?w.body=y.body:typeof y.body=="object"?w.body=JSON.stringify(y.body):w.body=y.body),y.params){const m=new URLSearchParams;for(const u in y.params)y.params[u]!==void 0&&y.params[u]!==null&&y.params[u]!==""&&m.append(u,y.params[u]);const h=m.toString();h&&(g+=(g.includes("?")?"&":"?")+h)}try{let h=await Promise.race([fetch(g,w),this.timeoutPromise(this.timeout)]);if(this.responseInterceptors.forEach(z=>{h=z(h)}),!h.ok)throw new re(`HTTP ${h.status}: ${h.statusText}`,h.status,h.status);const u=h.headers.get("content-type");let C;return u&&u.includes("application/json")?C=await h.json():C=await h.text(),C}catch(m){throw m instanceof re?m:new re(m instanceof Error?m.message:"网络错误",0,0)}}get(t,a,l){return this.request(t,{...l,method:"GET",params:a})}post(t,a,l){return this.request(t,{...l,method:"POST",body:a})}put(t,a,l){return this.request(t,{...l,method:"PUT",body:a})}delete(t,a){return this.request(t,{...a,method:"DELETE"})}}class Ee{constructor(t,a=null){this.config=t,this.endpoints=t.api.endpoints,this.customAdapter=t.api.adapter,a?this.http=a:this.http=new Ne({baseUrl:t.api.baseUrl,headers:t.headers})}async _call(t,...a){return this.customAdapter&&typeof this.customAdapter[t]=="function"?this.customAdapter[t](...a):this[`_${t}`](...a)}async getFriends(t){return this._call("getFriends",t)}async _getFriends(t){return this.http.get(this.endpoints.getFriends,{currentUser:t})}async getAvailableUsers(t){return this._call("getAvailableUsers",t)}async _getAvailableUsers(t){return this.http.get(this.endpoints.getAvailableUsers,{currentUser:t})}async addFriend(t,a){return this._call("addFriend",t,a)}async _addFriend(t,a){return this.http.post(this.endpoints.addFriend,{currentUser:t,friendUser:a})}async getApplyList(t){return this._call("getApplyList",t)}async _getApplyList(t){return this.http.get(this.endpoints.getApplyList,{currentUser:t})}async agreeFriend(t,a){return this._call("agreeFriend",t,a)}async _agreeFriend(t,a){return this.http.post(this.endpoints.agreeFriend,{applyUser:t,friendUser:a})}async setChatStatus(t,a,l=1){return this._call("setChatStatus",t,a,l)}async _setChatStatus(t,a,l){return this.http.post(this.endpoints.setChatStatus,null,{params:{currentUser:t,friendUser:a,status:l}})}async getHistory(t,a){return this._call("getHistory",t,a)}async _getHistory(t,a){return this.http.get(this.endpoints.getHistory,{fromUser:t,toUser:a})}async setRead(t,a){return this._call("setRead",t,a)}async _setRead(t,a){return this.http.post(this.endpoints.setRead,{currentUser:t,friendUser:a})}async uploadFile(t){return this._call("uploadFile",t)}async _uploadFile(t){const a=new FormData;return a.append("file",t),this.http.post(this.endpoints.uploadFile,a)}async getUserInfo(t){return this._call("getUserInfo",t)}async _getUserInfo(t){return this.http.get(this.endpoints.getUserInfo,{username:t})}async updateUserInfo(t,a){return this._call("updateUserInfo",t,a)}async _updateUserInfo(t,a){return this.http.put(this.endpoints.updateUserInfo,{username:t,...a})}async getUserAvatar(t){return this._call("getUserAvatar",t)}async _getUserAvatar(t){return this.http.get(this.endpoints.getUserAvatar,{username:t})}async uploadAvatar(t,a){return this._call("uploadAvatar",t,a)}async _uploadAvatar(t,a){const l=new FormData;return l.append("file",t),l.append("username",a),this.http.post(this.endpoints.uploadAvatar,l)}}function Ue(p){const t=new Ee(p);let a=null;const l=p.user.username,V=e.ref(p.user.avatar||`https://api.dicebear.com/7.x/avataaars/svg?seed=${l}`),E=e.ref({username:l,nickname:p.user.nickname||"",email:p.user.email||"",phone:p.user.phone||"",bio:p.user.bio||""}),B=e.ref(!1),g=e.ref([]),y=e.ref([]),w=e.ref([]),m=e.ref(""),h=e.ref(""),u=e.ref(""),C=e.ref(null),z=e.ref(!1),v=e.ref(""),K=e.ref([]),W=e.ref(!1),X=e.ref([]),O=e.ref(!1),f=e.computed(()=>{let o=y.value;if(h.value){const n=h.value.toLowerCase();o=o.filter(i=>i.username?.toLowerCase().includes(n))}return o.map(n=>({id:n.username,name:n.username,avatar:n.avatar||V.value,online:n.online,lastMsg:n.lastMsg||"暂无消息",lastTime:n.lastTime,unread:n.unReadNum||0}))}),x=e.computed(()=>{let o=g.value;if(h.value){const n=h.value.toLowerCase();o=o.filter(i=>i.username?.toLowerCase().includes(n))}return o.map(n=>({id:n.username,name:n.username,avatar:n.avatar||V.value,online:n.online,isChatting:n.isChatting}))}),b=e.computed(()=>v.value?K.value.filter(o=>o.username?.toLowerCase().includes(v.value.toLowerCase())):K.value),F=e.computed(()=>f.value.find(o=>o.id===m.value)||null),Y=e.computed(()=>w.value.map(o=>{const n=o.type==="file"||o.fileUrl||o.fileName,i=o.fileName||o.msgContent;return{text:o.msgContent,isSelf:o.sendUsername===l,time:o.createTime,sendUsername:o.sendUsername,type:n?"file":"text",fileType:ae(i)?"image":ne(i),fileUrl:o.fileUrl||"",fileName:i,fileSize:o.fileSize||0}})),M=o=>de(o).format("HH:mm"),se=o=>{if(!o)return"";const n=de(),i=de(o);return n.isSame(i,"day")?i.format("HH:mm"):n.diff(i,"day")===1?"昨天":n.diff(i,"day")<7?["周日","周一","周二","周三","周四","周五","周六"][i.day()]:i.format("MM/DD")},ae=o=>{if(!o)return!1;const n=["jpg","jpeg","png","gif","bmp","webp","svg"],i=o.split(".").pop().toLowerCase();return n.includes(i)},ne=o=>{if(!o)return"default";const n=o.split(".").pop().toLowerCase();return["xls","xlsx"].includes(n)?"excel":["pdf"].includes(n)?"pdf":["doc","docx"].includes(n)?"docx":"default"},j=()=>{e.nextTick(()=>{C.value&&(C.value.scrollTop=C.value.scrollHeight)})},D=async()=>{try{const n=(await t.getFriends(l)).data||[];g.value=n,y.value=n.filter(i=>i.isChatting===1);for(const i of y.value)try{const P=(await t.getHistory(l,i.username)).data||[];i.unReadNum=P.filter(q=>q.isRead===0&&q.sendUsername===i.username).length}catch{i.unReadNum=0}}catch(o){console.error("[VueChatKit] 获取好友列表失败",o)}},G=async o=>{try{const n=await t.getHistory(l,o);w.value=n.data||[],j()}catch(n){console.error("[VueChatKit] 获取聊天历史失败",n)}},De=async o=>{try{await t.setRead(l,o),D()}catch(n){console.error("[VueChatKit] 标记已读失败",n)}},me=async o=>{m.value=o.id,await G(o.id),await De(o.id),j()},fe=async(o,n=1)=>{try{return await t.setChatStatus(l,o,n),await D(),!0}catch(i){return console.error("[VueChatKit] 设置聊天状态失败",i),!1}},le=()=>{if(!u.value.trim()||!m.value||!a)return;if(a.send(m.value,u.value.trim(),"text")){const n={msgContent:u.value.trim(),sendUsername:l,receiveUsername:m.value,createTime:new Date,isRead:0,type:"text"};w.value.push(n),u.value="",j(),setTimeout(()=>{G(m.value),D()},300)}},ie=async o=>{if(!m.value||!a)return!1;try{const n=await t.uploadFile(o);if(n.code===200&&n.data){const{fileUrl:i,fileName:U}=n.data;if(a.send(m.value,U,"file",i,U,o.size)){const q={msgContent:U,sendUsername:l,receiveUsername:m.value,createTime:new Date,isRead:0,type:"file",fileUrl:i,fileName:U,fileSize:o.size};return w.value.push(q),j(),!0}}return!1}catch(n){return console.error("[VueChatKit] 发送文件失败",n),!1}},ce=async(o,n)=>{if(!(!m.value||!a)){if(n&&n.trim()&&a.send(m.value,n.trim(),"text")){const U={msgContent:n.trim(),sendUsername:l,receiveUsername:m.value,createTime:new Date,isRead:0,type:"text"};w.value.push(U)}for(const i of o){const U=i.file||i;await ie(U)}setTimeout(()=>{G(m.value),D()},300)}},pe=o=>{try{try{const i=JSON.parse(o);if(i.to||i.msg)return{to:i.to,content:i.msg,type:i.type||"text",fileUrl:i.fileUrl||"",fileName:i.fileName||"",fileSize:i.fileSize||0}}catch{}const n=o.match(/^\[(.+?)\]:(.+)$/);if(n)return{username:n[1],content:n[2],type:"text"}}catch(n){console.error("[VueChatKit] 解析消息失败",n)}return null},he=o=>{if(o.includes("【状态变更】")){const i=/【状态变更】(.+?) 已(上线|下线)/,U=o.match(i);if(U){const P=U[1],q=U[2]==="上线",ee=g.value.find(T=>T.username===P);ee&&(ee.online=q)}return}const n=pe(o);if(n){if(m.value){try{let i={msgContent:n.content,sendUsername:n.username||m.value,receiveUsername:l,createTime:new Date,isRead:0,type:n.type||"text",fileUrl:n.fileUrl||"",fileName:n.fileName||"",fileSize:n.fileSize||0};w.value.push(i),j()}catch(i){console.error("[VueChatKit] 添加临时消息失败",i)}G(m.value)}D()}},ue=()=>{const o=`${p.api.websocketUrl}?userId=${l}`;a=new _e(l,{wsUrl:o,maxReconnectAttempts:p.websocket.maxReconnectAttempts,reconnectDelay:p.websocket.reconnectDelay}),a.on("message",he),a.connect()},ge=()=>{a&&(a.close(),a=null)},ye=async()=>{z.value=!0,v.value="",await xe()},xe=async()=>{W.value=!0;try{const o=await t.getAvailableUsers(l);K.value=o?.data||[]}catch(o){console.error("[VueChatKit] 获取可用用户失败",o)}finally{W.value=!1}},be=async o=>{try{await t.addFriend(l,o.username),await D(),z.value=!1}catch(n){console.error("[VueChatKit] 添加好友失败",n)}},H=async()=>{O.value=!0;try{const o=await t.getApplyList(l);X.value=o.data||[]}catch(o){console.error("[VueChatKit] 获取好友申请列表失败",o)}finally{O.value=!1}},Q=async o=>{try{await t.agreeFriend(o,l),await H(),await D()}catch(n){console.error("[VueChatKit] 同意好友申请失败",n)}},S=async()=>{try{const o=await t.getUserAvatar(l);o.code===200&&o.data&&(V.value=o.data)}catch(o){console.warn("[VueChatKit] 加载头像失败",o)}},A=o=>{V.value=o},Z=async()=>{B.value=!0;try{const o=await t.getUserInfo(l);o.code===200&&o.data&&(E.value={...E.value,...o.data})}catch(o){console.error("[VueChatKit] 获取用户信息失败",o)}finally{B.value=!1}},L=async o=>{try{return(await t.updateUserInfo(l,o)).code===200?(E.value={...E.value,...o},!0):!1}catch(n){return console.error("[VueChatKit] 更新用户信息失败",n),!1}},R=()=>{m.value="",w.value=[],u.value="",h.value=""};return S(),{myUsername:l,myAvatar:V,userInfo:E,loadingUserInfo:B,friendList:g,chatList:y,filteredFriendList:x,chatMsgList:w,currentSelectName:m,searchText:h,inputText:u,messagesContainer:C,filteredUsers:f,filteredAvailableUsers:b,currentUser:F,currentMessages:Y,addFriendDialogVisible:z,addFriendSearchText:v,availableUsers:K,loadingAvailableUsers:W,friendApplyList:X,loadingFriendApply:O,formatTime:M,formatLastTime:se,scrollToBottom:j,getFriendList:D,getChatHistory:G,setFriendToChatStatus:fe,selectUser:me,sendMessage:le,sendFile:ie,sendFilesAndText:ce,initWebSocket:ue,closeWebSocket:ge,reset:R,openAddFriendDialog:ye,addFriend:be,loadFriendApplyList:H,agreeFriend:Q,updateMyAvatar:A,getUserInfo:Z,updateUserInfo:L}}const Be=(p,t)=>{const a=p.__vccOpts||p;for(const[l,V]of t)a[l]=V;return a},Me={class:"avatar-crop-container"},je=["src"],$e={class:"crop-overlay"},ve={class:"crop-box"},Ke={key:0,class:"crop-mask"},We={class:"zoom-controls"},Se=Be({__name:"AvatarCrop",props:{modelValue:{type:Boolean,default:!1},src:{type:String,default:""}},emits:["update:modelValue","confirm"],setup(p,{emit:t}){const a=p,l=t,V=e.computed({get:()=>a.modelValue,set:f=>l("update:modelValue",f)}),E=e.ref(""),B=e.ref(null),g=e.ref(null),y=e.ref(null),w=e.ref(1),m=e.ref({x:0,y:0}),h=e.ref(!1),u=e.ref({x:0,y:0}),C=e.ref({width:0,height:0});e.watch(()=>a.src,f=>{f&&(E.value=f,w.value=1,m.value={x:0,y:0})});const z=()=>{e.nextTick(()=>{if(B.value&&g.value){const f=B.value,x=g.value,b=Math.min(x.clientWidth,x.clientHeight);f.naturalWidth>f.naturalHeight?(C.value.height=b,C.value.width=f.naturalWidth/f.naturalHeight*b):(C.value.width=b,C.value.height=f.naturalHeight/f.naturalWidth*b),m.value={x:(b-C.value.width)/2,y:(b-C.value.height)/2}}})},v=f=>{h.value=!0;const x=f.touches?f.touches[0].clientX:f.clientX,b=f.touches?f.touches[0].clientY:f.clientY;u.value={x:x-m.value.x,y:b-m.value.y},document.addEventListener("mousemove",K),document.addEventListener("mouseup",W),document.addEventListener("touchmove",K),document.addEventListener("touchend",W)},K=f=>{if(!h.value)return;const x=f.touches?f.touches[0].clientX:f.clientX,b=f.touches?f.touches[0].clientY:f.clientY;m.value={x:x-u.value.x,y:b-u.value.y}},W=()=>{h.value=!1,document.removeEventListener("mousemove",K),document.removeEventListener("mouseup",W),document.removeEventListener("touchmove",K),document.removeEventListener("touchend",W)},X=()=>{const f=document.createElement("canvas"),x=f.getContext("2d"),b=200;f.width=b,f.height=b;const F=B.value,Y=y.value,M=g.value;if(F&&Y&&M){const se=Y.getBoundingClientRect(),ae=M.getBoundingClientRect(),ne=(se.left-ae.left-m.value.x)/w.value,j=(se.top-ae.top-m.value.y)/w.value,D=se.width/w.value;x.drawImage(F,ne*(F.naturalWidth/C.value.width),j*(F.naturalHeight/C.value.height),D*(F.naturalWidth/C.value.width),D*(F.naturalHeight/C.value.height),0,0,b,b),f.toBlob(G=>{l("confirm",{file:G,url:f.toDataURL("image/png")}),V.value=!1},"image/png")}},O=()=>{E.value="",w.value=1,m.value={x:0,y:0}};return(f,x)=>{const b=e.resolveComponent("el-slider"),F=e.resolveComponent("el-button"),Y=e.resolveComponent("el-dialog");return e.openBlock(),e.createBlock(Y,{modelValue:V.value,"onUpdate:modelValue":x[2]||(x[2]=M=>V.value=M),title:"裁剪头像",width:"500px","close-on-click-modal":!1,onClosed:O},{footer:e.withCtx(()=>[e.createVNode(F,{onClick:x[1]||(x[1]=M=>V.value=!1)},{default:e.withCtx(()=>[...x[3]||(x[3]=[e.createTextVNode("取消",-1)])]),_:1}),e.createVNode(F,{type:"primary",onClick:X},{default:e.withCtx(()=>[...x[4]||(x[4]=[e.createTextVNode("确定",-1)])]),_:1})]),default:e.withCtx(()=>[e.createElementVNode("div",Me,[e.createElementVNode("div",{class:"crop-area",ref_key:"cropAreaRef",ref:g},[e.createElementVNode("img",{src:E.value,ref_key:"imageRef",ref:B,class:"crop-image",onLoad:z,onMousedown:v,onTouchstart:v},null,40,je),e.createElementVNode("div",$e,[e.createElementVNode("div",ve,[e.createElementVNode("div",{class:"crop-border",ref_key:"cropBoxRef",ref:y},null,512)])]),h.value?(e.openBlock(),e.createElementBlock("div",Ke)):e.createCommentVNode("",!0)],512),e.createElementVNode("div",We,[e.createVNode(b,{modelValue:w.value,"onUpdate:modelValue":x[0]||(x[0]=M=>w.value=M),min:.5,max:3,step:.1,"show-tooltip":!1},null,8,["modelValue"])])])]),_:1},8,["modelValue"])}}},[["__scopeId","data-v-4e4a992b"]]),He={class:"chat-container flex h-[680px] bg-white overflow-hidden"},qe={class:"w-16 theme-white flex flex-col items-center gap-2 bg-gray-50 border-r"},Oe=["src"],Pe=["onClick"],Xe={key:0,class:"absolute -top-1 -right-1 w-4 h-4 bg-red-500 rounded-full text-xs text-white flex items-center justify-center"},Ye={class:"w-72 bg-[#f5f5f5] border-r border-gray-200 flex flex-col"},Ge={class:"p-3"},Je={class:"flex-1 overflow-y-auto min-h-0"},Qe={key:0},Ze=["onClick","onContextmenu"],et={class:"relative flex-shrink-0"},tt=["src","alt"],st={key:0,class:"absolute bottom-0 right-0 w-3 h-3 bg-green-500 rounded-full border-2 border-white"},at={class:"ml-3 flex-1 overflow-hidden"},ot={class:"flex justify-between items-center"},rt={class:"font-medium text-gray-800 text-sm"},nt={class:"text-xs text-gray-400"},lt={class:"flex justify-between items-center mt-1"},it={class:"text-xs text-gray-500 truncate pr-2"},ct={key:0,class:"bg-red-500 text-white text-xs rounded-full px-1.5 py-0.5 min-w-[18px] text-center"},dt={key:1},mt={class:"p-3"},ft={class:"w-11 h-11 bg-green-500 rounded-lg flex items-center justify-center"},pt=["onClick"],ht={class:"relative flex-shrink-0"},ut=["src","alt"],gt={class:"ml-3"},yt={class:"font-medium text-gray-800 text-sm"},xt={key:2},bt={class:"flex items-center"},kt=["src","alt"],wt={class:"ml-3"},Vt={class:"font-medium text-gray-800 text-sm"},Ct={class:"flex-1 flex flex-col min-w-0 bg-white"},_t={key:0,class:"flex-1 flex flex-col min-h-0"},Nt={class:"flex-1 flex flex-col items-center justify-center p-8 bg-[#f5f5f5]"},Et=["src","alt"],Ut={class:"text-xl font-medium text-gray-800 mb-2"},Bt={class:"flex items-center gap-2 mb-8"},St={class:"text-sm text-gray-500"},At={key:1,class:"flex-1 flex flex-col min-h-0"},Ft={class:"h-14 border-b border-gray-200 flex items-center justify-between px-4 bg-white"},Dt={class:"flex items-center gap-3"},Rt={class:"font-medium text-gray-800"},Tt={class:"flex items-center gap-3 text-gray-500"},zt={class:"flex-shrink-0"},Lt=["src"],It={key:0,class:"text-xs text-gray-500 mb-1 ml-1"},Mt={class:"relative group"},jt=["onClick"],$t=["src","alt"],vt={key:0,class:"absolute left-1 bottom-0 text-white"},Kt=["onClick"],Wt={class:"w-10 h-10 flex items-center justify-center rounded-lg flex-shrink-0"},Ht={class:"flex-1 min-w-0"},qt={key:0},Ot={class:"bg-white border-t border-gray-200"},Pt={key:0,class:"px-3 py-2 border-b border-gray-100 flex flex-wrap gap-2"},Xt={key:0,class:"relative w-20 h-20 rounded-lg overflow-hidden border border-gray-200"},Yt=["src","alt"],Gt=["onClick"],Jt={key:1,class:"relative w-24 h-20 rounded-lg border border-gray-200 bg-gray-50 flex flex-col items-center justify-center p-1"},Qt={class:"text-xs text-gray-500 truncate w-full text-center px-1"},Zt=["onClick"],es={key:1,class:"flex items-center p-3 gap-2"},ts={class:"px-3 pb-3"},ss=["onKeydown"],as={class:"flex justify-end px-3 pb-3"},os={key:2,class:"flex-1 flex items-center justify-center flex-col bg-[#f5f5f5]"},rs={class:"text-gray-400"},ns={key:0,class:"w-64 bg-[#f5f5f5] border-l border-gray-200 flex flex-col"},ls={class:"flex-1 p-4"},is={class:"flex flex-col items-center"},cs=["src","alt"],ds={class:"mt-3 font-medium text-gray-800 text-lg"},ms={class:"mb-4"},fs={class:"relative"},ps={class:"max-h-[400px] overflow-y-auto"},hs={class:"flex items-center"},us=["src","alt"],gs={class:"ml-3"},ys={class:"font-medium text-gray-800"},xs={class:"flex flex-col"},bs={class:"flex flex-col items-center mb-8 pb-6 border-b border-gray-100"},ks={class:"relative mb-4"},ws=["src"],Vs={class:"text-center"},Cs={class:"font-semibold text-gray-800 text-xl"},_s={class:"text-sm text-gray-500 mt-1"},Ns={class:"space-y-5"},Es={class:"flex items-center justify-between mb-2"},Us={class:"text-gray-700 font-semibold flex items-center gap-2"},Bs={class:"bg-gray-50 rounded-xl p-6 space-y-5"},Ss={key:1,class:"text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200"},As={key:1,class:"text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200"},Fs={key:1,class:"text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200"},Ds={key:1,class:"text-gray-800 bg-white rounded-lg px-4 py-3 border border-gray-200 min-h-[80px]"},Rs={key:0,class:"flex gap-3 justify-end pt-2"},Ts=Be({__name:"ChatWindow",props:{modelValue:{type:Boolean,default:!1},config:{type:Object,required:!0},width:{type:[String,Number],default:"1100px"}},emits:["update:modelValue","open","close","message","send","error"],setup(p,{emit:t}){const a=p,l=t,V=e.computed({get:()=>a.modelValue,set:c=>l("update:modelValue",c)}),{myUsername:E,myAvatar:B,userInfo:g,loadingUserInfo:y,friendList:w,filteredFriendList:m,searchText:h,inputText:u,messagesContainer:C,filteredUsers:z,filteredAvailableUsers:v,currentUser:K,currentMessages:W,addFriendDialogVisible:X,addFriendSearchText:O,availableUsers:f,loadingAvailableUsers:x,friendApplyList:b,loadingFriendApply:F,formatTime:Y,formatLastTime:M,scrollToBottom:se,getFriendList:ae,getChatHistory:ne,setFriendToChatStatus:j,selectUser:D,sendMessage:G,sendFile:De,sendFilesAndText:me,initWebSocket:fe,closeWebSocket:le,reset:ie,openAddFriendDialog:ce,addFriend:pe,loadFriendApplyList:he,agreeFriend:ue,updateMyAvatar:ge,getUserInfo:ye,updateUserInfo:xe}=Ue(a.config),be=e.computed(()=>{const c=[{id:"chat",icon:_.ChatDotRound,badge:0}];return a.config.modules.friends&&c.push({id:"friends",icon:_.UserFilled,badge:0}),a.config.modules.apply&&c.push({id:"apply",icon:_.Bell,badge:b.value?.length||0}),c}),H=e.ref("chat"),Q=e.ref(null),S=e.ref(null),A=e.ref(null),Z=e.ref(!1),L=e.ref(!1),R=e.ref({nickname:"",email:"",phone:"",bio:""}),o=e.ref(!1),n=e.ref(!1),i=e.ref(!1),U=e.ref(!1),P=e.ref(null),q=e.ref(""),ee=e.ref(null),T=e.ref([]),J=e.ref({visible:!1,x:0,y:0,chat:null}),Is=(c,r)=>{c.preventDefault(),c.stopPropagation(),J.value={visible:!0,x:c.clientX,y:c.clientY,chat:r}},ke=()=>{J.value.visible=!1},Ms=async()=>{if(!J.value.chat)return;await j(J.value.chat.id,0)&&Q.value===J.value.chat.id&&(Q.value=null,S.value=null),ke()},we=c=>{Q.value=c.id,S.value=c,A.value=null,Z.value=!1,D({id:c.id,name:c.name,avatar:c.avatar,online:c.online})},js=c=>{A.value=c,Q.value=null,S.value=null},$s=async()=>{if(!A.value)return;if(await j(A.value.id)){H.value="chat",await e.nextTick();const r=z.value.find(d=>d.id===A.value.id);r&&we(r),A.value=null}},vs=()=>{n.value=!0},Ks=()=>{P.value?.click()},Ws=()=>{ee.value?.click()},Hs=c=>{const r=Array.from(c.target.files||[]);if(r.length!==0){for(const d of r){if(d.size>50*1024*1024){I.ElMessage.warning(`文件 ${d.name} 超过50MB,已跳过`);continue}const k=URL.createObjectURL(d);T.value.push({id:Date.now()+Math.random(),file:d,name:d.name,size:d.size,type:d.type,previewUrl:k,isImage:d.type.startsWith("image/")})}ee.value&&(ee.value.value="")}},Re=c=>{const r=T.value[c];r.previewUrl&&URL.revokeObjectURL(r.previewUrl),T.value.splice(c,1)},Te=c=>{if(c===0)return"0 B";const r=1024,d=["B","KB","MB","GB"],k=Math.floor(Math.log(c)/Math.log(r));return parseFloat((c/Math.pow(r,k)).toFixed(2))+" "+d[k]},ze=async()=>{if(!u.value.trim()&&T.value.length===0)return;const c=[...T.value],r=u.value;u.value="",T.value.forEach(d=>{d.previewUrl&&URL.revokeObjectURL(d.previewUrl)}),T.value=[],await me(c,r),l("send",{text:r,files:c})},qs=c=>{const r=c.clipboardData?.items;if(r){for(const d of r)if(d.kind==="file"){const k=d.getAsFile();if(k){if(k.size>50*1024*1024){I.ElMessage.warning(`文件 ${k.name} 超过50MB,已跳过`);continue}const oe=URL.createObjectURL(k);T.value.push({id:Date.now()+Math.random(),file:k,name:k.name,size:k.size,type:k.type,previewUrl:oe,isImage:k.type.startsWith("image/")})}}}},Le=c=>{if(!c){I.ElMessage.warning("文件地址无效");return}window.open(c,"_blank")},Os=c=>{console.warn("图片加载失败",c)},Ps=c=>{const r=c.target.files[0];if(!r)return;if(!r.type.startsWith("image/")){I.ElMessage.error("只能上传图片文件");return}if(r.size>5*1024*1024){I.ElMessage.error("图片大小不能超过 5MB");return}const d=new FileReader;d.onload=k=>{q.value=k.target.result,i.value=!0},d.readAsDataURL(r)},Xs=async({file:c})=>{if(c){U.value=!0;try{const d=await new(require("../core/api.js")).ChatApi(a.config).uploadAvatar(c,E);d.code===200?(I.ElMessage.success("头像上传成功"),ge(d.data),Ie()):I.ElMessage.error(d.msg||"头像上传失败")}catch(r){console.error(r),I.ElMessage.error("头像上传失败")}finally{U.value=!1}}},Ie=()=>{q.value="",i.value=!1,P.value&&(P.value.value="")},Ys=()=>{R.value={nickname:g.value.nickname||"",email:g.value.email||"",phone:g.value.phone||"",bio:g.value.bio||""},L.value=!0},Gs=()=>{L.value=!1,R.value={nickname:"",email:"",phone:"",bio:""}},Js=async()=>{o.value=!0;try{await xe(R.value)?(I.ElMessage.success("保存成功"),L.value=!1):I.ElMessage.error("保存失败")}catch(c){console.error(c),I.ElMessage.error("保存失败")}finally{o.value=!1}},Qs=()=>{ie(),le(),Z.value=!1,n.value=!1,Ie(),L.value=!1,l("close")},Zs=async()=>{await Promise.all([ae(),he(),ye()]),fe(),z.value.length>0&&we(z.value[0]),l("open")};return e.onMounted(()=>{document.addEventListener("click",ke)}),e.onUnmounted(()=>{document.removeEventListener("click",ke),le()}),(c,r)=>{const d=e.resolveComponent("el-icon"),k=e.resolveComponent("el-input"),oe=e.resolveComponent("el-empty"),te=e.resolveComponent("el-button"),Ve=e.resolveComponent("el-dialog");return e.openBlock(),e.createBlock(Ve,{modelValue:V.value,"onUpdate:modelValue":r[13]||(r[13]=s=>V.value=s),width:p.width,"close-on-click-modal":!1,class:"chat-dialog","append-to-body":"",onClosed:Qs,onOpen:Zs},{default:e.withCtx(()=>[e.createElementVNode("div",He,[e.createElementVNode("div",qe,[e.createElementVNode("div",{class:"mb-4 cursor-pointer mt-4",onClick:vs},[e.createElementVNode("img",{src:e.unref(B),alt:"头像",class:"w-10 h-10 rounded-full border-2 border-gray-200"},null,8,Oe)]),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(be.value,s=>(e.openBlock(),e.createElementBlock("div",{key:s.id,class:e.normalizeClass(["w-10 h-10 flex items-center justify-center cursor-pointer rounded-lg transition-all relative",H.value===s.id?"bg-green-50 text-green-600":"text-gray-500 hover:bg-gray-100"]),onClick:$=>H.value=s.id},[e.createVNode(d,{size:24},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(s.icon)))]),_:2},1024),s.badge?(e.openBlock(),e.createElementBlock("span",Xe,e.toDisplayString(s.badge>99?"99+":s.badge),1)):e.createCommentVNode("",!0)],10,Pe))),128)),r[14]||(r[14]=e.createElementVNode("div",{class:"flex-1"},null,-1)),p.config.modules.settings?(e.openBlock(),e.createElementBlock("div",{key:0,class:"w-10 h-10 flex items-center justify-center cursor-pointer rounded-lg hover:bg-gray-100 transition-all mb-4 text-gray-500",onClick:r[0]||(r[0]=s=>n.value=!0),title:"设置"},[e.createVNode(d,{size:24},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Setting))]),_:1})])):e.createCommentVNode("",!0)]),e.createElementVNode("div",Ye,[e.createElementVNode("div",Ge,[e.createVNode(k,{modelValue:e.unref(h),"onUpdate:modelValue":r[1]||(r[1]=s=>e.isRef(h)?h.value=s:null),placeholder:"搜索","prefix-icon":e.unref(_.Search)},null,8,["modelValue","prefix-icon"])]),e.createElementVNode("div",Je,[H.value==="chat"?(e.openBlock(),e.createElementBlock("div",Qe,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(z),s=>(e.openBlock(),e.createElementBlock("div",{key:s.id,class:e.normalizeClass(["flex items-center p-3 cursor-pointer hover:bg-[#e5e5e5] transition-colors",Q.value===s.id?"bg-[#d6d6d6]":""]),onClick:$=>we(s),onContextmenu:e.withModifiers($=>Is($,s),["prevent","stop"])},[e.createElementVNode("div",et,[e.createElementVNode("img",{src:s.avatar,alt:s.name,class:"w-11 h-11 rounded-full object-cover"},null,8,tt),s.online?(e.openBlock(),e.createElementBlock("span",st)):e.createCommentVNode("",!0)]),e.createElementVNode("div",at,[e.createElementVNode("div",ot,[e.createElementVNode("span",rt,e.toDisplayString(s.name),1),e.createElementVNode("span",nt,e.toDisplayString(e.unref(M)(s.lastTime)),1)]),e.createElementVNode("div",lt,[e.createElementVNode("span",it,e.toDisplayString(s.lastMsg),1),s.unread>0?(e.openBlock(),e.createElementBlock("span",ct,e.toDisplayString(s.unread>99?"99+":s.unread),1)):e.createCommentVNode("",!0)])])],42,Ze))),128))])):e.createCommentVNode("",!0),H.value==="friends"&&p.config.modules.friends?(e.openBlock(),e.createElementBlock("div",dt,[e.createElementVNode("div",mt,[e.createElementVNode("div",{class:"flex items-center gap-2 p-2 rounded-lg cursor-pointer hover:bg-[#e5e5e5]",onClick:r[2]||(r[2]=(...s)=>e.unref(ce)&&e.unref(ce)(...s))},[e.createElementVNode("div",ft,[e.createVNode(d,{class:"text-white",size:20},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Plus))]),_:1})]),r[15]||(r[15]=e.createElementVNode("span",{class:"text-sm text-gray-800"},"添加好友",-1))])]),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(m),s=>(e.openBlock(),e.createElementBlock("div",{key:s.id,class:"flex items-center p-3 cursor-pointer hover:bg-[#e5e5e5] transition-colors",onClick:$=>js(s)},[e.createElementVNode("div",ht,[e.createElementVNode("img",{src:s.avatar,alt:s.name,class:"w-11 h-11 rounded-full object-cover"},null,8,ut),e.createElementVNode("span",{class:e.normalizeClass(["absolute bottom-0 right-0 w-3 h-3 rounded-full border-2 border-white",s.online?"bg-green-500":"bg-gray-400"])},null,2)]),e.createElementVNode("div",gt,[e.createElementVNode("span",yt,e.toDisplayString(s.name),1)])],8,pt))),128))])):e.createCommentVNode("",!0),H.value==="apply"&&p.config.modules.apply?(e.openBlock(),e.createElementBlock("div",xt,[e.unref(F)?(e.openBlock(),e.createBlock(oe,{key:0,description:"加载中..."})):e.unref(b).length===0?(e.openBlock(),e.createBlock(oe,{key:1,description:"暂无好友申请"})):(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:2},e.renderList(e.unref(b),s=>(e.openBlock(),e.createElementBlock("div",{key:s.applyUser||s.id,class:"flex items-center justify-between p-3 hover:bg-[#e5e5e5]"},[e.createElementVNode("div",bt,[e.createElementVNode("img",{src:`https://api.dicebear.com/7.x/avataaars/svg?seed=${s.applyUser}`,alt:s.applyUser,class:"w-11 h-11 rounded-full object-cover"},null,8,kt),e.createElementVNode("div",wt,[e.createElementVNode("div",Vt,e.toDisplayString(s.applyUser),1),r[16]||(r[16]=e.createElementVNode("div",{class:"text-xs text-gray-500 mt-1"},"请求添加你为好友",-1))])]),e.createVNode(te,{type:"primary",size:"small",onClick:$=>e.unref(ue)(s.applyUser)},{default:e.withCtx(()=>[...r[17]||(r[17]=[e.createTextVNode("同意",-1)])]),_:1},8,["onClick"])]))),128))])):e.createCommentVNode("",!0)])]),e.createElementVNode("div",Ct,[A.value&&!S.value?(e.openBlock(),e.createElementBlock("div",_t,[e.createElementVNode("div",Nt,[e.createElementVNode("img",{src:A.value.avatar,alt:A.value.name,class:"w-24 h-24 rounded-full object-cover mb-6"},null,8,Et),e.createElementVNode("div",Ut,e.toDisplayString(A.value.name),1),e.createElementVNode("div",Bt,[e.createElementVNode("span",{class:e.normalizeClass(["w-2 h-2 rounded-full",A.value.online?"bg-green-500":"bg-gray-400"])},null,2),e.createElementVNode("span",St,e.toDisplayString(A.value.online?"在线":"离线"),1)]),e.createVNode(te,{type:"primary",size:"large",onClick:$s,class:"w-40"},{default:e.withCtx(()=>[e.createVNode(d,null,{default:e.withCtx(()=>[e.createVNode(e.unref(_.ChatDotRound))]),_:1}),r[18]||(r[18]=e.createElementVNode("span",null,"发消息",-1))]),_:1})])])):e.createCommentVNode("",!0),S.value?(e.openBlock(),e.createElementBlock("div",At,[e.createElementVNode("div",Ft,[e.createElementVNode("div",Dt,[e.createElementVNode("span",Rt,e.toDisplayString(S.value.name),1),e.createElementVNode("span",{class:e.normalizeClass(["text-xs px-2 py-0.5 rounded",S.value.online?"bg-green-100 text-green-600":"bg-gray-100 text-gray-500"])},e.toDisplayString(S.value.online?"在线":"离线"),3)]),e.createElementVNode("div",Tt,[e.createVNode(d,{class:"cursor-pointer hover:text-gray-700"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Search))]),_:1}),e.createVNode(d,{class:"cursor-pointer hover:text-gray-700",onClick:r[3]||(r[3]=s=>Z.value=!Z.value)},{default:e.withCtx(()=>[e.createVNode(e.unref(_.MoreFilled))]),_:1})])]),e.createElementVNode("div",{ref_key:"messagesContainer",ref:C,class:"flex-1 overflow-y-auto p-4 bg-[#f5f5f5] min-h-0 message-list"},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(W),(s,$)=>(e.openBlock(),e.createElementBlock("div",{key:$,class:e.normalizeClass(["flex mb-6 items-start",s.isSelf?"flex-row-reverse":"flex-row"])},[e.createElementVNode("div",zt,[e.createElementVNode("img",{src:s.isSelf?e.unref(B):S.value.avatar,class:"w-10 h-10 rounded-lg object-cover"},null,8,Lt)]),e.createElementVNode("div",{class:e.normalizeClass(["flex flex-col max-w-[75%]",s.isSelf?"mr-3 items-end":"ml-3 items-start"])},[s.isSelf?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",It,e.toDisplayString(S.value.name),1)),e.createElementVNode("div",Mt,[s.type==="text"?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["px-3 py-2 text-sm break-all whitespace-pre-wrap rounded-lg shadow-sm",s.isSelf?"bg-[#95ec69] text-gray-800 self-end message-bubble-self":"bg-white text-gray-800 message-bubble-other"])},e.toDisplayString(s.text),3)):s.type==="file"&&s.fileType==="image"?(e.openBlock(),e.createElementBlock("div",{key:1,class:e.normalizeClass(["rounded-lg relative shadow-sm cursor-pointer overflow-hidden max-w-[300px]",s.isSelf?"self-end":"self-start"]),onClick:Ce=>Le(s.fileUrl)},[e.createElementVNode("img",{src:s.fileUrl,alt:s.fileName,class:"w-full h-auto block",onError:Os},null,40,$t),s.fileName||s.fileSize?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass([s.isSelf?"bg-[#95ec69] text-gray-700":"bg-white text-gray-500"])},[s.fileSize?(e.openBlock(),e.createElementBlock("div",vt,e.toDisplayString(Te(s.fileSize)),1)):e.createCommentVNode("",!0)],2)):e.createCommentVNode("",!0)],10,jt)):s.type==="file"?(e.openBlock(),e.createElementBlock("div",{key:2,class:e.normalizeClass(["rounded-lg shadow-sm cursor-pointer overflow-hidden min-w-[200px]",s.isSelf?"self-end message-bubble-self":"message-bubble-other"]),onClick:Ce=>Le(s.fileUrl)},[e.createElementVNode("div",{class:e.normalizeClass(["flex items-center gap-3 px-4 py-3",s.isSelf?"bg-[#95ec69]":"bg-white"])},[e.createElementVNode("div",Wt,[e.createVNode(d,{size:28,class:e.normalizeClass(s.isSelf?"text-gray-700":"text-gray-500")},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Document))]),_:1},8,["class"])]),e.createElementVNode("div",Ht,[e.createElementVNode("div",{class:e.normalizeClass(["truncate text-sm font-medium leading-tight",(s.isSelf,"text-gray-800")])},e.toDisplayString(s.fileName||s.text),3),e.createElementVNode("div",{class:e.normalizeClass(["text-xs mt-1 flex items-center gap-2",s.isSelf?"text-gray-600":"text-gray-500"])},[e.createVNode(d,{size:12},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Download))]),_:1}),r[19]||(r[19]=e.createElementVNode("span",null,"点击下载",-1)),s.fileSize?(e.openBlock(),e.createElementBlock("span",qt,"· "+e.toDisplayString(Te(s.fileSize)),1)):e.createCommentVNode("",!0)],2)])],2)],10,Kt)):e.createCommentVNode("",!0),e.createElementVNode("div",{class:e.normalizeClass(["text-[10px] text-gray-400 mt-1",s.isSelf?"text-right":"text-left"])},e.toDisplayString(e.unref(Y)(s.time)),3)])],2)],2))),128))],512),e.createElementVNode("div",Ot,[T.value.length>0?(e.openBlock(),e.createElementBlock("div",Pt,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(T.value,(s,$)=>(e.openBlock(),e.createElementBlock("div",{key:s.id,class:"relative group"},[s.isImage?(e.openBlock(),e.createElementBlock("div",Xt,[e.createElementVNode("img",{src:s.previewUrl,alt:s.name,class:"w-full h-full object-cover"},null,8,Yt),e.createElementVNode("button",{onClick:Ce=>Re($),class:"absolute top-1 right-1 w-5 h-5 bg-black/50 text-white rounded-full flex items-center justify-center hover:bg-black/70 transition-colors text-xs"}," × ",8,Gt)])):(e.openBlock(),e.createElementBlock("div",Jt,[e.createVNode(d,{class:"text-gray-400 text-2xl mb-1"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Folder))]),_:1}),e.createElementVNode("span",Qt,e.toDisplayString(s.name),1),e.createElementVNode("button",{onClick:Ce=>Re($),class:"absolute top-1 right-1 w-5 h-5 bg-black/50 text-white rounded-full flex items-center justify-center hover:bg-black/70 transition-colors text-xs"}," × ",8,Zt)]))]))),128))])):e.createCommentVNode("",!0),p.config.modules.fileUpload?(e.openBlock(),e.createElementBlock("div",es,[e.createVNode(d,{class:"text-gray-500 cursor-pointer hover:text-gray-700"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.ChatDotRound))]),_:1}),e.createVNode(d,{class:"text-gray-500 cursor-pointer hover:text-gray-700",onClick:Ws},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Folder))]),_:1}),e.createVNode(d,{class:"text-gray-500 cursor-pointer hover:text-gray-700"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Picture))]),_:1})])):e.createCommentVNode("",!0),e.createElementVNode("div",ts,[e.withDirectives(e.createElementVNode("textarea",{"onUpdate:modelValue":r[4]||(r[4]=s=>e.isRef(u)?u.value=s:null),onKeydown:e.withKeys(e.withModifiers(ze,["prevent"]),["enter"]),onPaste:qs,placeholder:"输入消息或粘贴文件...",class:"w-full resize-none border-0 outline-none text-sm h-[80px]",rows:"3"},null,40,ss),[[e.vModelText,e.unref(u)]])]),e.createElementVNode("div",as,[e.createVNode(te,{type:"primary",disabled:!e.unref(u).trim()&&T.value.length===0,onClick:ze,class:"bg-[#07c160] hover:bg-[#06ad56] border-0 text-sm px-6"},{default:e.withCtx(()=>[...r[20]||(r[20]=[e.createTextVNode(" 发送 ",-1)])]),_:1},8,["disabled"])]),e.createElementVNode("input",{ref_key:"fileInputRef",ref:ee,type:"file",multiple:"",class:"hidden",onChange:Hs},null,544)])])):A.value?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",os,[e.createVNode(d,{size:64,class:"text-gray-300 mb-2"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.ChatLineRound))]),_:1}),e.createElementVNode("div",rs,e.toDisplayString(H.value==="apply"?"在左侧选择好友申请":"在左侧选择好友开始聊天"),1)]))]),Z.value?(e.openBlock(),e.createElementBlock("div",ns,[r[22]||(r[22]=e.createElementVNode("div",{class:"h-14 flex items-center justify-center border-b border-gray-200"},[e.createElementVNode("span",{class:"font-medium text-gray-700"},"聊天详情")],-1)),e.createElementVNode("div",ls,[e.createElementVNode("div",is,[e.createElementVNode("img",{src:S.value?.avatar,alt:S.value?.name,class:"w-20 h-20 rounded-full object-cover"},null,8,cs),e.createElementVNode("div",ds,e.toDisplayString(S.value?.name),1),r[21]||(r[21]=e.createElementVNode("div",{class:"mt-6 w-full"},[e.createElementVNode("div",{class:"bg-white rounded-lg"},[e.createElementVNode("div",{class:"p-3 border-b border-gray-100 cursor-pointer hover:bg-gray-50"},[e.createElementVNode("span",{class:"text-sm text-gray-700"},"查找聊天记录")]),e.createElementVNode("div",{class:"p-3 border-b border-gray-100 cursor-pointer hover:bg-gray-50"},[e.createElementVNode("span",{class:"text-sm text-gray-700"},"清空聊天记录")])])],-1))])])])):e.createCommentVNode("",!0)]),e.createVNode(Ve,{modelValue:e.unref(X),"onUpdate:modelValue":r[6]||(r[6]=s=>e.isRef(X)?X.value=s:null),title:"添加好友",width:"500px","append-to-body":""},{default:e.withCtx(()=>[e.createElementVNode("div",ms,[e.createElementVNode("div",fs,[e.createVNode(k,{modelValue:e.unref(O),"onUpdate:modelValue":r[5]||(r[5]=s=>e.isRef(O)?O.value=s:null),placeholder:"搜索用户","prefix-icon":e.unref(_.Search)},null,8,["modelValue","prefix-icon"])])]),e.createElementVNode("div",ps,[e.unref(x)?(e.openBlock(),e.createBlock(oe,{key:0,description:"加载中..."})):e.unref(v).length===0?(e.openBlock(),e.createBlock(oe,{key:1,description:"暂无用户"})):(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:2},e.renderList(e.unref(v),s=>(e.openBlock(),e.createElementBlock("div",{key:s.username,class:"flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg mb-2 transition-colors"},[e.createElementVNode("div",hs,[e.createElementVNode("img",{src:`https://api.dicebear.com/7.x/avataaars/svg?seed=${s.username}`,alt:s.username,class:"w-10 h-10 rounded-full object-cover"},null,8,us),e.createElementVNode("div",gs,[e.createElementVNode("div",ys,e.toDisplayString(s.username),1)])]),e.createVNode(te,{type:"primary",size:"small",onClick:$=>e.unref(pe)(s)},{default:e.withCtx(()=>[...r[23]||(r[23]=[e.createTextVNode("添加",-1)])]),_:1},8,["onClick"])]))),128))])]),_:1},8,["modelValue"]),e.createVNode(Ve,{modelValue:n.value,"onUpdate:modelValue":r[11]||(r[11]=s=>n.value=s),title:"个人设置",width:"560px","close-on-click-modal":!1,"append-to-body":"",class:"settings-dialog"},{default:e.withCtx(()=>[e.createElementVNode("div",xs,[e.createElementVNode("div",bs,[e.createElementVNode("div",ks,[e.createElementVNode("img",{src:e.unref(B),alt:"头像",class:"w-28 h-28 rounded-full object-cover border-4 border-white shadow-lg"},null,8,ws),p.config.modules.avatarCrop?(e.openBlock(),e.createElementBlock("div",{key:0,class:"absolute -bottom-1 -right-1 w-10 h-10 bg-green-500 rounded-full flex items-center justify-center cursor-pointer hover:bg-green-600 transition-all shadow-md",onClick:Ks},[e.createVNode(d,{size:18,class:"text-white"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Camera))]),_:1})])):e.createCommentVNode("",!0),e.createElementVNode("input",{ref_key:"avatarInputRef",ref:P,type:"file",accept:"image/*",class:"hidden",onChange:Ps},null,544)]),e.createElementVNode("div",Vs,[e.createElementVNode("div",Cs,e.toDisplayString(e.unref(g).nickname||e.unref(E)),1),e.createElementVNode("div",_s,"@"+e.toDisplayString(e.unref(E)),1)])]),e.createElementVNode("div",Ns,[e.createElementVNode("div",Es,[e.createElementVNode("div",Us,[e.createVNode(d,null,{default:e.withCtx(()=>[e.createVNode(e.unref(_.UserFilled))]),_:1}),r[24]||(r[24]=e.createTextVNode(" 个人信息 ",-1))]),L.value?e.createCommentVNode("",!0):(e.openBlock(),e.createBlock(te,{key:0,type:"primary",size:"small",onClick:Ys,class:"rounded-full"},{default:e.withCtx(()=>[...r[25]||(r[25]=[e.createTextVNode(" 编辑 ",-1)])]),_:1}))]),e.createElementVNode("div",Bs,[e.createElementVNode("div",null,[r[26]||(r[26]=e.createElementVNode("label",{class:"block text-sm text-gray-600 mb-2 font-medium"},"昵称",-1)),L.value?(e.openBlock(),e.createBlock(k,{key:0,modelValue:R.value.nickname,"onUpdate:modelValue":r[7]||(r[7]=s=>R.value.nickname=s),placeholder:"请输入昵称",size:"large"},null,8,["modelValue"])):(e.openBlock(),e.createElementBlock("div",Ss,e.toDisplayString(e.unref(g).nickname||"未设置"),1))]),e.createElementVNode("div",null,[r[27]||(r[27]=e.createElementVNode("label",{class:"block text-sm text-gray-600 mb-2 font-medium"},"邮箱",-1)),L.value?(e.openBlock(),e.createBlock(k,{key:0,modelValue:R.value.email,"onUpdate:modelValue":r[8]||(r[8]=s=>R.value.email=s),placeholder:"请输入邮箱",size:"large"},null,8,["modelValue"])):(e.openBlock(),e.createElementBlock("div",As,e.toDisplayString(e.unref(g).email||"未设置"),1))]),e.createElementVNode("div",null,[r[28]||(r[28]=e.createElementVNode("label",{class:"block text-sm text-gray-600 mb-2 font-medium"},"手机号",-1)),L.value?(e.openBlock(),e.createBlock(k,{key:0,modelValue:R.value.phone,"onUpdate:modelValue":r[9]||(r[9]=s=>R.value.phone=s),placeholder:"请输入手机号",size:"large"},null,8,["modelValue"])):(e.openBlock(),e.createElementBlock("div",Fs,e.toDisplayString(e.unref(g).phone||"未设置"),1))]),e.createElementVNode("div",null,[r[29]||(r[29]=e.createElementVNode("label",{class:"block text-sm text-gray-600 mb-2 font-medium"},"个人简介",-1)),L.value?(e.openBlock(),e.createBlock(k,{key:0,modelValue:R.value.bio,"onUpdate:modelValue":r[10]||(r[10]=s=>R.value.bio=s),type:"textarea",rows:4,placeholder:"介绍一下自己吧...",size:"large"},null,8,["modelValue"])):(e.openBlock(),e.createElementBlock("div",Ds,e.toDisplayString(e.unref(g).bio||"这个人很懒,什么都没写~"),1))]),L.value?(e.openBlock(),e.createElementBlock("div",Rs,[e.createVNode(te,{size:"default",onClick:Gs},{default:e.withCtx(()=>[...r[30]||(r[30]=[e.createTextVNode("取消",-1)])]),_:1}),e.createVNode(te,{type:"primary",size:"default",loading:o.value,onClick:Js},{default:e.withCtx(()=>[...r[31]||(r[31]=[e.createTextVNode("保存更改",-1)])]),_:1},8,["loading"])])):e.createCommentVNode("",!0)])])])]),_:1},8,["modelValue"]),e.createVNode(Se,{modelValue:i.value,"onUpdate:modelValue":r[12]||(r[12]=s=>i.value=s),src:q.value,onConfirm:Xs},null,8,["modelValue","src"]),J.value.visible?(e.openBlock(),e.createElementBlock("div",{key:0,class:"context-menu fixed bg-white rounded-lg shadow-lg border py-1 z-50",style:e.normalizeStyle({left:J.value.x+"px",top:J.value.y+"px"})},[e.createElementVNode("div",{class:"px-4 py-2 hover:bg-gray-100 cursor-pointer",onClick:Ms},"删除聊天")],4)):e.createCommentVNode("",!0)]),_:1},8,["modelValue","width"])}}},[["__scopeId","data-v-fc6ab10a"]]),zs={api:{baseUrl:"",websocketUrl:"",endpoints:{getFriends:"/chart/friends",getHistory:"/chart/history",setRead:"/chart/read",uploadFile:"/chart/upload/file",addFriend:"/chart/friend/add",getApplyList:"/chart/friend/applyList",agreeFriend:"/chart/friend/agree",setChatStatus:"/chart/friend/chat/status",getAvailableUsers:"/chart/user/canAddFriend",getUserInfo:"/user/info",updateUserInfo:"/user/info",getUserAvatar:"/user/getAvatar",uploadAvatar:"/user/uploadAvatar"},adapter:null},user:{username:"",avatar:"",nickname:"",email:"",phone:"",bio:""},modules:{friends:!0,apply:!0,settings:!0,fileUpload:!0,avatarCrop:!0},theme:{primaryColor:"#07c160",selfMessageBg:"#95ec69",otherMessageBg:"#ffffff"},headers:{},websocket:{maxReconnectAttempts:5,reconnectDelay:3e3},file:{maxSize:50*1024*1024,allowedTypes:["*"]}};function Ls(p={}){const t=Ae(zs,p);return t.api.baseUrl||console.warn("[VueChatKit] 请配置 api.baseUrl"),t.api.websocketUrl||console.warn("[VueChatKit] 请配置 api.websocketUrl"),t.user.username||console.warn("[VueChatKit] 请配置 user.username"),t}function Ae(p,t){const a={...p};for(const l in t)t[l]&&typeof t[l]=="object"&&!Array.isArray(t[l])?a[l]=Ae(p[l]||{},t[l]):a[l]=t[l];return a}const Fe={install(p){p.component("ChatWindow",ChatWindow),p.component("AvatarCrop",AvatarCrop)}};N.AvatarCrop=Se,N.ChatApi=Ee,N.ChatWebSocket=_e,N.ChatWindow=Ts,N.HttpClient=Ne,N.VueChatKit=Fe,N.createChatConfig=Ls,N.default=Fe,N.useChat=Ue,Object.defineProperties(N,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-chat-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "一个功能完整的 Vue 3 聊天组件库,支持 WebSocket 实时通信、文件上传、好友管理等功能",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/vue-chat-kit.umd.js",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
],
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
15
16
|
"import": "./dist/vue-chat-kit.es.js",
|
|
16
|
-
"require": "./dist/vue-chat-kit.umd.js"
|
|
17
|
-
"types": "./dist/index.d.ts"
|
|
17
|
+
"require": "./dist/vue-chat-kit.umd.js"
|
|
18
18
|
},
|
|
19
19
|
"./style": "./dist/style.css"
|
|
20
20
|
},
|