@billtaofbj/core 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 @yourcompany
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("vue"),require("axios"),require("yjs"),require("@hocuspocus/provider"),require("@element-plus/icons-vue"),require("element-plus")):typeof define==`function`&&define.amd?define([`exports`,`vue`,`axios`,`yjs`,`@hocuspocus/provider`,`@element-plus/icons-vue`,`element-plus`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.YourCompanyCore={},e.Vue,e.axios,e.yjs,e._hocuspocus_provider,e.ElementPlusIconsVue,e.ElementPlus))})(this,function(e,t,n,r,i,a,o){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var s=Object.create,c=Object.defineProperty,l=Object.getOwnPropertyDescriptor,u=Object.getOwnPropertyNames,d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty,p=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=u(t),a=0,o=i.length,s;a<o;a++)s=i[a],!f.call(e,s)&&s!==n&&c(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=l(t,s))||r.enumerable});return e},m=(e,t,n)=>(n=e==null?{}:s(d(e)),p(t||!e||!e.__esModule?c(n,`default`,{value:e,enumerable:!0}):n,e));n=m(n,1),r=m(r,1);function h(){let e=(0,t.ref)([]),r=(0,t.ref)(!1),i=(0,t.ref)(!1),a=(0,t.ref)([]),o=(0,t.ref)({id:``,name:``,color:``}),s=(0,t.ref)(!1),c=null,l=null,u=null,d=new Set,f=`/api/chat`,p=null,m=({ydoc:n,provider:r,onlineUsers:l})=>{if(n){i.value=!0,u=l,p&&p(),p=(0,t.watch)(u,e=>{a.value=Array.isArray(e)?e:[]},{immediate:!0,deep:!0});try{c=n.getArray(`chat-messages`),c.observe(t=>{try{t.changes.added.forEach(t=>{t.content.getContent().forEach(t=>{t&&t._msgId&&!d.has(t._msgId)&&(d.add(t._msgId),e.value=[...e.value,t],t.mentioned_user&&t.user_id!==o.value.id&&(s.value=!0))})})}catch(e){console.warn(`[useChat] Y.Array observer error:`,e)}})}catch(e){console.warn(`[useChat] Failed to create Y.Array:`,e)}}},h=e=>{o.value={...o.value,...e}},g=e=>{a.value=e||[]},_=()=>{let e=new Date;return`${e.getHours().toString().padStart(2,`0`)}:${e.getMinutes().toString().padStart(2,`0`)}`},v=async(r,a={})=>{let s={_msgId:`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,role:`user`,content:r,time:_(),user_id:o.value.id,user_name:o.value.name,user_color:o.value.color,mentioned_user:a.mentionedUser||null};if(d.add(s._msgId),e.value=[...e.value,s],c&&(0,t.unref)(i))try{c.push([s])}catch(e){console.warn(`[useChat] Failed to push to Y.Array:`,e)}if(a.roomId)try{await n.default.post(f,{room_id:a.roomId,role:`user`,content:r,user_id:o.value.id,user_name:o.value.name,mentioned_user:a.mentionedUser||null})}catch(e){console.warn(`[useChat] Failed to persist message:`,e)}},y=async(r,a)=>{let o={_msgId:`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,role:`ai`,content:r,time:_(),user_id:`ai-assistant`,user_name:`AI助手`};if(d.add(o._msgId),e.value=[...e.value,o],c&&(0,t.unref)(i))try{c.push([o])}catch(e){console.warn(`[useChat] Failed to push AI message to Y.Array:`,e)}if(a)try{await n.default.post(f,{room_id:a,role:`ai`,content:r,user_id:`ai-assistant`,user_name:`AI助手`})}catch(e){console.warn(`[useChat] Failed to persist AI message:`,e)}},b=async t=>{if(t)try{let r=await n.default.get(f,{params:{room_id:t}});if(Array.isArray(r.data)){let t=r.data.map(e=>({_msgId:e._msgId||`hist-${e.id||Date.now()}`,role:e.role,content:e.content,time:e.time||_(),user_id:e.user_id||``,user_name:e.user_name||``,user_color:e.user_color||``,mentioned_user:e.mentioned_user||null}));t.forEach(e=>d.add(e._msgId)),e.value=[...t,...e.value]}}catch(e){console.warn(`[useChat] Failed to load history:`,e)}},x=async t=>{if(e.value=[],d.clear(),t)try{await n.default.delete(f,{params:{room_id:t}})}catch(e){console.warn(`[useChat] Failed to clear messages on server:`,e)}},S=()=>{s.value=!1},C=()=>{if(p&&=(p(),null),c&&l){try{c.unobserve(l)}catch{}l=null}c=null,u=null,d.clear()};return(0,t.onUnmounted)(()=>C()),{messages:e,loading:r,isCollabMode:i,collabUsers:a,currentUser:o,unreadMention:s,setCollabContext:m,setCurrentUser:h,updateCollabUsers:g,sendMessage:v,sendAiMessage:y,loadHistory:b,clearMessages:x,clearUnreadMention:S,destroy:C}}var g=`/api/document-versions`,_=5e3,v=()=>{let e=(0,t.ref)([]),r=(0,t.ref)(!1);return{versions:e,loading:r,saveVersion:async({documentId:e,docType:t,content:r,userId:i,userName:a})=>{if(!e||!t||!r)return null;try{let{data:o}=await n.default.post(g,{document_id:e,doc_type:t,content:typeof r==`string`?r:JSON.stringify(r),user_id:i||null,user_name:a||null},{timeout:_});return o}catch(e){return console.warn(`[useVersionHistory] Failed to save version:`,e),null}},loadVersions:async t=>{if(!t)return[];r.value=!0;try{let{data:r}=await n.default.get(g,{params:{document_id:t},timeout:_});return e.value=r,r}catch(t){return console.warn(`[useVersionHistory] Failed to load versions:`,t),e.value=[],[]}finally{r.value=!1}},getVersionContent:async e=>{try{let{data:t}=await n.default.get(`${g}/${e}`,{timeout:_});return t}catch(e){return console.warn(`[useVersionHistory] Failed to get version content:`,e),null}}}};function y(e,n={}){let a=new r.Doc,o=(0,t.ref)(!1),s=(0,t.ref)(!1),c=(0,t.ref)(null),l=(0,t.ref)([]),u=(0,t.ref)(!1),d=(0,t.reactive)({name:`用户${Math.floor(Math.random()*1e3)}`,color:`#${Math.floor(Math.random()*16777215).toString(16).padStart(6,`0`)}`}),f=null,p=null,m=null,h=()=>{g(),p=setInterval(()=>{if(f&&f.connection&&f.connection.ws&&f.connection.ws.readyState===WebSocket.CLOSED)try{f.connect()}catch(e){console.warn(`Reconnect failed:`,e)}},3e4)},g=()=>{p&&=(clearInterval(p),null)},_=(t,n)=>{f&&v(),f=new i.HocuspocusProvider({url:n||`ws://${window.location.hostname}:1234`,name:t||(typeof e==`object`?e.value:e),document:a,connect:!0,reconnect:!0,onConnect:()=>{o.value=!0,h()},onClose:()=>{o.value=!1,s.value=!1},onSynced:({state:e})=>{s.value=e},onAwarenessUpdate:({states:e})=>{l.value=Array.from(e.entries()).filter(([e])=>e!==a.clientID).map(([e,t])=>({clientId:e,...t.user||{}}))}}),c.value=f.awareness,h();let r=a.getMap(`_meta`);return r.observe(e=>{e.keysChanged.has(`_closed`)&&(u.value=r.get(`_closed`)===!0)}),f},v=()=>{if(g(),f){try{f.disconnect(),f.destroy()}catch(e){console.warn(`Collaboration disconnect error:`,e)}f=null}o.value=!1,s.value=!1,c.value=null,l.value=[]};return(0,t.onUnmounted)(()=>{v()}),{doc:a,isConnected:o,isSynced:s,awareness:c,peers:l,localUser:d,collaborationClosed:u,connect:_,disconnect:v,closeCollaboration:()=>{u.value=!0;let e=a.getMap(`_meta`);a.transact(()=>{e.set(`_closed`,!0)}),v()},checkCollaborationClosed:()=>a.getMap(`_meta`).get(`_closed`)===!0?(u.value=!0,!0):!1,setLocalUser:e=>{Object.assign(d,e),f&&f.awareness.setLocalStateField(`user`,d)},getSharedData:e=>a.get(e),setSharedData:(e,t)=>{let n=a.getMap(e);a.transact(()=>{typeof t==`object`&&t&&Object.entries(t).forEach(([e,t])=>{n.set(e,t)})})},syncToYjs:(e,t)=>{let n=a.getMap(e),r=JSON.stringify(t);m=r,a.transact(()=>{n.set(`_json`,r)})},onRemoteChange:(e,t)=>{let n=a.getMap(e);n.observe(()=>{let e=n.get(`_json`);if(e!==m&&e)try{t(JSON.parse(e))}catch(e){console.error(`[Collab] JSON parse failed:`,e)}})},observeSharedData:(e,t)=>{let n=a.getMap(e);return n.observe(t),()=>n.unobserve(t)},getSharedArray:e=>a.getArray(e),addToArray:(e,t)=>{a.getArray(e).push([t])},removeFromArray:(e,t)=>{a.getArray(e).delete(t,1)},updateArrayItem:(e,t,n)=>{let r=a.getArray(e);r.delete(t,1),r.insert(t,[n])},getSharedMap:e=>a.getMap(e),setMapValue:(e,t,n)=>{a.getMap(e).set(t,n)},deleteMapValue:(e,t)=>{a.getMap(e).delete(t)},observeMap:(e,t)=>{let n=a.getMap(e);return n.observe(t),()=>n.unobserve(t)},encodeState:()=>r.encodeStateAsUpdate(a),decodeState:e=>{r.applyUpdate(a,e)},getDocId:()=>a.clientID}}var b=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},x={class:`chat-header`},S={class:`chat-header-left`},C={class:`chat-title`},w={class:`online-users-list`},T={class:`online-user-item`},E={class:`online-user-name`},D={key:1},O={class:`online-user-name`},k={class:`chat-header-right`},A={key:0,class:`chat-empty`},j={class:`chat-empty-hint`},M={key:1},N={class:`message-content`},P={key:0,class:`message-meta`},F={key:0,class:`message-mention`},I=[`innerHTML`],L={class:`message-time`},R={key:1,class:`chat-message chat-message-ai`},z={class:`message-avatar ai`},B={class:`chat-input-area`},V={key:0,class:`mention-popup`},H=[`onClick`,`onMouseenter`],U={key:1},W=b({__name:`AiChatPanel`,props:{visible:{type:Boolean,default:!1},messages:{type:Array,default:()=>[]},loading:{type:Boolean,default:!1},panelWidth:{type:Number,default:360},isCollab:{type:Boolean,default:!1},collabUsers:{type:Array,default:()=>[]},currentUser:{type:Object,default:()=>({id:``,name:``,color:``})},isOwner:{type:Boolean,default:!0},unreadMention:{type:Boolean,default:!1}},emits:[`send`,`close`,`clear`,`clear-unread`],setup(e,{emit:n}){let r=e,i=n,o=(0,t.ref)(``),s=(0,t.ref)(null),c=(0,t.ref)(null),l=(0,t.ref)(!1),u=(0,t.ref)([]),d=(0,t.ref)(0),f=``,p=-1,m={id:`ai-assistant`,name:`AI助手`,color:`#409EFF`,isAi:!0},h=(0,t.computed)(()=>{let e=r.currentUser.id,t=new Set;return[m,...r.collabUsers.filter(n=>{let r=n.clientId||n.id||``;if(r&&r===e)return!1;let i=String(r||n.name||``);return t.has(i)?!1:(t.add(i),!0)})]}),g=(0,t.computed)(()=>h.value.length+1),_=e=>e.role===`ai`?`chat-message-ai`:r.isCollab&&e.user_id&&e.user_id!==r.currentUser.id?`chat-message-other`:`chat-message-user`,v=e=>e.role===`ai`?{background:`linear-gradient(135deg, #409EFF, #337ECC)`}:{background:e.user_color||`#67C23A`},y=e=>(e.user_name||`U`).charAt(0),b=e=>{if(!r.isCollab)return;let t=typeof e==`string`?e:e.target?.value||o.value,n=t.length,i=t.lastIndexOf(`@`,n);if(i!==-1&&i<n){let e=t.slice(i+1,n);if(!e.includes(` `)&&!e.includes(`
2
+ `)){f=e,p=i,u.value=h.value.filter(t=>t.name&&t.name.toLowerCase().includes(e.toLowerCase())),l.value=u.value.length>0,d.value=0;return}}l.value=!1},W=()=>{l.value&&(d.value=Math.min(d.value+1,u.value.length-1))},G=()=>{l.value&&(d.value=Math.max(d.value-1,0))},K=e=>{let t=o.value.slice(0,p),n=o.value.slice(p+f.length+1);o.value=`${t}@${e.name} ${n}`,l.value=!1},q=e=>{if(e){if(e.shiftKey)return;if(l.value){let t=u.value[d.value];if(t){e.preventDefault(),K(t);return}}e.preventDefault()}let t=o.value.trim();if(!t||r.loading)return;let n=null;if(r.isCollab){let e=t.match(/@(\S+)/);e&&(n=e[1])}i(`send`,t,{mentionedUser:n}),o.value=``,l.value=!1},J=()=>{(0,t.nextTick)(()=>{s.value&&(s.value.scrollTop=s.value.scrollHeight)})};return(0,t.watch)(()=>r.messages.length,J),(0,t.watch)(()=>r.messages,J,{deep:!0}),(n,r)=>{let f=(0,t.resolveComponent)(`el-icon`),p=(0,t.resolveComponent)(`el-tag`),m=(0,t.resolveComponent)(`el-popover`),J=(0,t.resolveComponent)(`el-button`),Y=(0,t.resolveComponent)(`el-input`);return e.visible?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:0,class:`ai-chat-panel`,style:(0,t.normalizeStyle)({width:e.panelWidth+`px`})},[(0,t.createElementVNode)(`div`,x,[(0,t.createElementVNode)(`div`,S,[(0,t.createVNode)(f,{size:18,color:`#409EFF`},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Monitor))]),_:1}),(0,t.createElementVNode)(`span`,C,(0,t.toDisplayString)(e.isCollab?`协作聊天`:`AI 助手`),1),e.isCollab?((0,t.openBlock)(),(0,t.createBlock)(m,{key:0,width:200,placement:`bottom-start`,trigger:`click`},{reference:(0,t.withCtx)(()=>[(0,t.createVNode)(p,{size:`small`,type:`success`,effect:`plain`,class:`online-tag`},{default:(0,t.withCtx)(()=>[(0,t.createTextVNode)((0,t.toDisplayString)(g.value)+`人在线 `,1)]),_:1})]),default:(0,t.withCtx)(()=>[(0,t.createElementVNode)(`div`,w,[(0,t.createElementVNode)(`div`,T,[(0,t.createElementVNode)(`div`,{class:`online-user-avatar`,style:(0,t.normalizeStyle)({background:e.currentUser.color||`#409EFF`})},(0,t.toDisplayString)((e.currentUser.name||`U`).charAt(0)),5),(0,t.createElementVNode)(`span`,E,(0,t.toDisplayString)(e.currentUser.name||`我`),1),(0,t.createVNode)(p,{size:`small`,type:e.isOwner?`warning`:`success`,effect:`plain`,class:`role-tag`},{default:(0,t.withCtx)(()=>[(0,t.createTextVNode)((0,t.toDisplayString)(e.isOwner?`发起人`:`协作人`),1)]),_:1},8,[`type`]),r[4]||=(0,t.createElementVNode)(`span`,{class:`self-tag`},`(我)`,-1)]),((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(h.value,e=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:e.id||e.clientId,class:`online-user-item`},[(0,t.createElementVNode)(`div`,{class:`online-user-avatar`,style:(0,t.normalizeStyle)({background:e.color||`#909399`})},[e.isAi?((0,t.openBlock)(),(0,t.createBlock)(f,{key:0,size:14},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Monitor))]),_:1})):((0,t.openBlock)(),(0,t.createElementBlock)(`span`,D,(0,t.toDisplayString)((e.name||`U`).charAt(0)),1))],4),(0,t.createElementVNode)(`span`,O,(0,t.toDisplayString)(e.name||`未知用户`),1),e.isAi?((0,t.openBlock)(),(0,t.createBlock)(p,{key:0,size:`small`,type:`primary`,effect:`plain`,class:`role-tag`},{default:(0,t.withCtx)(()=>[...r[5]||=[(0,t.createTextVNode)(`AI助手`,-1)]]),_:1})):((0,t.openBlock)(),(0,t.createBlock)(p,{key:1,size:`small`,type:`success`,effect:`plain`,class:`role-tag`},{default:(0,t.withCtx)(()=>[...r[6]||=[(0,t.createTextVNode)(`协作人`,-1)]]),_:1}))]))),128))])]),_:1})):(0,t.createCommentVNode)(``,!0)]),(0,t.createElementVNode)(`div`,k,[e.isCollab&&e.unreadMention?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:0,class:`mention-bell`,title:`有新消息`,onClick:r[0]||=e=>i(`clear-unread`)},[(0,t.createVNode)(f,{size:18,color:`#F56C6C`},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Bell))]),_:1})])):(0,t.createCommentVNode)(``,!0),(0,t.createVNode)(J,{text:``,circle:``,size:`small`,onClick:r[1]||=e=>n.$emit(`clear`),title:`清空对话`},{default:(0,t.withCtx)(()=>[(0,t.createVNode)(f,null,{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Delete))]),_:1})]),_:1}),(0,t.createVNode)(J,{text:``,circle:``,size:`small`,onClick:r[2]||=e=>n.$emit(`close`),title:`关闭`},{default:(0,t.withCtx)(()=>[(0,t.createVNode)(f,null,{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Close))]),_:1})]),_:1})])]),(0,t.createElementVNode)(`div`,{class:`chat-messages`,ref_key:`messagesRef`,ref:s},[e.messages.length===0?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,A,[(0,t.createVNode)(f,{size:40,color:`#c0c4cc`},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Monitor))]),_:1}),(0,t.createElementVNode)(`p`,null,(0,t.toDisplayString)(e.isCollab?`协作聊天室`:`你好!我是 AI 助手`),1),(0,t.createElementVNode)(`p`,j,(0,t.toDisplayString)(e.isCollab?`与团队成员和AI助手实时聊天`:`可以问我任何关于文档编辑的问题`),1)])):(0,t.createCommentVNode)(``,!0),((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(e.messages,n=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:n._msgId||n.time+n.content,class:(0,t.normalizeClass)([`chat-message`,_(n)])},[(0,t.createElementVNode)(`div`,{class:`message-avatar`,style:(0,t.normalizeStyle)(v(n))},[n.role===`ai`?((0,t.openBlock)(),(0,t.createBlock)(f,{key:0,size:16},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Monitor))]),_:1})):((0,t.openBlock)(),(0,t.createElementBlock)(`span`,M,(0,t.toDisplayString)(y(n)),1))],4),(0,t.createElementVNode)(`div`,N,[e.isCollab&&n.role===`user`?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,P,[(0,t.createElementVNode)(`span`,{class:`message-sender`,style:(0,t.normalizeStyle)({color:n.user_color||`#67C23A`})},(0,t.toDisplayString)(n.user_name||`用户`),5),n.mentioned_user?((0,t.openBlock)(),(0,t.createElementBlock)(`span`,F,`@`+(0,t.toDisplayString)(n.mentioned_user),1)):(0,t.createCommentVNode)(``,!0)])):(0,t.createCommentVNode)(``,!0),(0,t.createElementVNode)(`div`,{class:`message-text`,innerHTML:n.content},null,8,I),(0,t.createElementVNode)(`div`,L,(0,t.toDisplayString)(n.time),1)])],2))),128)),e.loading?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,R,[(0,t.createElementVNode)(`div`,z,[(0,t.createVNode)(f,{size:16},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Monitor))]),_:1})]),r[7]||=(0,t.createElementVNode)(`div`,{class:`message-content`},[(0,t.createElementVNode)(`div`,{class:`message-text typing-indicator`},[(0,t.createElementVNode)(`span`),(0,t.createElementVNode)(`span`),(0,t.createElementVNode)(`span`)])],-1)])):(0,t.createCommentVNode)(``,!0)],512),(0,t.createElementVNode)(`div`,B,[(0,t.createElementVNode)(`div`,{class:`chat-input-wrapper`,ref_key:`inputWrapperRef`,ref:c},[(0,t.createVNode)(Y,{modelValue:o.value,"onUpdate:modelValue":r[3]||=e=>o.value=e,type:`textarea`,autosize:{minRows:1,maxRows:4},placeholder:e.isCollab?`输入消息... @提及成员`:`输入消息...`,onKeydown:[(0,t.withKeys)((0,t.withModifiers)(q,[`exact`]),[`enter`]),(0,t.withKeys)((0,t.withModifiers)(W,[`prevent`]),[`down`]),(0,t.withKeys)((0,t.withModifiers)(G,[`prevent`]),[`up`])],onInput:b,resize:`none`},null,8,[`modelValue`,`placeholder`,`onKeydown`]),l.value?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,V,[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(u.value,(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:e.id||e.clientId,class:(0,t.normalizeClass)([`mention-item`,{active:n===d.value}]),onClick:t=>K(e),onMouseenter:e=>d.value=n},[(0,t.createElementVNode)(`div`,{class:`mention-avatar`,style:(0,t.normalizeStyle)({background:e.color||`#909399`})},[e.isAi?((0,t.openBlock)(),(0,t.createBlock)(f,{key:0,size:12},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Monitor))]),_:1})):((0,t.openBlock)(),(0,t.createElementBlock)(`span`,U,(0,t.toDisplayString)((e.name||`U`).charAt(0)),1))],4),(0,t.createElementVNode)(`span`,null,(0,t.toDisplayString)(e.name),1)],42,H))),128))])):(0,t.createCommentVNode)(``,!0),(0,t.createVNode)(J,{class:`send-btn`,type:`primary`,circle:``,disabled:!o.value.trim()||e.loading,onClick:q},{default:(0,t.withCtx)(()=>[(0,t.createVNode)(f,null,{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Promotion))]),_:1})]),_:1},8,[`disabled`])],512)])],4)):(0,t.createCommentVNode)(``,!0)}}},[[`__scopeId`,`data-v-b10aa283`]]),G={class:`version-history-panel`},K={key:0,class:`loading-state`},q={key:1,class:`empty-state`},J={key:2,class:`version-list`},Y={key:0,class:`current-version`},X={class:`current-version-header`},Z={class:`version-number`},Q=[`onClick`],$={class:`version-number`},ee={class:`version-user`},te={class:`panel-footer`},ne=b({__name:`VersionHistoryPanel`,props:{modelValue:{type:Boolean,default:!1},documentId:{type:[Number,String],default:null}},emits:[`update:modelValue`,`apply`],setup(e,{expose:n,emit:r}){let i=e,s=r,{versions:c,loading:l,loadVersions:u,getVersionContent:d}=v(),f=(0,t.ref)(!1),p=(0,t.ref)(null),m=(0,t.ref)(!1),h=(0,t.ref)(null);(0,t.watch)(()=>i.modelValue,e=>{f.value=e,e&&i.documentId&&(p.value=null,u(i.documentId).then(e=>{e&&e.length>0&&(h.value=e[0])}))}),(0,t.watch)(f,e=>{s(`update:modelValue`,e)});let g=e=>{p.value=e},_=async()=>{if(p.value){m.value=!0;try{let e=await d(p.value.id);e&&e.content?(h.value=p.value,p.value=null,s(`apply`,e.content),o.ElMessage.success(`已切换到版本 v`+h.value.version_number)):o.ElMessage.error(`获取版本内容失败`)}finally{m.value=!1}}},y=()=>{f.value=!1},b=e=>{if(!e)return``;let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`};return n({currentVersion:h}),(e,n)=>{let r=(0,t.resolveComponent)(`el-icon`),i=(0,t.resolveComponent)(`el-tag`),o=(0,t.resolveComponent)(`el-timeline-item`),s=(0,t.resolveComponent)(`el-timeline`),u=(0,t.resolveComponent)(`el-button`),d=(0,t.resolveComponent)(`el-drawer`);return(0,t.openBlock)(),(0,t.createBlock)(d,{modelValue:f.value,"onUpdate:modelValue":n[0]||=e=>f.value=e,title:`更新履历`,direction:`rtl`,size:`420px`,"before-close":y},{footer:(0,t.withCtx)(()=>[(0,t.createElementVNode)(`div`,te,[(0,t.createVNode)(u,{type:`primary`,disabled:!p.value,loading:m.value,onClick:_},{default:(0,t.withCtx)(()=>[...n[4]||=[(0,t.createTextVNode)(` 切换到此版本 `,-1)]]),_:1},8,[`disabled`,`loading`])])]),default:(0,t.withCtx)(()=>[(0,t.createElementVNode)(`div`,G,[(0,t.unref)(l)?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,K,[(0,t.createVNode)(r,{class:`is-loading`},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Loading))]),_:1}),n[1]||=(0,t.createElementVNode)(`span`,null,`加载中...`,-1)])):(0,t.unref)(c).length===0?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,q,[(0,t.createVNode)(r,{size:48,color:`#c0c4cc`},{default:(0,t.withCtx)(()=>[(0,t.createVNode)((0,t.unref)(a.Clock))]),_:1}),n[2]||=(0,t.createElementVNode)(`p`,null,`暂无历史版本`,-1)])):((0,t.openBlock)(),(0,t.createElementBlock)(`div`,J,[h.value?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,Y,[(0,t.createElementVNode)(`div`,X,[(0,t.createVNode)(i,{type:`success`,size:`small`},{default:(0,t.withCtx)(()=>[...n[3]||=[(0,t.createTextVNode)(`当前版本`,-1)]]),_:1}),(0,t.createElementVNode)(`span`,Z,`v`+(0,t.toDisplayString)(h.value.version_number),1)])])):(0,t.createCommentVNode)(``,!0),(0,t.createVNode)(s,null,{default:(0,t.withCtx)(()=>[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)((0,t.unref)(c),e=>((0,t.openBlock)(),(0,t.createBlock)(o,{key:e.id,timestamp:b(e.created_at),placement:`top`,type:p.value?.id===e.id?`primary`:``,hollow:p.value?.id!==e.id},{default:(0,t.withCtx)(()=>[(0,t.createElementVNode)(`div`,{class:(0,t.normalizeClass)([`version-item`,{active:p.value?.id===e.id}]),onClick:t=>g(e)},[(0,t.createElementVNode)(`span`,$,`版本号:v`+(0,t.toDisplayString)(e.version_number),1),(0,t.createElementVNode)(`span`,ee,`提交人:`+(0,t.toDisplayString)(e.user_name||`未知用户`),1)],10,Q)]),_:2},1032,[`timestamp`,`type`,`hollow`]))),128))]),_:1})]))])]),_:1},8,[`modelValue`])}}},[[`__scopeId`,`data-v-68d3257b`]]),re={class:`brand-watermark`},ie=[`title`],ae={class:`brand-text`},oe=b({__name:`BrandWatermark`,props:{text:{type:String,default:`Powered by @billtaofbj`},tooltip:{type:String,default:`@billtaofbj Editor Suite`}},setup(e){return(n,r)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,re,[(0,t.createElementVNode)(`div`,{class:`brand-logo`,title:e.tooltip},[r[0]||=(0,t.createElementVNode)(`svg`,{viewBox:`0 0 24 24`,width:`16`,height:`16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[(0,t.createElementVNode)(`rect`,{width:`24`,height:`24`,rx:`4`,fill:`#409EFF`}),(0,t.createElementVNode)(`text`,{x:`12`,y:`16`,"text-anchor":`middle`,fill:`white`,"font-size":`12`,"font-weight":`bold`,"font-family":`Arial`},`Y`)],-1),(0,t.createElementVNode)(`span`,ae,(0,t.toDisplayString)(e.text),1)],8,ie)]))}},[[`__scopeId`,`data-v-d6cec390`]]);e.AiChatPanel=W,e.BrandWatermark=oe,e.VersionHistoryPanel=ne,e.useChat=h,e.useCollaboration=y,e.useVersionHistory=v});
package/dist/core.css ADDED
@@ -0,0 +1,2 @@
1
+ .ai-chat-panel[data-v-b10aa283]{z-index:2000;background:#fff;border-left:1px solid #e4e7ed;flex-direction:column;height:100vh;display:flex;position:fixed;top:0;right:0;box-shadow:-2px 0 12px #0000001a}.chat-header[data-v-b10aa283]{background:linear-gradient(#fff,#fafafa);border-bottom:1px solid #e4e7ed;justify-content:space-between;align-items:center;min-height:44px;padding:10px 16px;display:flex}.chat-header-left[data-v-b10aa283]{align-items:center;gap:8px;display:flex}.chat-title[data-v-b10aa283]{color:#303133;font-size:14px;font-weight:600}.chat-header-right[data-v-b10aa283]{align-items:center;gap:2px;display:flex}.online-tag[data-v-b10aa283]{cursor:pointer}.mention-bell[data-v-b10aa283]{cursor:pointer;justify-content:center;align-items:center;padding:2px;animation:.8s ease-in-out infinite bellShake-b10aa283;display:flex}.mention-bell[data-v-b10aa283]:hover{opacity:.8}@keyframes bellShake-b10aa283{0%,to{transform:rotate(0)}15%{transform:rotate(15deg)}30%{transform:rotate(-15deg)}45%{transform:rotate(10deg)}60%{transform:rotate(-10deg)}75%{transform:rotate(5deg)}}.online-users-list[data-v-b10aa283]{flex-direction:column;gap:8px;max-height:280px;display:flex;overflow-y:auto}.online-user-item[data-v-b10aa283]{align-items:center;gap:10px;display:flex}.online-user-avatar[data-v-b10aa283]{color:#fff;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:28px;height:28px;font-size:13px;font-weight:600;display:flex}.online-user-name[data-v-b10aa283]{color:#303133;text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px;overflow:hidden}.role-tag[data-v-b10aa283]{flex-shrink:0}.self-tag[data-v-b10aa283]{color:#909399;flex-shrink:0;font-size:12px}.chat-messages[data-v-b10aa283]{flex-direction:column;flex:1;gap:12px;padding:16px;display:flex;overflow-y:auto}.chat-empty[data-v-b10aa283]{color:#909399;flex-direction:column;justify-content:center;align-items:center;height:100%;display:flex}.chat-empty p[data-v-b10aa283]{margin:8px 0 0;font-size:14px}.chat-empty-hint[data-v-b10aa283]{color:#c0c4cc!important;font-size:12px!important}.chat-message[data-v-b10aa283]{gap:10px;max-width:90%;display:flex}.chat-message-user[data-v-b10aa283]{flex-direction:row-reverse;align-self:flex-end}.chat-message-ai[data-v-b10aa283],.chat-message-other[data-v-b10aa283]{align-self:flex-start}.message-avatar[data-v-b10aa283]{color:#fff;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;font-size:13px;font-weight:600;display:flex}.message-avatar.ai[data-v-b10aa283]{background:linear-gradient(135deg,#409eff,#337ecc)}.message-content[data-v-b10aa283]{flex-direction:column;gap:4px;display:flex}.chat-message-user .message-content[data-v-b10aa283]{align-items:flex-end}.message-meta[data-v-b10aa283]{align-items:center;gap:6px;padding:0 4px;display:flex}.message-sender[data-v-b10aa283]{font-size:11px;font-weight:600}.message-mention[data-v-b10aa283]{color:#409eff;font-size:11px;font-weight:600}.message-text[data-v-b10aa283]{word-break:break-word;border-radius:12px;padding:10px 14px;font-size:13px;line-height:1.6}.chat-message-ai .message-text[data-v-b10aa283]{color:#303133;background:#f4f4f5;border-top-left-radius:4px}.chat-message-user .message-text[data-v-b10aa283]{color:#fff;background:linear-gradient(135deg,#409eff,#337ecc);border-top-right-radius:4px}.chat-message-other .message-text[data-v-b10aa283]{color:#303133;background:#f0f9ff;border:1px solid #d9ecff;border-top-left-radius:4px}.message-time[data-v-b10aa283]{color:#c0c4cc;padding:0 4px;font-size:11px}.chat-input-area[data-v-b10aa283]{background:#fafafa;border-top:1px solid #e4e7ed;padding:12px 16px}.chat-input-wrapper[data-v-b10aa283]{align-items:flex-end;gap:8px;display:flex;position:relative}.chat-input-wrapper[data-v-b10aa283] .el-textarea__inner{border:1px solid #dcdfe6;border-radius:10px;padding:8px 12px;font-size:13px;box-shadow:0 1px 4px #0000000f}.chat-input-wrapper[data-v-b10aa283] .el-textarea__inner:focus{border-color:#409eff;box-shadow:0 1px 6px #409eff26}.send-btn[data-v-b10aa283]{flex-shrink:0;width:34px;height:34px}.mention-popup[data-v-b10aa283]{z-index:10;background:#fff;border:1px solid #e4e7ed;border-radius:8px;min-width:160px;max-height:200px;margin-bottom:4px;position:absolute;bottom:100%;left:0;overflow-y:auto;box-shadow:0 4px 12px #0000001a}.mention-item[data-v-b10aa283]{cursor:pointer;align-items:center;gap:8px;padding:8px 12px;font-size:13px;display:flex}.mention-item[data-v-b10aa283]:hover,.mention-item.active[data-v-b10aa283]{background:#f5f7fa}.mention-avatar[data-v-b10aa283]{color:#fff;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:24px;height:24px;font-size:12px;font-weight:600;display:flex}.typing-indicator[data-v-b10aa283]{align-items:center;gap:4px;display:flex;padding:12px 16px!important}.typing-indicator span[data-v-b10aa283]{background:#c0c4cc;border-radius:50%;width:6px;height:6px;animation:1.2s infinite typingBounce-b10aa283}.typing-indicator span[data-v-b10aa283]:nth-child(2){animation-delay:.2s}.typing-indicator span[data-v-b10aa283]:nth-child(3){animation-delay:.4s}@keyframes typingBounce-b10aa283{0%,60%,to{opacity:.4;transform:translateY(0)}30%{opacity:1;transform:translateY(-4px)}}.version-history-panel[data-v-68d3257b]{flex-direction:column;height:100%;display:flex}.loading-state[data-v-68d3257b],.empty-state[data-v-68d3257b]{color:#909399;flex-direction:column;justify-content:center;align-items:center;height:200px;display:flex}.empty-state p[data-v-68d3257b]{margin-top:12px}.version-list[data-v-68d3257b]{flex:1;padding:0 4px;overflow-y:auto}.current-version[data-v-68d3257b]{background:#f0f9eb;border-radius:6px;flex-direction:column;gap:4px;margin-bottom:16px;padding:8px 12px;display:flex}.current-version-header[data-v-68d3257b]{align-items:center;gap:8px;display:flex}.version-meta[data-v-68d3257b]{color:#606266;font-size:13px}.version-item[data-v-68d3257b]{cursor:pointer;border-radius:6px;align-items:center;gap:20px;padding:8px 12px;transition:background .2s;display:flex}.version-item[data-v-68d3257b]:hover{background:#f5f7fa}.version-item.active[data-v-68d3257b]{background:#ecf5ff}.version-number[data-v-68d3257b]{color:#409eff;font-size:14px;font-weight:600}.version-user[data-v-68d3257b]{color:#303133;font-size:14px}.version-time[data-v-68d3257b]{color:#909399;margin-top:2px;font-size:12px}.panel-footer[data-v-68d3257b]{justify-content:flex-end;padding:12px 0;display:flex}.brand-watermark[data-v-d6cec390]{z-index:10;pointer-events:none;position:absolute;bottom:8px;left:8px}.brand-logo[data-v-d6cec390]{opacity:.4;align-items:center;gap:4px;transition:opacity .3s;display:flex}.brand-logo[data-v-d6cec390]:hover{opacity:.8}.brand-text[data-v-d6cec390]{color:#909399;-webkit-user-select:none;user-select:none;font-family:Arial,sans-serif;font-size:11px}
2
+ /*$vite$:1*/
@@ -0,0 +1,845 @@
1
+ import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, nextTick as c, normalizeClass as l, normalizeStyle as u, onUnmounted as d, openBlock as f, reactive as p, ref as m, renderList as h, resolveComponent as g, toDisplayString as _, unref as v, watch as y, withCtx as b, withKeys as x, withModifiers as S } from "vue";
2
+ import C from "axios";
3
+ import * as w from "yjs";
4
+ import { HocuspocusProvider as T } from "@hocuspocus/provider";
5
+ import { Bell as E, Clock as D, Close as O, Delete as k, Loading as A, Monitor as j, Promotion as M } from "@element-plus/icons-vue";
6
+ import { ElMessage as N } from "element-plus";
7
+ //#region src/composables/useChat.js
8
+ function P() {
9
+ let e = m([]), t = m(!1), n = m(!1), r = m([]), i = m({
10
+ id: "",
11
+ name: "",
12
+ color: ""
13
+ }), a = m(!1), o = null, s = null, c = null, l = /* @__PURE__ */ new Set(), u = "/api/chat", f = null, p = ({ ydoc: t, provider: s, onlineUsers: u }) => {
14
+ if (t) {
15
+ n.value = !0, c = u, f && f(), f = y(c, (e) => {
16
+ r.value = Array.isArray(e) ? e : [];
17
+ }, {
18
+ immediate: !0,
19
+ deep: !0
20
+ });
21
+ try {
22
+ o = t.getArray("chat-messages"), o.observe((t) => {
23
+ try {
24
+ t.changes.added.forEach((t) => {
25
+ t.content.getContent().forEach((t) => {
26
+ t && t._msgId && !l.has(t._msgId) && (l.add(t._msgId), e.value = [...e.value, t], t.mentioned_user && t.user_id !== i.value.id && (a.value = !0));
27
+ });
28
+ });
29
+ } catch (e) {
30
+ console.warn("[useChat] Y.Array observer error:", e);
31
+ }
32
+ });
33
+ } catch (e) {
34
+ console.warn("[useChat] Failed to create Y.Array:", e);
35
+ }
36
+ }
37
+ }, h = (e) => {
38
+ i.value = {
39
+ ...i.value,
40
+ ...e
41
+ };
42
+ }, g = (e) => {
43
+ r.value = e || [];
44
+ }, _ = () => {
45
+ let e = /* @__PURE__ */ new Date();
46
+ return `${e.getHours().toString().padStart(2, "0")}:${e.getMinutes().toString().padStart(2, "0")}`;
47
+ }, b = async (t, r = {}) => {
48
+ let a = {
49
+ _msgId: `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
50
+ role: "user",
51
+ content: t,
52
+ time: _(),
53
+ user_id: i.value.id,
54
+ user_name: i.value.name,
55
+ user_color: i.value.color,
56
+ mentioned_user: r.mentionedUser || null
57
+ };
58
+ if (l.add(a._msgId), e.value = [...e.value, a], o && v(n)) try {
59
+ o.push([a]);
60
+ } catch (e) {
61
+ console.warn("[useChat] Failed to push to Y.Array:", e);
62
+ }
63
+ if (r.roomId) try {
64
+ await C.post(u, {
65
+ room_id: r.roomId,
66
+ role: "user",
67
+ content: t,
68
+ user_id: i.value.id,
69
+ user_name: i.value.name,
70
+ mentioned_user: r.mentionedUser || null
71
+ });
72
+ } catch (e) {
73
+ console.warn("[useChat] Failed to persist message:", e);
74
+ }
75
+ }, x = async (t, r) => {
76
+ let i = {
77
+ _msgId: `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
78
+ role: "ai",
79
+ content: t,
80
+ time: _(),
81
+ user_id: "ai-assistant",
82
+ user_name: "AI助手"
83
+ };
84
+ if (l.add(i._msgId), e.value = [...e.value, i], o && v(n)) try {
85
+ o.push([i]);
86
+ } catch (e) {
87
+ console.warn("[useChat] Failed to push AI message to Y.Array:", e);
88
+ }
89
+ if (r) try {
90
+ await C.post(u, {
91
+ room_id: r,
92
+ role: "ai",
93
+ content: t,
94
+ user_id: "ai-assistant",
95
+ user_name: "AI助手"
96
+ });
97
+ } catch (e) {
98
+ console.warn("[useChat] Failed to persist AI message:", e);
99
+ }
100
+ }, S = async (t) => {
101
+ if (t) try {
102
+ let n = await C.get(u, { params: { room_id: t } });
103
+ if (Array.isArray(n.data)) {
104
+ let t = n.data.map((e) => ({
105
+ _msgId: e._msgId || `hist-${e.id || Date.now()}`,
106
+ role: e.role,
107
+ content: e.content,
108
+ time: e.time || _(),
109
+ user_id: e.user_id || "",
110
+ user_name: e.user_name || "",
111
+ user_color: e.user_color || "",
112
+ mentioned_user: e.mentioned_user || null
113
+ }));
114
+ t.forEach((e) => l.add(e._msgId)), e.value = [...t, ...e.value];
115
+ }
116
+ } catch (e) {
117
+ console.warn("[useChat] Failed to load history:", e);
118
+ }
119
+ }, w = async (t) => {
120
+ if (e.value = [], l.clear(), t) try {
121
+ await C.delete(u, { params: { room_id: t } });
122
+ } catch (e) {
123
+ console.warn("[useChat] Failed to clear messages on server:", e);
124
+ }
125
+ }, T = () => {
126
+ a.value = !1;
127
+ }, E = () => {
128
+ if (f &&= (f(), null), o && s) {
129
+ try {
130
+ o.unobserve(s);
131
+ } catch {}
132
+ s = null;
133
+ }
134
+ o = null, c = null, l.clear();
135
+ };
136
+ return d(() => E()), {
137
+ messages: e,
138
+ loading: t,
139
+ isCollabMode: n,
140
+ collabUsers: r,
141
+ currentUser: i,
142
+ unreadMention: a,
143
+ setCollabContext: p,
144
+ setCurrentUser: h,
145
+ updateCollabUsers: g,
146
+ sendMessage: b,
147
+ sendAiMessage: x,
148
+ loadHistory: S,
149
+ clearMessages: w,
150
+ clearUnreadMention: T,
151
+ destroy: E
152
+ };
153
+ }
154
+ //#endregion
155
+ //#region src/composables/useVersionHistory.js
156
+ var F = "/api/document-versions", I = 5e3, L = () => {
157
+ let e = m([]), t = m(!1);
158
+ return {
159
+ versions: e,
160
+ loading: t,
161
+ saveVersion: async ({ documentId: e, docType: t, content: n, userId: r, userName: i }) => {
162
+ if (!e || !t || !n) return null;
163
+ try {
164
+ let { data: a } = await C.post(F, {
165
+ document_id: e,
166
+ doc_type: t,
167
+ content: typeof n == "string" ? n : JSON.stringify(n),
168
+ user_id: r || null,
169
+ user_name: i || null
170
+ }, { timeout: I });
171
+ return a;
172
+ } catch (e) {
173
+ return console.warn("[useVersionHistory] Failed to save version:", e), null;
174
+ }
175
+ },
176
+ loadVersions: async (n) => {
177
+ if (!n) return [];
178
+ t.value = !0;
179
+ try {
180
+ let { data: t } = await C.get(F, {
181
+ params: { document_id: n },
182
+ timeout: I
183
+ });
184
+ return e.value = t, t;
185
+ } catch (t) {
186
+ return console.warn("[useVersionHistory] Failed to load versions:", t), e.value = [], [];
187
+ } finally {
188
+ t.value = !1;
189
+ }
190
+ },
191
+ getVersionContent: async (e) => {
192
+ try {
193
+ let { data: t } = await C.get(`${F}/${e}`, { timeout: I });
194
+ return t;
195
+ } catch (e) {
196
+ return console.warn("[useVersionHistory] Failed to get version content:", e), null;
197
+ }
198
+ }
199
+ };
200
+ };
201
+ //#endregion
202
+ //#region src/composables/useCollaboration.js
203
+ function R(e, t = {}) {
204
+ let n = new w.Doc(), r = m(!1), i = m(!1), a = m(null), o = m([]), s = m(!1), c = p({
205
+ name: `用户${Math.floor(Math.random() * 1e3)}`,
206
+ color: `#${Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")}`
207
+ }), l = null, u = null, f = null, h = () => {
208
+ g(), u = setInterval(() => {
209
+ if (l && l.connection && l.connection.ws && l.connection.ws.readyState === WebSocket.CLOSED) try {
210
+ l.connect();
211
+ } catch (e) {
212
+ console.warn("Reconnect failed:", e);
213
+ }
214
+ }, 3e4);
215
+ }, g = () => {
216
+ u &&= (clearInterval(u), null);
217
+ }, _ = (t, c) => {
218
+ l && v(), l = new T({
219
+ url: c || `ws://${window.location.hostname}:1234`,
220
+ name: t || (typeof e == "object" ? e.value : e),
221
+ document: n,
222
+ connect: !0,
223
+ reconnect: !0,
224
+ onConnect: () => {
225
+ r.value = !0, h();
226
+ },
227
+ onClose: () => {
228
+ r.value = !1, i.value = !1;
229
+ },
230
+ onSynced: ({ state: e }) => {
231
+ i.value = e;
232
+ },
233
+ onAwarenessUpdate: ({ states: e }) => {
234
+ o.value = Array.from(e.entries()).filter(([e]) => e !== n.clientID).map(([e, t]) => ({
235
+ clientId: e,
236
+ ...t.user || {}
237
+ }));
238
+ }
239
+ }), a.value = l.awareness, h();
240
+ let u = n.getMap("_meta");
241
+ return u.observe((e) => {
242
+ e.keysChanged.has("_closed") && (s.value = u.get("_closed") === !0);
243
+ }), l;
244
+ }, v = () => {
245
+ if (g(), l) {
246
+ try {
247
+ l.disconnect(), l.destroy();
248
+ } catch (e) {
249
+ console.warn("Collaboration disconnect error:", e);
250
+ }
251
+ l = null;
252
+ }
253
+ r.value = !1, i.value = !1, a.value = null, o.value = [];
254
+ };
255
+ return d(() => {
256
+ v();
257
+ }), {
258
+ doc: n,
259
+ isConnected: r,
260
+ isSynced: i,
261
+ awareness: a,
262
+ peers: o,
263
+ localUser: c,
264
+ collaborationClosed: s,
265
+ connect: _,
266
+ disconnect: v,
267
+ closeCollaboration: () => {
268
+ s.value = !0;
269
+ let e = n.getMap("_meta");
270
+ n.transact(() => {
271
+ e.set("_closed", !0);
272
+ }), v();
273
+ },
274
+ checkCollaborationClosed: () => n.getMap("_meta").get("_closed") === !0 ? (s.value = !0, !0) : !1,
275
+ setLocalUser: (e) => {
276
+ Object.assign(c, e), l && l.awareness.setLocalStateField("user", c);
277
+ },
278
+ getSharedData: (e) => n.get(e),
279
+ setSharedData: (e, t) => {
280
+ let r = n.getMap(e);
281
+ n.transact(() => {
282
+ typeof t == "object" && t && Object.entries(t).forEach(([e, t]) => {
283
+ r.set(e, t);
284
+ });
285
+ });
286
+ },
287
+ syncToYjs: (e, t) => {
288
+ let r = n.getMap(e), i = JSON.stringify(t);
289
+ f = i, n.transact(() => {
290
+ r.set("_json", i);
291
+ });
292
+ },
293
+ onRemoteChange: (e, t) => {
294
+ let r = n.getMap(e);
295
+ r.observe(() => {
296
+ let e = r.get("_json");
297
+ if (e !== f && e) try {
298
+ t(JSON.parse(e));
299
+ } catch (e) {
300
+ console.error("[Collab] JSON parse failed:", e);
301
+ }
302
+ });
303
+ },
304
+ observeSharedData: (e, t) => {
305
+ let r = n.getMap(e);
306
+ return r.observe(t), () => r.unobserve(t);
307
+ },
308
+ getSharedArray: (e) => n.getArray(e),
309
+ addToArray: (e, t) => {
310
+ n.getArray(e).push([t]);
311
+ },
312
+ removeFromArray: (e, t) => {
313
+ n.getArray(e).delete(t, 1);
314
+ },
315
+ updateArrayItem: (e, t, r) => {
316
+ let i = n.getArray(e);
317
+ i.delete(t, 1), i.insert(t, [r]);
318
+ },
319
+ getSharedMap: (e) => n.getMap(e),
320
+ setMapValue: (e, t, r) => {
321
+ n.getMap(e).set(t, r);
322
+ },
323
+ deleteMapValue: (e, t) => {
324
+ n.getMap(e).delete(t);
325
+ },
326
+ observeMap: (e, t) => {
327
+ let r = n.getMap(e);
328
+ return r.observe(t), () => r.unobserve(t);
329
+ },
330
+ encodeState: () => w.encodeStateAsUpdate(n),
331
+ decodeState: (e) => {
332
+ w.applyUpdate(n, e);
333
+ },
334
+ getDocId: () => n.clientID
335
+ };
336
+ }
337
+ //#endregion
338
+ //#region \0plugin-vue:export-helper
339
+ var z = (e, t) => {
340
+ let n = e.__vccOpts || e;
341
+ for (let [e, r] of t) n[e] = r;
342
+ return n;
343
+ }, ee = { class: "chat-header" }, te = { class: "chat-header-left" }, ne = { class: "chat-title" }, re = { class: "online-users-list" }, ie = { class: "online-user-item" }, ae = { class: "online-user-name" }, oe = { key: 1 }, se = { class: "online-user-name" }, ce = { class: "chat-header-right" }, le = {
344
+ key: 0,
345
+ class: "chat-empty"
346
+ }, ue = { class: "chat-empty-hint" }, B = { key: 1 }, V = { class: "message-content" }, H = {
347
+ key: 0,
348
+ class: "message-meta"
349
+ }, de = {
350
+ key: 0,
351
+ class: "message-mention"
352
+ }, fe = ["innerHTML"], pe = { class: "message-time" }, me = {
353
+ key: 1,
354
+ class: "chat-message chat-message-ai"
355
+ }, he = { class: "message-avatar ai" }, ge = { class: "chat-input-area" }, _e = {
356
+ key: 0,
357
+ class: "mention-popup"
358
+ }, ve = ["onClick", "onMouseenter"], ye = { key: 1 }, U = /*#__PURE__*/ z({
359
+ __name: "AiChatPanel",
360
+ props: {
361
+ visible: {
362
+ type: Boolean,
363
+ default: !1
364
+ },
365
+ messages: {
366
+ type: Array,
367
+ default: () => []
368
+ },
369
+ loading: {
370
+ type: Boolean,
371
+ default: !1
372
+ },
373
+ panelWidth: {
374
+ type: Number,
375
+ default: 360
376
+ },
377
+ isCollab: {
378
+ type: Boolean,
379
+ default: !1
380
+ },
381
+ collabUsers: {
382
+ type: Array,
383
+ default: () => []
384
+ },
385
+ currentUser: {
386
+ type: Object,
387
+ default: () => ({
388
+ id: "",
389
+ name: "",
390
+ color: ""
391
+ })
392
+ },
393
+ isOwner: {
394
+ type: Boolean,
395
+ default: !0
396
+ },
397
+ unreadMention: {
398
+ type: Boolean,
399
+ default: !1
400
+ }
401
+ },
402
+ emits: [
403
+ "send",
404
+ "close",
405
+ "clear",
406
+ "clear-unread"
407
+ ],
408
+ setup(d, { emit: p }) {
409
+ let C = d, w = p, T = m(""), D = m(null), A = m(null), N = m(!1), P = m([]), F = m(0), I = "", L = -1, R = {
410
+ id: "ai-assistant",
411
+ name: "AI助手",
412
+ color: "#409EFF",
413
+ isAi: !0
414
+ }, z = t(() => {
415
+ let e = C.currentUser.id, t = /* @__PURE__ */ new Set();
416
+ return [R, ...C.collabUsers.filter((n) => {
417
+ let r = n.clientId || n.id || "";
418
+ if (r && r === e) return !1;
419
+ let i = String(r || n.name || "");
420
+ return t.has(i) ? !1 : (t.add(i), !0);
421
+ })];
422
+ }), U = t(() => z.value.length + 1), W = (e) => e.role === "ai" ? "chat-message-ai" : C.isCollab && e.user_id && e.user_id !== C.currentUser.id ? "chat-message-other" : "chat-message-user", G = (e) => e.role === "ai" ? { background: "linear-gradient(135deg, #409EFF, #337ECC)" } : { background: e.user_color || "#67C23A" }, K = (e) => (e.user_name || "U").charAt(0), q = (e) => {
423
+ if (!C.isCollab) return;
424
+ let t = typeof e == "string" ? e : e.target?.value || T.value, n = t.length, r = t.lastIndexOf("@", n);
425
+ if (r !== -1 && r < n) {
426
+ let e = t.slice(r + 1, n);
427
+ if (!e.includes(" ") && !e.includes("\n")) {
428
+ I = e, L = r, P.value = z.value.filter((t) => t.name && t.name.toLowerCase().includes(e.toLowerCase())), N.value = P.value.length > 0, F.value = 0;
429
+ return;
430
+ }
431
+ }
432
+ N.value = !1;
433
+ }, J = () => {
434
+ N.value && (F.value = Math.min(F.value + 1, P.value.length - 1));
435
+ }, Y = () => {
436
+ N.value && (F.value = Math.max(F.value - 1, 0));
437
+ }, X = (e) => {
438
+ let t = T.value.slice(0, L), n = T.value.slice(L + I.length + 1);
439
+ T.value = `${t}@${e.name} ${n}`, N.value = !1;
440
+ }, Z = (e) => {
441
+ if (e) {
442
+ if (e.shiftKey) return;
443
+ if (N.value) {
444
+ let t = P.value[F.value];
445
+ if (t) {
446
+ e.preventDefault(), X(t);
447
+ return;
448
+ }
449
+ }
450
+ e.preventDefault();
451
+ }
452
+ let t = T.value.trim();
453
+ if (!t || C.loading) return;
454
+ let n = null;
455
+ if (C.isCollab) {
456
+ let e = t.match(/@(\S+)/);
457
+ e && (n = e[1]);
458
+ }
459
+ w("send", t, { mentionedUser: n }), T.value = "", N.value = !1;
460
+ }, Q = () => {
461
+ c(() => {
462
+ D.value && (D.value.scrollTop = D.value.scrollHeight);
463
+ });
464
+ };
465
+ return y(() => C.messages.length, Q), y(() => C.messages, Q, { deep: !0 }), (t, c) => {
466
+ let p = g("el-icon"), m = g("el-tag"), y = g("el-popover"), C = g("el-button"), I = g("el-input");
467
+ return d.visible ? (f(), i("div", {
468
+ key: 0,
469
+ class: "ai-chat-panel",
470
+ style: u({ width: d.panelWidth + "px" })
471
+ }, [
472
+ a("div", ee, [a("div", te, [
473
+ s(p, {
474
+ size: 18,
475
+ color: "#409EFF"
476
+ }, {
477
+ default: b(() => [s(v(j))]),
478
+ _: 1
479
+ }),
480
+ a("span", ne, _(d.isCollab ? "协作聊天" : "AI 助手"), 1),
481
+ d.isCollab ? (f(), n(y, {
482
+ key: 0,
483
+ width: 200,
484
+ placement: "bottom-start",
485
+ trigger: "click"
486
+ }, {
487
+ reference: b(() => [s(m, {
488
+ size: "small",
489
+ type: "success",
490
+ effect: "plain",
491
+ class: "online-tag"
492
+ }, {
493
+ default: b(() => [o(_(U.value) + "人在线 ", 1)]),
494
+ _: 1
495
+ })]),
496
+ default: b(() => [a("div", re, [a("div", ie, [
497
+ a("div", {
498
+ class: "online-user-avatar",
499
+ style: u({ background: d.currentUser.color || "#409EFF" })
500
+ }, _((d.currentUser.name || "U").charAt(0)), 5),
501
+ a("span", ae, _(d.currentUser.name || "我"), 1),
502
+ s(m, {
503
+ size: "small",
504
+ type: d.isOwner ? "warning" : "success",
505
+ effect: "plain",
506
+ class: "role-tag"
507
+ }, {
508
+ default: b(() => [o(_(d.isOwner ? "发起人" : "协作人"), 1)]),
509
+ _: 1
510
+ }, 8, ["type"]),
511
+ c[4] ||= a("span", { class: "self-tag" }, "(我)", -1)
512
+ ]), (f(!0), i(e, null, h(z.value, (e) => (f(), i("div", {
513
+ key: e.id || e.clientId,
514
+ class: "online-user-item"
515
+ }, [
516
+ a("div", {
517
+ class: "online-user-avatar",
518
+ style: u({ background: e.color || "#909399" })
519
+ }, [e.isAi ? (f(), n(p, {
520
+ key: 0,
521
+ size: 14
522
+ }, {
523
+ default: b(() => [s(v(j))]),
524
+ _: 1
525
+ })) : (f(), i("span", oe, _((e.name || "U").charAt(0)), 1))], 4),
526
+ a("span", se, _(e.name || "未知用户"), 1),
527
+ e.isAi ? (f(), n(m, {
528
+ key: 0,
529
+ size: "small",
530
+ type: "primary",
531
+ effect: "plain",
532
+ class: "role-tag"
533
+ }, {
534
+ default: b(() => [...c[5] ||= [o("AI助手", -1)]]),
535
+ _: 1
536
+ })) : (f(), n(m, {
537
+ key: 1,
538
+ size: "small",
539
+ type: "success",
540
+ effect: "plain",
541
+ class: "role-tag"
542
+ }, {
543
+ default: b(() => [...c[6] ||= [o("协作人", -1)]]),
544
+ _: 1
545
+ }))
546
+ ]))), 128))])]),
547
+ _: 1
548
+ })) : r("", !0)
549
+ ]), a("div", ce, [
550
+ d.isCollab && d.unreadMention ? (f(), i("div", {
551
+ key: 0,
552
+ class: "mention-bell",
553
+ title: "有新消息",
554
+ onClick: c[0] ||= (e) => w("clear-unread")
555
+ }, [s(p, {
556
+ size: 18,
557
+ color: "#F56C6C"
558
+ }, {
559
+ default: b(() => [s(v(E))]),
560
+ _: 1
561
+ })])) : r("", !0),
562
+ s(C, {
563
+ text: "",
564
+ circle: "",
565
+ size: "small",
566
+ onClick: c[1] ||= (e) => t.$emit("clear"),
567
+ title: "清空对话"
568
+ }, {
569
+ default: b(() => [s(p, null, {
570
+ default: b(() => [s(v(k))]),
571
+ _: 1
572
+ })]),
573
+ _: 1
574
+ }),
575
+ s(C, {
576
+ text: "",
577
+ circle: "",
578
+ size: "small",
579
+ onClick: c[2] ||= (e) => t.$emit("close"),
580
+ title: "关闭"
581
+ }, {
582
+ default: b(() => [s(p, null, {
583
+ default: b(() => [s(v(O))]),
584
+ _: 1
585
+ })]),
586
+ _: 1
587
+ })
588
+ ])]),
589
+ a("div", {
590
+ class: "chat-messages",
591
+ ref_key: "messagesRef",
592
+ ref: D
593
+ }, [
594
+ d.messages.length === 0 ? (f(), i("div", le, [
595
+ s(p, {
596
+ size: 40,
597
+ color: "#c0c4cc"
598
+ }, {
599
+ default: b(() => [s(v(j))]),
600
+ _: 1
601
+ }),
602
+ a("p", null, _(d.isCollab ? "协作聊天室" : "你好!我是 AI 助手"), 1),
603
+ a("p", ue, _(d.isCollab ? "与团队成员和AI助手实时聊天" : "可以问我任何关于文档编辑的问题"), 1)
604
+ ])) : r("", !0),
605
+ (f(!0), i(e, null, h(d.messages, (e) => (f(), i("div", {
606
+ key: e._msgId || e.time + e.content,
607
+ class: l(["chat-message", W(e)])
608
+ }, [a("div", {
609
+ class: "message-avatar",
610
+ style: u(G(e))
611
+ }, [e.role === "ai" ? (f(), n(p, {
612
+ key: 0,
613
+ size: 16
614
+ }, {
615
+ default: b(() => [s(v(j))]),
616
+ _: 1
617
+ })) : (f(), i("span", B, _(K(e)), 1))], 4), a("div", V, [
618
+ d.isCollab && e.role === "user" ? (f(), i("div", H, [a("span", {
619
+ class: "message-sender",
620
+ style: u({ color: e.user_color || "#67C23A" })
621
+ }, _(e.user_name || "用户"), 5), e.mentioned_user ? (f(), i("span", de, "@" + _(e.mentioned_user), 1)) : r("", !0)])) : r("", !0),
622
+ a("div", {
623
+ class: "message-text",
624
+ innerHTML: e.content
625
+ }, null, 8, fe),
626
+ a("div", pe, _(e.time), 1)
627
+ ])], 2))), 128)),
628
+ d.loading ? (f(), i("div", me, [a("div", he, [s(p, { size: 16 }, {
629
+ default: b(() => [s(v(j))]),
630
+ _: 1
631
+ })]), c[7] ||= a("div", { class: "message-content" }, [a("div", { class: "message-text typing-indicator" }, [
632
+ a("span"),
633
+ a("span"),
634
+ a("span")
635
+ ])], -1)])) : r("", !0)
636
+ ], 512),
637
+ a("div", ge, [a("div", {
638
+ class: "chat-input-wrapper",
639
+ ref_key: "inputWrapperRef",
640
+ ref: A
641
+ }, [
642
+ s(I, {
643
+ modelValue: T.value,
644
+ "onUpdate:modelValue": c[3] ||= (e) => T.value = e,
645
+ type: "textarea",
646
+ autosize: {
647
+ minRows: 1,
648
+ maxRows: 4
649
+ },
650
+ placeholder: d.isCollab ? "输入消息... @提及成员" : "输入消息...",
651
+ onKeydown: [
652
+ x(S(Z, ["exact"]), ["enter"]),
653
+ x(S(J, ["prevent"]), ["down"]),
654
+ x(S(Y, ["prevent"]), ["up"])
655
+ ],
656
+ onInput: q,
657
+ resize: "none"
658
+ }, null, 8, [
659
+ "modelValue",
660
+ "placeholder",
661
+ "onKeydown"
662
+ ]),
663
+ N.value ? (f(), i("div", _e, [(f(!0), i(e, null, h(P.value, (e, t) => (f(), i("div", {
664
+ key: e.id || e.clientId,
665
+ class: l(["mention-item", { active: t === F.value }]),
666
+ onClick: (t) => X(e),
667
+ onMouseenter: (e) => F.value = t
668
+ }, [a("div", {
669
+ class: "mention-avatar",
670
+ style: u({ background: e.color || "#909399" })
671
+ }, [e.isAi ? (f(), n(p, {
672
+ key: 0,
673
+ size: 12
674
+ }, {
675
+ default: b(() => [s(v(j))]),
676
+ _: 1
677
+ })) : (f(), i("span", ye, _((e.name || "U").charAt(0)), 1))], 4), a("span", null, _(e.name), 1)], 42, ve))), 128))])) : r("", !0),
678
+ s(C, {
679
+ class: "send-btn",
680
+ type: "primary",
681
+ circle: "",
682
+ disabled: !T.value.trim() || d.loading,
683
+ onClick: Z
684
+ }, {
685
+ default: b(() => [s(p, null, {
686
+ default: b(() => [s(v(M))]),
687
+ _: 1
688
+ })]),
689
+ _: 1
690
+ }, 8, ["disabled"])
691
+ ], 512)])
692
+ ], 4)) : r("", !0);
693
+ };
694
+ }
695
+ }, [["__scopeId", "data-v-b10aa283"]]), W = { class: "version-history-panel" }, G = {
696
+ key: 0,
697
+ class: "loading-state"
698
+ }, K = {
699
+ key: 1,
700
+ class: "empty-state"
701
+ }, q = {
702
+ key: 2,
703
+ class: "version-list"
704
+ }, J = {
705
+ key: 0,
706
+ class: "current-version"
707
+ }, Y = { class: "current-version-header" }, X = { class: "version-number" }, Z = ["onClick"], Q = { class: "version-number" }, be = { class: "version-user" }, xe = { class: "panel-footer" }, Se = /*#__PURE__*/ z({
708
+ __name: "VersionHistoryPanel",
709
+ props: {
710
+ modelValue: {
711
+ type: Boolean,
712
+ default: !1
713
+ },
714
+ documentId: {
715
+ type: [Number, String],
716
+ default: null
717
+ }
718
+ },
719
+ emits: ["update:modelValue", "apply"],
720
+ setup(t, { expose: c, emit: u }) {
721
+ let d = t, p = u, { versions: x, loading: S, loadVersions: C, getVersionContent: w } = L(), T = m(!1), E = m(null), O = m(!1), k = m(null);
722
+ y(() => d.modelValue, (e) => {
723
+ T.value = e, e && d.documentId && (E.value = null, C(d.documentId).then((e) => {
724
+ e && e.length > 0 && (k.value = e[0]);
725
+ }));
726
+ }), y(T, (e) => {
727
+ p("update:modelValue", e);
728
+ });
729
+ let j = (e) => {
730
+ E.value = e;
731
+ }, M = async () => {
732
+ if (E.value) {
733
+ O.value = !0;
734
+ try {
735
+ let e = await w(E.value.id);
736
+ e && e.content ? (k.value = E.value, E.value = null, p("apply", e.content), N.success("已切换到版本 v" + k.value.version_number)) : N.error("获取版本内容失败");
737
+ } finally {
738
+ O.value = !1;
739
+ }
740
+ }
741
+ }, P = () => {
742
+ T.value = !1;
743
+ }, F = (e) => {
744
+ if (!e) return "";
745
+ let t = new Date(e), n = (e) => String(e).padStart(2, "0");
746
+ return `${t.getFullYear()}-${n(t.getMonth() + 1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`;
747
+ };
748
+ return c({ currentVersion: k }), (t, c) => {
749
+ let u = g("el-icon"), d = g("el-tag"), p = g("el-timeline-item"), m = g("el-timeline"), y = g("el-button"), C = g("el-drawer");
750
+ return f(), n(C, {
751
+ modelValue: T.value,
752
+ "onUpdate:modelValue": c[0] ||= (e) => T.value = e,
753
+ title: "更新履历",
754
+ direction: "rtl",
755
+ size: "420px",
756
+ "before-close": P
757
+ }, {
758
+ footer: b(() => [a("div", xe, [s(y, {
759
+ type: "primary",
760
+ disabled: !E.value,
761
+ loading: O.value,
762
+ onClick: M
763
+ }, {
764
+ default: b(() => [...c[4] ||= [o(" 切换到此版本 ", -1)]]),
765
+ _: 1
766
+ }, 8, ["disabled", "loading"])])]),
767
+ default: b(() => [a("div", W, [v(S) ? (f(), i("div", G, [s(u, { class: "is-loading" }, {
768
+ default: b(() => [s(v(A))]),
769
+ _: 1
770
+ }), c[1] ||= a("span", null, "加载中...", -1)])) : v(x).length === 0 ? (f(), i("div", K, [s(u, {
771
+ size: 48,
772
+ color: "#c0c4cc"
773
+ }, {
774
+ default: b(() => [s(v(D))]),
775
+ _: 1
776
+ }), c[2] ||= a("p", null, "暂无历史版本", -1)])) : (f(), i("div", q, [k.value ? (f(), i("div", J, [a("div", Y, [s(d, {
777
+ type: "success",
778
+ size: "small"
779
+ }, {
780
+ default: b(() => [...c[3] ||= [o("当前版本", -1)]]),
781
+ _: 1
782
+ }), a("span", X, "v" + _(k.value.version_number), 1)])])) : r("", !0), s(m, null, {
783
+ default: b(() => [(f(!0), i(e, null, h(v(x), (e) => (f(), n(p, {
784
+ key: e.id,
785
+ timestamp: F(e.created_at),
786
+ placement: "top",
787
+ type: E.value?.id === e.id ? "primary" : "",
788
+ hollow: E.value?.id !== e.id
789
+ }, {
790
+ default: b(() => [a("div", {
791
+ class: l(["version-item", { active: E.value?.id === e.id }]),
792
+ onClick: (t) => j(e)
793
+ }, [a("span", Q, "版本号:v" + _(e.version_number), 1), a("span", be, "提交人:" + _(e.user_name || "未知用户"), 1)], 10, Z)]),
794
+ _: 2
795
+ }, 1032, [
796
+ "timestamp",
797
+ "type",
798
+ "hollow"
799
+ ]))), 128))]),
800
+ _: 1
801
+ })]))])]),
802
+ _: 1
803
+ }, 8, ["modelValue"]);
804
+ };
805
+ }
806
+ }, [["__scopeId", "data-v-68d3257b"]]), Ce = { class: "brand-watermark" }, $ = ["title"], we = { class: "brand-text" }, Te = /*#__PURE__*/ z({
807
+ __name: "BrandWatermark",
808
+ props: {
809
+ text: {
810
+ type: String,
811
+ default: "Powered by @billtaofbj"
812
+ },
813
+ tooltip: {
814
+ type: String,
815
+ default: "@billtaofbj Editor Suite"
816
+ }
817
+ },
818
+ setup(e) {
819
+ return (t, n) => (f(), i("div", Ce, [a("div", {
820
+ class: "brand-logo",
821
+ title: e.tooltip
822
+ }, [n[0] ||= a("svg", {
823
+ viewBox: "0 0 24 24",
824
+ width: "16",
825
+ height: "16",
826
+ fill: "none",
827
+ xmlns: "http://www.w3.org/2000/svg"
828
+ }, [a("rect", {
829
+ width: "24",
830
+ height: "24",
831
+ rx: "4",
832
+ fill: "#409EFF"
833
+ }), a("text", {
834
+ x: "12",
835
+ y: "16",
836
+ "text-anchor": "middle",
837
+ fill: "white",
838
+ "font-size": "12",
839
+ "font-weight": "bold",
840
+ "font-family": "Arial"
841
+ }, "Y")], -1), a("span", we, _(e.text), 1)], 8, $)]));
842
+ }
843
+ }, [["__scopeId", "data-v-d6cec390"]]);
844
+ //#endregion
845
+ export { U as AiChatPanel, Te as BrandWatermark, Se as VersionHistoryPanel, P as useChat, R as useCollaboration, L as useVersionHistory };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@billtaofbj/core",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./dist/core.cjs.js",
6
+ "module": "./dist/core.es.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/core.es.js",
11
+ "require": "./dist/core.cjs.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./style.css": "./dist/style.css"
15
+ },
16
+ "files": ["dist"],
17
+ "scripts": {
18
+ "build": "vite build && node scripts/fix-paths.js"
19
+ },
20
+ "peerDependencies": {
21
+ "vue": "^3.4.0",
22
+ "element-plus": "^2.6.0",
23
+ "@element-plus/icons-vue": "^2.3.0",
24
+ "yjs": "^13.6.0",
25
+ "@hocuspocus/provider": "^4.1.0"
26
+ },
27
+ "dependencies": {
28
+ "axios": "^1.6.7"
29
+ }
30
+ }