Browse Source

更新用

mh
cuitw 1 month ago
parent
commit
3af95243c9
  1. 502
      ruoyi-ui/src/views/childRoom/FourTPanel.vue

502
ruoyi-ui/src/views/childRoom/FourTPanel.vue

@ -1,97 +1,74 @@
<template>
<div
v-show="visible"
class="four-t-panel"
:class="{ 'four-t-panel-ready': layoutReady }"
:style="panelStyle"
>
<div class="four-t-panel-header" @mousedown="onDragStart">
<span class="four-t-panel-title">4T</span>
<div class="four-t-header-actions" @mousedown.stop>
<el-button
v-if="!isEditMode"
type="primary"
size="mini"
<!-- 4T 悬浮窗空军 4T 作战任务面板样式 -->
<div v-show="visible" class="four-t-panel" :class="{ 'four-t-panel-ready': layoutReady }">
<div class="panel-container" :style="panelStyle">
<!-- 十字分割线 -->
<div class="cross-line-v"></div>
<div class="cross-line-h"></div>
<!-- 十字中心点 -->
<div class="cross-center"></div>
<!-- 顶部操作栏左侧编辑/完成右侧关闭 -->
<div class="panel-actions" @mousedown="onDragStart">
<button
class="btn-edit"
:class="{ complete: isEditMode }"
@mousedown.stop
@click="enterEditMode"
@click="isEditMode ? saveAndExitEdit() : enterEditMode()"
>
编辑
</el-button>
<template v-else>
<el-button
type="success"
size="mini"
@mousedown.stop
@click="saveAndExitEdit"
>
保存
</el-button>
<el-button
size="mini"
@mousedown.stop
@click="cancelEdit"
>
取消
</el-button>
</template>
<i class="el-icon-close close-btn" @mousedown.stop @click="$emit('update:visible', false)" title="关闭"></i>
{{ isEditMode ? '完成' : '编辑' }}
</button>
<button class="btn-close" @mousedown.stop @click="$emit('update:visible', false)">×</button>
</div>
</div>
<div class="four-t-panel-body">
<div
v-for="section in sections"
:key="section.key"
class="four-t-section"
>
<div class="four-t-section-header">
<span class="four-t-section-title">{{ section.title }}</span>
<div
v-if="isEditMode"
class="four-t-add-btn four-t-add-btn-inline"
@click="addImage(section.key)"
title="插入图片"
>
<i class="el-icon-plus"></i>
</div>
</div>
<div class="four-t-section-content four-t-content-box">
<el-input
v-model="localData[section.key].text"
type="textarea"
:autosize="{ minRows: 2, maxRows: 8 }"
:placeholder="isEditMode ? '请输入文本内容' : ''"
:disabled="!isEditMode"
class="four-t-textarea"
/>
<div v-if="localData[section.key].images.length > 0" class="four-t-images-inline">
<div
v-for="(img, idx) in localData[section.key].images"
:key="idx"
class="four-t-image-item"
>
<img :src="img" alt="插入的图片" />
<i
v-if="isEditMode"
class="el-icon-close remove-img"
@click="removeImage(section.key, idx)"
></i>
</div>
</div>
</div>
<!-- 四个象限 -->
<div class="quadrant quadrant-top-left">
<div class="quadrant-title">THREAT</div>
<textarea
class="quadrant-content"
:readonly="!isEditMode"
v-model="localData.threat.text"
placeholder="请输入威胁描述..."
></textarea>
</div>
<div class="quadrant quadrant-top-right">
<div class="quadrant-title">TARGET</div>
<textarea
class="quadrant-content"
:readonly="!isEditMode"
v-model="localData.target.text"
placeholder="请输入打击目标..."
></textarea>
</div>
<div class="quadrant quadrant-bottom-left">
<div class="quadrant-title">TASK</div>
<textarea
class="quadrant-content"
v-model="localData.task.text"
:readonly="!isEditMode"
placeholder="请输入任务内容..."
></textarea>
</div>
<div class="quadrant quadrant-bottom-right">
<div class="quadrant-title">TACTIC</div>
<textarea
class="quadrant-content"
v-model="localData.tactic.text"
:readonly="!isEditMode"
placeholder="请输入战术方案..."
></textarea>
</div>
<!-- 右下角拖拽调整大小 -->
<div
class="four-t-resize-handle"
@mousedown="onResizeStart"
title="拖动调整大小"
></div>
</div>
<div
class="four-t-resize-handle"
@mousedown="onResizeStart"
title="拖动调整大小"
></div>
<input
ref="fileInput"
type="file"
accept="image/*"
style="display: none"
@change="onFileSelected"
/>
</div>
</template>
@ -358,207 +335,253 @@ export default {
</script>
<style scoped>
/* 根容器:覆盖全屏,居中显示 4T 面板 */
.four-t-panel {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.12); /* 轻微遮罩,突出面板 */
z-index: 200;
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease-out;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border: 1px solid rgba(0, 138, 255, 0.2);
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 138, 255, 0.15);
z-index: 200;
overflow: hidden;
display: flex;
flex-direction: column;
}
.four-t-panel-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
background: rgba(0, 138, 255, 0.1);
border-bottom: 1px solid rgba(0, 138, 255, 0.15);
cursor: move;
user-select: none;
}
.four-t-panel-title {
font-weight: 600;
color: #008aff;
font-size: 14px;
.four-t-panel.four-t-panel-ready {
opacity: 1;
pointer-events: auto;
}
.four-t-header-actions {
display: flex;
align-items: center;
gap: 8px;
/* 面板容器 */
.panel-container {
position: fixed;
width: 100%;
max-width: 800px;
height: 600px;
background-color: #ffffff;
border-radius: 16px;
box-shadow: 0 8px 24px rgba(25, 148, 254, 0.1);
overflow: hidden;
border: 1px solid #e0edff;
z-index: 201;
}
.four-t-header-actions .el-button {
margin: 0;
/* 十字分割线 */
.cross-line-v {
position: absolute;
left: 50%;
top: 20px;
bottom: 20px;
width: 1px;
background-color: #1994fe;
transform: translateX(-50%);
z-index: 10;
opacity: 0.6;
}
.close-btn {
cursor: pointer;
font-size: 16px;
color: #606266;
}
.close-btn:hover {
color: #008aff;
.cross-line-h {
position: absolute;
top: 50%;
left: 20px;
right: 20px;
height: 1px;
background-color: #1994fe;
transform: translateY(-50%);
z-index: 10;
opacity: 0.6;
}
.four-t-panel-body {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 12px;
padding: 12px;
flex: 1;
min-height: 0;
overflow-y: auto;
/* 十字中心点 */
.cross-center {
position: absolute;
top: 50%;
left: 50%;
width: 8px;
height: 8px;
background-color: #1994fe;
border-radius: 50%;
transform: translate(-50%, -50%);
z-index: 15;
box-shadow: 0 0 6px rgba(25, 148, 254, 0.2);
}
.four-t-section {
/* 象限容器 */
.quadrant {
position: absolute;
width: 50%;
height: 50%;
padding: 24px;
display: flex;
flex-direction: column;
gap: 8px;
background: #fff;
border: 1px solid #e4e7ed;
border-radius: 6px;
padding: 10px;
min-height: 0;
flex: 1;
}
.four-t-section-header {
display: flex;
justify-content: center;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
gap: 8px;
text-align: center;
}
.four-t-section-title {
font-weight: 600;
font-size: 12px;
color: #606266;
user-select: none;
.quadrant-top-left {
top: 0;
left: 0;
}
.four-t-add-btn-inline {
flex-shrink: 0;
width: 28px;
height: 28px;
font-size: 14px;
.quadrant-top-right {
top: 0;
right: 0;
}
.four-t-section-content {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
gap: 0;
.quadrant-bottom-left {
bottom: 0;
left: 0;
}
.four-t-content-box {
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 8px;
background: #fff;
overflow-y: auto;
flex: 1;
min-height: 60px;
.quadrant-bottom-right {
bottom: 0;
right: 0;
}
.four-t-section-content .four-t-textarea {
flex: 0 0 auto;
display: block;
margin-bottom: 0;
/* 标题样式 */
.quadrant-title {
font-size: 18px;
font-weight: 600;
color: #0078e0;
margin-bottom: 16px;
letter-spacing: 0.5px;
text-transform: uppercase;
}
.four-t-section-content .four-t-textarea >>> .el-textarea {
margin-bottom: 0;
/* 文本区域样式 */
.quadrant-content {
width: 92%;
height: 80%;
border: 1px solid #cce5ff;
border-radius: 10px;
padding: 16px;
font-size: 15px;
color: #263238;
resize: none;
background-color: #f9fcff;
transition: all 0.2s ease;
line-height: 1.6;
}
.four-t-section-content .four-t-textarea >>> textarea.el-textarea__inner {
font-size: 12px;
border: none !important;
padding: 0 !important;
resize: none;
box-sizing: border-box;
min-height: 36px !important;
background: transparent !important;
.quadrant-content:focus {
outline: none;
border-color: #1994fe;
background-color: #ffffff;
box-shadow: 0 0 0 4px rgba(25, 148, 254, 0.1);
}
.four-t-section-content >>> .el-textarea.is-disabled .el-textarea__inner {
background: transparent !important;
color: #606266;
/* 只读状态 */
.quadrant-content[readonly] {
background-color: #e8f4ff;
color: #0078e0;
font-weight: 500;
cursor: default;
}
.four-t-images-inline {
/* 操作栏 */
.panel-actions {
position: absolute;
top: 20px;
left: 20px;
right: 20px;
z-index: 20;
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 8px;
align-items: flex-start;
flex-shrink: 0;
justify-content: space-between;
align-items: center;
/* 放大可拖动区域,并使用十字拖拽光标 */
padding: 8px 0;
cursor: move;
}
.four-t-image-item {
position: relative;
width: 64px;
height: 64px;
flex-shrink: 0;
/* 编辑按钮 */
.btn-edit {
background-color: #f0f7ff;
color: #1994fe;
border: 1px solid #cce5ff;
padding: 6px 12px;
border-radius: 6px;
font-size: 13px;
font-weight: 500;
transition: all 0.2s ease;
cursor: pointer;
}
.four-t-image-item img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 4px;
border: 1px solid #e4e7ed;
display: block;
.btn-edit.complete {
background-color: #f0fff4;
color: #00c853;
border: 1px solid #ccffdd;
}
.four-t-image-item .remove-img {
position: absolute;
top: -4px;
right: -4px;
width: 16px;
height: 16px;
background: #f56c6c;
color: #fff;
border-radius: 50%;
font-size: 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
.btn-edit:hover {
background-color: #e8f4ff;
border-color: #1994fe;
}
.btn-edit.complete:hover {
background-color: #e6fffa;
border-color: #00c853;
color: #00a142;
}
.four-t-add-btn {
width: 36px;
height: 36px;
border: 1px dashed #dcdfe6;
border-radius: 4px;
/* 关闭按钮 */
.btn-close {
background-color: #f0f7ff;
border: 1px solid #cce5ff;
font-size: 14px;
color: #1994fe;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.2s ease;
cursor: pointer;
color: #909399;
font-size: 18px;
transition: all 0.2s;
}
.four-t-add-btn:hover {
border-color: #008aff;
color: #008aff;
background: rgba(0, 138, 255, 0.05);
.btn-close:hover {
background-color: #e8f4ff;
color: #0078e0;
}
/* 响应式适配 */
@media (max-width: 768px) {
.panel-container {
height: 500px;
max-width: 95%;
}
.quadrant {
padding: 16px;
}
.quadrant-title {
font-size: 16px;
margin-bottom: 12px;
}
.quadrant-content {
font-size: 14px;
padding: 12px;
width: 95%;
height: 75%;
}
.btn-edit {
padding: 5px 10px;
font-size: 12px;
}
.btn-close {
width: 28px;
height: 28px;
font-size: 13px;
}
}
/* 右下角拖拽调整大小手柄 */
.four-t-resize-handle {
position: absolute;
right: 0;
@ -568,15 +591,10 @@ export default {
cursor: nwse-resize;
user-select: none;
z-index: 10;
/* 右下角三角形拖拽区域 */
background: linear-gradient(to top left, transparent 50%, rgba(0, 138, 255, 0.2) 50%);
}
.four-t-resize-handle:hover {
background: linear-gradient(to top left, transparent 50%, rgba(0, 138, 255, 0.4) 50%);
background: linear-gradient(to top left, transparent 50%, rgba(25, 148, 254, 0.2) 50%);
}
.four-t-panel.four-t-panel-ready {
opacity: 1;
pointer-events: auto;
.four-t-resize-handle:hover {
background: linear-gradient(to top left, transparent 50%, rgba(25, 148, 254, 0.4) 50%);
}
</style>

Loading…
Cancel
Save