mirror of
https://github.com/jumpserver/lina.git
synced 2025-11-19 23:29:07 +00:00
Compare commits
4 Commits
pr@dev@k8s
...
perf_termi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4917212fff | ||
|
|
d84a7c824b | ||
|
|
56f4f3f144 | ||
|
|
fea1d35981 |
@@ -33,7 +33,7 @@
|
|||||||
<!-- eslint-disable-next-line -->
|
<!-- eslint-disable-next-line -->
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<p>
|
<p>
|
||||||
<MessageText :message="item.reasoning" />
|
<MessageText :message="item.reasoning" @insert-code="handleInsertCode" />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<span v-if="isServerError" class="error">
|
<span v-if="isServerError" class="error">
|
||||||
{{ isServerError }}
|
{{ isServerError }}
|
||||||
</span>
|
</span>
|
||||||
<MessageText :message="item.result" />
|
<MessageText :message="item.result" @insert-code="handleInsertCode" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -142,6 +142,9 @@ export default {
|
|||||||
if (value === 'copy') {
|
if (value === 'copy') {
|
||||||
copy(this.item.result.content)
|
copy(this.item.result.content)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handleInsertCode(code) {
|
||||||
|
this.$emit('insert-code', code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,26 +69,61 @@ export default {
|
|||||||
this.markdown.use(mdKatex, { blockClass: 'katexmath-block rounded-md', errorColor: ' #cc0000' })
|
this.markdown.use(mdKatex, { blockClass: 'katexmath-block rounded-md', errorColor: ' #cc0000' })
|
||||||
},
|
},
|
||||||
highlightBlock(str, lang) {
|
highlightBlock(str, lang) {
|
||||||
return `<pre class="code-block-wrapper"><div class="code-block-header"><span class="code-block-header__lang">${lang}</span><span class="code-block-header__copy">${'Copy'}</span></div><code class="hljs code-block-body ${lang}">${str}</code></pre>`
|
return `<pre class="code-block-wrapper">
|
||||||
|
<div class="code-block-header">
|
||||||
|
<span class="code-block-header__lang">${lang}</span>
|
||||||
|
<span class="code-block-header__actions">
|
||||||
|
<span class="code-block-header__insert">${'insert'}</span>
|
||||||
|
<span class="code-block-header__copy">${'Copy'}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<code class="hljs code-block-body ${lang}">${str}</code></pre>`
|
||||||
},
|
},
|
||||||
addCopyEvents() {
|
addCopyEvents() {
|
||||||
const copyBtn = document.querySelectorAll('.code-block-header__copy')
|
this.addBtnClickEvents('.code-block-header__copy', this.handlerClickCopy)
|
||||||
copyBtn.forEach((btn) => {
|
this.addBtnClickEvents('.code-block-header__insert', this.handlerClickInsert)
|
||||||
btn.addEventListener('click', () => {
|
},
|
||||||
const code = btn.parentElement?.nextElementSibling?.textContent
|
|
||||||
if (code) {
|
handlerClickCopy(event) {
|
||||||
copy(code)
|
const wrapper = event.target.closest('.code-block-wrapper')
|
||||||
|
if (wrapper) {
|
||||||
|
// 查找里面的 code 元素
|
||||||
|
const codeElement = wrapper.querySelector('code.code-block-body')
|
||||||
|
if (codeElement) {
|
||||||
|
const codeText = codeElement.textContent
|
||||||
|
copy(codeText)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlerClickInsert(event) {
|
||||||
|
const wrapper = event.target.closest('.code-block-wrapper')
|
||||||
|
if (wrapper) {
|
||||||
|
// 查找里面的 code 元素
|
||||||
|
const codeElement = wrapper.querySelector('code.code-block-body')
|
||||||
|
if (codeElement) {
|
||||||
|
const codeText = codeElement.textContent
|
||||||
|
console.log('insert code', codeText)
|
||||||
|
this.$emit('insert-code', codeText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addBtnClickEvents(selector, callback) {
|
||||||
|
const buttons = this.$refs.textRef.querySelectorAll(selector)
|
||||||
|
buttons.forEach((btn) => {
|
||||||
|
btn.addEventListener('click', callback)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
removeBtnClickEvent(selector) {
|
||||||
|
const buttons = this.$refs.textRef.querySelectorAll(selector)
|
||||||
|
buttons.forEach((btn) => {
|
||||||
|
btn.removeEventListener('click', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
removeCopyEvents() {
|
removeCopyEvents() {
|
||||||
if (this.$refs.textRef) {
|
if (this.$refs.textRef) {
|
||||||
const copyBtn = this.$refs.textRef.querySelectorAll('.code-block-header__copy')
|
this.removeBtnClickEvent('.code-block-header__copy')
|
||||||
copyBtn.forEach((btn) => {
|
this.addBtnClickEvents('.code-block-header__insert')
|
||||||
btn.removeEventListener('click', () => {
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,28 +150,48 @@ export default {
|
|||||||
|
|
||||||
&::v-deep .code-block-wrapper {
|
&::v-deep .code-block-wrapper {
|
||||||
background: #1F2329;
|
background: #1F2329;
|
||||||
padding: 2px 6px;
|
padding: 0;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
.code-block-body {
|
.code-block-body {
|
||||||
padding: 5px 10px 0;
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
;
|
|
||||||
|
|
||||||
.code-block-header {
|
.code-block-header {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #353946;
|
background: #353946;
|
||||||
color: #c2d1e1;
|
color: #c2d1e1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 4px 8px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.code-block-header__actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
.code-block-header__copy {
|
.code-block-header__copy {
|
||||||
float: right;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #6e747b;
|
color: #6e747b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.code-block-header__insert {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #6e747b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs.code-block-body.javascript {
|
.hljs.code-block-body.javascript {
|
||||||
@@ -178,6 +233,7 @@ export default {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ChatMessage v-for="(item, index) in activeChat.chats" :key="index" :item="item" />
|
<ChatMessage v-for="(item, index) in activeChat.chats" :key="index" :item="item" @insert-code="insertCode" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-box">
|
<div class="input-box">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -60,6 +60,10 @@ export default {
|
|||||||
expanded: {
|
expanded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
terminalContent: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -68,7 +72,8 @@ export default {
|
|||||||
prompt: '',
|
prompt: '',
|
||||||
conversationId: '',
|
conversationId: '',
|
||||||
showIntroduction: false,
|
showIntroduction: false,
|
||||||
introduction: []
|
introduction: [],
|
||||||
|
terminalContext: this.terminalContent || null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -204,7 +209,11 @@ export default {
|
|||||||
sendIntroduction(item) {
|
sendIntroduction(item) {
|
||||||
this.showIntroduction = false
|
this.showIntroduction = false
|
||||||
this.onSendHandle(item.content)
|
this.onSendHandle(item.content)
|
||||||
|
},
|
||||||
|
insertCode(code) {
|
||||||
|
console.log(' receive insertCode', code)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ export default {
|
|||||||
robotUrl: require('@/assets/img/robot-assistant.png'),
|
robotUrl: require('@/assets/img/robot-assistant.png'),
|
||||||
height: '400px',
|
height: '400px',
|
||||||
expanded: false,
|
expanded: false,
|
||||||
clientOffset: {}
|
clientOffset: {},
|
||||||
|
currentTerminalContent: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -89,6 +90,15 @@ export default {
|
|||||||
window.addEventListener('message', (event) => {
|
window.addEventListener('message', (event) => {
|
||||||
if (event.data === 'show-chat-panel') {
|
if (event.data === 'show-chat-panel') {
|
||||||
this.$refs.drawer.show = true
|
this.$refs.drawer.show = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const msg = event.data
|
||||||
|
switch (msg.name) {
|
||||||
|
case 'current_terminal_content':
|
||||||
|
// {content: '...', terminalId: '',sessionId: '',viewId: '',viewName: ''}
|
||||||
|
this.$log.debug('current_terminal_content', msg)
|
||||||
|
this.currentTerminalContent = msg.data
|
||||||
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -96,6 +106,11 @@ export default {
|
|||||||
this.$refs.drawer.handleHeaderMoveDown(event)
|
this.$refs.drawer.handleHeaderMoveDown(event)
|
||||||
},
|
},
|
||||||
handleMouseMoveUp(event) {
|
handleMouseMoveUp(event) {
|
||||||
|
// Prevent the new chat button from triggering the header move up
|
||||||
|
const newButton = event.target.closest('.new')
|
||||||
|
if (newButton) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.$refs.drawer.handleHeaderMoveUp(event)
|
this.$refs.drawer.handleHeaderMoveUp(event)
|
||||||
},
|
},
|
||||||
initWebSocket() {
|
initWebSocket() {
|
||||||
|
|||||||
Reference in New Issue
Block a user