refactor(components): 修复代码错误,重新格式化代码

This commit is contained in:
2025-09-02 14:50:24 +08:00
parent b586e311be
commit 7f622de857
16 changed files with 268 additions and 348 deletions

View File

@@ -252,7 +252,7 @@ onUnmounted(() => {
} }
.log-entry:hover { .log-entry:hover {
background: var(--ant-color-fill-quaternary);
} }
.log-highlight { .log-highlight {
@@ -311,7 +311,7 @@ onUnmounted(() => {
} }
.log-data-content { .log-data-content {
background: var(--ant-color-fill-quaternary);
padding: 8px; padding: 8px;
border-radius: 4px; border-radius: 4px;
margin-top: 4px; margin-top: 4px;

View File

@@ -92,10 +92,9 @@ const md = new MarkdownIt({
const notices = computed(() => Object.keys(props.noticeData)) const notices = computed(() => Object.keys(props.noticeData))
// 当前公告索引 // 当前公告索引
const currentNoticeIndex = computed(() => { computed(() => {
return notices.value.findIndex(title => title === activeNoticeKey.value) return notices.value.findIndex(title => title === activeNoticeKey.value)
}) })
// 渲染 markdown // 渲染 markdown
const renderMarkdown = (content: string) => { const renderMarkdown = (content: string) => {
return md.render(content) return md.render(content)

View File

@@ -211,10 +211,7 @@
剩余关卡: {{ user.Info.Stage_Remain }} 剩余关卡: {{ user.Info.Stage_Remain }}
</a-tag> </a-tag>
<a-tag <a-tag class="info-tag" color="magenta">
class="info-tag"
color="magenta"
>
备注: {{ truncateText(user.Info.Notes) }} 备注: {{ truncateText(user.Info.Notes) }}
</a-tag> </a-tag>
</div> </div>
@@ -270,10 +267,7 @@
<!-- 空状态 --> <!-- 空状态 -->
<div v-else class="empty-users"> <div v-else class="empty-users">
<a-empty <a-empty description="暂无用户" class="compact-empty">
description="暂无用户"
class="compact-empty"
>
<a-button type="primary" size="small" @click="handleAddUser(script)"> <a-button type="primary" size="small" @click="handleAddUser(script)">
<template #icon> <template #icon>
<PlusOutlined /> <PlusOutlined />
@@ -365,23 +359,6 @@ const handleDisconnectMAA = (script: Script) => {
const handleToggleUserStatus = (user: User) => { const handleToggleUserStatus = (user: User) => {
emit('toggleUserStatus', user) emit('toggleUserStatus', user)
} }
function get_annihilation_name(annihilation_name) {
if (annihilation_name == 'Annihilation') {
return '当期剿灭'
}
if (annihilation_name == 'Chernobog@Annihilation') {
return '切尔诺伯格'
}
if (annihilation_name == 'LungmenOutskirts@Annihilation') {
return '龙门外环'
}
if (annihilation_name == 'LungmenDowntown@Annihilation') {
return '龙门市区'
}
return '未开启'
}
const truncateText = (text: string, maxLength: number = 10): string => { const truncateText = (text: string, maxLength: number = 10): string => {
if (!text) return '' if (!text) return ''
return text.length > maxLength ? text.substring(0, maxLength) + '...' : text return text.length > maxLength ? text.substring(0, maxLength) + '...' : text

View File

@@ -23,7 +23,7 @@
<h4>{{ mirror.name }}</h4> <h4>{{ mirror.name }}</h4>
<a-tag v-if="mirror.recommended" color="gold" size="small">推荐</a-tag> <a-tag v-if="mirror.recommended" color="gold" size="small">推荐</a-tag>
</div> </div>
<div class="speed-badge" :class="getSpeedClass(mirror.speed)"> <div class="speed-badge" :class="getSpeedClass(mirror.speed ?? null)">
<span v-if="mirror.speed === null && !testingGitSpeed">未测试</span> <span v-if="mirror.speed === null && !testingGitSpeed">未测试</span>
<span v-else-if="testingGitSpeed">测试中...</span> <span v-else-if="testingGitSpeed">测试中...</span>
<span v-else-if="mirror.speed === 9999">超时</span> <span v-else-if="mirror.speed === 9999">超时</span>
@@ -54,7 +54,7 @@
<div class="mirror-title"> <div class="mirror-title">
<h4>{{ mirror.name }}</h4> <h4>{{ mirror.name }}</h4>
</div> </div>
<div class="speed-badge" :class="getSpeedClass(mirror.speed)"> <div class="speed-badge" :class="getSpeedClass(mirror.speed ?? null)">
<span v-if="mirror.speed === null && !testingGitSpeed">未测试</span> <span v-if="mirror.speed === null && !testingGitSpeed">未测试</span>
<span v-else-if="testingGitSpeed">测试中...</span> <span v-else-if="testingGitSpeed">测试中...</span>
<span v-else-if="mirror.speed === 9999">超时</span> <span v-else-if="mirror.speed === 9999">超时</span>

View File

@@ -23,7 +23,7 @@
<h4>{{ mirror.name }}</h4> <h4>{{ mirror.name }}</h4>
<a-tag v-if="mirror.recommended" color="gold" size="small">推荐</a-tag> <a-tag v-if="mirror.recommended" color="gold" size="small">推荐</a-tag>
</div> </div>
<div class="speed-badge" :class="getSpeedClass(mirror.speed)"> <div class="speed-badge" :class="getSpeedClass(mirror.speed ?? null)">
<span v-if="mirror.speed === null && !testingPipSpeed">未测试</span> <span v-if="mirror.speed === null && !testingPipSpeed">未测试</span>
<span v-else-if="testingPipSpeed">测试中...</span> <span v-else-if="testingPipSpeed">测试中...</span>
<span v-else-if="mirror.speed === 9999">超时</span> <span v-else-if="mirror.speed === 9999">超时</span>
@@ -54,7 +54,7 @@
<div class="mirror-title"> <div class="mirror-title">
<h4>{{ mirror.name }}</h4> <h4>{{ mirror.name }}</h4>
</div> </div>
<div class="speed-badge" :class="getSpeedClass(mirror.speed)"> <div class="speed-badge" :class="getSpeedClass(mirror.speed ?? null)">
<span v-if="mirror.speed === null && !testingPipSpeed">未测试</span> <span v-if="mirror.speed === null && !testingPipSpeed">未测试</span>
<span v-else-if="testingPipSpeed">测试中...</span> <span v-else-if="testingPipSpeed">测试中...</span>
<span v-else-if="mirror.speed === 9999">超时</span> <span v-else-if="mirror.speed === 9999">超时</span>
@@ -80,12 +80,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, computed } from 'vue' import { ref, onMounted, computed } from 'vue'
import { getConfig, saveConfig } from '@/utils/config' import { getConfig, saveConfig } from '@/utils/config'
import { import {
PIP_MIRRORS, PIP_MIRRORS,
getOfficialMirrors, getOfficialMirrors,
getMirrorMirrors, getMirrorMirrors,
sortMirrorsBySpeedAndRecommendation, sortMirrorsBySpeedAndRecommendation,
type MirrorConfig type MirrorConfig,
} from '@/config/mirrors' } from '@/config/mirrors'
const pipMirrors = ref<MirrorConfig[]>(PIP_MIRRORS) const pipMirrors = ref<MirrorConfig[]>(PIP_MIRRORS)
@@ -95,7 +95,9 @@ const officialMirrors = computed(() => getOfficialMirrors('pip'))
const mirrorMirrors = computed(() => getMirrorMirrors('pip')) const mirrorMirrors = computed(() => getMirrorMirrors('pip'))
// 按速度和推荐排序的镜像源 // 按速度和推荐排序的镜像源
const sortedOfficialMirrors = computed(() => sortMirrorsBySpeedAndRecommendation(officialMirrors.value)) const sortedOfficialMirrors = computed(() =>
sortMirrorsBySpeedAndRecommendation(officialMirrors.value)
)
const sortedMirrorMirrors = computed(() => sortMirrorsBySpeedAndRecommendation(mirrorMirrors.value)) const sortedMirrorMirrors = computed(() => sortMirrorsBySpeedAndRecommendation(mirrorMirrors.value))
const selectedPipMirror = ref('aliyun') const selectedPipMirror = ref('aliyun')
@@ -259,8 +261,6 @@ onMounted(async () => {
color: var(--ant-color-text); color: var(--ant-color-text);
} }
.speed-badge { .speed-badge {
padding: 4px 8px; padding: 4px 8px;
border-radius: 4px; border-radius: 4px;
@@ -268,26 +268,6 @@ onMounted(async () => {
font-weight: 500; font-weight: 500;
} }
.speed-badge.speed-unknown {
color: var(--ant-color-text-tertiary);
}
.speed-badge.speed-fast {
color: var(--ant-color-success);
}
.speed-badge.speed-medium {
color: var(--ant-color-warning);
}
.speed-badge.speed-slow {
color: var(--ant-color-error);
}
.speed-badge.speed-timeout {
color: var(--ant-color-error);
}
.mirror-description { .mirror-description {
font-size: 13px; font-size: 13px;
color: var(--ant-color-text-secondary); color: var(--ant-color-text-secondary);
@@ -301,7 +281,6 @@ onMounted(async () => {
word-break: break-all; word-break: break-all;
} }
.section-header { .section-header {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -327,4 +306,4 @@ onMounted(async () => {
font-size: 12px; font-size: 12px;
color: var(--ant-color-text-tertiary); color: var(--ant-color-text-tertiary);
} }
</style> </style>

View File

@@ -105,17 +105,4 @@ defineExpose({
gap: 20px; gap: 20px;
} }
.reinstall-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.reinstall-note {
font-size: 12px;
color: var(--ant-color-text-tertiary);
text-align: center;
margin: 0;
}
</style> </style>

View File

@@ -160,10 +160,6 @@ const dependenciesStepRef = ref()
const serviceStepRef = ref() const serviceStepRef = ref()
// 事件处理 // 事件处理
function handleSkipToHome() {
props.onSkipToHome()
}
function handleJumpToStep(step: number) { function handleJumpToStep(step: number) {
currentStep.value = step currentStep.value = step
} }

View File

@@ -23,7 +23,7 @@
<h4>{{ mirror.name }}</h4> <h4>{{ mirror.name }}</h4>
<a-tag v-if="mirror.recommended" color="gold" size="small">推荐</a-tag> <a-tag v-if="mirror.recommended" color="gold" size="small">推荐</a-tag>
</div> </div>
<div class="speed-badge" :class="getSpeedClass(mirror.speed)"> <div class="speed-badge" :class="getSpeedClass(mirror.speed ?? null)">
<span v-if="mirror.speed === null && !testingSpeed">未测试</span> <span v-if="mirror.speed === null && !testingSpeed">未测试</span>
<span v-else-if="testingSpeed">测试中...</span> <span v-else-if="testingSpeed">测试中...</span>
<span v-else-if="mirror.speed === 9999">超时</span> <span v-else-if="mirror.speed === 9999">超时</span>
@@ -54,7 +54,7 @@
<div class="mirror-title"> <div class="mirror-title">
<h4>{{ mirror.name }}</h4> <h4>{{ mirror.name }}</h4>
</div> </div>
<div class="speed-badge" :class="getSpeedClass(mirror.speed)"> <div class="speed-badge" :class="getSpeedClass(mirror.speed ?? null)">
<span v-if="mirror.speed === null && !testingSpeed">未测试</span> <span v-if="mirror.speed === null && !testingSpeed">未测试</span>
<span v-else-if="testingSpeed">测试中...</span> <span v-else-if="testingSpeed">测试中...</span>
<span v-else-if="mirror.speed === 9999">超时</span> <span v-else-if="mirror.speed === 9999">超时</span>

View File

@@ -48,7 +48,6 @@
</template> </template>
</a-table> </a-table>
<!-- 队列项编辑弹窗 --> <!-- 队列项编辑弹窗 -->
<a-modal <a-modal
v-model:open="modalVisible" v-model:open="modalVisible"
@@ -73,17 +72,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch, onMounted, h } from 'vue' import { onMounted, reactive, ref, watch } from 'vue'
import { message } from 'ant-design-vue'
import {
PlusOutlined,
ReloadOutlined,
EditOutlined,
DeleteOutlined,
MoreOutlined,
} from '@ant-design/icons-vue'
import { Service } from '@/api'
import type { FormInstance } from 'ant-design-vue' import type { FormInstance } from 'ant-design-vue'
import { message } from 'ant-design-vue'
import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { Service } from '@/api'
// Props // Props
interface Props { interface Props {

View File

@@ -89,11 +89,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch } from 'vue' import { reactive, ref, watch } from 'vue'
import { message } from 'ant-design-vue'
import { PlusOutlined, ReloadOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import { Service } from '@/api'
import type { FormInstance } from 'ant-design-vue' import type { FormInstance } from 'ant-design-vue'
import { message } from 'ant-design-vue'
import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { Service } from '@/api'
import dayjs from 'dayjs' import dayjs from 'dayjs'
// 时间处理工具函数 // 时间处理工具函数
@@ -192,11 +192,6 @@ watch(
{ deep: true, immediate: true } { deep: true, immediate: true }
) )
// 刷新数据
const refreshData = () => {
emit('refresh')
}
// 添加定时项 // 添加定时项
const addTimeSet = () => { const addTimeSet = () => {
editingTimeSet.value = null editingTimeSet.value = null
@@ -372,14 +367,12 @@ const deleteTimeSet = async (timeSetId: string) => {
font-weight: 600; font-weight: 600;
} }
/* 表格样式优化 */ /* 表格样式优化 */
:deep(.ant-table-tbody > tr > td) { :deep(.ant-table-tbody > tr > td) {
padding: 12px 16px; padding: 12px 16px;
} }
:deep(.ant-table-thead > tr > th) { :deep(.ant-table-thead > tr > th) {
background: var(--ant-color-fill-quaternary);
font-weight: 600; font-weight: 600;
} }
@@ -398,10 +391,9 @@ const deleteTimeSet = async (timeSetId: string) => {
font-weight: 600; font-weight: 600;
color: var(--ant-color-text); color: var(--ant-color-text);
padding: 4px 8px; padding: 4px 8px;
background: var(--ant-color-fill-quaternary);
border-radius: 4px; border-radius: 4px;
display: inline-block; display: inline-block;
min-width: 60px; min-width: 60px;
text-align: center; text-align: center;
} }
</style> </style>

View File

@@ -89,40 +89,40 @@ const router = createRouter({
routes, routes,
}) })
// // 添加路由守卫,确保在生产环境中也能正确进入初始化页面 // 添加路由守卫,确保在生产环境中也能正确进入初始化页面
// router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
// console.log('路由守卫:', { to: to.path, from: from.path }) console.log('路由守卫:', { to: to.path, from: from.path })
//
// // 如果目标就是初始化页,放行并清除一次性标记,避免反复跳转 // 如果目标就是初始化页,放行并清除一次性标记,避免反复跳转
// if (to.path === '/initialization') { if (to.path === '/initialization') {
// needInitLanding = false needInitLanding = false
// next() next()
// return return
// } }
//
// // (可选)开发环境跳过检查,可按需恢复 // (可选)开发环境跳过检查,可按需恢复
// const isDev = import.meta.env.VITE_APP_ENV === 'dev' const isDev = import.meta.env.VITE_APP_ENV === 'dev'
// if (isDev) return next() if (isDev) return next()
//
// // 先按原逻辑:未初始化 => 强制进入初始化 // 先按原逻辑:未初始化 => 强制进入初始化
// const initialized = await isAppInitialized() const initialized = await isAppInitialized()
// console.log('检查初始化状态:', initialized) console.log('检查初始化状态:', initialized)
// if (!initialized) { if (!initialized) {
// needInitLanding = false // 以免重复重定向 needInitLanding = false // 以免重复重定向
// next('/initialization') next('/initialization')
// return return
// } }
//
// // 已初始化:如果是“本次启动的第一次进入”,也先去初始化页一次 // 已初始化:如果是“本次启动的第一次进入”,也先去初始化页一次
// if (needInitLanding) { if (needInitLanding) {
// needInitLanding = false needInitLanding = false
// next({ path: '/initialization', query: { redirect: to.fullPath } }) next({ path: '/initialization', query: { redirect: to.fullPath } })
// return return
// } }
//
// // 其他情况正常放行 // 其他情况正常放行
// next() next()
// }) })
export default router export default router

View File

@@ -724,7 +724,7 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: var(--ant-color-fill-quaternary);
border-radius: 6px; border-radius: 6px;
overflow: hidden; overflow: hidden;
} }

View File

@@ -1,208 +1,196 @@
<template> <template>
<!-- 加载状态 --> <!-- 加载状态 -->
<div v-if="loading" class="loading-container"> <div v-if="loading" class="loading-container">
<a-spin size="large" tip="加载中,请稍候..." /> <a-spin size="large" tip="加载中,请稍候..." />
</div> </div>
<!-- 主要内容 --> <!-- 主要内容 -->
<div v-else class="plans-main"> <div v-else class="plans-main">
<!-- 页面头部 --> <!-- 页面头部 -->
<div class="plans-header"> <div class="plans-header">
<div class="header-left"> <div class="header-left">
<h1 class="page-title">计划管理</h1> <h1 class="page-title">计划管理</h1>
</div>
<div class="header-actions">
<a-space size="middle">
<a-button
type="primary"
size="large"
@click="handleAddPlan"
v-if="planList.length > 0 || currentPlanData"
>
<template #icon>
<PlusOutlined />
</template>
新建计划
</a-button>
<a-popconfirm
v-if="planList.length > 0"
title="确定要删除这个计划吗?"
ok-text="确定"
cancel-text="取消"
@confirm="handleRemovePlan(activePlanId)"
>
<a-button
danger
size="large"
:disabled="!activePlanId"
>
<template #icon>
<DeleteOutlined />
</template>
删除当前计划
</a-button>
</a-popconfirm>
<a-button size="large" @click="handleRefresh">
<template #icon>
<ReloadOutlined />
</template>
刷新
</a-button>
</a-space>
</div>
</div> </div>
<div class="header-actions">
<!-- 空状态 --> <a-space size="middle">
<div v-if="!planList.length || !currentPlanData" class="empty-state"> <a-button
<a-empty type="primary"
image="https://gw.alipayobjects.com/zos/antfincdn/ZHrcdLPrvN/empty.svg" size="large"
:image-style="{ height: '120px' }" @click="handleAddPlan"
description="当前没有计划" v-if="planList.length > 0 || currentPlanData"
> >
<template #description>
<span class="empty-description">
您还没有创建任何计划点击下方按钮来创建您的第一个计划
</span>
</template>
<a-button type="primary" size="large" @click="handleAddPlan">
<template #icon> <template #icon>
<PlusOutlined /> <PlusOutlined />
</template> </template>
新建计划 新建计划
</a-button> </a-button>
</a-empty>
</div>
<!-- 计划内容 --> <a-popconfirm
<div v-else class="plans-content"> v-if="planList.length > 0"
<!-- 计划选择卡片 --> title="确定要删除这个计划吗?"
<a-card class="plan-selector-card" :bordered="false"> ok-text="确定"
<template #title> cancel-text="取消"
<div class="card-title"> @confirm="handleRemovePlan(activePlanId)"
<span>计划选择</span> >
<a-tag :color="planList.length > 0 ? 'success' : 'default'"> <a-button danger size="large" :disabled="!activePlanId">
{{ planList.length }} 个计划 <template #icon>
</a-tag> <DeleteOutlined />
</div>
</template>
<div class="plan-selection-container">
<!-- 计划按钮组 -->
<div class="plan-buttons-container">
<a-space wrap size="middle">
<a-button
v-for="plan in planList"
:key="plan.id"
:type="activePlanId === plan.id ? 'primary' : 'default'"
size="large"
@click="onPlanChange(plan.id)"
class="plan-button"
>
{{ plan.name }}
</a-button>
</a-space>
</div>
</div>
</a-card>
<!-- 计划配置卡片 -->
<a-card class="plan-config-card" :bordered="false">
<template #title>
<div class="plan-title-container">
<div v-if="!isEditingPlanName" class="plan-title-display">
<span class="plan-title-text">{{ currentPlanName || '计划配置' }}</span>
<a-button
type="text"
size="small"
@click="startEditPlanName"
class="plan-edit-btn"
>
<template #icon>
<EditOutlined />
</template>
</a-button>
</div>
<div v-else class="plan-title-edit">
<a-input
v-model:value="currentPlanName"
placeholder="请输入计划名称"
size="small"
class="plan-title-input"
@blur="finishEditPlanName"
@pressEnter="finishEditPlanName"
:maxlength="50"
ref="planNameInputRef"
/>
</div>
</div>
</template>
<template #extra>
<a-space>
<span class="mode-label">执行模式</span>
<a-segmented
v-model:value="currentMode"
@change="onModeChange"
:options="[
{ label: '全局模式', value: 'ALL' },
{ label: '周计划模式', value: 'Weekly' }
]"
/>
</a-space>
</template>
<!-- 配置表格 -->
<div class="config-table-container">
<a-table
:columns="dynamicTableColumns"
:data-source="tableData"
:pagination="false"
class="config-table"
size="middle"
:bordered="true"
:scroll="{ x: false }"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'taskName'">
<div class="task-name-cell">
<a-tag
:color="getTaskTagColor(record.taskName)"
class="task-tag"
>
{{ record.taskName }}
</a-tag>
</div>
</template>
<template v-else-if="record.taskName === '吃理智药'">
<a-input-number
v-model:value="record[column.key]"
size="small"
:min="0"
:max="999"
:placeholder="getPlaceholder(column.key, record.taskName)"
class="config-input-number"
:controls="false"
/>
</template>
<template v-else>
<a-select
v-model:value="record[column.key]"
size="small"
:options="getSelectOptions(column.key, record.taskName)"
:placeholder="getPlaceholder(column.key, record.taskName)"
class="config-select"
allow-clear
:show-search="true"
:filter-option="filterOption"
/>
</template>
</template> </template>
</a-table> 删除当前计划
</div> </a-button>
</a-card> </a-popconfirm>
<a-button size="large" @click="handleRefresh">
<template #icon>
<ReloadOutlined />
</template>
刷新
</a-button>
</a-space>
</div> </div>
</div> </div>
<!-- 空状态 -->
<div v-if="!planList.length || !currentPlanData" class="empty-state">
<a-empty
image="https://gw.alipayobjects.com/zos/antfincdn/ZHrcdLPrvN/empty.svg"
:image-style="{ height: '120px' }"
description="当前没有计划"
>
<template #description>
<span class="empty-description">
您还没有创建任何计划点击下方按钮来创建您的第一个计划
</span>
</template>
<a-button type="primary" size="large" @click="handleAddPlan">
<template #icon>
<PlusOutlined />
</template>
新建计划
</a-button>
</a-empty>
</div>
<!-- 计划内容 -->
<div v-else class="plans-content">
<!-- 计划选择卡片 -->
<a-card class="plan-selector-card" :bordered="false">
<template #title>
<div class="card-title">
<span>计划选择</span>
<a-tag :color="planList.length > 0 ? 'success' : 'default'">
{{ planList.length }} 个计划
</a-tag>
</div>
</template>
<div class="plan-selection-container">
<!-- 计划按钮组 -->
<div class="plan-buttons-container">
<a-space wrap size="middle">
<a-button
v-for="plan in planList"
:key="plan.id"
:type="activePlanId === plan.id ? 'primary' : 'default'"
size="large"
@click="onPlanChange(plan.id)"
class="plan-button"
>
{{ plan.name }}
</a-button>
</a-space>
</div>
</div>
</a-card>
<!-- 计划配置卡片 -->
<a-card class="plan-config-card" :bordered="false">
<template #title>
<div class="plan-title-container">
<div v-if="!isEditingPlanName" class="plan-title-display">
<span class="plan-title-text">{{ currentPlanName || '计划配置' }}</span>
<a-button type="text" size="small" @click="startEditPlanName" class="plan-edit-btn">
<template #icon>
<EditOutlined />
</template>
</a-button>
</div>
<div v-else class="plan-title-edit">
<a-input
v-model:value="currentPlanName"
placeholder="请输入计划名称"
size="small"
class="plan-title-input"
@blur="finishEditPlanName"
@pressEnter="finishEditPlanName"
:maxlength="50"
ref="planNameInputRef"
/>
</div>
</div>
</template>
<template #extra>
<a-space>
<span class="mode-label">执行模式</span>
<a-segmented
v-model:value="currentMode"
@change="onModeChange"
:options="[
{ label: '全局模式', value: 'ALL' },
{ label: '周计划模式', value: 'Weekly' },
]"
/>
</a-space>
</template>
<!-- 配置表格 -->
<div class="config-table-container">
<a-table
:columns="dynamicTableColumns"
:data-source="tableData"
:pagination="false"
class="config-table"
size="middle"
:bordered="true"
:scroll="{ x: false }"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'taskName'">
<div class="task-name-cell">
<a-tag :color="getTaskTagColor(record.taskName)" class="task-tag">
{{ record.taskName }}
</a-tag>
</div>
</template>
<template v-else-if="record.taskName === '吃理智药'">
<a-input-number
v-model:value="record[column.key]"
size="small"
:min="0"
:max="999"
:placeholder="getPlaceholder(column.key, record.taskName)"
class="config-input-number"
:controls="false"
/>
</template>
<template v-else>
<a-select
v-model:value="record[column.key]"
size="small"
:options="getSelectOptions(column.key, record.taskName)"
:placeholder="getPlaceholder(column.key, record.taskName)"
class="config-select"
allow-clear
:show-search="true"
:filter-option="filterOption"
/>
</template>
</template>
</a-table>
</div>
</a-card>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -539,7 +527,7 @@ const handleSave = async () => {
const handleAddPlan = async () => { const handleAddPlan = async () => {
try { try {
const response = await createPlan('MaaPlan') const response = await createPlan('MaaPlan')
const defaultName = '新MAA计划表' const defaultName = '新 MAA 计划表'
const newPlan = { const newPlan = {
id: response.planId, id: response.planId,
name: defaultName, name: defaultName,
@@ -741,13 +729,13 @@ onMounted(() => {
// 新增方法:获取任务标签颜色 // 新增方法:获取任务标签颜色
const getTaskTagColor = (taskName: string) => { const getTaskTagColor = (taskName: string) => {
const colorMap: Record<string, string> = { const colorMap: Record<string, string> = {
'吃理智药': 'blue', 吃理智药: 'blue',
'连战次数': 'green', 连战次数: 'green',
'关卡选择': 'orange', 关卡选择: 'orange',
'备选-1': 'purple', '备选-1': 'purple',
'备选-2': 'purple', '备选-2': 'purple',
'备选-3': 'purple', '备选-3': 'purple',
'剩余理智': 'cyan' 剩余理智: 'cyan',
} }
return colorMap[taskName] || 'default' return colorMap[taskName] || 'default'
} }

View File

@@ -520,7 +520,7 @@ const handleAddQueue = async () => {
const response = await Service.addQueueApiQueueAddPost() const response = await Service.addQueueApiQueueAddPost()
if (response.code === 200 && response.queueId) { if (response.code === 200 && response.queueId) {
const defaultName = '新调度队列' const defaultName = '新队列'
const newQueue = { const newQueue = {
id: response.queueId, id: response.queueId,
name: defaultName, name: defaultName,

View File

@@ -242,18 +242,17 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref, onUnmounted, computed } from 'vue' import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import { import {
PlusOutlined,
ReloadOutlined,
FileTextOutlined,
SettingOutlined,
ClockCircleOutlined, ClockCircleOutlined,
FileSearchOutlined, FileSearchOutlined,
FileTextOutlined,
PlusOutlined,
ReloadOutlined,
SettingOutlined,
UserOutlined, UserOutlined,
CheckCircleFilled,
} from '@ant-design/icons-vue' } from '@ant-design/icons-vue'
import ScriptTable from '@/components/ScriptTable.vue' import ScriptTable from '@/components/ScriptTable.vue'
import type { Script, ScriptType, User } from '@/types/script' import type { Script, ScriptType, User } from '@/types/script'

View File

@@ -1,13 +1,23 @@
{ {
"extends": "./tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"target": "ES2020", "target": "ES2020",
"module": "CommonJS", "module": "CommonJS",
"moduleResolution": "Node",
"strict": true, "strict": true,
"outDir": "dist-electron",
"rootDir": "electron", "rootDir": "electron",
"outDir": "dist-electron",
"esModuleInterop": true, "esModuleInterop": true,
"types": ["node", "electron"] "allowSyntheticDefaultImports": true,
"types": ["node", "electron"],
// 仅供 IDE 跳转可选加入(不影响运行)
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] },
// 关键:不要把 ESM import 原样保留,交给 TS 转成 require
"verbatimModuleSyntax": false
}, },
"include": ["electron"] "include": ["electron"]
} }