window.dash_clientside = Object.assign({}, window.dash_clientside, { clientside: { // 处理全屏切换 handleChatContainerFullscreen: (nClicks, icon) => { return [ icon === 'antd-full-screen' ? 'antd-full-screen-exit' : 'antd-full-screen', ( icon === 'antd-full-screen' ? { width: '100vw', height: '100vh' } : { width: '90vw', height: '90vh', maxWidth: 1200, borderRadius: 16, border: '1px solid #dedede' } ) ]; }, handleOperationButtonGroupVisible: (isHovering, originStyle) => { if (isHovering) { delete (originStyle.transform) return { ...originStyle, opacity: 1, transform: 'scale(1) translateY(0)' } } return { ...originStyle, opacity: 0, transform: 'scale(0.8) translateY(10px)' } }, handleUserNewMessageSend: (_, __, ___, value) => { if (!value) { return window.dash_clientside.no_update; } if (window.dash_clientside.callback_context.triggered_id === 'shift-enter-keypress') { return [ window.dash_clientside.no_update, `${value}\n` ] } window.dash_clientside.set_props('input-text', { disabled: true }) window.dash_clientside.set_props('send-input-text', { loading: true }) return [ value, '' ]; }, handleUserNewMessageSend1: (_, __, ___, value) => { if (!value) { return window.dash_clientside.no_update; } if (window.dash_clientside.callback_context.triggered_id === 'shift-enter-keypress') { return [ window.dash_clientside.no_update, `${value}\n` ] } window.dash_clientside.set_props('input-text1', { disabled: true }) // window.dash_clientside.set_props('send-input-text1', { loading: true }) return [ value, '' ]; }, handleStreamResponse: (data, markdownStr) => { if (data) { data = JSON.parse(data) if (['<无效问题>', '<回复结束>', '<频率限制>', '<连接失败>', '<鉴权错误>', '<系统错误>'].includes(data.type)) { window.dash_clientside.set_props('input-text', { disabled: false }) window.dash_clientside.set_props('send-input-text', { loading: false }) window.dash_clientside.set_props('input-text1', { disabled: false }) // window.dash_clientside.set_props('send-input-text1', { loading: false }) if (data.type === "<无效问题>") { return [ null, { namespace: 'feffery_antd_components', type: 'AntdAlert', props: { type: 'info', message: data.content, showIcon: true } } ] } else if (data.type === "<回复结束>") { return [data.content.replaceAll("<换行符>", "\n"), null]; } return [ null, { namespace: 'feffery_antd_components', type: 'AntdAlert', props: { type: 'warning', message: data.type, description: data.content, showIcon: true } } ] } else { return [ markdownStr + data.content.replaceAll("<换行符>", "\n"), null ]; } } return window.dash_clientside.no_update; }, handleChatAreaScroll: (height, checked) => { if (checked) { let scrollTarget = document.getElementById('chat-area') scrollTarget.scrollTo({ top: scrollTarget.scrollHeight }); } }, handleChatAreaToTopBottom: (nClicksTop, nClicksBottom) => { let scrollTarget = document.getElementById('chat-area') if (window.dash_clientside.callback_context.triggered_id === 'chat-area-to-top') { scrollTarget.scrollTo({ top: 0 }); } else { scrollTarget.scrollTo({ top: scrollTarget.scrollHeight }); } }, handleAssistantOutputStop: (nClicks) => { window.dash_clientside.set_props('input-text', { disabled: false }) window.dash_clientside.set_props('send-input-text', { loading: false }) window.dash_clientside.set_props('input-text1', { disabled: false }) // window.dash_clientside.set_props('send-input-text1', { loading: false }) return 'close' }, handleAssistantOutputRetry: (nClicks) => { window.dash_clientside.set_props('input-text', { disabled: true }) window.dash_clientside.set_props('send-input-text', { loading: true }) return ['', null, Date.now().toString()] }, handleAssistantOutputCopy: (nClicks, jsonData) => { if (typeof jsonData === 'object') { jsonData = JSON.stringify(jsonData, null, 2); } navigator.clipboard.writeText(jsonData).then(() => { window.dash_clientside.set_props( 'global-message', { children: { namespace: 'feffery_antd_components', type: 'AntdMessage', props: { content: '复制成功!', type: 'success' } } } ) }).catch(err => { console.error('复制失败:', err); }); return window.dash_clientside.no_update; }, // ER 图渲染 renderER: (nClicks, inputValue) => { const { Graph, Shape } = window.X6; const LINE_HEIGHT = 24; const NODE_WIDTH = 150; let dpath = ""; if (inputValue == '资讯域') { dpath = '/assets/json/mder.json'; } else if (inputValue == '客户域') { dpath = '/assets/json/er.json'; } Graph.registerPortLayout( 'erPortPosition', (portsPositionArgs) => { return portsPositionArgs.map((_, index) => { return { position: { x: 0, y: (index + 1) * LINE_HEIGHT, }, angle: 0, } }) }, true, ) Graph.registerNode( 'er-rect', { inherit: 'rect', markup: [ { tagName: 'rect', selector: 'body' }, { tagName: 'text', selector: 'label' }, ], attrs: { rect: { strokeWidth: 1, stroke: '#5F95FF', fill: '#5F95FF', }, label: { fontWeight: 'bold', fill: '#ffffff', fontSize: 12, }, }, ports: { groups: { list: { markup: [ { tagName: 'rect', selector: 'portBody' }, { tagName: 'text', selector: 'portNameLabel' }, { tagName: 'text', selector: 'portTypeLabel' }, ], attrs: { portBody: { width: NODE_WIDTH, height: LINE_HEIGHT, strokeWidth: 1, stroke: '#5F95FF', fill: '#EFF4FF', magnet: true, }, portNameLabel: { refX: 6, refY: 6, fontSize: 10 }, portTypeLabel: { refX: 95, refY: 6, fontSize: 10 }, }, position: 'erPortPosition', }, }, }, }, true, ) const graph = new Graph({ container: document.getElementById('er-container'), mousewheel: { enabled: true, zoomAtMousePosition: true, modifiers: 'ctrl', minScale: 0.5, maxScale: 3 }, panning: { enabled: true, eventTypes: ['leftMouseDown', 'mouseWheel'] }, connecting: { router: { name: 'er', args: { offset: 25, direction: 'H' } }, createEdge() { return new Shape.Edge({ attrs: { line: { stroke: '#A2B1C3', strokeWidth: 2 } } }) } }, }); const savedGraphData = localStorage.getItem('savedGraphData'); if (savedGraphData) { graph.fromJSON(JSON.parse(savedGraphData)); graph.zoomToFit({ padding: 10, maxScale: 1 }); } else { const fetchData = inputValue == '资讯域' ? '/assets/json/zxmder.json' : '/assets/json/khmder.json'; fetch(fetchData) .then((response) => response.json()) .then((data) => { graph.fromJSON(data); graph.zoomToFit({ padding: 10, maxScale: 1 }); }); } } } });