feat(ai-assistant): 添加全屏切换功能

- 添加全屏按钮,支持点击或双击标题栏切换全屏
  - 全屏时禁用拖动和调整大小
  - 全屏状态下占满视口(保留 12px 边距)
  - 关闭窗口时自动退出全屏状态
This commit is contained in:
kuaifan 2026-01-16 10:26:57 +00:00
parent a3caf5ebdf
commit b7213f8c47
2 changed files with 83 additions and 12 deletions

View File

@ -1281,7 +1281,7 @@ export default {
.ai-assistant-header-actions { .ai-assistant-header-actions {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 6px;
.ai-assistant-header-btn { .ai-assistant-header-btn {
display: flex; display: flex;
@ -1650,6 +1650,31 @@ export default {
cursor: sw-resize; cursor: sw-resize;
} }
.ai-assistant-fullscreen {
position: absolute;
top: 11px;
right: 48px;
z-index: 1;
width: 28px;
height: 28px;
padding: 4px;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s;
svg {
width: 100%;
height: 100%;
stroke: #777;
transition: stroke 0.2s;
}
&:hover {
background-color: rgba(0, 0, 0, 0.06);
svg {
stroke: #444;
}
}
}
.ai-assistant-close { .ai-assistant-close {
position: absolute; position: absolute;
top: 6px; top: 6px;
@ -1673,7 +1698,7 @@ export default {
} }
.ai-assistant-header { .ai-assistant-header {
margin: 6px 48px 6px 16px; margin: 6px 82px 6px 16px;
.ai-assistant-header-title { .ai-assistant-header-title {
> span { > span {
@ -1780,6 +1805,22 @@ export default {
.ai-assistant-input { .ai-assistant-input {
padding: 4px 12px 12px; padding: 4px 12px 12px;
} }
//
&.is-fullscreen {
top: 12px;
left: 12px;
right: 12px;
bottom: 12px;
width: auto;
height: auto;
max-width: none;
max-height: none;
.ai-assistant-drag-handle {
cursor: default;
}
}
} }
.ai-assistant-modal { .ai-assistant-modal {

View File

@ -5,15 +5,28 @@
v-if="visible" v-if="visible"
ref="chatWindow" ref="chatWindow"
class="ai-assistant-chat" class="ai-assistant-chat"
:class="{'is-fullscreen': isFullscreen}"
:style="chatStyle"> :style="chatStyle">
<div class="ai-assistant-fullscreen" @click="toggleFullscreen">
<svg v-if="isFullscreen" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="4 10 10 10 10 4"/><polyline points="14 4 14 10 20 10"/>
<polyline points="10 20 10 14 4 14"/><polyline points="20 14 14 14 14 20"/>
</svg>
<svg v-else viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="5 9 5 5 9 5"/><polyline points="19 9 19 5 15 5"/>
<polyline points="5 15 5 19 9 19"/><polyline points="19 15 19 19 15 19"/>
</svg>
</div>
<Icon class="ai-assistant-close" type="ios-close" @click="onClose"/> <Icon class="ai-assistant-close" type="ios-close" @click="onClose"/>
<div <div
class="ai-assistant-drag-handle" class="ai-assistant-drag-handle"
@dblclick="toggleFullscreen"
@mousedown.stop.prevent="onDragMouseDown"> @mousedown.stop.prevent="onDragMouseDown">
<slot name="header"></slot> <slot name="header"></slot>
</div> </div>
<slot></slot> <slot></slot>
<!-- 调整大小的控制点 --> <!-- 调整大小的控制点 -->
<template v-if="!isFullscreen">
<div class="ai-assistant-resize-handle ai-assistant-resize-n" @mousedown.stop.prevent="onResizeMouseDown($event, 'n')"></div> <div class="ai-assistant-resize-handle ai-assistant-resize-n" @mousedown.stop.prevent="onResizeMouseDown($event, 'n')"></div>
<div class="ai-assistant-resize-handle ai-assistant-resize-s" @mousedown.stop.prevent="onResizeMouseDown($event, 's')"></div> <div class="ai-assistant-resize-handle ai-assistant-resize-s" @mousedown.stop.prevent="onResizeMouseDown($event, 's')"></div>
<div class="ai-assistant-resize-handle ai-assistant-resize-e" @mousedown.stop.prevent="onResizeMouseDown($event, 'e')"></div> <div class="ai-assistant-resize-handle ai-assistant-resize-e" @mousedown.stop.prevent="onResizeMouseDown($event, 'e')"></div>
@ -22,6 +35,7 @@
<div class="ai-assistant-resize-handle ai-assistant-resize-nw" @mousedown.stop.prevent="onResizeMouseDown($event, 'nw')"></div> <div class="ai-assistant-resize-handle ai-assistant-resize-nw" @mousedown.stop.prevent="onResizeMouseDown($event, 'nw')"></div>
<div class="ai-assistant-resize-handle ai-assistant-resize-se" @mousedown.stop.prevent="onResizeMouseDown($event, 'se')"></div> <div class="ai-assistant-resize-handle ai-assistant-resize-se" @mousedown.stop.prevent="onResizeMouseDown($event, 'se')"></div>
<div class="ai-assistant-resize-handle ai-assistant-resize-sw" @mousedown.stop.prevent="onResizeMouseDown($event, 'sw')"></div> <div class="ai-assistant-resize-handle ai-assistant-resize-sw" @mousedown.stop.prevent="onResizeMouseDown($event, 'sw')"></div>
</template>
</div> </div>
</transition> </transition>
</div> </div>
@ -98,6 +112,8 @@ export default {
resizing: false, resizing: false,
resizeDirection: null, resizeDirection: null,
resizeRecord: {}, resizeRecord: {},
//
isFullscreen: false,
}; };
}, },
@ -141,6 +157,10 @@ export default {
opacity: 0, opacity: 0,
}; };
} }
//
if (this.isFullscreen) {
return {};
}
const style = { const style = {
left: `${this.left}px`, left: `${this.left}px`,
top: `${this.top}px`, top: `${this.top}px`,
@ -162,6 +182,9 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateWindowSize(); this.updateWindowSize();
}); });
} else if (!val) {
//
this.isFullscreen = false;
} }
}, },
windowWidth() { windowWidth() {
@ -252,8 +275,8 @@ export default {
* 拖动鼠标按下 * 拖动鼠标按下
*/ */
onDragMouseDown(e) { onDragMouseDown(e) {
// //
if (e.button !== 0) return; if (e.button !== 0 || this.isFullscreen) return;
this.updateWindowSize(); this.updateWindowSize();
this.record = { this.record = {
@ -267,6 +290,13 @@ export default {
document.addEventListener('contextmenu', this.onContextMenu); document.addEventListener('contextmenu', this.onContextMenu);
}, },
/**
* 切换全屏
*/
toggleFullscreen() {
this.isFullscreen = !this.isFullscreen;
},
/** /**
* 右键菜单弹出时取消拖动/调整大小 * 右键菜单弹出时取消拖动/调整大小
*/ */