feat(Scripts.vue): 添加MAA配置遮罩层并优化样式布局

This commit is contained in:
MoeSnowyFox
2025-09-20 23:43:02 +08:00
parent e0ba88d7b0
commit cd706640d9

View File

@@ -1,4 +1,29 @@
<template> <template>
<!-- MAA配置遮罩层 -->
<div v-if="showMAAConfigMask" class="maa-config-mask">
<div class="mask-content">
<div class="mask-icon">
<SettingOutlined :style="{ fontSize: '48px', color: '#1890ff' }" />
</div>
<h2 class="mask-title">正在进行MAA配置</h2>
<p class="mask-description">
当前正在配置MAA脚本请在MAA配置界面完成相关设置
<br />
配置完成后请点击"保存配置"按钮来解除页面锁定
</p>
<div class="mask-actions">
<a-button
v-if="currentConfigScript"
type="primary"
size="large"
@click="handleSaveMAAConfig(currentConfigScript)"
>
保存配置
</a-button>
</div>
</div>
</div>
<!-- 加载状态 --> <!-- 加载状态 -->
<div v-if="loading" class="loading-container"> <div v-if="loading" class="loading-container">
<a-spin size="large" tip="加载中,请稍候..." /> <a-spin size="large" tip="加载中,请稍候..." />
@@ -260,6 +285,8 @@ const templates = ref<WebConfigTemplate[]>([])
const addLoading = ref(false) const addLoading = ref(false)
const templateLoading = ref(false) const templateLoading = ref(false)
const searchKeyword = ref('') const searchKeyword = ref('')
const showMAAConfigMask = ref(false) // 控制MAA配置遮罩层的显示
const currentConfigScript = ref<Script | null>(null) // 当前正在配置的脚本
// WebSocket连接管理 // WebSocket连接管理
const activeConnections = ref<Map<string, string>>(new Map()) // scriptId -> websocketId const activeConnections = ref<Map<string, string>>(new Map()) // scriptId -> websocketId
@@ -515,18 +542,28 @@ const handleStartMAAConfig = async (script: Script) => {
}) })
if (response.code === 200) { if (response.code === 200) {
// 显示遮罩层
showMAAConfigMask.value = true
currentConfigScript.value = script
// 订阅WebSocket消息 // 订阅WebSocket消息
subscribe(response.websocketId, { subscribe(response.websocketId, {
onError: error => { onError: error => {
console.error(`脚本 ${script.name} 连接错误:`, error) console.error(`脚本 ${script.name} 连接错误:`, error)
message.error(`MAA配置连接失败: ${error}`) message.error(`MAA配置连接失败: ${error}`)
activeConnections.value.delete(script.id) activeConnections.value.delete(script.id)
// 连接错误时隐藏遮罩
showMAAConfigMask.value = false
currentConfigScript.value = null
}, },
onResult: (data: any) => { onResult: (data: any) => {
// 处理配置完成消息(兼容任何结构) // 处理配置完成消息(兼容任何结构)
if (data.Accomplish) { if (data.Accomplish) {
message.success(`${script.name} 配置已完成`) message.success(`${script.name} 配置已完成`)
activeConnections.value.delete(script.id) activeConnections.value.delete(script.id)
// 自动隐藏遮罩
showMAAConfigMask.value = false
currentConfigScript.value = null
} }
}, },
}) })
@@ -544,6 +581,9 @@ const handleStartMAAConfig = async (script: Script) => {
unsubscribe(wsId) unsubscribe(wsId)
} }
activeConnections.value.delete(script.id) activeConnections.value.delete(script.id)
// 超时时隐藏遮罩
showMAAConfigMask.value = false
currentConfigScript.value = null
message.info(`${script.name} 配置会话已超时断开`) message.info(`${script.name} 配置会话已超时断开`)
} }
}, },
@@ -575,6 +615,11 @@ const handleSaveMAAConfig = async (script: Script) => {
// 取消订阅 // 取消订阅
unsubscribe(websocketId) unsubscribe(websocketId)
activeConnections.value.delete(script.id) activeConnections.value.delete(script.id)
// 隐藏遮罩
showMAAConfigMask.value = false
currentConfigScript.value = null
message.success(`${script.name} 的配置已保存`) message.success(`${script.name} 的配置已保存`)
} else { } else {
message.error(response.message || '保存配置失败') message.error(response.message || '保存配置失败')
@@ -604,12 +649,9 @@ const handleToggleUserStatus = async (user: User) => {
}) })
if (result) { if (result) {
// 更新本地数据状态
const targetUser = script.users.find(u => u.id === user.id)
if (targetUser) {
targetUser.Info.Status = newStatus
}
message.success('用户状态更新成功') message.success('用户状态更新成功')
// 更新本地用户状态
user.Info.Status = newStatus
} }
} catch (error) { } catch (error) {
console.error('更新用户状态失败:', error) console.error('更新用户状态失败:', error)
@@ -619,175 +661,186 @@ const handleToggleUserStatus = async (user: User) => {
</script> </script>
<style scoped> <style scoped>
.loading-container { .maa-config-mask {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background: rgba(0, 0, 0, 0.45);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 9999; z-index: 9999;
} }
.scripts-header { .mask-content {
display: flex; background: var(--ant-color-bg-elevated);
justify-content: space-between; border-radius: 8px;
align-items: flex-end; padding: 24px;
margin-bottom: 24px; max-width: 480px;
padding: 0 4px; width: 100%;
text-align: center;
box-shadow:
0 6px 16px 0 rgba(0, 0, 0, 0.08),
0 3px 6px -4px rgba(0, 0, 0, 0.12),
0 9px 28px 8px rgba(0, 0, 0, 0.05);
border: 1px solid var(--ant-color-border);
} }
.header-left { .mask-icon {
flex: 1; margin-bottom: 16px;
} }
.page-title { .mask-title {
margin: 0 0 8px 0; font-size: 18px;
font-size: 32px; font-weight: 600;
font-weight: 700; margin: 0 0 8px;
color: var(--ant-color-text); color: var(--ant-color-text);
background: linear-gradient(135deg, var(--ant-color-primary), var(--ant-color-primary-hover)); }
-webkit-background-clip: text;
-webkit-text-fill-color: transparent; .mask-description {
background-clip: text; font-size: 14px;
color: var(--ant-color-text-secondary);
margin: 0 0 24px;
line-height: 1.5;
}
.mask-actions {
display: flex;
justify-content: center;
}
.link {
display: inline-flex;
align-items: center;
}
.link .anticon {
margin-right: 8px;
}
.loading-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
} }
.empty-state { .empty-state {
display: flex;
align-items: center;
justify-content: center;
height: calc(100vh - 200px);
text-align: center; text-align: center;
padding: 40px 20px;
} }
.empty-image-container { .empty-image-container {
margin-bottom: 16px; margin-bottom: 16px;
} }
.empty-image {
max-width: 100%;
height: auto;
}
.empty-title { .empty-title {
font-size: 22px; font-size: 18px;
font-weight: 500; font-weight: 500;
margin: 0 0 8px 0; margin: 0;
color: var(--ant-color-text);
} }
.empty-description { .empty-description {
font-size: 16px; font-size: 14px;
color: var(--ant-color-text-secondary); color: var(--ant-color-text-secondary);
margin: 0;
} }
/* 模态框通用样式 */ .scripts-header {
.type-select-modal :deep(.ant-modal-content), display: flex;
.general-mode-modal :deep(.ant-modal-content), align-items: center;
.template-select-modal :deep(.ant-modal-content) { justify-content: space-between;
border-radius: 12px; margin-bottom: 24px;
} }
.type-select-modal :deep(.ant-modal-header), .page-title {
.general-mode-modal :deep(.ant-modal-header), font-size: 24px;
.template-select_modal :deep(.ant-modal-header) { font-weight: 500;
border-bottom: 1px solid var(--ant-color-border); margin: 0;
padding: 16px 24px; color: var(--ant-color-text);
} }
.type-select-modal :deep(.ant-modal-title), .type-select-modal,
.general-mode_modal :deep(.ant-modal-title), .general-mode-modal,
.template-select-modal :deep(.ant-modal-title) { .template-select-modal {
font-size: 18px; text-align: left;
font-weight: 600;
} }
.type-select-modal :deep(.ant-modal-body),
.general-mode-modal :deep(.ant-modal-body) {
padding: 24px;
}
.template-select-modal :deep(.ant-modal-body) {
padding: 0;
}
/* 选择组样式 */
.type-selection, .type-selection,
.mode-selection { .mode-selection,
margin: 16px 0; .template-selection {
margin-top: 16px;
} }
.type-radio-group, .type-radio-group,
.mode-radio-group { .mode-radio-group {
width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px;
} }
.type-radio-group :deep(.ant-radio-button-wrapper), .type-option,
.mode-radio-group :deep(.ant-radio-button-wrapper) { .mode-option {
height: auto;
padding: 0;
border: 1px solid var(--ant-color-border);
border-radius: 8px;
background: var(--ant-color-bg-container);
transition: all 0.3s ease;
text-align: left;
}
.type-radio-group :deep(.ant-radio-button-wrapper:hover),
.mode-radio-group :deep(.ant-radio-button-wrapper:hover) {
border-color: var(--ant-color-primary);
}
.type-radio-group :deep(.ant-radio-button-wrapper-checked),
.mode-radio-group :deep(.ant-radio-button-wrapper-checked) {
border-color: var(--ant-color-primary);
background: var(--ant-color-primary-bg);
color: var(--ant-color-primary);
}
.type-radio-group :deep(.ant-radio-button-wrapper::before),
.mode-radio-group :deep(.ant-radio-button-wrapper::before) {
display: none;
}
.type-radio-group :deep(.ant-radio-button-wrapper .ant-radio-button),
.mode-radio-group :deep(.ant-radio-button-wrapper .ant-radio-button) {
display: none;
}
.type-content {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 16px; padding: 12px;
padding: 16px 20px; border: 1px solid var(--ant-color-border);
width: 100%; border-radius: 8px;
margin-bottom: 8px;
cursor: pointer;
transition: all 0.3s;
background: var(--ant-color-bg-container);
} }
.type-option:hover,
.mode-option:hover {
border-color: var(--ant-color-primary);
background: var(--ant-color-primary-bg);
}
.type-content,
.mode-content { .mode-content {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; width: 100%;
padding: 16px 20px;
} }
.type-logo-container { .type-logo-container,
.mode-icon {
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 8px; margin-right: 12px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: var(--ant-color-bg-elevated); border-radius: 6px;
border: 1px solid var(--ant-color-border-secondary); background: var(--ant-color-primary-bg);
flex-shrink: 0;
} }
.type-logo { .type-logo {
width: 32px; width: 32px;
height: 32px; height: 32px;
object-fit: contain;
} }
.mode-icon { .mode-icon {
font-size: 24px; font-size: 20px;
color: var(--ant-color-primary); color: var(--ant-color-primary);
flex-shrink: 0;
} }
.type-info, .type-info,
@@ -798,68 +851,53 @@ const handleToggleUserStatus = async (user: User) => {
.type-title, .type-title,
.mode-title { .mode-title {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 500;
margin: 0 0 4px;
color: var(--ant-color-text); color: var(--ant-color-text);
margin-bottom: 4px;
} }
.type-description, .type-description,
.mode-description { .mode-description {
font-size: 14px; font-size: 14px;
color: var(--ant-color-text-secondary); color: var(--ant-color-text-secondary);
line-height: 1.4; margin: 0;
}
/* 模板选择样式 */
.template-selection {
min-height: 400px;
}
.no-templates {
text-align: center;
padding: 60px 20px;
}
.no-templates-content {
color: var(--ant-color-text-secondary);
}
.no-templates-icon {
font-size: 48px;
margin-bottom: 16px;
color: var(--ant-color-text-tertiary);
} }
.templates-container { .templates-container {
height: 600px; margin-top: 16px;
display: flex;
flex-direction: column;
} }
.templates-header { .templates-header {
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
padding: 24px; justify-content: space-between;
border-bottom: 1px solid var(--ant-color-border); margin-bottom: 16px;
} }
.templates-count { .templates-count {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; font-size: 14px;
color: var(--ant-color-text);
} }
.count-badge { .count-badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 6px;
border-radius: 10px;
background: var(--ant-color-primary); background: var(--ant-color-primary);
color: white; color: #fff;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px; font-size: 12px;
font-weight: 600; font-weight: 500;
margin-right: 8px;
} }
.count-text { .count-text {
font-size: 14px;
color: var(--ant-color-text-secondary); color: var(--ant-color-text-secondary);
} }
@@ -869,70 +907,59 @@ const handleToggleUserStatus = async (user: User) => {
margin-left: 16px; margin-left: 16px;
} }
.template-search {
width: 100%;
}
.templates-list { .templates-list {
flex: 1; max-height: 400px;
overflow-y: auto; overflow-y: auto;
padding: 0 24px 24px;
/* 隐藏滚动条 */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
}
.templates-list::-webkit-scrollbar {
display: none; /* Chrome, Safari and Opera */
}
.no-search-results {
text-align: center;
padding: 60px 20px;
color: var(--ant-color-text-secondary);
}
.no-results-icon {
font-size: 48px;
margin-bottom: 16px;
color: var(--ant-color-text-tertiary);
}
.no-results-tip {
font-size: 14px;
color: var(--ant-color-text-tertiary);
}
.template-item {
border: 1px solid var(--ant-color-border); border: 1px solid var(--ant-color-border);
border-radius: 8px; border-radius: 6px;
margin-bottom: 16px;
cursor: pointer;
transition: all 0.3s ease;
background: var(--ant-color-bg-container); background: var(--ant-color-bg-container);
} }
.template-item:hover { .template-item {
border-color: var(--ant-color-primary); padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); border-bottom: 1px solid var(--ant-color-border);
cursor: pointer;
transition: background-color 0.3s;
background: var(--ant-color-bg-container);
} }
.template-item.selected { .template-item:last-child {
border-color: var(--ant-color-primary); border-bottom: none;
}
.template-item:hover {
background: var(--ant-color-primary-bg); background: var(--ant-color-primary-bg);
} }
.template-item.selected {
background: var(--ant-color-primary-bg);
border-color: var(--ant-color-primary);
}
.template-content { .template-content {
padding: 20px; display: flex;
flex-direction: column;
} }
.template-header { .template-header {
display: flex; display: flex;
align-items: center;
justify-content: space-between; justify-content: space-between;
align-items: flex-start; margin-bottom: 8px;
margin-bottom: 12px; }
.template-info {
flex: 1;
} }
.template-name { .template-name {
margin: 0 0 8px 0;
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 500;
margin: 0 0 4px;
color: var(--ant-color-text); color: var(--ant-color-text);
} }
@@ -951,15 +978,39 @@ const handleToggleUserStatus = async (user: User) => {
} }
.template-description { .template-description {
font-size: 14px;
color: var(--ant-color-text-secondary); color: var(--ant-color-text-secondary);
margin: 0;
line-height: 1.5; line-height: 1.5;
} }
.template-description :deep(p) { .no-search-results,
margin: 0 0 8px 0; .no-templates {
text-align: center;
padding: 32px 16px;
color: var(--ant-color-text-secondary);
} }
.template-description :deep(p:last-child) { .no-results-icon,
margin-bottom: 0; .no-templates-icon {
font-size: 48px;
color: var(--ant-color-text-tertiary);
margin-bottom: 16px;
}
.no-templates-content h3 {
color: var(--ant-color-text);
margin: 0 0 8px;
}
.no-templates-content p {
color: var(--ant-color-text-secondary);
margin: 0;
}
.no-results-tip {
font-size: 12px;
color: var(--ant-color-text-tertiary);
margin-top: 4px;
} }
</style> </style>