fix: 修复用户页面的MAA配置按钮与通用脚本配置按钮失效
This commit is contained in:
@@ -50,6 +50,33 @@
|
|||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 通用配置遮罩层 -->
|
||||||
|
<teleport to="body">
|
||||||
|
<div v-if="showGeneralConfigMask" class="maa-config-mask">
|
||||||
|
<div class="mask-content">
|
||||||
|
<div class="mask-icon">
|
||||||
|
<SettingOutlined :style="{ fontSize: '48px', color: '#1890ff' }" />
|
||||||
|
</div>
|
||||||
|
<h2 class="mask-title">正在进行通用配置</h2>
|
||||||
|
<p class="mask-description">
|
||||||
|
当前正在进行该用户的通用配置,请在配置界面完成相关设置。
|
||||||
|
<br />
|
||||||
|
配置完成后,请点击"保存配置"按钮来结束配置会话。
|
||||||
|
</p>
|
||||||
|
<div class="mask-actions">
|
||||||
|
<a-button
|
||||||
|
v-if="generalWebsocketId"
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
@click="handleSaveGeneralConfig"
|
||||||
|
>
|
||||||
|
保存配置
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</teleport>
|
||||||
|
|
||||||
<div class="user-edit-content">
|
<div class="user-edit-content">
|
||||||
<a-card class="config-card">
|
<a-card class="config-card">
|
||||||
<a-form ref="formRef" :model="formData" :rules="rules" layout="vertical" class="config-form">
|
<a-form ref="formRef" :model="formData" :rules="rules" layout="vertical" class="config-form">
|
||||||
@@ -355,6 +382,8 @@ import type { FormInstance, Rule } from 'ant-design-vue/es/form'
|
|||||||
import { useUserApi } from '@/composables/useUserApi'
|
import { useUserApi } from '@/composables/useUserApi'
|
||||||
import { useScriptApi } from '@/composables/useScriptApi'
|
import { useScriptApi } from '@/composables/useScriptApi'
|
||||||
import { useWebSocket } from '@/composables/useWebSocket'
|
import { useWebSocket } from '@/composables/useWebSocket'
|
||||||
|
import { Service } from '@/api'
|
||||||
|
import { TaskCreateIn } from '@/api/models/TaskCreateIn'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -376,6 +405,8 @@ const scriptName = ref('')
|
|||||||
// 通用配置相关
|
// 通用配置相关
|
||||||
const generalConfigLoading = ref(false)
|
const generalConfigLoading = ref(false)
|
||||||
const generalWebsocketId = ref<string | null>(null)
|
const generalWebsocketId = ref<string | null>(null)
|
||||||
|
const showGeneralConfigMask = ref(false)
|
||||||
|
let generalConfigTimeout: number | null = null
|
||||||
|
|
||||||
// 通用脚本默认用户数据
|
// 通用脚本默认用户数据
|
||||||
const getDefaultGeneralUserData = () => ({
|
const getDefaultGeneralUserData = () => ({
|
||||||
@@ -556,31 +587,106 @@ const handleGeneralConfig = async () => {
|
|||||||
try {
|
try {
|
||||||
generalConfigLoading.value = true
|
generalConfigLoading.value = true
|
||||||
|
|
||||||
|
// 先立即显示遮罩以避免后端延迟导致无法感知
|
||||||
|
showGeneralConfigMask.value = true
|
||||||
|
|
||||||
|
// 如果已有连接,先断开并清理
|
||||||
if (generalWebsocketId.value) {
|
if (generalWebsocketId.value) {
|
||||||
unsubscribe(generalWebsocketId.value)
|
unsubscribe(generalWebsocketId.value)
|
||||||
generalWebsocketId.value = null
|
generalWebsocketId.value = null
|
||||||
|
showGeneralConfigMask.value = false
|
||||||
|
if (generalConfigTimeout) {
|
||||||
|
window.clearTimeout(generalConfigTimeout)
|
||||||
|
generalConfigTimeout = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const subId = userId
|
// 调用后端启动任务接口,传入 userId 作为 taskId 与设置模式
|
||||||
|
const response = await Service.addTaskApiDispatchStartPost({
|
||||||
subscribe(subId, {
|
taskId: userId,
|
||||||
onError: error => {
|
mode: TaskCreateIn.mode.SettingScriptMode,
|
||||||
console.error(`用户 ${formData.userName} 通用配置错误:`, error)
|
|
||||||
message.error(`通用配置连接失败: ${error}`)
|
|
||||||
generalWebsocketId.value = null
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
generalWebsocketId.value = subId
|
console.debug('通用配置 start 接口返回:', response)
|
||||||
message.success(`已开始配置用户 ${formData.userName} 的通用设置`)
|
if (response && response.websocketId) {
|
||||||
|
const wsId = response.websocketId
|
||||||
|
|
||||||
|
console.debug('订阅 websocketId:', wsId)
|
||||||
|
|
||||||
|
// 订阅 websocket
|
||||||
|
subscribe(wsId, {
|
||||||
|
onMessage: (wsMessage: any) => {
|
||||||
|
if (wsMessage.type === 'error') {
|
||||||
|
console.error(`用户 ${formData.userName} 通用配置错误:`, wsMessage.data)
|
||||||
|
message.error(`通用配置连接失败: ${wsMessage.data}`)
|
||||||
|
unsubscribe(wsId)
|
||||||
|
generalWebsocketId.value = null
|
||||||
|
showGeneralConfigMask.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wsMessage.data && wsMessage.data.Accomplish) {
|
||||||
|
message.success(`用户 ${formData.userName} 的配置已完成`)
|
||||||
|
unsubscribe(wsId)
|
||||||
|
generalWebsocketId.value = null
|
||||||
|
showGeneralConfigMask.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
generalWebsocketId.value = wsId
|
||||||
|
showGeneralConfigMask.value = true
|
||||||
|
message.success(`已开始配置用户 ${formData.userName} 的通用设置`)
|
||||||
|
|
||||||
|
// 设置 30 分钟超时自动断开
|
||||||
|
generalConfigTimeout = window.setTimeout(() => {
|
||||||
|
if (generalWebsocketId.value) {
|
||||||
|
const id = generalWebsocketId.value
|
||||||
|
unsubscribe(id)
|
||||||
|
generalWebsocketId.value = null
|
||||||
|
showGeneralConfigMask.value = false
|
||||||
|
message.info(`用户 ${formData.userName} 的配置会话已超时断开`)
|
||||||
|
}
|
||||||
|
generalConfigTimeout = null
|
||||||
|
}, 30 * 60 * 1000)
|
||||||
|
} else {
|
||||||
|
message.error(response?.message || '启动通用配置失败')
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('通用配置失败:', error)
|
console.error('启动通用配置失败:', error)
|
||||||
message.error('通用配置失败')
|
message.error('启动通用配置失败')
|
||||||
} finally {
|
} finally {
|
||||||
generalConfigLoading.value = false
|
generalConfigLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSaveGeneralConfig = async () => {
|
||||||
|
try {
|
||||||
|
const websocketId = generalWebsocketId.value
|
||||||
|
if (!websocketId) {
|
||||||
|
message.error('未找到活动的配置会话')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await Service.stopTaskApiDispatchStopPost({ taskId: websocketId })
|
||||||
|
if (response && response.code === 200) {
|
||||||
|
unsubscribe(websocketId)
|
||||||
|
generalWebsocketId.value = null
|
||||||
|
showGeneralConfigMask.value = false
|
||||||
|
if (generalConfigTimeout) {
|
||||||
|
window.clearTimeout(generalConfigTimeout)
|
||||||
|
generalConfigTimeout = null
|
||||||
|
}
|
||||||
|
message.success('用户的通用配置已保存')
|
||||||
|
} else {
|
||||||
|
message.error(response.message || '保存配置失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存通用配置失败:', error)
|
||||||
|
message.error('保存通用配置失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 文件选择方法
|
// 文件选择方法
|
||||||
const selectScriptBeforeTask = async () => {
|
const selectScriptBeforeTask = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -622,6 +728,11 @@ const handleCancel = () => {
|
|||||||
if (generalWebsocketId.value) {
|
if (generalWebsocketId.value) {
|
||||||
unsubscribe(generalWebsocketId.value)
|
unsubscribe(generalWebsocketId.value)
|
||||||
generalWebsocketId.value = null
|
generalWebsocketId.value = null
|
||||||
|
showGeneralConfigMask.value = false
|
||||||
|
if (generalConfigTimeout) {
|
||||||
|
window.clearTimeout(generalConfigTimeout)
|
||||||
|
generalConfigTimeout = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
router.push('/scripts')
|
router.push('/scripts')
|
||||||
}
|
}
|
||||||
@@ -829,4 +940,55 @@ onMounted(() => {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 通用/MAA 配置遮罩样式(用于全局覆盖) */
|
||||||
|
.maa-config-mask {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-content {
|
||||||
|
background: var(--ant-color-bg-elevated);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
max-width: 480px;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
color: var(--ant-color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-description {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--ant-color-text-secondary);
|
||||||
|
margin: 0 0 24px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,5 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="user-edit-container">
|
<div class="user-edit-container">
|
||||||
|
<!-- MAA配置遮罩层 -->
|
||||||
|
<teleport to="body">
|
||||||
|
<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="maaWebsocketId"
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
@click="handleSaveMAAConfig"
|
||||||
|
>
|
||||||
|
保存配置
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</teleport>
|
||||||
<!-- 头部组件 -->
|
<!-- 头部组件 -->
|
||||||
<MAAUserEditHeader
|
<MAAUserEditHeader
|
||||||
:script-id="scriptId"
|
:script-id="scriptId"
|
||||||
@@ -104,13 +130,14 @@
|
|||||||
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
|
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
import { SaveOutlined } from '@ant-design/icons-vue'
|
import { SaveOutlined, SettingOutlined } from '@ant-design/icons-vue'
|
||||||
import type { FormInstance, Rule } from 'ant-design-vue/es/form'
|
import type { FormInstance, Rule } from 'ant-design-vue/es/form'
|
||||||
import { useUserApi } from '@/composables/useUserApi'
|
import { useUserApi } from '@/composables/useUserApi'
|
||||||
import { useScriptApi } from '@/composables/useScriptApi'
|
import { useScriptApi } from '@/composables/useScriptApi'
|
||||||
import { usePlanApi } from '@/composables/usePlanApi'
|
import { usePlanApi } from '@/composables/usePlanApi'
|
||||||
import { useWebSocket } from '@/composables/useWebSocket'
|
import { useWebSocket } from '@/composables/useWebSocket'
|
||||||
import { Service } from '@/api'
|
import { Service } from '@/api'
|
||||||
|
import { TaskCreateIn } from '@/api/models/TaskCreateIn'
|
||||||
import { GetStageIn } from '@/api/models/GetStageIn'
|
import { GetStageIn } from '@/api/models/GetStageIn'
|
||||||
import { getTodayWeekdayEast12 } from '@/utils/dateUtils'
|
import { getTodayWeekdayEast12 } from '@/utils/dateUtils'
|
||||||
|
|
||||||
@@ -143,6 +170,8 @@ const scriptName = ref('')
|
|||||||
// MAA配置相关
|
// MAA配置相关
|
||||||
const maaConfigLoading = ref(false)
|
const maaConfigLoading = ref(false)
|
||||||
const maaWebsocketId = ref<string | null>(null)
|
const maaWebsocketId = ref<string | null>(null)
|
||||||
|
const showMAAConfigMask = ref(false)
|
||||||
|
let maaConfigTimeout: number | null = null
|
||||||
|
|
||||||
// 基建配置文件相关
|
// 基建配置文件相关
|
||||||
const infrastructureConfigPath = ref('')
|
const infrastructureConfigPath = ref('')
|
||||||
@@ -741,28 +770,96 @@ const handleMAAConfig = async () => {
|
|||||||
if (maaWebsocketId.value) {
|
if (maaWebsocketId.value) {
|
||||||
unsubscribe(maaWebsocketId.value)
|
unsubscribe(maaWebsocketId.value)
|
||||||
maaWebsocketId.value = null
|
maaWebsocketId.value = null
|
||||||
|
showMAAConfigMask.value = false
|
||||||
|
if (maaConfigTimeout) {
|
||||||
|
window.clearTimeout(maaConfigTimeout)
|
||||||
|
maaConfigTimeout = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 直接订阅(旧 connect 参数移除)
|
// 调用后端启动任务接口,传入 userId 作为 taskId 与设置模式
|
||||||
const subId = userId
|
const response = await Service.addTaskApiDispatchStartPost({
|
||||||
subscribe(subId, {
|
taskId: userId,
|
||||||
onError: error => {
|
mode: TaskCreateIn.mode.SettingScriptMode,
|
||||||
console.error(`用户 ${formData.userName} MAA配置错误:`, error)
|
|
||||||
message.error(`MAA配置连接失败: ${error}`)
|
|
||||||
maaWebsocketId.value = null
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
maaWebsocketId.value = subId
|
if (response && response.websocketId) {
|
||||||
message.success(`已开始配置用户 ${formData.userName} 的MAA设置`)
|
const wsId = response.websocketId
|
||||||
|
|
||||||
|
// 订阅 websocket
|
||||||
|
subscribe(wsId, {
|
||||||
|
onMessage: (wsMessage: any) => {
|
||||||
|
if (wsMessage.type === 'error') {
|
||||||
|
console.error(`用户 ${formData.Info?.Name || formData.userName} MAA配置错误:`, wsMessage.data)
|
||||||
|
message.error(`MAA配置连接失败: ${wsMessage.data}`)
|
||||||
|
unsubscribe(wsId)
|
||||||
|
maaWebsocketId.value = null
|
||||||
|
showMAAConfigMask.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wsMessage.data && wsMessage.data.Accomplish) {
|
||||||
|
message.success(`用户 ${formData.Info?.Name || formData.userName} 的配置已完成`)
|
||||||
|
unsubscribe(wsId)
|
||||||
|
maaWebsocketId.value = null
|
||||||
|
showMAAConfigMask.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
maaWebsocketId.value = wsId
|
||||||
|
showMAAConfigMask.value = true
|
||||||
|
message.success(`已开始配置用户 ${formData.Info?.Name || formData.userName} 的MAA设置`)
|
||||||
|
|
||||||
|
// 设置 30 分钟超时自动断开
|
||||||
|
maaConfigTimeout = window.setTimeout(() => {
|
||||||
|
if (maaWebsocketId.value) {
|
||||||
|
const id = maaWebsocketId.value
|
||||||
|
unsubscribe(id)
|
||||||
|
maaWebsocketId.value = null
|
||||||
|
showMAAConfigMask.value = false
|
||||||
|
message.info(`用户 ${formData.Info?.Name || formData.userName} 的配置会话已超时断开`)
|
||||||
|
}
|
||||||
|
maaConfigTimeout = null
|
||||||
|
}, 30 * 60 * 1000)
|
||||||
|
} else {
|
||||||
|
message.error(response?.message || '启动MAA配置失败')
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('MAA配置失败:', error)
|
console.error('启动MAA配置失败:', error)
|
||||||
message.error('MAA配置失败')
|
message.error('启动MAA配置失败')
|
||||||
} finally {
|
} finally {
|
||||||
maaConfigLoading.value = false
|
maaConfigLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSaveMAAConfig = async () => {
|
||||||
|
try {
|
||||||
|
const websocketId = maaWebsocketId.value
|
||||||
|
if (!websocketId) {
|
||||||
|
message.error('未找到活动的配置会话')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await Service.stopTaskApiDispatchStopPost({ taskId: websocketId })
|
||||||
|
if (response && response.code === 200) {
|
||||||
|
unsubscribe(websocketId)
|
||||||
|
maaWebsocketId.value = null
|
||||||
|
showMAAConfigMask.value = false
|
||||||
|
if (maaConfigTimeout) {
|
||||||
|
window.clearTimeout(maaConfigTimeout)
|
||||||
|
maaConfigTimeout = null
|
||||||
|
}
|
||||||
|
message.success('用户的配置已保存')
|
||||||
|
} else {
|
||||||
|
message.error(response.message || '保存配置失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存MAA配置失败:', error)
|
||||||
|
message.error('保存MAA配置失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 验证关卡名称格式
|
// 验证关卡名称格式
|
||||||
const validateStageName = (stageName: string): boolean => {
|
const validateStageName = (stageName: string): boolean => {
|
||||||
if (!stageName || !stageName.trim()) {
|
if (!stageName || !stageName.trim()) {
|
||||||
@@ -1020,4 +1117,55 @@ onMounted(() => {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* MAA 配置遮罩样式(与 Scripts.vue 一致,用于全局覆盖) */
|
||||||
|
.maa-config-mask {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-content {
|
||||||
|
background: var(--ant-color-bg-elevated);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
max-width: 480px;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-icon {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
color: var(--ant-color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-description {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--ant-color-text-secondary);
|
||||||
|
margin: 0 0 24px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user