|
|
@ -23,95 +23,272 @@ |
|
|
|
<div id="app" class="h-full"> |
|
|
|
<a-row class="h-full"> |
|
|
|
|
|
|
|
|
|
|
|
<a-col :span="3"> |
|
|
|
<a-col :span="3" class="sidebar"> |
|
|
|
<div style="display:flex;padding:5px;"> |
|
|
|
<a-input v-model:value="wsUrl" style="margin-right:5px;"></a-input> |
|
|
|
<a-button v-if="null === ws" @click="actionConnect">连接</a-button> |
|
|
|
<a-button v-else @click="actionDisconnect">断开</a-button> |
|
|
|
<a-button v-if="null === ws" @click="actionConnect" type="primary" class="connect-btn">连接</a-button> |
|
|
|
<a-button v-else @click="actionDisconnect" type="primary" danger class="disconnect-btn">断开</a-button> |
|
|
|
</div> |
|
|
|
<a-menu mode="inline" :items="actionMenuItems" @click="actionGroupMenuItemClick"></a-menu> |
|
|
|
<a-menu mode="inline" :items="actionMenuItems" @click="actionGroupMenuItemClick" class="menu"></a-menu> |
|
|
|
</a-col> |
|
|
|
|
|
|
|
|
|
|
|
<!-- --> |
|
|
|
<a-col :span="15" style="background-color: #f1f1f1;display:flex;flex-direction: column;"> |
|
|
|
|
|
|
|
|
|
|
|
<div v-if="null !== actionActiveGroup" |
|
|
|
style="height:0;flex-grow: 1;overflow-y: auto;margin-bottom: 10px;padding: 10px;"> |
|
|
|
|
|
|
|
<div v-for="item in actionActiveGroup.items" class="action" |
|
|
|
style="margin-bottom: 5px;background:white;padding:5px;border-radius: 5px; "> |
|
|
|
|
|
|
|
<!-- 按键 --> |
|
|
|
<a-button ghost type="primary" |
|
|
|
style="margin-right: 5px; min-width:230px ;font-weight: bold; text-align: left;" |
|
|
|
<a-col :span="15" style="display:flex;flex-direction: column;" class="main-content"> |
|
|
|
<div v-if="null !== actionActiveGroup" class="action-container"> |
|
|
|
<div v-for="item in actionActiveGroup.items" class="action-item"> |
|
|
|
<a-button type="primary" class="action-btn" |
|
|
|
@click="actionActionExecute(item)"> |
|
|
|
{{item.fnDispName}}</a-button> |
|
|
|
|
|
|
|
<!-- 参数 --> |
|
|
|
<div v-for="param in item.params" style="margin-right: 10px; width:150px "> |
|
|
|
|
|
|
|
<a-select v-if="item.paramInfoMap[param].isEnum" style=" width:150px" v-model:value="item.values[param]" |
|
|
|
<div v-for="param in item.params" class="param-input"> |
|
|
|
<a-select v-if="item.paramInfoMap[param].isEnum" v-model:value="item.values[param]" |
|
|
|
:placeholder="param" :dropdownMatchSelectWidth="false"> |
|
|
|
<!-- --> |
|
|
|
<a-select-option v-for="enumValue in item.paramInfoMap[param].enumValues" :key="enumValue" |
|
|
|
:value="enumValue">{{enumValue}}</a-select-option> |
|
|
|
|
|
|
|
<!-- --> |
|
|
|
</a-select> |
|
|
|
|
|
|
|
<a-input v-else v-model:value="item.values[param]" :placeholder="param" |
|
|
|
@click="showKeyboard(item.values, param)"></a-input> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</a-col> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a-col :span="6" style="height: 100%;display: flex;flex-direction: column;"> |
|
|
|
<a-col :span="6" class="log-section"> |
|
|
|
<div style="text-align: right; padding:10px;"> |
|
|
|
<a-button @click="actionClearLogs">清空日志</a-button> |
|
|
|
<a-button @click="actionClearLogs" class="clear-btn">清空日志</a-button> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div style="height:0;flex-grow:1;overflow-y: auto;"> |
|
|
|
<div class="log-container"> |
|
|
|
<a-collapse> |
|
|
|
<a-collapse-panel v-for="(entry,index) in logs" :key="index" :header="entry.title"> |
|
|
|
<div style="white-space: pre-wrap;"> |
|
|
|
<div class="log-content"> |
|
|
|
{{entry.content}} |
|
|
|
</div> |
|
|
|
</a-collapse-panel> |
|
|
|
</a-collapse> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div style="padding:10px;"> |
|
|
|
<div style="margin-bottom: 5px;height: 600px; overflow-y: auto;"> |
|
|
|
<a-collapse> |
|
|
|
<a-collapse-panel v-for="(entry,index) in reports" :key="index" :header="entry.title"> |
|
|
|
<div style="white-space: pre-wrap;"> |
|
|
|
{{entry.content}} |
|
|
|
</div> |
|
|
|
</a-collapse-panel> |
|
|
|
</a-collapse> |
|
|
|
</div> |
|
|
|
<div class="report-container"> |
|
|
|
<a-collapse> |
|
|
|
<a-collapse-panel v-for="(entry,index) in reports" :key="index" :header="entry.title"> |
|
|
|
<div class="report-content"> |
|
|
|
{{entry.content}} |
|
|
|
</div> |
|
|
|
</a-collapse-panel> |
|
|
|
</a-collapse> |
|
|
|
</div> |
|
|
|
|
|
|
|
</a-col> |
|
|
|
</a-row> |
|
|
|
</div> |
|
|
|
|
|
|
|
<style> |
|
|
|
:root { |
|
|
|
--primary-color: #1890ff; /* 主蓝色 */ |
|
|
|
--primary-hover: #40a9ff; /* 悬停蓝色 */ |
|
|
|
--success-color: #52c41a; /* 成功绿色 */ |
|
|
|
--warning-color: #faad14; /* 警告黄色 */ |
|
|
|
--error-color: #f5222d; /* 错误红色 */ |
|
|
|
--text-color: rgba(0, 0, 0, 0.85); /* 主文本颜色 */ |
|
|
|
--text-color-secondary: rgba(0, 0, 0, 0.45); /* 次文本颜色 */ |
|
|
|
--border-color: #d9d9d9; /* 边框颜色 */ |
|
|
|
--background-color: #f5f5f5; /* 背景色 */ |
|
|
|
--sidebar-bg: #f0f2f5; /* 侧边栏背景 */ |
|
|
|
--card-bg: #ffffff; /* 卡片背景 */ |
|
|
|
--action-btn-bg: #1890ff; /* 操作按钮背景 */ |
|
|
|
--action-btn-hover: #40a9ff; /* 操作按钮悬停 */ |
|
|
|
--disinfect-color: #13c2c2; /* 消毒主题色 - 青蓝色 */ |
|
|
|
} |
|
|
|
|
|
|
|
body { |
|
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; |
|
|
|
color: var(--text-color); |
|
|
|
background-color: var(--background-color); |
|
|
|
margin: 0; |
|
|
|
padding: 0; |
|
|
|
height: 100vh; |
|
|
|
} |
|
|
|
|
|
|
|
.h-full { |
|
|
|
height: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
/* 侧边栏样式 */ |
|
|
|
.sidebar { |
|
|
|
background-color: var(--sidebar-bg); |
|
|
|
border-right: 1px solid var(--border-color); |
|
|
|
height: 100%; |
|
|
|
padding: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.menu { |
|
|
|
border-right: none; |
|
|
|
} |
|
|
|
|
|
|
|
.menu .ant-menu-item { |
|
|
|
margin: 4px 0; |
|
|
|
border-radius: 4px; |
|
|
|
} |
|
|
|
|
|
|
|
.menu .ant-menu-item:hover { |
|
|
|
background-color: #e6f7ff; |
|
|
|
} |
|
|
|
|
|
|
|
.menu .ant-menu-item-selected { |
|
|
|
background-color: var(--primary-color); |
|
|
|
color: white; |
|
|
|
} |
|
|
|
|
|
|
|
/* 主内容区样式 */ |
|
|
|
.main-content { |
|
|
|
padding: 15px; |
|
|
|
background-color: white; |
|
|
|
} |
|
|
|
|
|
|
|
.action-container { |
|
|
|
height: 0; |
|
|
|
flex-grow: 1; |
|
|
|
overflow-y: auto; |
|
|
|
margin-bottom: 10px; |
|
|
|
padding: 10px; |
|
|
|
background-color: white; |
|
|
|
border-radius: 4px; |
|
|
|
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03); |
|
|
|
} |
|
|
|
|
|
|
|
.action-item { |
|
|
|
display: flex; |
|
|
|
flex-direction: row; |
|
|
|
margin-bottom: 10px; |
|
|
|
padding: 10px; |
|
|
|
background-color: #f6ffed; |
|
|
|
border-radius: 4px; |
|
|
|
border-left: 3px solid var(--success-color); |
|
|
|
transition: all 0.3s; |
|
|
|
} |
|
|
|
|
|
|
|
.action-item:hover { |
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09); |
|
|
|
} |
|
|
|
|
|
|
|
.action-btn { |
|
|
|
margin-right: 10px; |
|
|
|
min-width: 230px; |
|
|
|
font-weight: bold; |
|
|
|
text-align: left; |
|
|
|
background-color: var(--disinfect-color); |
|
|
|
border-color: var(--disinfect-color); |
|
|
|
} |
|
|
|
|
|
|
|
.action-btn:hover { |
|
|
|
background-color: #36cfc9; |
|
|
|
border-color: #36cfc9; |
|
|
|
} |
|
|
|
|
|
|
|
.param-input { |
|
|
|
margin-right: 10px; |
|
|
|
width: 150px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 日志区域样式 */ |
|
|
|
.log-section { |
|
|
|
height: 100%; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
background-color: white; |
|
|
|
border-left: 1px solid var(--border-color); |
|
|
|
padding: 0 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.clear-btn { |
|
|
|
color: var(--text-color-secondary); |
|
|
|
border-color: var(--border-color); |
|
|
|
} |
|
|
|
|
|
|
|
.clear-btn:hover { |
|
|
|
color: var(--primary-color); |
|
|
|
border-color: var(--primary-color); |
|
|
|
} |
|
|
|
|
|
|
|
.log-container, .report-container { |
|
|
|
height: 0; |
|
|
|
flex-grow: 1; |
|
|
|
overflow-y: auto; |
|
|
|
margin-bottom: 10px; |
|
|
|
background-color: white; |
|
|
|
border-radius: 4px; |
|
|
|
} |
|
|
|
|
|
|
|
.report-container { |
|
|
|
height: 600px; |
|
|
|
} |
|
|
|
|
|
|
|
.ant-collapse { |
|
|
|
background-color: white; |
|
|
|
border: none; |
|
|
|
} |
|
|
|
|
|
|
|
.ant-collapse-item { |
|
|
|
border-bottom: 1px solid var(--border-color); |
|
|
|
} |
|
|
|
|
|
|
|
.ant-collapse-header { |
|
|
|
font-weight: 500; |
|
|
|
color: var(--text-color); |
|
|
|
} |
|
|
|
|
|
|
|
.log-content, .report-content { |
|
|
|
white-space: pre-wrap; |
|
|
|
font-family: 'Courier New', Courier, monospace; |
|
|
|
font-size: 13px; |
|
|
|
color: var(--text-color); |
|
|
|
background-color: #fafafa; |
|
|
|
padding: 10px; |
|
|
|
border-radius: 2px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 连接按钮样式 */ |
|
|
|
.connect-btn { |
|
|
|
background-color: var(--success-color); |
|
|
|
border-color: var(--success-color); |
|
|
|
} |
|
|
|
|
|
|
|
.connect-btn:hover { |
|
|
|
background-color: #73d13d; |
|
|
|
border-color: #73d13d; |
|
|
|
} |
|
|
|
|
|
|
|
.disconnect-btn { |
|
|
|
background-color: var(--error-color); |
|
|
|
border-color: var(--error-color); |
|
|
|
} |
|
|
|
|
|
|
|
.disconnect-btn:hover { |
|
|
|
background-color: #ff4d4f; |
|
|
|
border-color: #ff4d4f; |
|
|
|
} |
|
|
|
|
|
|
|
/* 响应式调整 */ |
|
|
|
@media (max-width: 1200px) { |
|
|
|
.action-item { |
|
|
|
flex-direction: column; |
|
|
|
} |
|
|
|
|
|
|
|
.action-btn { |
|
|
|
margin-bottom: 8px; |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
.param-input { |
|
|
|
width: 100%; |
|
|
|
margin-right: 0; |
|
|
|
margin-bottom: 8px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |
|
|
|
|
|
|
|
<!-- 保留原有的script内容 --> |
|
|
|
<script> |
|
|
|
// 原有的JavaScript代码保持不变 |
|
|
|
const { createApp } = Vue |
|
|
|
createApp({ |
|
|
|
data() { |
|
|
@ -330,16 +507,6 @@ |
|
|
|
.use(antd) |
|
|
|
.mount('#app'); |
|
|
|
</script> |
|
|
|
<style> |
|
|
|
.h-full { |
|
|
|
height: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
.action { |
|
|
|
display: flex; |
|
|
|
flex-direction: row; |
|
|
|
} |
|
|
|
</style> |
|
|
|
</body> |
|
|
|
|
|
|
|
</html> |