refactor(components): 修复代码错误,重新格式化代码
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user