@duxi999/usdp-eacp-conversation 0.0.2 → 0.0.3

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/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),ce=require("@element-plus/icons-vue"),j=require("element-plus"),Ae={class:"conversation-session"},Re={key:0,class:"status-placeholder"},De={key:1,class:"status-placeholder"},Me={key:2,class:"status-placeholder"},$e={key:3,class:"iframe-container"},qe=["src"],Pe={key:4,class:"status-placeholder"},Oe={key:5,class:"status-placeholder"},je={class:"env-limit-dialog"},de=30,ze=2e3,He=45,Xe=300*1e3,We=t.defineComponent({name:"UsdpXjgzConversation",__name:"UsdpEacpConversation",props:{appCode:{},request:{},appConfig:{}},emits:["state-change"],setup(h,{expose:z,emit:D}){const i=h,H=D,X=t.computed(()=>i.appCode!==void 0&&i.appCode!==null&&i.appCode!==""?String(i.appCode):void 0),M=t.computed(()=>{const e=i.appConfig;if(e==null)return;let n=null;if(typeof e=="string")try{n=JSON.parse(e)}catch{return}else typeof e=="object"&&(n=e);const o=n==null?void 0:n.projectId;if(o==null)return;const r=String(o).trim();return r===""?void 0:r}),a=t.ref("not_exist"),W=t.ref(""),s=t.ref(""),l=t.ref(""),f=t.ref(""),x=t.ref(""),p=t.ref(!1),m=t.computed(()=>a.value);t.computed(()=>l.value||"智能助手");const ve=t.computed(()=>x.value||X.value||null);t.watch([m,()=>l.value,ve],([e,n,o])=>{H("state-change",{status:e,nickname:n,appCode:o})},{immediate:!0});const E=t.ref(!1),fe={workspace:"工作区",knowledge_base:"知识库",agent:"智能体",skill:"技能构建",personal_assistant:"个人助手",bid:"智能投标"},Y=t.ref(!1),F=t.ref(!1),G=t.ref([]),V=t.ref([]),pe=t.ref();function me(e){if(!e)return"-";try{return new Date(e).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}catch{return e}}async function ge(){Y.value=!0,V.value=[];try{G.value=await i.request.get("/app-conversation/my-running-environments")}catch{j.ElMessage.error("获取运行中环境列表失败"),G.value=[]}finally{Y.value=!1}}t.watch(E,e=>{e&&ge()});function ye(e){V.value=e}async function he(){if(V.value.length!==0){F.value=!0;try{const e=V.value.map(o=>({appCode:o.appCode,...M.value?{projectId:M.value}:{}})),n=await i.request.post("/app-conversation/batch-stop-environments",{environments:e});n.allSuccess||j.ElMessage.warning(`关闭完成:成功 ${n.successCount} 个,失败 ${n.failedCount} 个`),E.value=!1,await Ce()}catch{j.ElMessage.error("关闭环境失败,请重试")}finally{F.value=!1}}}const g=t.ref(""),ne=t.ref(null),y=t.ref("");let T=0,I=null,L=null,U=null,_=null,B=!1,$=null,q=0,P=null;function O(e){if(!e)return"";try{const n=new URL(e);return n.searchParams.delete("token"),n.toString()}catch{return e}}async function J(){p.value=!0;try{const e=await i.request.post("/app-conversation/start-environment",{appCode:i.appCode,...M.value?{projectId:M.value}:{}});return e.status!==a.value&&(a.value=e.status),e.environmentId&&e.environmentId!==f.value&&(f.value=e.environmentId),e.proxyUrl&&e.proxyUrl!==s.value&&(s.value=e.proxyUrl),e}finally{p.value=!1}}async function N(){try{const e=await i.request.get("/app-conversation/environment-status",{appCode:i.appCode},{silent:!0});e.status!==a.value&&(a.value=e.status),e.environmentId&&e.environmentId!==f.value&&(f.value=e.environmentId),e.proxyUrl&&e.proxyUrl!==s.value&&(s.value=e.proxyUrl)}catch{}}async function ae(){p.value=!0;try{await i.request.post("/app-conversation/stop-environment",{appCode:i.appCode}),a.value="stopped"}finally{p.value=!1}}async function _e(){p.value=!0;try{await i.request.post("/app-conversation/destroy-environment",{appCode:i.appCode}),a.value="not_exist",s.value="",f.value=""}finally{p.value=!1}}async function C(){try{const e=await i.request.get("/app-conversation/session-info",{appCode:i.appCode},{silent:!0});return e.sessionId!==W.value&&(W.value=e.sessionId),e.proxyUrl!==s.value&&(s.value=e.proxyUrl),e.agentNickname!==l.value&&(l.value=e.agentNickname),e.environmentId!==f.value&&(f.value=e.environmentId),e.appCode&&e.appCode!==x.value&&(x.value=e.appCode),e.environmentStatus!==a.value&&(a.value=e.environmentStatus),e}catch{return}}function A(){u(),q=0,$=setInterval(async()=>{if(q++,q>He){if(await N(),a.value==="running"){u(),w(),l.value||C();return}u(),a.value="start_failed";return}await N(),a.value==="running"?(u(),w(),l.value||C()):a.value==="start_failed"&&u()},ze)}function u(){$!==null&&(clearInterval($),$=null),q=0}function w(){S(),P=setInterval(async()=>{document.visibilityState==="visible"&&await N()},Xe)}function S(){P!==null&&(clearInterval(P),P=null)}function K(){u(),S(),a.value="not_exist",W.value="",s.value="",l.value="",f.value="",x.value="",p.value=!1}t.watch([()=>a.value,()=>s.value],([e,n],[o,r])=>{if(!n||e!=="running"){g.value="",y.value="",c(),k();return}O(n)!==O(r||"")&&re(n,o==="starting")},{immediate:!0}),t.watch(()=>a.value,(e,n)=>{if(e==="running"&&n==="starting"){const o=s.value;if(!o)return;(!g.value||O(o)===O(g.value))&&re(o,!0)}});async function b(){if(p.value)return;const e=a.value;if(!(e==="running"||e==="starting")){if(e==="start_failed"){await N();const n=a.value;if(n==="running"){w();return}if(n==="starting"){A();return}}try{await J(),l.value||C(),a.value==="starting"?A():a.value==="running"&&w()}catch(n){if((n==null?void 0:n.code)===23010){E.value=!0;return}}}}async function Ce(){await new Promise(e=>setTimeout(e,500)),await b()}async function we(){a.value="stopping",u(),S(),c(),k();try{return await ae(),!0}catch{return a.value="running",!1}}async function xe(){let e=x.value||X.value;return e||(await C(),e=x.value||X.value),e||void 0}function Ee(){const e=g.value;if(!e)return;c(),T=0;const n=e.includes("?")?"&":"?";y.value=`${e}${n}_refresh=${Date.now()}`,Z(y.value)}function Te(){oe()}function Ne(){ee("network")}function oe(){B&&(c(),T=0)}function Se(e){try{const n=new URL(e);return n.pathname="/test",n.search="",n.hash="",n.toString()}catch{return`${e.split("?")[0].split("#")[0].replace(/\/+$/,"")}/test`}}async function be(e){try{const n=Se(e),o=new AbortController,r=setTimeout(()=>o.abort(),5e3),d=await fetch(n,{method:"HEAD",mode:"cors",cache:"no-cache",signal:o.signal});return clearTimeout(r),d.status===200}catch{return!1}}async function Q(e,n=0){if(await be(e)){ie(e);return}n<de?I=setTimeout(()=>{Q(e,n+1)},100):ie(e)}function ie(e){g.value=e,y.value=e,Z(e)}function re(e,n){c(),k(),T=0,n?L=setTimeout(()=>{Q(e),L=null},1500):Q(e)}function k(){I&&(clearTimeout(I),I=null),L&&(clearTimeout(L),L=null),_&&(clearTimeout(_),_=null)}function Z(e){if(c(),!window.PerformanceObserver){le();return}B=!0;try{U=new PerformanceObserver(n=>{for(const o of n.getEntries()){const r=o;if(o.name!==e&&o.name!==y.value)continue;const d=r.responseStatus;if(d===502){ee("502");return}d>=200&&d<400&&oe()}}),U.observe({type:"resource",buffered:!0})}catch{}le()}function c(){U&&(U.disconnect(),U=null),_&&(clearTimeout(_),_=null),B=!1}function le(e){_=setTimeout(()=>{B&&ee("timeout")},15e3)}function ee(e){if(!B)return;if(c(),T++,T>de){j.ElMessage.error("应用加载失败,请刷新页面重试");return}console.warn(`[ConversationSession] 加载失败: ${e==="network"?"网络错误":e==="timeout"?"加载超时":"应用暂不可用"}, 第 ${T} 次重试`),I=setTimeout(()=>{if(!g.value)return;const o=g.value.includes("?")?"&":"?";y.value=`${g.value}${o}_retry=${Date.now()}`,Z(y.value)},1e3)}function se(){document.visibilityState==="visible"&&m.value==="running"&&N()}t.onMounted(async()=>{document.addEventListener("visibilitychange",se),await N();const e=a.value;e==="not_exist"||e==="stopped"?b():(await C(),e==="starting"?A():e==="running"&&w())});async function ke(){const e=a.value;if(a.value="stopping",u(),S(),c(),k(),e==="running"||e==="starting")try{await ae()}catch{}K(),a.value="starting";try{await J(),C(),a.value==="starting"?A():a.value==="running"&&w()}catch{}}async function Ve(){a.value="stopping",u(),S(),c(),k();try{await _e()}catch{}K(),a.value="starting";try{await J(),C(),a.value==="starting"?A():a.value==="running"&&w()}catch{}}function Ie(e,n){var r;const o=(r=ne.value)==null?void 0:r.contentWindow;o&&o.postMessage({target:"dsh",type:e,payload:n},"*")}return z({start:b,stop:we,restart:ke,rebuild:Ve,refresh:Ee,resolveAgentId:xe,postDshEvent:Ie}),t.onUnmounted(()=>{u(),S(),document.removeEventListener("visibilitychange",se),c(),k(),K()}),(e,n)=>{const o=t.resolveComponent("el-button"),r=t.resolveComponent("el-empty"),d=t.resolveComponent("el-icon"),ue=t.resolveComponent("el-result"),R=t.resolveComponent("el-table-column"),Le=t.resolveComponent("el-table"),Ue=t.resolveComponent("el-dialog"),Be=t.resolveDirective("loading");return t.openBlock(),t.createElementBlock("div",Ae,[m.value==="not_exist"?(t.openBlock(),t.createElementBlock("div",Re,[t.createVNode(r,{description:`${l.value} 环境未启动`},{default:t.withCtx(()=>[t.createVNode(o,{type:"primary",onClick:b},{default:t.withCtx(()=>[...n[2]||(n[2]=[t.createTextVNode("启动环境",-1)])]),_:1})]),_:1},8,["description"])])):m.value==="starting"?(t.openBlock(),t.createElementBlock("div",De,[t.createVNode(d,{class:"is-loading",size:48},{default:t.withCtx(()=>[t.createVNode(t.unref(ce.Loading))]),_:1}),t.createElementVNode("p",null,t.toDisplayString(l.value)+" 环境启动中...",1)])):m.value==="stopping"?(t.openBlock(),t.createElementBlock("div",Me,[t.createVNode(d,{class:"is-loading",size:48},{default:t.withCtx(()=>[t.createVNode(t.unref(ce.Loading))]),_:1}),t.createElementVNode("p",null,"正在停止 "+t.toDisplayString(l.value)+"...",1)])):m.value==="running"?(t.openBlock(),t.createElementBlock("div",$e,[t.createElementVNode("iframe",{ref_key:"iframeRef",ref:ne,src:y.value,class:"conversation-iframe",onLoad:Te,onError:Ne},null,40,qe)])):m.value==="start_failed"?(t.openBlock(),t.createElementBlock("div",Pe,[t.createVNode(ue,{icon:"error",title:"环境启动失败"},{extra:t.withCtx(()=>[t.createVNode(o,{type:"primary",onClick:b},{default:t.withCtx(()=>[...n[3]||(n[3]=[t.createTextVNode("重新启动",-1)])]),_:1})]),_:1})])):m.value==="stopped"?(t.openBlock(),t.createElementBlock("div",Oe,[t.createVNode(ue,{icon:"info",title:"环境已停止"},{extra:t.withCtx(()=>[t.createVNode(o,{type:"primary",onClick:b},{default:t.withCtx(()=>[...n[4]||(n[4]=[t.createTextVNode("重新启动",-1)])]),_:1})]),_:1})])):t.createCommentVNode("",!0),t.createVNode(Ue,{"model-value":E.value,title:"运行中环境数量已达上限",width:"720px","close-on-click-modal":!1,"onUpdate:modelValue":n[1]||(n[1]=v=>E.value=v)},{footer:t.withCtx(()=>[t.createVNode(o,{onClick:n[0]||(n[0]=v=>E.value=!1)},{default:t.withCtx(()=>[...n[6]||(n[6]=[t.createTextVNode("暂不关闭",-1)])]),_:1}),t.createVNode(o,{type:"primary",loading:F.value,disabled:V.value.length===0,onClick:he},{default:t.withCtx(()=>[...n[7]||(n[7]=[t.createTextVNode(" 关闭已选环境 ",-1)])]),_:1},8,["loading","disabled"])]),default:t.withCtx(()=>[t.createElementVNode("div",je,[n[5]||(n[5]=t.createElementVNode("p",{class:"env-limit-dialog__tip"}," 您的运行中智能会话数量已达上限,请选择需要关闭的会话后重试。 ",-1)),t.withDirectives((t.openBlock(),t.createBlock(Le,{ref_key:"envLimitTableRef",ref:pe,data:G.value,"max-height":"520","header-cell-style":{textAlign:"center"},onSelectionChange:ye},{default:t.withCtx(()=>[t.createVNode(R,{type:"selection",width:"42"}),t.createVNode(R,{label:"场景类型","min-width":"100"},{default:t.withCtx(({row:v})=>[t.createTextVNode(t.toDisplayString(fe[v.sceneType]||v.sceneType),1)]),_:1}),t.createVNode(R,{prop:"sceneName",label:"场景名称","min-width":"150","show-overflow-tooltip":""}),t.createVNode(R,{label:"智能体","min-width":"130","show-overflow-tooltip":""},{default:t.withCtx(({row:v})=>[t.createTextVNode(t.toDisplayString(v.agentNickname||"-"),1)]),_:1}),t.createVNode(R,{label:"创建时间","min-width":"170"},{default:t.withCtx(({row:v})=>[t.createTextVNode(t.toDisplayString(me(v.createdAt)),1)]),_:1})]),_:1},8,["data"])),[[Be,Y.value]])])]),_:1},8,["model-value"])])}}}),Ye=(h,z)=>{const D=h.__vccOpts||h;for(const[i,H]of z)D[i]=H;return D},te=Ye(We,[["__scopeId","data-v-f0ca27ea"]]),Fe="usdp-eacp-conversation",Ge={install(h){h.component(Fe,te),h.component("UsdpEacpConversation",te)}};exports.ConversationSession=te;exports.default=Ge;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),de=require("@element-plus/icons-vue"),z=require("element-plus"),De={class:"conversation-session"},Me={key:0,class:"status-placeholder"},$e={key:1,class:"status-placeholder"},qe={key:2,class:"status-placeholder"},Pe={key:3,class:"status-placeholder"},Oe={key:4,class:"iframe-container"},je=["src"],ze={key:5,class:"status-placeholder"},He={key:6,class:"status-placeholder"},Xe={class:"env-limit-dialog"},ve=30,We=2e3,Ye=45,Fe=300*1e3,Ge=e.defineComponent({name:"UsdpXjgzConversation",__name:"UsdpEacpConversation",props:{appCode:{},request:{},appConfig:{}},emits:["state-change"],setup(h,{expose:H,emit:M}){const i=h,X=M,W=e.computed(()=>i.appCode!==void 0&&i.appCode!==null&&i.appCode!==""?String(i.appCode):void 0),$=e.computed(()=>{const t=i.appConfig;if(t==null)return;let n=null;if(typeof t=="string")try{n=JSON.parse(t)}catch{return}else typeof t=="object"&&(n=t);const o=n==null?void 0:n.projectId;if(o==null)return;const r=String(o).trim();return r===""?void 0:r}),x=e.ref(/^\/aisys\/[^/]+/.test(window.location.pathname)),a=e.ref("not_exist"),Y=e.ref(""),u=e.ref(""),s=e.ref(""),f=e.ref(""),E=e.ref(""),p=e.ref(!1),m=e.computed(()=>a.value);e.computed(()=>s.value||"智能助手");const fe=e.computed(()=>E.value||W.value||null);e.watch([m,()=>s.value,fe],([t,n,o])=>{X("state-change",{status:t,nickname:n,appCode:o})},{immediate:!0});const N=e.ref(!1),pe={workspace:"工作区",knowledge_base:"知识库",agent:"智能体",skill:"技能构建",personal_assistant:"个人助手",bid:"智能投标"},F=e.ref(!1),G=e.ref(!1),J=e.ref([]),I=e.ref([]),me=e.ref();function ge(t){if(!t)return"-";try{return new Date(t).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}catch{return t}}async function ye(){F.value=!0,I.value=[];try{J.value=await i.request.get("/app-conversation/my-running-environments")}catch{z.ElMessage.error("获取运行中环境列表失败"),J.value=[]}finally{F.value=!1}}e.watch(N,t=>{t&&ye()});function he(t){I.value=t}async function _e(){if(I.value.length!==0){G.value=!0;try{const t=I.value.map(o=>({appCode:o.appCode,...$.value?{projectId:$.value}:{}})),n=await i.request.post("/app-conversation/batch-stop-environments",{environments:t});n.allSuccess||z.ElMessage.warning(`关闭完成:成功 ${n.successCount} 个,失败 ${n.failedCount} 个`),N.value=!1,await we()}catch{z.ElMessage.error("关闭环境失败,请重试")}finally{G.value=!1}}}const g=e.ref(""),ae=e.ref(null),y=e.ref("");let T=0,L=null,B=null,U=null,_=null,A=!1,q=null,P=0,O=null;function j(t){if(!t)return"";try{const n=new URL(t);return n.searchParams.delete("token"),n.toString()}catch{return t}}async function K(){p.value=!0;try{const t=await i.request.post("/app-conversation/start-environment",{appCode:i.appCode,...$.value?{projectId:$.value}:{}});return t.status!==a.value&&(a.value=t.status),t.environmentId&&t.environmentId!==f.value&&(f.value=t.environmentId),t.proxyUrl&&t.proxyUrl!==u.value&&(u.value=t.proxyUrl),t}finally{p.value=!1}}async function k(){try{const t=await i.request.get("/app-conversation/environment-status",{appCode:i.appCode},{silent:!0});t.status!==a.value&&(a.value=t.status),t.environmentId&&t.environmentId!==f.value&&(f.value=t.environmentId),t.proxyUrl&&t.proxyUrl!==u.value&&(u.value=t.proxyUrl)}catch{}}async function oe(){p.value=!0;try{await i.request.post("/app-conversation/stop-environment",{appCode:i.appCode}),a.value="stopped"}finally{p.value=!1}}async function Ce(){p.value=!0;try{await i.request.post("/app-conversation/destroy-environment",{appCode:i.appCode}),a.value="not_exist",u.value="",f.value=""}finally{p.value=!1}}async function C(){try{const t=await i.request.get("/app-conversation/session-info",{appCode:i.appCode},{silent:!0});return t.sessionId!==Y.value&&(Y.value=t.sessionId),t.proxyUrl!==u.value&&(u.value=t.proxyUrl),t.agentNickname!==s.value&&(s.value=t.agentNickname),t.environmentId!==f.value&&(f.value=t.environmentId),t.appCode&&t.appCode!==E.value&&(E.value=t.appCode),t.environmentStatus!==a.value&&(a.value=t.environmentStatus),t}catch{return}}function R(){c(),P=0,q=setInterval(async()=>{if(P++,P>Ye){if(await k(),a.value==="running"){c(),w(),s.value||C();return}c(),a.value="start_failed";return}await k(),a.value==="running"?(c(),w(),s.value||C()):a.value==="start_failed"&&c()},We)}function c(){q!==null&&(clearInterval(q),q=null),P=0}function w(){S(),O=setInterval(async()=>{document.visibilityState==="visible"&&await k()},Fe)}function S(){O!==null&&(clearInterval(O),O=null)}function Q(){c(),S(),a.value="not_exist",Y.value="",u.value="",s.value="",f.value="",E.value="",p.value=!1}e.watch([()=>a.value,()=>u.value],([t,n],[o,r])=>{if(!n||t!=="running"){g.value="",y.value="",d(),V();return}j(n)!==j(r||"")&&le(n,o==="starting")},{immediate:!0}),e.watch(()=>a.value,(t,n)=>{if(t==="running"&&n==="starting"){const o=u.value;if(!o)return;(!g.value||j(o)===j(g.value))&&le(o,!0)}});async function b(){if(x.value||p.value)return;const t=a.value;if(!(t==="running"||t==="starting")){if(t==="start_failed"){await k();const n=a.value;if(n==="running"){w();return}if(n==="starting"){R();return}}try{await K(),s.value||C(),a.value==="starting"?R():a.value==="running"&&w()}catch(n){if((n==null?void 0:n.code)===23010){N.value=!0;return}}}}async function we(){await new Promise(t=>setTimeout(t,500)),await b()}async function xe(){if(x.value)return!1;a.value="stopping",c(),S(),d(),V();try{return await oe(),!0}catch{return a.value="running",!1}}async function Ee(){let t=E.value||W.value;return t||(await C(),t=E.value||W.value),t||void 0}function Ne(){const t=g.value;if(!t)return;d(),T=0;const n=t.includes("?")?"&":"?";y.value=`${t}${n}_refresh=${Date.now()}`,ee(y.value)}function Te(){ie()}function ke(){te("network")}function ie(){A&&(d(),T=0)}function Se(t){try{const n=new URL(t);return n.pathname="/test",n.search="",n.hash="",n.toString()}catch{return`${t.split("?")[0].split("#")[0].replace(/\/+$/,"")}/test`}}async function be(t){try{const n=Se(t),o=new AbortController,r=setTimeout(()=>o.abort(),5e3),l=await fetch(n,{method:"HEAD",mode:"cors",cache:"no-cache",signal:o.signal});return clearTimeout(r),l.status===200}catch{return!1}}async function Z(t,n=0){if(await be(t)){re(t);return}n<ve?L=setTimeout(()=>{Z(t,n+1)},100):re(t)}function re(t){g.value=t,y.value=t,ee(t)}function le(t,n){d(),V(),T=0,n?B=setTimeout(()=>{Z(t),B=null},1500):Z(t)}function V(){L&&(clearTimeout(L),L=null),B&&(clearTimeout(B),B=null),_&&(clearTimeout(_),_=null)}function ee(t){if(d(),!window.PerformanceObserver){se();return}A=!0;try{U=new PerformanceObserver(n=>{for(const o of n.getEntries()){const r=o;if(o.name!==t&&o.name!==y.value)continue;const l=r.responseStatus;if(l===502){te("502");return}l>=200&&l<400&&ie()}}),U.observe({type:"resource",buffered:!0})}catch{}se()}function d(){U&&(U.disconnect(),U=null),_&&(clearTimeout(_),_=null),A=!1}function se(t){_=setTimeout(()=>{A&&te("timeout")},15e3)}function te(t){if(!A)return;if(d(),T++,T>ve){z.ElMessage.error("应用加载失败,请刷新页面重试");return}console.warn(`[ConversationSession] 加载失败: ${t==="network"?"网络错误":t==="timeout"?"加载超时":"应用暂不可用"}, 第 ${T} 次重试`),L=setTimeout(()=>{if(!g.value)return;const o=g.value.includes("?")?"&":"?";y.value=`${g.value}${o}_retry=${Date.now()}`,ee(y.value)},1e3)}function ue(){document.visibilityState==="visible"&&m.value==="running"&&k()}e.onMounted(async()=>{if(x.value)return;document.addEventListener("visibilitychange",ue),await k();const t=a.value;t==="not_exist"||t==="stopped"?b():(await C(),t==="starting"?R():t==="running"&&w())});async function Ve(){if(x.value)return;const t=a.value;if(a.value="stopping",c(),S(),d(),V(),t==="running"||t==="starting")try{await oe()}catch{}Q(),a.value="starting";try{await K(),C(),a.value==="starting"?R():a.value==="running"&&w()}catch{}}async function Ie(){if(!x.value){a.value="stopping",c(),S(),d(),V();try{await Ce()}catch{}Q(),a.value="starting";try{await K(),C(),a.value==="starting"?R():a.value==="running"&&w()}catch{}}}function Le(t,n){var r;const o=(r=ae.value)==null?void 0:r.contentWindow;o&&o.postMessage({target:"dsh",type:t,payload:n},"*")}return H({start:b,stop:xe,restart:Ve,rebuild:Ie,refresh:Ne,resolveAgentId:Ee,postDshEvent:Le}),e.onUnmounted(()=>{c(),S(),document.removeEventListener("visibilitychange",ue),d(),V(),Q()}),(t,n)=>{const o=e.resolveComponent("el-text"),r=e.resolveComponent("el-result"),l=e.resolveComponent("el-button"),Be=e.resolveComponent("el-empty"),ce=e.resolveComponent("el-icon"),D=e.resolveComponent("el-table-column"),Ue=e.resolveComponent("el-table"),Ae=e.resolveComponent("el-dialog"),Re=e.resolveDirective("loading");return e.openBlock(),e.createElementBlock("div",De,[x.value?(e.openBlock(),e.createElementBlock("div",Me,[e.createVNode(r,{icon:"warning",title:"当前应用包需要创建应用通过应用访问智能体服务"},{extra:e.withCtx(()=>[e.createVNode(o,{type:"info",size:"small"},{default:e.withCtx(()=>[...n[2]||(n[2]=[e.createTextVNode("请在本平台创建智能应用并绑定本应用包后,通过应用入口访问",-1)])]),_:1})]),_:1})])):m.value==="not_exist"?(e.openBlock(),e.createElementBlock("div",$e,[e.createVNode(Be,{description:`${s.value} 环境未启动`},{default:e.withCtx(()=>[e.createVNode(l,{type:"primary",onClick:b},{default:e.withCtx(()=>[...n[3]||(n[3]=[e.createTextVNode("启动环境",-1)])]),_:1})]),_:1},8,["description"])])):m.value==="starting"?(e.openBlock(),e.createElementBlock("div",qe,[e.createVNode(ce,{class:"is-loading",size:48},{default:e.withCtx(()=>[e.createVNode(e.unref(de.Loading))]),_:1}),e.createElementVNode("p",null,e.toDisplayString(s.value)+" 环境启动中...",1)])):m.value==="stopping"?(e.openBlock(),e.createElementBlock("div",Pe,[e.createVNode(ce,{class:"is-loading",size:48},{default:e.withCtx(()=>[e.createVNode(e.unref(de.Loading))]),_:1}),e.createElementVNode("p",null,"正在停止 "+e.toDisplayString(s.value)+"...",1)])):m.value==="running"?(e.openBlock(),e.createElementBlock("div",Oe,[e.createElementVNode("iframe",{ref_key:"iframeRef",ref:ae,src:y.value,class:"conversation-iframe",onLoad:Te,onError:ke},null,40,je)])):m.value==="start_failed"?(e.openBlock(),e.createElementBlock("div",ze,[e.createVNode(r,{icon:"error",title:"环境启动失败"},{extra:e.withCtx(()=>[e.createVNode(l,{type:"primary",onClick:b},{default:e.withCtx(()=>[...n[4]||(n[4]=[e.createTextVNode("重新启动",-1)])]),_:1})]),_:1})])):m.value==="stopped"?(e.openBlock(),e.createElementBlock("div",He,[e.createVNode(r,{icon:"info",title:"环境已停止"},{extra:e.withCtx(()=>[e.createVNode(l,{type:"primary",onClick:b},{default:e.withCtx(()=>[...n[5]||(n[5]=[e.createTextVNode("重新启动",-1)])]),_:1})]),_:1})])):e.createCommentVNode("",!0),e.createVNode(Ae,{"model-value":N.value,title:"运行中环境数量已达上限",width:"720px","close-on-click-modal":!1,"onUpdate:modelValue":n[1]||(n[1]=v=>N.value=v)},{footer:e.withCtx(()=>[e.createVNode(l,{onClick:n[0]||(n[0]=v=>N.value=!1)},{default:e.withCtx(()=>[...n[7]||(n[7]=[e.createTextVNode("暂不关闭",-1)])]),_:1}),e.createVNode(l,{type:"primary",loading:G.value,disabled:I.value.length===0,onClick:_e},{default:e.withCtx(()=>[...n[8]||(n[8]=[e.createTextVNode(" 关闭已选环境 ",-1)])]),_:1},8,["loading","disabled"])]),default:e.withCtx(()=>[e.createElementVNode("div",Xe,[n[6]||(n[6]=e.createElementVNode("p",{class:"env-limit-dialog__tip"}," 您的运行中智能会话数量已达上限,请选择需要关闭的会话后重试。 ",-1)),e.withDirectives((e.openBlock(),e.createBlock(Ue,{ref_key:"envLimitTableRef",ref:me,data:J.value,"max-height":"520","header-cell-style":{textAlign:"center"},onSelectionChange:he},{default:e.withCtx(()=>[e.createVNode(D,{type:"selection",width:"42"}),e.createVNode(D,{label:"场景类型","min-width":"100"},{default:e.withCtx(({row:v})=>[e.createTextVNode(e.toDisplayString(pe[v.sceneType]||v.sceneType),1)]),_:1}),e.createVNode(D,{prop:"sceneName",label:"场景名称","min-width":"150","show-overflow-tooltip":""}),e.createVNode(D,{label:"智能体","min-width":"130","show-overflow-tooltip":""},{default:e.withCtx(({row:v})=>[e.createTextVNode(e.toDisplayString(v.agentNickname||"-"),1)]),_:1}),e.createVNode(D,{label:"创建时间","min-width":"170"},{default:e.withCtx(({row:v})=>[e.createTextVNode(e.toDisplayString(ge(v.createdAt)),1)]),_:1})]),_:1},8,["data"])),[[Re,F.value]])])]),_:1},8,["model-value"])])}}}),Je=(h,H)=>{const M=h.__vccOpts||h;for(const[i,X]of H)M[i]=X;return M},ne=Je(Ge,[["__scopeId","data-v-ad448334"]]),Ke="usdp-eacp-conversation",Qe={install(h){h.component(Ke,ne),h.component("UsdpEacpConversation",ne)}};exports.ConversationSession=ne;exports.default=Qe;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/components/UsdpEacpConversation.vue","../src/index.ts"],"sourcesContent":["<template>\r\n <div class=\"conversation-session\">\r\n <!-- not_exist 状态:启动提示 -->\r\n <div v-if=\"status === 'not_exist'\" class=\"status-placeholder\">\r\n <el-empty :description=\"`${agentNickname} 环境未启动`\">\r\n <el-button type=\"primary\" @click=\"handleStart\">启动环境</el-button>\r\n </el-empty>\r\n </div>\r\n\r\n <!-- starting 状态:加载动画 -->\r\n <div v-else-if=\"status === 'starting'\" class=\"status-placeholder\">\r\n <el-icon class=\"is-loading\" :size=\"48\"><Loading /></el-icon>\r\n <p>{{ agentNickname }} 环境启动中...</p>\r\n </div>\r\n\r\n <!-- stopping 状态:停止中动画 -->\r\n <div v-else-if=\"status === 'stopping'\" class=\"status-placeholder\">\r\n <el-icon class=\"is-loading\" :size=\"48\"><Loading /></el-icon>\r\n <p>正在停止 {{ agentNickname }}...</p>\r\n </div>\r\n\r\n <!-- running 状态:iframe -->\r\n <div v-else-if=\"status === 'running'\" class=\"iframe-container\">\r\n <iframe\r\n ref=\"iframeRef\"\r\n :src=\"displayedIframeSrc\"\r\n class=\"conversation-iframe\"\r\n @load=\"onIframeLoad\"\r\n @error=\"onIframeError\"\r\n />\r\n </div>\r\n\r\n <!-- start_failed 状态:错误提示 -->\r\n <div v-else-if=\"status === 'start_failed'\" class=\"status-placeholder\">\r\n <el-result icon=\"error\" title=\"环境启动失败\">\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"handleStart\">重新启动</el-button>\r\n </template>\r\n </el-result>\r\n </div>\r\n\r\n <!-- stopped 状态:已停止 -->\r\n <div v-else-if=\"status === 'stopped'\" class=\"status-placeholder\">\r\n <el-result icon=\"info\" title=\"环境已停止\">\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"handleStart\">重新启动</el-button>\r\n </template>\r\n </el-result>\r\n </div>\r\n\r\n <!-- 环境数量超限弹窗 -->\r\n <el-dialog\r\n :model-value=\"envLimitDialogVisible\"\r\n title=\"运行中环境数量已达上限\"\r\n width=\"720px\"\r\n :close-on-click-modal=\"false\"\r\n @update:model-value=\"envLimitDialogVisible = $event\"\r\n >\r\n <div class=\"env-limit-dialog\">\r\n <p class=\"env-limit-dialog__tip\">\r\n 您的运行中智能会话数量已达上限,请选择需要关闭的会话后重试。\r\n </p>\r\n\r\n <el-table\r\n ref=\"envLimitTableRef\"\r\n :data=\"runningEnvironments\"\r\n v-loading=\"envLimitLoading\"\r\n max-height=\"520\"\r\n :header-cell-style=\"{ textAlign: 'center' }\"\r\n @selection-change=\"handleEnvSelectionChange\"\r\n >\r\n <el-table-column type=\"selection\" width=\"42\" />\r\n <el-table-column label=\"场景类型\" min-width=\"100\">\r\n <template #default=\"{ row }\">\r\n {{ SCENE_TYPE_LABELS[row.sceneType] || row.sceneType }}\r\n </template>\r\n </el-table-column>\r\n <el-table-column prop=\"sceneName\" label=\"场景名称\" min-width=\"150\" show-overflow-tooltip />\r\n <el-table-column label=\"智能体\" min-width=\"130\" show-overflow-tooltip>\r\n <template #default=\"{ row }\">\r\n {{ row.agentNickname || '-' }}\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"创建时间\" min-width=\"170\">\r\n <template #default=\"{ row }\">\r\n {{ formatTime(row.createdAt) }}\r\n </template>\r\n </el-table-column>\r\n </el-table>\r\n </div>\r\n\r\n <template #footer>\r\n <el-button @click=\"envLimitDialogVisible = false\">暂不关闭</el-button>\r\n <el-button\r\n type=\"primary\"\r\n :loading=\"envLimitClosing\"\r\n :disabled=\"selectedEnvItems.length === 0\"\r\n @click=\"handleCloseEnvironments\"\r\n >\r\n 关闭已选环境\r\n </el-button>\r\n </template>\r\n </el-dialog>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n/**\r\n * 单个智能对话会话组件\r\n *\r\n * 承载一个智能体会话的完整生命周期(环境查询/启动/停止/重启/重建、iframe 加载监控、\r\n * 轮询与心跳保活)。组件完全自包含:\r\n *\r\n * 组件名与包名一致(usdp-xjgz-conversation),模板中可使用:\r\n * - <usdp-xjgz-conversation>\r\n * - <UsdpXjgzConversation>\r\n */\r\n\r\ndefineOptions({ name: 'UsdpXjgzConversation' })\r\n\r\n/**\r\n * 由宿主注入 RequestAdapter(axios 封装),通过 props 传入;\r\n * 组件内部直接调用具体请求地址,不依赖任何外部 store / api / utils 模块;\r\n * 每个组件实例拥有独立的状态和定时器,避免多会话状态覆盖。\r\n */\r\n\r\nimport { computed, onMounted, onUnmounted, ref, watch } from 'vue'\r\nimport { Loading } from '@element-plus/icons-vue'\r\nimport { ElMessage } from 'element-plus'\r\nimport type {\r\n BatchStopResult,\r\n EnvironmentStatus,\r\n EnvironmentStatusResult,\r\n RequestAdapter,\r\n RunningEnvironmentItem,\r\n SessionInfoResult,\r\n} from '../types'\r\n\r\n// ==================== Props ====================\r\n\r\ninterface Props {\r\n /** 应用编码 */\r\n appCode: string\r\n /** 由宿主注入的 HTTP 请求适配器(axios 封装),必传 */\r\n request: RequestAdapter\r\n /**\r\n * 应用配置(来自宿主 APP_INIT 下发的 payload.appConfig,可选)\r\n * 支持对象或 JSON 字符串;若其中配置了 projectId,\r\n * 组件调用 start-environment / batch-stop-environments 时会携带该参数给后端\r\n * (后端 workspace_mode=dynamic_project 模式必需)\r\n */\r\n appConfig?: unknown\r\n}\r\n\r\nconst props = defineProps<Props>()\r\n\r\n/** 会话状态变更事件(供外层堆叠面板渲染标题栏) */\r\nconst emit = defineEmits<{\r\n (e: 'state-change', value: { status: EnvironmentStatus; nickname: string; appCode: string | null }): void\r\n}>()\r\n\r\n/** 转换为字符串的智能体ID(用于接口调用) */\r\nconst effectiveAgentId = computed<string | undefined>(() =>\r\n props.appCode !== undefined && props.appCode !== null && props.appCode !== ''\r\n ? String(props.appCode)\r\n : undefined\r\n)\r\n\r\n/**\r\n * 从 appConfig 提取 projectId(可选):\r\n * - 对象:直接取 projectId 字段;\r\n * - JSON 字符串:解析后取 projectId;\r\n * - 未配置 / 为空 / 解析失败时返回 undefined,接口调用不携带该参数。\r\n */\r\nconst appProjectId = computed<string | undefined>(() => {\r\n const cfg = props.appConfig\r\n if (cfg === undefined || cfg === null) return undefined\r\n let obj: Record<string, unknown> | null = null\r\n if (typeof cfg === 'string') {\r\n try {\r\n obj = JSON.parse(cfg) as Record<string, unknown>\r\n } catch {\r\n return undefined\r\n }\r\n } else if (typeof cfg === 'object') {\r\n obj = cfg as Record<string, unknown>\r\n }\r\n const pid = obj?.projectId\r\n if (pid === undefined || pid === null) return undefined\r\n const pidStr = String(pid).trim()\r\n return pidStr === '' ? undefined : pidStr\r\n})\r\n\r\n// ==================== 状态(每组件实例独立) ====================\r\n\r\nconst environmentStatus = ref<EnvironmentStatus>('not_exist')\r\nconst sessionId = ref<string>('')\r\nconst proxyUrl = ref<string>('')\r\nconst agentNickname = ref<string>('')\r\nconst environmentId = ref<string>('')\r\nconst appCode = ref<string>('')\r\nconst loading = ref<boolean>(false)\r\n\r\n// ==================== 计算属性 ====================\r\n\r\n/** 当前环境状态 */\r\nconst status = computed(() => environmentStatus.value)\r\n\r\n/** 智能体昵称(用于状态提示文案) */\r\nconst displayNickname = computed(() => agentNickname.value || '智能助手')\r\n\r\n/** 当前智能体 ID(用于详情弹窗与更新智能体) */\r\nconst currentAgentId = computed<string | null>(() => {\r\n const resolved: string | undefined = appCode.value || effectiveAgentId.value\r\n return resolved || null\r\n})\r\n\r\n/** 同步会话状态到外层堆叠面板 */\r\nwatch(\r\n [status, () => agentNickname.value, currentAgentId],\r\n ([st, nickname, agentIdVal]) => {\r\n emit('state-change', {\r\n status: st,\r\n nickname: nickname,\r\n appCode: agentIdVal,\r\n })\r\n },\r\n { immediate: true }\r\n)\r\n\r\n/** 环境数量超限弹窗可见状态 */\r\nconst envLimitDialogVisible = ref(false)\r\n\r\n// ==================== 环境数量超限弹窗(合并自 EnvironmentLimitDialog) ====================\r\n\r\n/** 场景类型中文标签映射(保留 agent 标签以兼容历史运行中环境展示) */\r\nconst SCENE_TYPE_LABELS: Record<string, string> = {\r\n workspace: '工作区',\r\n knowledge_base: '知识库',\r\n agent: '智能体',\r\n skill: '技能构建',\r\n personal_assistant: '个人助手',\r\n bid: '智能投标',\r\n}\r\n\r\n/** 运行中环境列表加载状态 */\r\nconst envLimitLoading = ref(false)\r\n\r\n/** 批量关闭进行中状态 */\r\nconst envLimitClosing = ref(false)\r\n\r\n/** 运行中环境列表 */\r\nconst runningEnvironments = ref<RunningEnvironmentItem[]>([])\r\n\r\n/** 多选选中的环境 */\r\nconst selectedEnvItems = ref<RunningEnvironmentItem[]>([])\r\n\r\n/** 环境表格 ref */\r\nconst envLimitTableRef = ref()\r\n\r\n/** 格式化时间 */\r\nfunction formatTime(time: string): string {\r\n if (!time) return '-'\r\n try {\r\n const d = new Date(time)\r\n return d.toLocaleString('zh-CN', {\r\n year: 'numeric',\r\n month: '2-digit',\r\n day: '2-digit',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n })\r\n } catch {\r\n return time\r\n }\r\n}\r\n\r\n/** 加载运行中环境列表 */\r\nasync function loadRunningEnvironments() {\r\n envLimitLoading.value = true\r\n selectedEnvItems.value = []\r\n try {\r\n runningEnvironments.value = await props.request.get<RunningEnvironmentItem[]>('/app-conversation/my-running-environments')\r\n } catch {\r\n ElMessage.error('获取运行中环境列表失败')\r\n runningEnvironments.value = []\r\n } finally {\r\n envLimitLoading.value = false\r\n }\r\n}\r\n\r\n/** 弹窗打开时加载数据 */\r\nwatch(envLimitDialogVisible, (val) => {\r\n if (val) {\r\n loadRunningEnvironments()\r\n }\r\n})\r\n\r\n/** 多选变化 */\r\nfunction handleEnvSelectionChange(rows: RunningEnvironmentItem[]) {\r\n selectedEnvItems.value = rows\r\n}\r\n\r\n/** 关闭已选环境:批量并行停止后触发重试 */\r\nasync function handleCloseEnvironments() {\r\n if (selectedEnvItems.value.length === 0) return\r\n envLimitClosing.value = true\r\n try {\r\n const environments = selectedEnvItems.value.map((item) => ({\r\n appCode: item.appCode,\r\n // appConfig 配置了 projectId 时携带(与 start-environment 对齐)\r\n ...(appProjectId.value ? { projectId: appProjectId.value } : {})\r\n }))\r\n const result = await props.request.post<BatchStopResult>('/app-conversation/batch-stop-environments', { environments })\r\n if (!result.allSuccess) {\r\n ElMessage.warning(`关闭完成:成功 ${result.successCount} 个,失败 ${result.failedCount} 个`)\r\n }\r\n envLimitDialogVisible.value = false\r\n await handleEnvClosedAndRetry()\r\n } catch {\r\n ElMessage.error('关闭环境失败,请重试')\r\n } finally {\r\n envLimitClosing.value = false\r\n }\r\n}\r\n\r\n/** iframe 地址缓存(避免无差异的 proxyUrl 更新导致 iframe 重新加载) */\r\nconst iframeSrc = ref('')\r\n\r\n/** iframe 元素引用(用于向 dsh 内部 postMessage 抛事件) */\r\nconst iframeRef = ref<HTMLIFrameElement | null>(null)\r\n\r\n/** 实际展示在 iframe 上的地址(支持刷新时附加随机参数) */\r\nconst displayedIframeSrc = ref('')\r\n\r\n/** 自动重试次数 */\r\nlet retryCount = 0\r\nconst MAX_RETRY_COUNT = 30\r\n\r\n/** 重试定时器 */\r\nlet retryTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n/** 启动后延迟加载定时器 */\r\nlet delayTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n/** PerformanceObserver 实例 */\r\nlet perfObserver: PerformanceObserver | null = null\r\n\r\n/** 加载超时定时器 */\r\nlet loadTimeout: ReturnType<typeof setTimeout> | null = null\r\n\r\n/** 当前是否处于等待 iframe 加载成功状态 */\r\nlet isWaitingLoadSuccess = false\r\n\r\n/** 轮询定时器 */\r\nlet pollTimer: ReturnType<typeof setInterval> | null = null\r\n\r\n/** 轮询计数器 */\r\nlet pollCount = 0\r\n\r\n/** 心跳定时器 */\r\nlet heartbeatTimer: ReturnType<typeof setInterval> | null = null\r\n\r\n/** 轮询间隔(毫秒) */\r\nconst POLL_INTERVAL = 2000\r\n\r\n/** 轮询最大次数(2秒 × 45次 = 90秒超时;覆盖容器创建+引擎就绪的完整启动窗口) */\r\nconst POLL_MAX_COUNT = 45\r\n\r\n/** 心跳间隔(毫秒,5分钟) */\r\nconst HEARTBEAT_INTERVAL = 5 * 60 * 1000\r\n\r\n/** 提取不含 token 的基础 URL,用于比对是否只有 token 刷新 */\r\nfunction getBaseUrl(url: string): string {\r\n if (!url) return ''\r\n try {\r\n const u = new URL(url)\r\n u.searchParams.delete('token')\r\n return u.toString()\r\n } catch {\r\n return url\r\n }\r\n}\r\n\r\n// ==================== Actions(直接调用请求地址) ====================\r\n\r\n/**\r\n * 启动执行环境\r\n */\r\nasync function startEnv(): Promise<EnvironmentStatusResult> {\r\n loading.value = true\r\n try {\r\n const res = await props.request.post<EnvironmentStatusResult>('/app-conversation/start-environment', {\r\n appCode: props.appCode,\r\n // appConfig 配置了 projectId 时携带(dynamic_project 模式后端必需)\r\n ...(appProjectId.value ? { projectId: appProjectId.value } : {})\r\n })\r\n if (res.status !== environmentStatus.value) {\r\n environmentStatus.value = res.status\r\n }\r\n if (res.environmentId && res.environmentId !== environmentId.value) {\r\n environmentId.value = res.environmentId\r\n }\r\n if (res.proxyUrl && res.proxyUrl !== proxyUrl.value) {\r\n proxyUrl.value = res.proxyUrl\r\n }\r\n return res\r\n } finally {\r\n loading.value = false\r\n }\r\n}\r\n\r\n/**\r\n * 查询环境状态(兼心跳保活)\r\n */\r\nasync function queryStatus(): Promise<void> {\r\n try {\r\n // silent: 状态轮询为后台尽力而为查询。环境启动窗口期后端可能返回瞬时的\r\n // 系统内部错误(如 10001),属预期暂态:宿主请求层应对其静默(不弹全局提示),\r\n // 本组件捕获后保持当前状态继续轮询,直至环境就绪。\r\n const res = await props.request.get<EnvironmentStatusResult>('/app-conversation/environment-status', {\r\n appCode: props.appCode\r\n }, { silent: true })\r\n if (res.status !== environmentStatus.value) {\r\n environmentStatus.value = res.status\r\n }\r\n if (res.environmentId && res.environmentId !== environmentId.value) {\r\n environmentId.value = res.environmentId\r\n }\r\n if (res.proxyUrl && res.proxyUrl !== proxyUrl.value) {\r\n proxyUrl.value = res.proxyUrl\r\n }\r\n } catch {\r\n // 查询失败静默处理,保持当前状态\r\n }\r\n}\r\n\r\n/**\r\n * 停止执行环境\r\n */\r\nasync function stopEnv(): Promise<void> {\r\n loading.value = true\r\n try {\r\n await props.request.post<null>('/app-conversation/stop-environment', {\r\n appCode: props.appCode\r\n })\r\n environmentStatus.value = 'stopped'\r\n } finally {\r\n loading.value = false\r\n }\r\n}\r\n\r\n/**\r\n * 销毁执行环境(销毁容器并重置 session,下次启动将创建全新容器)\r\n */\r\nasync function destroyEnv(): Promise<void> {\r\n loading.value = true\r\n try {\r\n await props.request.post<null>('/app-conversation/destroy-environment', {\r\n appCode: props.appCode\r\n })\r\n environmentStatus.value = 'not_exist'\r\n proxyUrl.value = ''\r\n environmentId.value = ''\r\n } finally {\r\n loading.value = false\r\n }\r\n}\r\n\r\n/**\r\n * 获取会话信息\r\n *\r\n * @returns 会话信息,失败时返回 undefined\r\n */\r\nasync function fetchSessionInfo(): Promise<SessionInfoResult | undefined> {\r\n try {\r\n // silent: 会话信息为补偿性查询(昵称/会话ID回填),启动窗口期可能瞬时失败,\r\n // 由宿主请求层静默处理,组件捕获后返回 undefined,待环境就绪后再补拉。\r\n const res = await props.request.get<SessionInfoResult>('/app-conversation/session-info', {\r\n appCode: props.appCode\r\n }, { silent: true })\r\n if (res.sessionId !== sessionId.value) {\r\n sessionId.value = res.sessionId\r\n }\r\n if (res.proxyUrl !== proxyUrl.value) {\r\n proxyUrl.value = res.proxyUrl\r\n }\r\n if (res.agentNickname !== agentNickname.value) {\r\n agentNickname.value = res.agentNickname\r\n }\r\n if (res.environmentId !== environmentId.value) {\r\n environmentId.value = res.environmentId\r\n }\r\n if (res.appCode && res.appCode !== appCode.value) {\r\n appCode.value = res.appCode\r\n }\r\n if (res.environmentStatus !== environmentStatus.value) {\r\n environmentStatus.value = res.environmentStatus\r\n }\r\n return res\r\n } catch {\r\n // 获取会话信息失败静默处理\r\n return undefined\r\n }\r\n}\r\n\r\n/**\r\n * 启动轮询(2秒间隔,60秒超时)\r\n */\r\nfunction startPolling(): void {\r\n stopPolling()\r\n pollCount = 0\r\n pollTimer = setInterval(async () => {\r\n pollCount++\r\n if (pollCount > POLL_MAX_COUNT) {\r\n // 到达轮询预算:先做最后一次状态确认再判定,避免环境刚就绪(启动窗口\r\n // 末尾查询仍在瞬时失败)时被误判为 start_failed\r\n await queryStatus()\r\n if (environmentStatus.value === 'running') {\r\n stopPolling()\r\n startHeartbeat()\r\n if (!agentNickname.value) {\r\n // 启动窗口期补拉会话信息失败的兜底:环境就绪后回填昵称/会话ID\r\n fetchSessionInfo()\r\n }\r\n return\r\n }\r\n // 超时:停止轮询,标记启动失败(可由用户手动重新启动)\r\n stopPolling()\r\n environmentStatus.value = 'start_failed'\r\n return\r\n }\r\n await queryStatus()\r\n if (environmentStatus.value === 'running') {\r\n // 环境就绪:停止轮询,启动心跳\r\n stopPolling()\r\n startHeartbeat()\r\n if (!agentNickname.value) {\r\n // 启动窗口期 fetchSessionInfo 可能因瞬时错误被跳过,就绪后补拉一次\r\n fetchSessionInfo()\r\n }\r\n } else if (environmentStatus.value === 'start_failed') {\r\n // 启动失败:停止轮询\r\n stopPolling()\r\n }\r\n }, POLL_INTERVAL)\r\n}\r\n\r\n/**\r\n * 停止轮询\r\n */\r\nfunction stopPolling(): void {\r\n if (pollTimer !== null) {\r\n clearInterval(pollTimer)\r\n pollTimer = null\r\n }\r\n pollCount = 0\r\n}\r\n\r\n/**\r\n * 启动心跳(5分钟间隔)\r\n */\r\nfunction startHeartbeat(): void {\r\n stopHeartbeat()\r\n heartbeatTimer = setInterval(async () => {\r\n // 仅在页面可见时发送心跳\r\n if (document.visibilityState === 'visible') {\r\n await queryStatus()\r\n }\r\n }, HEARTBEAT_INTERVAL)\r\n}\r\n\r\n/**\r\n * 停止心跳\r\n */\r\nfunction stopHeartbeat(): void {\r\n if (heartbeatTimer !== null) {\r\n clearInterval(heartbeatTimer)\r\n heartbeatTimer = null\r\n }\r\n}\r\n\r\n/**\r\n * 重置所有状态并清理定时器\r\n */\r\nfunction resetState(): void {\r\n stopPolling()\r\n stopHeartbeat()\r\n environmentStatus.value = 'not_exist'\r\n sessionId.value = ''\r\n proxyUrl.value = ''\r\n agentNickname.value = ''\r\n environmentId.value = ''\r\n appCode.value = ''\r\n loading.value = false\r\n}\r\n\r\n// ==================== iframe 监控逻辑(保持原样) ====================\r\n\r\nwatch(\r\n [() => environmentStatus.value, () => proxyUrl.value],\r\n ([newStatus, newUrl], [oldStatus, oldUrl]) => {\r\n if (!newUrl || newStatus !== 'running') {\r\n iframeSrc.value = ''\r\n displayedIframeSrc.value = ''\r\n stopLoadMonitoring()\r\n clearTimers()\r\n return\r\n }\r\n // 仅在运行状态且基础 URL 变化(非 token 刷新)时才更新 iframe\r\n if (getBaseUrl(newUrl) !== getBaseUrl(oldUrl || '')) {\r\n const freshStart = oldStatus === 'starting'\r\n updateIframeSrc(newUrl, freshStart)\r\n }\r\n },\r\n { immediate: true }\r\n)\r\n\r\nwatch(\r\n () => environmentStatus.value,\r\n (newStatus, oldStatus) => {\r\n // 重启等场景下 proxyUrl 基础地址可能未变,需要单独监听 running 强制刷新\r\n if (newStatus === 'running' && oldStatus === 'starting') {\r\n const url = proxyUrl.value\r\n if (!url) return\r\n // iframeSrc 为空(重启后 reset 清空)或基础地址相同时,均需强制加载\r\n if (!iframeSrc.value || getBaseUrl(url) === getBaseUrl(iframeSrc.value)) {\r\n updateIframeSrc(url, true)\r\n }\r\n }\r\n }\r\n)\r\n\r\n/**\r\n * 启动环境\r\n */\r\nasync function handleStart() {\r\n // 防止重复调用:loading 中或已在 running/starting 状态时直接忽略\r\n if (loading.value) return\r\n const currentStatus = environmentStatus.value\r\n if (currentStatus === 'running' || currentStatus === 'starting') return\r\n\r\n // start_failed 状态时,先查一次真实状态:\r\n // 容器可能已成功启动但前端因接口超时等原因误显了 start_failed\r\n if (currentStatus === 'start_failed') {\r\n await queryStatus()\r\n const refreshedStatus = environmentStatus.value\r\n if (refreshedStatus === 'running') {\r\n // 容器已在运行,启动心跳即可\r\n startHeartbeat()\r\n return\r\n }\r\n if (refreshedStatus === 'starting') {\r\n // 已在启动中,开始轮询即可\r\n startPolling()\r\n return\r\n }\r\n }\r\n\r\n try {\r\n await startEnv()\r\n // 启动成功后补查会话信息(首次启动时 fetchSessionInfo 因会话不存在被跳过,此处补偿)\r\n if (!agentNickname.value) {\r\n fetchSessionInfo()\r\n }\r\n // 启动成功后如果状态为 starting,开启轮询\r\n if (environmentStatus.value === 'starting') {\r\n startPolling()\r\n } else if (environmentStatus.value === 'running') {\r\n // 直接变为 running,启动心跳\r\n startHeartbeat()\r\n }\r\n } catch (err: any) {\r\n // 环境数量超限:弹出运行中环境列表,用户关闭后可自动重试\r\n if (err?.code === 23010) {\r\n envLimitDialogVisible.value = true\r\n return\r\n }\r\n // 其他接口错误已由宿主 request 统一处理\r\n }\r\n}\r\n\r\n/**\r\n * 环境数量超限弹窗关闭环境后重试启动\r\n */\r\nasync function handleEnvClosedAndRetry() {\r\n // 等待一小段时间让后端状态同步完成\r\n await new Promise((resolve) => setTimeout(resolve, 500))\r\n await handleStart()\r\n}\r\n\r\n/**\r\n * 停止环境(确认交互由外层标题栏负责)\r\n *\r\n * @returns 是否停止成功\r\n */\r\nasync function stop(): Promise<boolean> {\r\n // 立即切换到停止中状态,让 UI 即时响应\r\n environmentStatus.value = 'stopping'\r\n // 清理轮询、心跳、加载监控与定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n stopLoadMonitoring()\r\n clearTimers()\r\n try {\r\n await stopEnv()\r\n return true\r\n } catch {\r\n // 接口错误已由宿主请求统一处理,回退状态为 running\r\n environmentStatus.value = 'running'\r\n return false\r\n }\r\n}\r\n\r\n/**\r\n * 解析当前会话的智能体ID(用于更新智能体等需要 appCode 的操作)\r\n */\r\nasync function resolveAgentId(): Promise<string | undefined> {\r\n // 尝试获取 appCode:优先使用已缓存的,否则重新查询会话信息\r\n let resolved = appCode.value || effectiveAgentId.value\r\n if (!resolved) {\r\n // 会话信息可能因初始化时序未成功获取,此处补查一次\r\n await fetchSessionInfo()\r\n resolved = appCode.value || effectiveAgentId.value\r\n }\r\n return resolved || undefined\r\n}\r\n\r\n/**\r\n * 手动刷新 iframe(附加随机参数强制重新加载)\r\n */\r\nfunction refresh() {\r\n const url = iframeSrc.value\r\n if (!url) return\r\n stopLoadMonitoring()\r\n retryCount = 0\r\n const separator = url.includes('?') ? '&' : '?'\r\n displayedIframeSrc.value = `${url}${separator}_refresh=${Date.now()}`\r\n startLoadMonitoring(displayedIframeSrc.value)\r\n}\r\n\r\n/**\r\n * iframe 加载完成\r\n */\r\nfunction onIframeLoad() {\r\n handleLoadSuccess()\r\n}\r\n\r\n/**\r\n * iframe 加载失败\r\n */\r\nfunction onIframeError() {\r\n handleLoadFailure('network')\r\n}\r\n\r\n/**\r\n * 标记加载成功:停止监控、取消超时、重置重试计数\r\n */\r\nfunction handleLoadSuccess() {\r\n if (!isWaitingLoadSuccess) return\r\n stopLoadMonitoring()\r\n retryCount = 0\r\n}\r\n\r\n// ==================== 域名探测与加载监控机制(保持原样) ====================\r\n\r\nfunction buildTestUrl(url: string): string {\r\n try {\r\n const u = new URL(url)\r\n u.pathname = '/test'\r\n u.search = ''\r\n u.hash = ''\r\n return u.toString()\r\n } catch {\r\n const base = url.split('?')[0].split('#')[0]\r\n return `${base.replace(/\\/+$/, '')}/test`\r\n }\r\n}\r\n\r\nasync function probeTargetUrl(url: string): Promise<boolean> {\r\n try {\r\n const testUrl = buildTestUrl(url)\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), 5000)\r\n const res = await fetch(testUrl, {\r\n method: 'HEAD',\r\n mode: 'cors',\r\n cache: 'no-cache',\r\n signal: controller.signal,\r\n })\r\n clearTimeout(timeoutId)\r\n return res.status === 200\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nasync function ensureTargetReachableThenLoad(url: string, attempt = 0) {\r\n if (await probeTargetUrl(url)) {\r\n setIframeSrcAndMonitor(url)\r\n return\r\n }\r\n\r\n if (attempt < MAX_RETRY_COUNT) {\r\n retryTimer = setTimeout(() => {\r\n ensureTargetReachableThenLoad(url, attempt + 1)\r\n }, 100)\r\n } else {\r\n setIframeSrcAndMonitor(url)\r\n }\r\n}\r\n\r\nfunction setIframeSrcAndMonitor(url: string) {\r\n iframeSrc.value = url\r\n displayedIframeSrc.value = url\r\n startLoadMonitoring(url)\r\n}\r\n\r\nfunction updateIframeSrc(url: string, delay: boolean) {\r\n stopLoadMonitoring()\r\n clearTimers()\r\n retryCount = 0\r\n\r\n if (delay) {\r\n delayTimer = setTimeout(() => {\r\n ensureTargetReachableThenLoad(url)\r\n delayTimer = null\r\n }, 1500)\r\n } else {\r\n ensureTargetReachableThenLoad(url)\r\n }\r\n}\r\n\r\nfunction clearTimers() {\r\n if (retryTimer) {\r\n clearTimeout(retryTimer)\r\n retryTimer = null\r\n }\r\n if (delayTimer) {\r\n clearTimeout(delayTimer)\r\n delayTimer = null\r\n }\r\n if (loadTimeout) {\r\n clearTimeout(loadTimeout)\r\n loadTimeout = null\r\n }\r\n}\r\n\r\nfunction startLoadMonitoring(url: string) {\r\n stopLoadMonitoring()\r\n if (!window.PerformanceObserver) {\r\n startLoadTimeout(url)\r\n return\r\n }\r\n\r\n isWaitingLoadSuccess = true\r\n\r\n try {\r\n perfObserver = new PerformanceObserver((list) => {\r\n for (const entry of list.getEntries()) {\r\n const resEntry = entry as PerformanceResourceTiming\r\n if (entry.name !== url && entry.name !== displayedIframeSrc.value) continue\r\n\r\n const status = resEntry.responseStatus\r\n\r\n // 仅处理明确的 502 错误(跨域时 status 始终为 0,不可作为失败判据)\r\n if (status === 502) {\r\n handleLoadFailure('502')\r\n return\r\n }\r\n\r\n // 加载成功(仅同域或设置了 Timing-Allow-Origin 时有效)\r\n if (status >= 200 && status < 400) {\r\n handleLoadSuccess()\r\n }\r\n }\r\n })\r\n perfObserver.observe({ type: 'resource', buffered: true })\r\n } catch {\r\n // 浏览器不支持 PerformanceObserver 时静默忽略\r\n }\r\n\r\n startLoadTimeout(url)\r\n}\r\n\r\nfunction stopLoadMonitoring() {\r\n if (perfObserver) {\r\n perfObserver.disconnect()\r\n perfObserver = null\r\n }\r\n if (loadTimeout) {\r\n clearTimeout(loadTimeout)\r\n loadTimeout = null\r\n }\r\n isWaitingLoadSuccess = false\r\n}\r\n\r\nfunction startLoadTimeout(_url: string) {\r\n loadTimeout = setTimeout(() => {\r\n if (isWaitingLoadSuccess) {\r\n handleLoadFailure('timeout')\r\n }\r\n }, 15000)\r\n}\r\n\r\nfunction handleLoadFailure(reason: '502' | 'network' | 'timeout') {\r\n if (!isWaitingLoadSuccess) return\r\n stopLoadMonitoring()\r\n\r\n retryCount++\r\n if (retryCount > MAX_RETRY_COUNT) {\r\n ElMessage.error('应用加载失败,请刷新页面重试')\r\n return\r\n }\r\n\r\n const reasonText = reason === 'network'\r\n ? '网络错误'\r\n : reason === 'timeout'\r\n ? '加载超时'\r\n : '应用暂不可用'\r\n console.warn(`[ConversationSession] 加载失败: ${reasonText}, 第 ${retryCount} 次重试`)\r\n\r\n retryTimer = setTimeout(() => {\r\n if (!iframeSrc.value) return\r\n const separator = iframeSrc.value.includes('?') ? '&' : '?'\r\n displayedIframeSrc.value = `${iframeSrc.value}${separator}_retry=${Date.now()}`\r\n startLoadMonitoring(displayedIframeSrc.value)\r\n }, 1000)\r\n}\r\n\r\n// ==================== 页面可见性监听 ====================\r\n\r\nfunction handleVisibilityChange() {\r\n if (document.visibilityState === 'visible' && status.value === 'running') {\r\n // 页面恢复可见时,立即查询一次状态保活\r\n queryStatus()\r\n }\r\n}\r\n\r\n// ==================== 生命周期 ====================\r\n\r\nonMounted(async () => {\r\n // 监听页面可见性变化\r\n document.addEventListener('visibilitychange', handleVisibilityChange)\r\n\r\n // 查询当前环境状态\r\n await queryStatus()\r\n\r\n const st = environmentStatus.value\r\n if (st === 'not_exist' || st === 'stopped') {\r\n // 会话尚未创建,先启动环境,fetchSessionInfo 由 handleStart 成功后补调\r\n handleStart()\r\n } else {\r\n // 环境已存在,安全获取昵称\r\n await fetchSessionInfo()\r\n if (st === 'starting') {\r\n // 正在启动,开始轮询\r\n startPolling()\r\n } else if (st === 'running') {\r\n // 已在运行,启动心跳\r\n startHeartbeat()\r\n }\r\n }\r\n})\r\n\r\n/**\r\n * 重启会话:停止当前环境 → 重置状态 → 重新启动\r\n */\r\nasync function restart() {\r\n // 立即切换到停止中,让 UI 及时响应\r\n const originalStatus = environmentStatus.value\r\n environmentStatus.value = 'stopping'\r\n\r\n // 清理旧环境的轮询、心跳、加载监控与定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n stopLoadMonitoring()\r\n clearTimers()\r\n\r\n // 如果当前环境正在运行或已启动,先停止\r\n if (originalStatus === 'running' || originalStatus === 'starting') {\r\n try {\r\n await stopEnv()\r\n } catch {\r\n // 停止失败不阻塞重启流程\r\n }\r\n }\r\n\r\n // 重置状态\r\n resetState()\r\n // 立即切换到启动中,避免内容区闪现\"环境未启动\"\r\n environmentStatus.value = 'starting'\r\n\r\n // 直接调用启动,绕过 handleStart 的状态守卫(因为已手动设置 starting)\r\n try {\r\n await startEnv()\r\n // 重新启动后重新获取昵称(reset 已清空)\r\n fetchSessionInfo()\r\n if (environmentStatus.value === 'starting') {\r\n startPolling()\r\n } else if (environmentStatus.value === 'running') {\r\n startHeartbeat()\r\n }\r\n } catch {\r\n // 接口错误已由宿主请求统一处理\r\n }\r\n}\r\n\r\n/**\r\n * 重建会话:销毁当前容器 → 重置状态 → 创建全新环境\r\n */\r\nasync function rebuild() {\r\n // 立即切换到停止中,让 UI 及时响应\r\n environmentStatus.value = 'stopping'\r\n\r\n // 清理旧环境的轮询、心跳、加载监控与定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n stopLoadMonitoring()\r\n clearTimers()\r\n\r\n // 销毁当前环境(容器销毁 + session 重置为 not_exist)\r\n try {\r\n await destroyEnv()\r\n } catch {\r\n // 销毁失败不阻塞后续启动流程\r\n }\r\n\r\n // 重置全部状态\r\n resetState()\r\n // 立即切换到启动中,避免内容区闪现\"环境未启动\"\r\n environmentStatus.value = 'starting'\r\n\r\n // 创建全新环境\r\n try {\r\n await startEnv()\r\n fetchSessionInfo()\r\n if (environmentStatus.value === 'starting') {\r\n startPolling()\r\n } else if (environmentStatus.value === 'running') {\r\n startHeartbeat()\r\n }\r\n } catch {\r\n // 接口错误已由宿主请求统一处理\r\n }\r\n}\r\n\r\n/**\r\n * 向 dsh 内部(iframe 沙箱)抛出一个事件。\r\n *\r\n * 供外层宿主(ConversationPanel 经 dsh-bridge)把提示词注入等事件投递给 dsh。\r\n * 消息协议与 dsh 插件保持一致:{ target: 'dsh', type, payload }。\r\n *\r\n * @param type - 事件类型(如 prompt:inject)。\r\n * @param payload - 事件载荷。\r\n */\r\nfunction postDshEvent(type: string, payload: unknown) {\r\n const win = iframeRef.value?.contentWindow\r\n if (win) {\r\n win.postMessage({ target: 'dsh', type, payload }, '*')\r\n }\r\n}\r\n\r\n// ==================== 对外暴露 ====================\r\n\r\ndefineExpose({ start: handleStart, stop, restart, rebuild, refresh, resolveAgentId, postDshEvent })\r\n\r\nonUnmounted(() => {\r\n // 清理轮询和心跳定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n // 移除页面可见性监听\r\n document.removeEventListener('visibilitychange', handleVisibilityChange)\r\n // 停止加载监控与定时器\r\n stopLoadMonitoring()\r\n clearTimers()\r\n // 重置状态\r\n resetState()\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.conversation-session {\r\n flex: 1;\r\n min-width: 0;\r\n overflow: hidden;\r\n margin: 8px 8px 8px 0;\r\n border-radius: 4px;\r\n background: #F8FBFC;\r\n}\r\n\r\n/* 占位状态 */\r\n.status-placeholder {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--el-text-color-secondary);\r\n font-size: var(--text-meta);\r\n}\r\n\r\n.status-placeholder p {\r\n margin-top: var(--space-4);\r\n color: var(--el-text-color-secondary);\r\n}\r\n\r\n/* iframe 容器 */\r\n.iframe-container {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.conversation-iframe {\r\n width: 100%;\r\n height: 100%;\r\n border: none;\r\n}\r\n\r\n/* 环境数量超限弹窗(合并自 EnvironmentLimitDialog) */\r\n.env-limit-dialog__tip {\r\n margin-bottom: var(--space-4);\r\n color: var(--el-text-color-regular);\r\n font-size: var(--el-font-size-base);\r\n}\r\n\r\n.env-limit-dialog :deep(.el-table__body-wrapper) {\r\n overflow-x: hidden;\r\n}\r\n</style>","/**\n * @duxi999/usdp-eacp-conversation 组件库入口\n *\n * 导出对话会话组件(已合并环境超限弹窗)以及共享类型。\n * request 对象由宿主应用通过 props 注入,组件内部直接调用请求地址。\n */\n\nimport type { App } from 'vue'\nimport ConversationSession from './components/UsdpEacpConversation.vue'\n\n// ==================== 组件 ====================\n\nexport { ConversationSession }\n\n// ==================== 共享类型 ====================\n\nexport type {\n EnvironmentStatus,\n SceneType,\n EnvironmentParams,\n EnvironmentStatusResult,\n SessionInfoResult,\n RunningEnvironmentItem,\n BatchStopResult,\n RequestAdapter,\n RequestOptions,\n} from './types'\n\n// ==================== 组件库插件(可选,支持 app.use 全局注册) ====================\n\n/** 全局注册使用的组件名(与包名 usdp-eacp-conversation 一致,模板中可写 <usdp-eacp-conversation>) */\nconst REGISTERED_NAME = 'usdp-eacp-conversation'\n\nexport default {\n install(app: App) {\n // 以包名注册,便于模板中使用 <usdp-eacp-conversation>\n app.component(REGISTERED_NAME, ConversationSession)\n // 同时注册 PascalCase 与 camelCase 变体,兼容不同书写习惯\n app.component('UsdpEacpConversation', ConversationSession)\n },\n}\n\nexport type ConversationSessionInstance = InstanceType<typeof ConversationSession>"],"names":["MAX_RETRY_COUNT","POLL_INTERVAL","POLL_MAX_COUNT","HEARTBEAT_INTERVAL","props","__props","emit","__emit","effectiveAgentId","computed","appProjectId","cfg","obj","pid","pidStr","environmentStatus","ref","sessionId","proxyUrl","agentNickname","environmentId","appCode","loading","status","currentAgentId","watch","st","nickname","agentIdVal","envLimitDialogVisible","SCENE_TYPE_LABELS","envLimitLoading","envLimitClosing","runningEnvironments","selectedEnvItems","envLimitTableRef","formatTime","time","loadRunningEnvironments","ElMessage","val","handleEnvSelectionChange","rows","handleCloseEnvironments","environments","item","result","handleEnvClosedAndRetry","iframeSrc","iframeRef","displayedIframeSrc","retryCount","retryTimer","delayTimer","perfObserver","loadTimeout","isWaitingLoadSuccess","pollTimer","pollCount","heartbeatTimer","getBaseUrl","url","u","startEnv","res","queryStatus","stopEnv","destroyEnv","fetchSessionInfo","startPolling","stopPolling","startHeartbeat","stopHeartbeat","resetState","newStatus","newUrl","oldStatus","oldUrl","stopLoadMonitoring","clearTimers","updateIframeSrc","handleStart","currentStatus","refreshedStatus","err","resolve","stop","resolveAgentId","resolved","refresh","separator","startLoadMonitoring","onIframeLoad","handleLoadSuccess","onIframeError","handleLoadFailure","buildTestUrl","probeTargetUrl","testUrl","controller","timeoutId","ensureTargetReachableThenLoad","attempt","setIframeSrcAndMonitor","delay","startLoadTimeout","list","entry","resEntry","_url","reason","handleVisibilityChange","onMounted","restart","originalStatus","rebuild","postDshEvent","type","payload","win","_a","__expose","onUnmounted","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_createVNode","_component_el_empty","_component_el_button","_cache","_hoisted_3","_component_el_icon","_unref","Loading","_createElementVNode","_toDisplayString","_hoisted_4","_hoisted_5","_hoisted_7","_component_el_result","_hoisted_8","_component_el_dialog","$event","_hoisted_9","_createBlock","_component_el_table","_component_el_table_column","_withCtx","row","_createTextVNode","REGISTERED_NAME","index","app","ConversationSession"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/components/UsdpEacpConversation.vue","../src/index.ts"],"sourcesContent":["<template>\r\n <div class=\"conversation-session\">\r\n <!-- /aisys 直接访问:应用包未经应用编排,不执行环境接口 -->\r\n <div v-if=\"isAisysContext\" class=\"status-placeholder\">\r\n <el-result icon=\"warning\" title=\"当前应用包需要创建应用通过应用访问智能体服务\">\r\n <template #extra>\r\n <el-text type=\"info\" size=\"small\">请在本平台创建智能应用并绑定本应用包后,通过应用入口访问</el-text>\r\n </template>\r\n </el-result>\r\n </div>\r\n\r\n <!-- not_exist 状态:启动提示 -->\r\n <div v-else-if=\"status === 'not_exist'\" class=\"status-placeholder\">\r\n <el-empty :description=\"`${agentNickname} 环境未启动`\">\r\n <el-button type=\"primary\" @click=\"handleStart\">启动环境</el-button>\r\n </el-empty>\r\n </div>\r\n\r\n <!-- starting 状态:加载动画 -->\r\n <div v-else-if=\"status === 'starting'\" class=\"status-placeholder\">\r\n <el-icon class=\"is-loading\" :size=\"48\"><Loading /></el-icon>\r\n <p>{{ agentNickname }} 环境启动中...</p>\r\n </div>\r\n\r\n <!-- stopping 状态:停止中动画 -->\r\n <div v-else-if=\"status === 'stopping'\" class=\"status-placeholder\">\r\n <el-icon class=\"is-loading\" :size=\"48\"><Loading /></el-icon>\r\n <p>正在停止 {{ agentNickname }}...</p>\r\n </div>\r\n\r\n <!-- running 状态:iframe -->\r\n <div v-else-if=\"status === 'running'\" class=\"iframe-container\">\r\n <iframe\r\n ref=\"iframeRef\"\r\n :src=\"displayedIframeSrc\"\r\n class=\"conversation-iframe\"\r\n @load=\"onIframeLoad\"\r\n @error=\"onIframeError\"\r\n />\r\n </div>\r\n\r\n <!-- start_failed 状态:错误提示 -->\r\n <div v-else-if=\"status === 'start_failed'\" class=\"status-placeholder\">\r\n <el-result icon=\"error\" title=\"环境启动失败\">\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"handleStart\">重新启动</el-button>\r\n </template>\r\n </el-result>\r\n </div>\r\n\r\n <!-- stopped 状态:已停止 -->\r\n <div v-else-if=\"status === 'stopped'\" class=\"status-placeholder\">\r\n <el-result icon=\"info\" title=\"环境已停止\">\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"handleStart\">重新启动</el-button>\r\n </template>\r\n </el-result>\r\n </div>\r\n\r\n <!-- 环境数量超限弹窗 -->\r\n <el-dialog\r\n :model-value=\"envLimitDialogVisible\"\r\n title=\"运行中环境数量已达上限\"\r\n width=\"720px\"\r\n :close-on-click-modal=\"false\"\r\n @update:model-value=\"envLimitDialogVisible = $event\"\r\n >\r\n <div class=\"env-limit-dialog\">\r\n <p class=\"env-limit-dialog__tip\">\r\n 您的运行中智能会话数量已达上限,请选择需要关闭的会话后重试。\r\n </p>\r\n\r\n <el-table\r\n ref=\"envLimitTableRef\"\r\n :data=\"runningEnvironments\"\r\n v-loading=\"envLimitLoading\"\r\n max-height=\"520\"\r\n :header-cell-style=\"{ textAlign: 'center' }\"\r\n @selection-change=\"handleEnvSelectionChange\"\r\n >\r\n <el-table-column type=\"selection\" width=\"42\" />\r\n <el-table-column label=\"场景类型\" min-width=\"100\">\r\n <template #default=\"{ row }\">\r\n {{ SCENE_TYPE_LABELS[row.sceneType] || row.sceneType }}\r\n </template>\r\n </el-table-column>\r\n <el-table-column prop=\"sceneName\" label=\"场景名称\" min-width=\"150\" show-overflow-tooltip />\r\n <el-table-column label=\"智能体\" min-width=\"130\" show-overflow-tooltip>\r\n <template #default=\"{ row }\">\r\n {{ row.agentNickname || '-' }}\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"创建时间\" min-width=\"170\">\r\n <template #default=\"{ row }\">\r\n {{ formatTime(row.createdAt) }}\r\n </template>\r\n </el-table-column>\r\n </el-table>\r\n </div>\r\n\r\n <template #footer>\r\n <el-button @click=\"envLimitDialogVisible = false\">暂不关闭</el-button>\r\n <el-button\r\n type=\"primary\"\r\n :loading=\"envLimitClosing\"\r\n :disabled=\"selectedEnvItems.length === 0\"\r\n @click=\"handleCloseEnvironments\"\r\n >\r\n 关闭已选环境\r\n </el-button>\r\n </template>\r\n </el-dialog>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n/**\r\n * 单个智能对话会话组件\r\n *\r\n * 承载一个智能体会话的完整生命周期(环境查询/启动/停止/重启/重建、iframe 加载监控、\r\n * 轮询与心跳保活)。组件完全自包含:\r\n *\r\n * 组件名与包名一致(usdp-xjgz-conversation),模板中可使用:\r\n * - <usdp-xjgz-conversation>\r\n * - <UsdpXjgzConversation>\r\n */\r\n\r\ndefineOptions({ name: 'UsdpXjgzConversation' })\r\n\r\n/**\r\n * 由宿主注入 RequestAdapter(axios 封装),通过 props 传入;\r\n * 组件内部直接调用具体请求地址,不依赖任何外部 store / api / utils 模块;\r\n * 每个组件实例拥有独立的状态和定时器,避免多会话状态覆盖。\r\n */\r\n\r\nimport { computed, onMounted, onUnmounted, ref, watch } from 'vue'\r\nimport { Loading } from '@element-plus/icons-vue'\r\nimport { ElMessage } from 'element-plus'\r\nimport type {\r\n BatchStopResult,\r\n EnvironmentStatus,\r\n EnvironmentStatusResult,\r\n RequestAdapter,\r\n RunningEnvironmentItem,\r\n SessionInfoResult,\r\n} from '../types'\r\n\r\n// ==================== Props ====================\r\n\r\ninterface Props {\r\n /** 应用编码 */\r\n appCode: string\r\n /** 由宿主注入的 HTTP 请求适配器(axios 封装),必传 */\r\n request: RequestAdapter\r\n /**\r\n * 应用配置(来自宿主 APP_INIT 下发的 payload.appConfig,可选)\r\n * 支持对象或 JSON 字符串;若其中配置了 projectId,\r\n * 组件调用 start-environment / batch-stop-environments 时会携带该参数给后端\r\n * (后端 workspace_mode=dynamic_project 模式必需)\r\n */\r\n appConfig?: unknown\r\n}\r\n\r\nconst props = defineProps<Props>()\r\n\r\n/** 会话状态变更事件(供外层堆叠面板渲染标题栏) */\r\nconst emit = defineEmits<{\r\n (e: 'state-change', value: { status: EnvironmentStatus; nickname: string; appCode: string | null }): void\r\n}>()\r\n\r\n/** 转换为字符串的智能体ID(用于接口调用) */\r\nconst effectiveAgentId = computed<string | undefined>(() =>\r\n props.appCode !== undefined && props.appCode !== null && props.appCode !== ''\r\n ? String(props.appCode)\r\n : undefined\r\n)\r\n\r\n/**\r\n * 从 appConfig 提取 projectId(可选):\r\n * - 对象:直接取 projectId 字段;\r\n * - JSON 字符串:解析后取 projectId;\r\n * - 未配置 / 为空 / 解析失败时返回 undefined,接口调用不携带该参数。\r\n */\r\nconst appProjectId = computed<string | undefined>(() => {\r\n const cfg = props.appConfig\r\n if (cfg === undefined || cfg === null) return undefined\r\n let obj: Record<string, unknown> | null = null\r\n if (typeof cfg === 'string') {\r\n try {\r\n obj = JSON.parse(cfg) as Record<string, unknown>\r\n } catch {\r\n return undefined\r\n }\r\n } else if (typeof cfg === 'object') {\r\n obj = cfg as Record<string, unknown>\r\n }\r\n const pid = obj?.projectId\r\n if (pid === undefined || pid === null) return undefined\r\n const pidStr = String(pid).trim()\r\n return pidStr === '' ? undefined : pidStr\r\n})\r\n\r\n/**\r\n * 官方应用包直接访问上下文检测:\r\n * 浏览器地址为 /aisys/{rootRoute}/?token=xxx 时,访问的是应用包本身(appCode 实为应用包根路由),\r\n * 未经过智能应用编排,start-environment 无法启动智能体环境。\r\n * 此时组件不执行环境接口,仅展示引导提示。\r\n */\r\nconst isAisysContext = ref(/^\\/aisys\\/[^/]+/.test(window.location.pathname))\r\n\r\n// ==================== 状态(每组件实例独立) ====================\r\n\r\nconst environmentStatus = ref<EnvironmentStatus>('not_exist')\r\nconst sessionId = ref<string>('')\r\nconst proxyUrl = ref<string>('')\r\nconst agentNickname = ref<string>('')\r\nconst environmentId = ref<string>('')\r\nconst appCode = ref<string>('')\r\nconst loading = ref<boolean>(false)\r\n\r\n// ==================== 计算属性 ====================\r\n\r\n/** 当前环境状态 */\r\nconst status = computed(() => environmentStatus.value)\r\n\r\n/** 智能体昵称(用于状态提示文案) */\r\nconst displayNickname = computed(() => agentNickname.value || '智能助手')\r\n\r\n/** 当前智能体 ID(用于详情弹窗与更新智能体) */\r\nconst currentAgentId = computed<string | null>(() => {\r\n const resolved: string | undefined = appCode.value || effectiveAgentId.value\r\n return resolved || null\r\n})\r\n\r\n/** 同步会话状态到外层堆叠面板 */\r\nwatch(\r\n [status, () => agentNickname.value, currentAgentId],\r\n ([st, nickname, agentIdVal]) => {\r\n emit('state-change', {\r\n status: st,\r\n nickname: nickname,\r\n appCode: agentIdVal,\r\n })\r\n },\r\n { immediate: true }\r\n)\r\n\r\n/** 环境数量超限弹窗可见状态 */\r\nconst envLimitDialogVisible = ref(false)\r\n\r\n// ==================== 环境数量超限弹窗(合并自 EnvironmentLimitDialog) ====================\r\n\r\n/** 场景类型中文标签映射(保留 agent 标签以兼容历史运行中环境展示) */\r\nconst SCENE_TYPE_LABELS: Record<string, string> = {\r\n workspace: '工作区',\r\n knowledge_base: '知识库',\r\n agent: '智能体',\r\n skill: '技能构建',\r\n personal_assistant: '个人助手',\r\n bid: '智能投标',\r\n}\r\n\r\n/** 运行中环境列表加载状态 */\r\nconst envLimitLoading = ref(false)\r\n\r\n/** 批量关闭进行中状态 */\r\nconst envLimitClosing = ref(false)\r\n\r\n/** 运行中环境列表 */\r\nconst runningEnvironments = ref<RunningEnvironmentItem[]>([])\r\n\r\n/** 多选选中的环境 */\r\nconst selectedEnvItems = ref<RunningEnvironmentItem[]>([])\r\n\r\n/** 环境表格 ref */\r\nconst envLimitTableRef = ref()\r\n\r\n/** 格式化时间 */\r\nfunction formatTime(time: string): string {\r\n if (!time) return '-'\r\n try {\r\n const d = new Date(time)\r\n return d.toLocaleString('zh-CN', {\r\n year: 'numeric',\r\n month: '2-digit',\r\n day: '2-digit',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n })\r\n } catch {\r\n return time\r\n }\r\n}\r\n\r\n/** 加载运行中环境列表 */\r\nasync function loadRunningEnvironments() {\r\n envLimitLoading.value = true\r\n selectedEnvItems.value = []\r\n try {\r\n runningEnvironments.value = await props.request.get<RunningEnvironmentItem[]>('/app-conversation/my-running-environments')\r\n } catch {\r\n ElMessage.error('获取运行中环境列表失败')\r\n runningEnvironments.value = []\r\n } finally {\r\n envLimitLoading.value = false\r\n }\r\n}\r\n\r\n/** 弹窗打开时加载数据 */\r\nwatch(envLimitDialogVisible, (val) => {\r\n if (val) {\r\n loadRunningEnvironments()\r\n }\r\n})\r\n\r\n/** 多选变化 */\r\nfunction handleEnvSelectionChange(rows: RunningEnvironmentItem[]) {\r\n selectedEnvItems.value = rows\r\n}\r\n\r\n/** 关闭已选环境:批量并行停止后触发重试 */\r\nasync function handleCloseEnvironments() {\r\n if (selectedEnvItems.value.length === 0) return\r\n envLimitClosing.value = true\r\n try {\r\n const environments = selectedEnvItems.value.map((item) => ({\r\n appCode: item.appCode,\r\n // appConfig 配置了 projectId 时携带(与 start-environment 对齐)\r\n ...(appProjectId.value ? { projectId: appProjectId.value } : {})\r\n }))\r\n const result = await props.request.post<BatchStopResult>('/app-conversation/batch-stop-environments', { environments })\r\n if (!result.allSuccess) {\r\n ElMessage.warning(`关闭完成:成功 ${result.successCount} 个,失败 ${result.failedCount} 个`)\r\n }\r\n envLimitDialogVisible.value = false\r\n await handleEnvClosedAndRetry()\r\n } catch {\r\n ElMessage.error('关闭环境失败,请重试')\r\n } finally {\r\n envLimitClosing.value = false\r\n }\r\n}\r\n\r\n/** iframe 地址缓存(避免无差异的 proxyUrl 更新导致 iframe 重新加载) */\r\nconst iframeSrc = ref('')\r\n\r\n/** iframe 元素引用(用于向 dsh 内部 postMessage 抛事件) */\r\nconst iframeRef = ref<HTMLIFrameElement | null>(null)\r\n\r\n/** 实际展示在 iframe 上的地址(支持刷新时附加随机参数) */\r\nconst displayedIframeSrc = ref('')\r\n\r\n/** 自动重试次数 */\r\nlet retryCount = 0\r\nconst MAX_RETRY_COUNT = 30\r\n\r\n/** 重试定时器 */\r\nlet retryTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n/** 启动后延迟加载定时器 */\r\nlet delayTimer: ReturnType<typeof setTimeout> | null = null\r\n\r\n/** PerformanceObserver 实例 */\r\nlet perfObserver: PerformanceObserver | null = null\r\n\r\n/** 加载超时定时器 */\r\nlet loadTimeout: ReturnType<typeof setTimeout> | null = null\r\n\r\n/** 当前是否处于等待 iframe 加载成功状态 */\r\nlet isWaitingLoadSuccess = false\r\n\r\n/** 轮询定时器 */\r\nlet pollTimer: ReturnType<typeof setInterval> | null = null\r\n\r\n/** 轮询计数器 */\r\nlet pollCount = 0\r\n\r\n/** 心跳定时器 */\r\nlet heartbeatTimer: ReturnType<typeof setInterval> | null = null\r\n\r\n/** 轮询间隔(毫秒) */\r\nconst POLL_INTERVAL = 2000\r\n\r\n/** 轮询最大次数(2秒 × 45次 = 90秒超时;覆盖容器创建+引擎就绪的完整启动窗口) */\r\nconst POLL_MAX_COUNT = 45\r\n\r\n/** 心跳间隔(毫秒,5分钟) */\r\nconst HEARTBEAT_INTERVAL = 5 * 60 * 1000\r\n\r\n/** 提取不含 token 的基础 URL,用于比对是否只有 token 刷新 */\r\nfunction getBaseUrl(url: string): string {\r\n if (!url) return ''\r\n try {\r\n const u = new URL(url)\r\n u.searchParams.delete('token')\r\n return u.toString()\r\n } catch {\r\n return url\r\n }\r\n}\r\n\r\n// ==================== Actions(直接调用请求地址) ====================\r\n\r\n/**\r\n * 启动执行环境\r\n */\r\nasync function startEnv(): Promise<EnvironmentStatusResult> {\r\n loading.value = true\r\n try {\r\n const res = await props.request.post<EnvironmentStatusResult>('/app-conversation/start-environment', {\r\n appCode: props.appCode,\r\n // appConfig 配置了 projectId 时携带(dynamic_project 模式后端必需)\r\n ...(appProjectId.value ? { projectId: appProjectId.value } : {})\r\n })\r\n if (res.status !== environmentStatus.value) {\r\n environmentStatus.value = res.status\r\n }\r\n if (res.environmentId && res.environmentId !== environmentId.value) {\r\n environmentId.value = res.environmentId\r\n }\r\n if (res.proxyUrl && res.proxyUrl !== proxyUrl.value) {\r\n proxyUrl.value = res.proxyUrl\r\n }\r\n return res\r\n } finally {\r\n loading.value = false\r\n }\r\n}\r\n\r\n/**\r\n * 查询环境状态(兼心跳保活)\r\n */\r\nasync function queryStatus(): Promise<void> {\r\n try {\r\n // silent: 状态轮询为后台尽力而为查询。环境启动窗口期后端可能返回瞬时的\r\n // 系统内部错误(如 10001),属预期暂态:宿主请求层应对其静默(不弹全局提示),\r\n // 本组件捕获后保持当前状态继续轮询,直至环境就绪。\r\n const res = await props.request.get<EnvironmentStatusResult>('/app-conversation/environment-status', {\r\n appCode: props.appCode\r\n }, { silent: true })\r\n if (res.status !== environmentStatus.value) {\r\n environmentStatus.value = res.status\r\n }\r\n if (res.environmentId && res.environmentId !== environmentId.value) {\r\n environmentId.value = res.environmentId\r\n }\r\n if (res.proxyUrl && res.proxyUrl !== proxyUrl.value) {\r\n proxyUrl.value = res.proxyUrl\r\n }\r\n } catch {\r\n // 查询失败静默处理,保持当前状态\r\n }\r\n}\r\n\r\n/**\r\n * 停止执行环境\r\n */\r\nasync function stopEnv(): Promise<void> {\r\n loading.value = true\r\n try {\r\n await props.request.post<null>('/app-conversation/stop-environment', {\r\n appCode: props.appCode\r\n })\r\n environmentStatus.value = 'stopped'\r\n } finally {\r\n loading.value = false\r\n }\r\n}\r\n\r\n/**\r\n * 销毁执行环境(销毁容器并重置 session,下次启动将创建全新容器)\r\n */\r\nasync function destroyEnv(): Promise<void> {\r\n loading.value = true\r\n try {\r\n await props.request.post<null>('/app-conversation/destroy-environment', {\r\n appCode: props.appCode\r\n })\r\n environmentStatus.value = 'not_exist'\r\n proxyUrl.value = ''\r\n environmentId.value = ''\r\n } finally {\r\n loading.value = false\r\n }\r\n}\r\n\r\n/**\r\n * 获取会话信息\r\n *\r\n * @returns 会话信息,失败时返回 undefined\r\n */\r\nasync function fetchSessionInfo(): Promise<SessionInfoResult | undefined> {\r\n try {\r\n // silent: 会话信息为补偿性查询(昵称/会话ID回填),启动窗口期可能瞬时失败,\r\n // 由宿主请求层静默处理,组件捕获后返回 undefined,待环境就绪后再补拉。\r\n const res = await props.request.get<SessionInfoResult>('/app-conversation/session-info', {\r\n appCode: props.appCode\r\n }, { silent: true })\r\n if (res.sessionId !== sessionId.value) {\r\n sessionId.value = res.sessionId\r\n }\r\n if (res.proxyUrl !== proxyUrl.value) {\r\n proxyUrl.value = res.proxyUrl\r\n }\r\n if (res.agentNickname !== agentNickname.value) {\r\n agentNickname.value = res.agentNickname\r\n }\r\n if (res.environmentId !== environmentId.value) {\r\n environmentId.value = res.environmentId\r\n }\r\n if (res.appCode && res.appCode !== appCode.value) {\r\n appCode.value = res.appCode\r\n }\r\n if (res.environmentStatus !== environmentStatus.value) {\r\n environmentStatus.value = res.environmentStatus\r\n }\r\n return res\r\n } catch {\r\n // 获取会话信息失败静默处理\r\n return undefined\r\n }\r\n}\r\n\r\n/**\r\n * 启动轮询(2秒间隔,60秒超时)\r\n */\r\nfunction startPolling(): void {\r\n stopPolling()\r\n pollCount = 0\r\n pollTimer = setInterval(async () => {\r\n pollCount++\r\n if (pollCount > POLL_MAX_COUNT) {\r\n // 到达轮询预算:先做最后一次状态确认再判定,避免环境刚就绪(启动窗口\r\n // 末尾查询仍在瞬时失败)时被误判为 start_failed\r\n await queryStatus()\r\n if (environmentStatus.value === 'running') {\r\n stopPolling()\r\n startHeartbeat()\r\n if (!agentNickname.value) {\r\n // 启动窗口期补拉会话信息失败的兜底:环境就绪后回填昵称/会话ID\r\n fetchSessionInfo()\r\n }\r\n return\r\n }\r\n // 超时:停止轮询,标记启动失败(可由用户手动重新启动)\r\n stopPolling()\r\n environmentStatus.value = 'start_failed'\r\n return\r\n }\r\n await queryStatus()\r\n if (environmentStatus.value === 'running') {\r\n // 环境就绪:停止轮询,启动心跳\r\n stopPolling()\r\n startHeartbeat()\r\n if (!agentNickname.value) {\r\n // 启动窗口期 fetchSessionInfo 可能因瞬时错误被跳过,就绪后补拉一次\r\n fetchSessionInfo()\r\n }\r\n } else if (environmentStatus.value === 'start_failed') {\r\n // 启动失败:停止轮询\r\n stopPolling()\r\n }\r\n }, POLL_INTERVAL)\r\n}\r\n\r\n/**\r\n * 停止轮询\r\n */\r\nfunction stopPolling(): void {\r\n if (pollTimer !== null) {\r\n clearInterval(pollTimer)\r\n pollTimer = null\r\n }\r\n pollCount = 0\r\n}\r\n\r\n/**\r\n * 启动心跳(5分钟间隔)\r\n */\r\nfunction startHeartbeat(): void {\r\n stopHeartbeat()\r\n heartbeatTimer = setInterval(async () => {\r\n // 仅在页面可见时发送心跳\r\n if (document.visibilityState === 'visible') {\r\n await queryStatus()\r\n }\r\n }, HEARTBEAT_INTERVAL)\r\n}\r\n\r\n/**\r\n * 停止心跳\r\n */\r\nfunction stopHeartbeat(): void {\r\n if (heartbeatTimer !== null) {\r\n clearInterval(heartbeatTimer)\r\n heartbeatTimer = null\r\n }\r\n}\r\n\r\n/**\r\n * 重置所有状态并清理定时器\r\n */\r\nfunction resetState(): void {\r\n stopPolling()\r\n stopHeartbeat()\r\n environmentStatus.value = 'not_exist'\r\n sessionId.value = ''\r\n proxyUrl.value = ''\r\n agentNickname.value = ''\r\n environmentId.value = ''\r\n appCode.value = ''\r\n loading.value = false\r\n}\r\n\r\n// ==================== iframe 监控逻辑(保持原样) ====================\r\n\r\nwatch(\r\n [() => environmentStatus.value, () => proxyUrl.value],\r\n ([newStatus, newUrl], [oldStatus, oldUrl]) => {\r\n if (!newUrl || newStatus !== 'running') {\r\n iframeSrc.value = ''\r\n displayedIframeSrc.value = ''\r\n stopLoadMonitoring()\r\n clearTimers()\r\n return\r\n }\r\n // 仅在运行状态且基础 URL 变化(非 token 刷新)时才更新 iframe\r\n if (getBaseUrl(newUrl) !== getBaseUrl(oldUrl || '')) {\r\n const freshStart = oldStatus === 'starting'\r\n updateIframeSrc(newUrl, freshStart)\r\n }\r\n },\r\n { immediate: true }\r\n)\r\n\r\nwatch(\r\n () => environmentStatus.value,\r\n (newStatus, oldStatus) => {\r\n // 重启等场景下 proxyUrl 基础地址可能未变,需要单独监听 running 强制刷新\r\n if (newStatus === 'running' && oldStatus === 'starting') {\r\n const url = proxyUrl.value\r\n if (!url) return\r\n // iframeSrc 为空(重启后 reset 清空)或基础地址相同时,均需强制加载\r\n if (!iframeSrc.value || getBaseUrl(url) === getBaseUrl(iframeSrc.value)) {\r\n updateIframeSrc(url, true)\r\n }\r\n }\r\n }\r\n)\r\n\r\n/**\r\n * 启动环境\r\n */\r\nasync function handleStart() {\r\n // /aisys 直接访问上下文:不执行环境启动接口\r\n if (isAisysContext.value) return\r\n // 防止重复调用:loading 中或已在 running/starting 状态时直接忽略\r\n if (loading.value) return\r\n const currentStatus = environmentStatus.value\r\n if (currentStatus === 'running' || currentStatus === 'starting') return\r\n\r\n // start_failed 状态时,先查一次真实状态:\r\n // 容器可能已成功启动但前端因接口超时等原因误显了 start_failed\r\n if (currentStatus === 'start_failed') {\r\n await queryStatus()\r\n const refreshedStatus = environmentStatus.value\r\n if (refreshedStatus === 'running') {\r\n // 容器已在运行,启动心跳即可\r\n startHeartbeat()\r\n return\r\n }\r\n if (refreshedStatus === 'starting') {\r\n // 已在启动中,开始轮询即可\r\n startPolling()\r\n return\r\n }\r\n }\r\n\r\n try {\r\n await startEnv()\r\n // 启动成功后补查会话信息(首次启动时 fetchSessionInfo 因会话不存在被跳过,此处补偿)\r\n if (!agentNickname.value) {\r\n fetchSessionInfo()\r\n }\r\n // 启动成功后如果状态为 starting,开启轮询\r\n if (environmentStatus.value === 'starting') {\r\n startPolling()\r\n } else if (environmentStatus.value === 'running') {\r\n // 直接变为 running,启动心跳\r\n startHeartbeat()\r\n }\r\n } catch (err: any) {\r\n // 环境数量超限:弹出运行中环境列表,用户关闭后可自动重试\r\n if (err?.code === 23010) {\r\n envLimitDialogVisible.value = true\r\n return\r\n }\r\n // 其他接口错误已由宿主 request 统一处理\r\n }\r\n}\r\n\r\n/**\r\n * 环境数量超限弹窗关闭环境后重试启动\r\n */\r\nasync function handleEnvClosedAndRetry() {\r\n // 等待一小段时间让后端状态同步完成\r\n await new Promise((resolve) => setTimeout(resolve, 500))\r\n await handleStart()\r\n}\r\n\r\n/**\r\n * 停止环境(确认交互由外层标题栏负责)\r\n *\r\n * @returns 是否停止成功\r\n */\r\nasync function stop(): Promise<boolean> {\r\n // /aisys 直接访问上下文:不执行环境停止接口\r\n if (isAisysContext.value) return false\r\n // 立即切换到停止中状态,让 UI 即时响应\r\n environmentStatus.value = 'stopping'\r\n // 清理轮询、心跳、加载监控与定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n stopLoadMonitoring()\r\n clearTimers()\r\n try {\r\n await stopEnv()\r\n return true\r\n } catch {\r\n // 接口错误已由宿主请求统一处理,回退状态为 running\r\n environmentStatus.value = 'running'\r\n return false\r\n }\r\n}\r\n\r\n/**\r\n * 解析当前会话的智能体ID(用于更新智能体等需要 appCode 的操作)\r\n */\r\nasync function resolveAgentId(): Promise<string | undefined> {\r\n // 尝试获取 appCode:优先使用已缓存的,否则重新查询会话信息\r\n let resolved = appCode.value || effectiveAgentId.value\r\n if (!resolved) {\r\n // 会话信息可能因初始化时序未成功获取,此处补查一次\r\n await fetchSessionInfo()\r\n resolved = appCode.value || effectiveAgentId.value\r\n }\r\n return resolved || undefined\r\n}\r\n\r\n/**\r\n * 手动刷新 iframe(附加随机参数强制重新加载)\r\n */\r\nfunction refresh() {\r\n const url = iframeSrc.value\r\n if (!url) return\r\n stopLoadMonitoring()\r\n retryCount = 0\r\n const separator = url.includes('?') ? '&' : '?'\r\n displayedIframeSrc.value = `${url}${separator}_refresh=${Date.now()}`\r\n startLoadMonitoring(displayedIframeSrc.value)\r\n}\r\n\r\n/**\r\n * iframe 加载完成\r\n */\r\nfunction onIframeLoad() {\r\n handleLoadSuccess()\r\n}\r\n\r\n/**\r\n * iframe 加载失败\r\n */\r\nfunction onIframeError() {\r\n handleLoadFailure('network')\r\n}\r\n\r\n/**\r\n * 标记加载成功:停止监控、取消超时、重置重试计数\r\n */\r\nfunction handleLoadSuccess() {\r\n if (!isWaitingLoadSuccess) return\r\n stopLoadMonitoring()\r\n retryCount = 0\r\n}\r\n\r\n// ==================== 域名探测与加载监控机制(保持原样) ====================\r\n\r\nfunction buildTestUrl(url: string): string {\r\n try {\r\n const u = new URL(url)\r\n u.pathname = '/test'\r\n u.search = ''\r\n u.hash = ''\r\n return u.toString()\r\n } catch {\r\n const base = url.split('?')[0].split('#')[0]\r\n return `${base.replace(/\\/+$/, '')}/test`\r\n }\r\n}\r\n\r\nasync function probeTargetUrl(url: string): Promise<boolean> {\r\n try {\r\n const testUrl = buildTestUrl(url)\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), 5000)\r\n const res = await fetch(testUrl, {\r\n method: 'HEAD',\r\n mode: 'cors',\r\n cache: 'no-cache',\r\n signal: controller.signal,\r\n })\r\n clearTimeout(timeoutId)\r\n return res.status === 200\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nasync function ensureTargetReachableThenLoad(url: string, attempt = 0) {\r\n if (await probeTargetUrl(url)) {\r\n setIframeSrcAndMonitor(url)\r\n return\r\n }\r\n\r\n if (attempt < MAX_RETRY_COUNT) {\r\n retryTimer = setTimeout(() => {\r\n ensureTargetReachableThenLoad(url, attempt + 1)\r\n }, 100)\r\n } else {\r\n setIframeSrcAndMonitor(url)\r\n }\r\n}\r\n\r\nfunction setIframeSrcAndMonitor(url: string) {\r\n iframeSrc.value = url\r\n displayedIframeSrc.value = url\r\n startLoadMonitoring(url)\r\n}\r\n\r\nfunction updateIframeSrc(url: string, delay: boolean) {\r\n stopLoadMonitoring()\r\n clearTimers()\r\n retryCount = 0\r\n\r\n if (delay) {\r\n delayTimer = setTimeout(() => {\r\n ensureTargetReachableThenLoad(url)\r\n delayTimer = null\r\n }, 1500)\r\n } else {\r\n ensureTargetReachableThenLoad(url)\r\n }\r\n}\r\n\r\nfunction clearTimers() {\r\n if (retryTimer) {\r\n clearTimeout(retryTimer)\r\n retryTimer = null\r\n }\r\n if (delayTimer) {\r\n clearTimeout(delayTimer)\r\n delayTimer = null\r\n }\r\n if (loadTimeout) {\r\n clearTimeout(loadTimeout)\r\n loadTimeout = null\r\n }\r\n}\r\n\r\nfunction startLoadMonitoring(url: string) {\r\n stopLoadMonitoring()\r\n if (!window.PerformanceObserver) {\r\n startLoadTimeout(url)\r\n return\r\n }\r\n\r\n isWaitingLoadSuccess = true\r\n\r\n try {\r\n perfObserver = new PerformanceObserver((list) => {\r\n for (const entry of list.getEntries()) {\r\n const resEntry = entry as PerformanceResourceTiming\r\n if (entry.name !== url && entry.name !== displayedIframeSrc.value) continue\r\n\r\n const status = resEntry.responseStatus\r\n\r\n // 仅处理明确的 502 错误(跨域时 status 始终为 0,不可作为失败判据)\r\n if (status === 502) {\r\n handleLoadFailure('502')\r\n return\r\n }\r\n\r\n // 加载成功(仅同域或设置了 Timing-Allow-Origin 时有效)\r\n if (status >= 200 && status < 400) {\r\n handleLoadSuccess()\r\n }\r\n }\r\n })\r\n perfObserver.observe({ type: 'resource', buffered: true })\r\n } catch {\r\n // 浏览器不支持 PerformanceObserver 时静默忽略\r\n }\r\n\r\n startLoadTimeout(url)\r\n}\r\n\r\nfunction stopLoadMonitoring() {\r\n if (perfObserver) {\r\n perfObserver.disconnect()\r\n perfObserver = null\r\n }\r\n if (loadTimeout) {\r\n clearTimeout(loadTimeout)\r\n loadTimeout = null\r\n }\r\n isWaitingLoadSuccess = false\r\n}\r\n\r\nfunction startLoadTimeout(_url: string) {\r\n loadTimeout = setTimeout(() => {\r\n if (isWaitingLoadSuccess) {\r\n handleLoadFailure('timeout')\r\n }\r\n }, 15000)\r\n}\r\n\r\nfunction handleLoadFailure(reason: '502' | 'network' | 'timeout') {\r\n if (!isWaitingLoadSuccess) return\r\n stopLoadMonitoring()\r\n\r\n retryCount++\r\n if (retryCount > MAX_RETRY_COUNT) {\r\n ElMessage.error('应用加载失败,请刷新页面重试')\r\n return\r\n }\r\n\r\n const reasonText = reason === 'network'\r\n ? '网络错误'\r\n : reason === 'timeout'\r\n ? '加载超时'\r\n : '应用暂不可用'\r\n console.warn(`[ConversationSession] 加载失败: ${reasonText}, 第 ${retryCount} 次重试`)\r\n\r\n retryTimer = setTimeout(() => {\r\n if (!iframeSrc.value) return\r\n const separator = iframeSrc.value.includes('?') ? '&' : '?'\r\n displayedIframeSrc.value = `${iframeSrc.value}${separator}_retry=${Date.now()}`\r\n startLoadMonitoring(displayedIframeSrc.value)\r\n }, 1000)\r\n}\r\n\r\n// ==================== 页面可见性监听 ====================\r\n\r\nfunction handleVisibilityChange() {\r\n if (document.visibilityState === 'visible' && status.value === 'running') {\r\n // 页面恢复可见时,立即查询一次状态保活\r\n queryStatus()\r\n }\r\n}\r\n\r\n// ==================== 生命周期 ====================\r\n\r\nonMounted(async () => {\r\n // /aisys 直接访问上下文:不执行任何环境接口,仅展示引导提示\r\n if (isAisysContext.value) return\r\n\r\n // 监听页面可见性变化\r\n document.addEventListener('visibilitychange', handleVisibilityChange)\r\n\r\n // 查询当前环境状态\r\n await queryStatus()\r\n\r\n const st = environmentStatus.value\r\n if (st === 'not_exist' || st === 'stopped') {\r\n // 会话尚未创建,先启动环境,fetchSessionInfo 由 handleStart 成功后补调\r\n handleStart()\r\n } else {\r\n // 环境已存在,安全获取昵称\r\n await fetchSessionInfo()\r\n if (st === 'starting') {\r\n // 正在启动,开始轮询\r\n startPolling()\r\n } else if (st === 'running') {\r\n // 已在运行,启动心跳\r\n startHeartbeat()\r\n }\r\n }\r\n})\r\n\r\n/**\r\n * 重启会话:停止当前环境 → 重置状态 → 重新启动\r\n */\r\nasync function restart() {\r\n // /aisys 直接访问上下文:不执行环境重启\r\n if (isAisysContext.value) return\r\n // 立即切换到停止中,让 UI 及时响应\r\n const originalStatus = environmentStatus.value\r\n environmentStatus.value = 'stopping'\r\n\r\n // 清理旧环境的轮询、心跳、加载监控与定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n stopLoadMonitoring()\r\n clearTimers()\r\n\r\n // 如果当前环境正在运行或已启动,先停止\r\n if (originalStatus === 'running' || originalStatus === 'starting') {\r\n try {\r\n await stopEnv()\r\n } catch {\r\n // 停止失败不阻塞重启流程\r\n }\r\n }\r\n\r\n // 重置状态\r\n resetState()\r\n // 立即切换到启动中,避免内容区闪现\"环境未启动\"\r\n environmentStatus.value = 'starting'\r\n\r\n // 直接调用启动,绕过 handleStart 的状态守卫(因为已手动设置 starting)\r\n try {\r\n await startEnv()\r\n // 重新启动后重新获取昵称(reset 已清空)\r\n fetchSessionInfo()\r\n if (environmentStatus.value === 'starting') {\r\n startPolling()\r\n } else if (environmentStatus.value === 'running') {\r\n startHeartbeat()\r\n }\r\n } catch {\r\n // 接口错误已由宿主请求统一处理\r\n }\r\n}\r\n\r\n/**\r\n * 重建会话:销毁当前容器 → 重置状态 → 创建全新环境\r\n */\r\nasync function rebuild() {\r\n // /aisys 直接访问上下文:不执行环境重建\r\n if (isAisysContext.value) return\r\n // 立即切换到停止中,让 UI 及时响应\r\n environmentStatus.value = 'stopping'\r\n\r\n // 清理旧环境的轮询、心跳、加载监控与定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n stopLoadMonitoring()\r\n clearTimers()\r\n\r\n // 销毁当前环境(容器销毁 + session 重置为 not_exist)\r\n try {\r\n await destroyEnv()\r\n } catch {\r\n // 销毁失败不阻塞后续启动流程\r\n }\r\n\r\n // 重置全部状态\r\n resetState()\r\n // 立即切换到启动中,避免内容区闪现\"环境未启动\"\r\n environmentStatus.value = 'starting'\r\n\r\n // 创建全新环境\r\n try {\r\n await startEnv()\r\n fetchSessionInfo()\r\n if (environmentStatus.value === 'starting') {\r\n startPolling()\r\n } else if (environmentStatus.value === 'running') {\r\n startHeartbeat()\r\n }\r\n } catch {\r\n // 接口错误已由宿主请求统一处理\r\n }\r\n}\r\n\r\n/**\r\n * 向 dsh 内部(iframe 沙箱)抛出一个事件。\r\n *\r\n * 供外层宿主(ConversationPanel 经 dsh-bridge)把提示词注入等事件投递给 dsh。\r\n * 消息协议与 dsh 插件保持一致:{ target: 'dsh', type, payload }。\r\n *\r\n * @param type - 事件类型(如 prompt:inject)。\r\n * @param payload - 事件载荷。\r\n */\r\nfunction postDshEvent(type: string, payload: unknown) {\r\n const win = iframeRef.value?.contentWindow\r\n if (win) {\r\n win.postMessage({ target: 'dsh', type, payload }, '*')\r\n }\r\n}\r\n\r\n// ==================== 对外暴露 ====================\r\n\r\ndefineExpose({ start: handleStart, stop, restart, rebuild, refresh, resolveAgentId, postDshEvent })\r\n\r\nonUnmounted(() => {\r\n // 清理轮询和心跳定时器\r\n stopPolling()\r\n stopHeartbeat()\r\n // 移除页面可见性监听\r\n document.removeEventListener('visibilitychange', handleVisibilityChange)\r\n // 停止加载监控与定时器\r\n stopLoadMonitoring()\r\n clearTimers()\r\n // 重置状态\r\n resetState()\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.conversation-session {\r\n flex: 1;\r\n min-width: 0;\r\n overflow: hidden;\r\n margin: 8px 8px 8px 0;\r\n border-radius: 4px;\r\n background: #F8FBFC;\r\n}\r\n\r\n/* 占位状态 */\r\n.status-placeholder {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--el-text-color-secondary);\r\n font-size: var(--text-meta);\r\n}\r\n\r\n.status-placeholder p {\r\n margin-top: var(--space-4);\r\n color: var(--el-text-color-secondary);\r\n}\r\n\r\n/* iframe 容器 */\r\n.iframe-container {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.conversation-iframe {\r\n width: 100%;\r\n height: 100%;\r\n border: none;\r\n}\r\n\r\n/* 环境数量超限弹窗(合并自 EnvironmentLimitDialog) */\r\n.env-limit-dialog__tip {\r\n margin-bottom: var(--space-4);\r\n color: var(--el-text-color-regular);\r\n font-size: var(--el-font-size-base);\r\n}\r\n\r\n.env-limit-dialog :deep(.el-table__body-wrapper) {\r\n overflow-x: hidden;\r\n}\r\n</style>","/**\n * @duxi999/usdp-eacp-conversation 组件库入口\n *\n * 导出对话会话组件(已合并环境超限弹窗)以及共享类型。\n * request 对象由宿主应用通过 props 注入,组件内部直接调用请求地址。\n */\n\nimport type { App } from 'vue'\nimport ConversationSession from './components/UsdpEacpConversation.vue'\n\n// ==================== 组件 ====================\n\nexport { ConversationSession }\n\n// ==================== 共享类型 ====================\n\nexport type {\n EnvironmentStatus,\n SceneType,\n EnvironmentParams,\n EnvironmentStatusResult,\n SessionInfoResult,\n RunningEnvironmentItem,\n BatchStopResult,\n RequestAdapter,\n RequestOptions,\n} from './types'\n\n// ==================== 组件库插件(可选,支持 app.use 全局注册) ====================\n\n/** 全局注册使用的组件名(与包名 usdp-eacp-conversation 一致,模板中可写 <usdp-eacp-conversation>) */\nconst REGISTERED_NAME = 'usdp-eacp-conversation'\n\nexport default {\n install(app: App) {\n // 以包名注册,便于模板中使用 <usdp-eacp-conversation>\n app.component(REGISTERED_NAME, ConversationSession)\n // 同时注册 PascalCase 与 camelCase 变体,兼容不同书写习惯\n app.component('UsdpEacpConversation', ConversationSession)\n },\n}\n\nexport type ConversationSessionInstance = InstanceType<typeof ConversationSession>"],"names":["MAX_RETRY_COUNT","POLL_INTERVAL","POLL_MAX_COUNT","HEARTBEAT_INTERVAL","props","__props","emit","__emit","effectiveAgentId","computed","appProjectId","cfg","obj","pid","pidStr","isAisysContext","ref","environmentStatus","sessionId","proxyUrl","agentNickname","environmentId","appCode","loading","status","currentAgentId","watch","st","nickname","agentIdVal","envLimitDialogVisible","SCENE_TYPE_LABELS","envLimitLoading","envLimitClosing","runningEnvironments","selectedEnvItems","envLimitTableRef","formatTime","time","loadRunningEnvironments","ElMessage","val","handleEnvSelectionChange","rows","handleCloseEnvironments","environments","item","result","handleEnvClosedAndRetry","iframeSrc","iframeRef","displayedIframeSrc","retryCount","retryTimer","delayTimer","perfObserver","loadTimeout","isWaitingLoadSuccess","pollTimer","pollCount","heartbeatTimer","getBaseUrl","url","u","startEnv","res","queryStatus","stopEnv","destroyEnv","fetchSessionInfo","startPolling","stopPolling","startHeartbeat","stopHeartbeat","resetState","newStatus","newUrl","oldStatus","oldUrl","stopLoadMonitoring","clearTimers","updateIframeSrc","handleStart","currentStatus","refreshedStatus","err","resolve","stop","resolveAgentId","resolved","refresh","separator","startLoadMonitoring","onIframeLoad","handleLoadSuccess","onIframeError","handleLoadFailure","buildTestUrl","probeTargetUrl","testUrl","controller","timeoutId","ensureTargetReachableThenLoad","attempt","setIframeSrcAndMonitor","delay","startLoadTimeout","list","entry","resEntry","_url","reason","handleVisibilityChange","onMounted","restart","originalStatus","rebuild","postDshEvent","type","payload","win","_a","__expose","onUnmounted","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_createVNode","_component_el_result","_component_el_text","_cache","_hoisted_3","_component_el_empty","_component_el_button","_hoisted_4","_component_el_icon","_unref","Loading","_createElementVNode","_toDisplayString","_hoisted_5","_hoisted_6","_hoisted_8","_hoisted_9","_component_el_dialog","$event","_hoisted_10","_createBlock","_component_el_table","_component_el_table_column","_withCtx","row","_createTextVNode","REGISTERED_NAME","index","app","ConversationSession"],"mappings":"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"}
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- .conversation-session[data-v-f0ca27ea]{flex:1;min-width:0;overflow:hidden;margin:8px 8px 8px 0;border-radius:4px;background:#f8fbfc}.status-placeholder[data-v-f0ca27ea]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--el-text-color-secondary);font-size:var(--text-meta)}.status-placeholder p[data-v-f0ca27ea]{margin-top:var(--space-4);color:var(--el-text-color-secondary)}.iframe-container[data-v-f0ca27ea]{width:100%;height:100%}.conversation-iframe[data-v-f0ca27ea]{width:100%;height:100%;border:none}.env-limit-dialog__tip[data-v-f0ca27ea]{margin-bottom:var(--space-4);color:var(--el-text-color-regular);font-size:var(--el-font-size-base)}.env-limit-dialog[data-v-f0ca27ea] .el-table__body-wrapper{overflow-x:hidden}
1
+ .conversation-session[data-v-ad448334]{flex:1;min-width:0;overflow:hidden;margin:8px 8px 8px 0;border-radius:4px;background:#f8fbfc}.status-placeholder[data-v-ad448334]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--el-text-color-secondary);font-size:var(--text-meta)}.status-placeholder p[data-v-ad448334]{margin-top:var(--space-4);color:var(--el-text-color-secondary)}.iframe-container[data-v-ad448334]{width:100%;height:100%}.conversation-iframe[data-v-ad448334]{width:100%;height:100%;border:none}.env-limit-dialog__tip[data-v-ad448334]{margin-bottom:var(--space-4);color:var(--el-text-color-regular);font-size:var(--el-font-size-base)}.env-limit-dialog[data-v-ad448334] .el-table__body-wrapper{overflow-x:hidden}