feat(script): 添加脚本删除功能并优化脚本编辑界面
- 在 ScriptEdit.vue 中添加删除脚本 API 响应类型 - 在 Scripts.vue 和 ScriptTable.vue 中移除冗余样式 - 在 tsconfig.json 中添加路径别名配置 - 重构 useScriptApi.ts 中的 deleteScript 函数,实现真正的脚本删除
This commit is contained in:
@@ -292,7 +292,6 @@ const handleDeleteUser = (user: User) => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 现代化表格样式 */
|
||||
.modern-table :deep(.ant-table) {
|
||||
background: var(--ant-color-bg-container);
|
||||
border-radius: 12px;
|
||||
|
||||
@@ -6,8 +6,9 @@ import type {
|
||||
GeneralScriptConfig,
|
||||
GetScriptsResponse,
|
||||
ScriptDetail,
|
||||
ScriptIndexItem
|
||||
} from '@/types/script'
|
||||
ScriptIndexItem,
|
||||
DeleteScriptResponse
|
||||
} from '../types/script.ts'
|
||||
|
||||
const API_BASE_URL = 'http://localhost:8000/api'
|
||||
|
||||
@@ -173,24 +174,35 @@ export function useScriptApi() {
|
||||
}
|
||||
}
|
||||
|
||||
// 删除脚本(暂时模拟)
|
||||
const deleteScript = async (scriptId: string) => {
|
||||
// 删除脚本
|
||||
const deleteScript = async (scriptId: string): Promise<boolean> => {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/delete/scripts/${scriptId}`, {
|
||||
method: 'DELETE',
|
||||
const response = await fetch(`${API_BASE_URL}/delete/scripts`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ scriptId }),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
const apiResponse: DeleteScriptResponse = await response.json()
|
||||
|
||||
// 根据code判断是否成功(非200就是不成功)
|
||||
if (apiResponse.code !== 200) {
|
||||
throw new Error(apiResponse.message || '删除脚本失败')
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err.message : '删除脚本失败'
|
||||
return null
|
||||
return false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
4
frontend/src/types/electron.d.ts
vendored
4
frontend/src/types/electron.d.ts
vendored
@@ -3,7 +3,9 @@ export {}
|
||||
declare global {
|
||||
interface Window {
|
||||
electronAPI: {
|
||||
openDevTools: () => void
|
||||
openDevTools: () => void,
|
||||
selectFolder: () => Promise<string | null>
|
||||
selectFile: (filters?: Array<{ name: string; extensions: string[] }>) => Promise<string | null>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,3 +169,10 @@ export interface ScriptDetail {
|
||||
config: MAAScriptConfig | GeneralScriptConfig
|
||||
createTime?: string
|
||||
}
|
||||
|
||||
// 删除脚本API响应
|
||||
export interface DeleteScriptResponse {
|
||||
code: number
|
||||
status: string
|
||||
message: string
|
||||
}
|
||||
@@ -4,9 +4,7 @@
|
||||
<div class="header-nav">
|
||||
<a-breadcrumb class="breadcrumb">
|
||||
<a-breadcrumb-item>
|
||||
<router-link to="/scripts" class="breadcrumb-link">
|
||||
脚本管理
|
||||
</router-link>
|
||||
<router-link to="/scripts" class="breadcrumb-link"> 脚本管理</router-link>
|
||||
</a-breadcrumb-item>
|
||||
<a-breadcrumb-item>
|
||||
<div class="breadcrumb-current">
|
||||
@@ -16,12 +14,7 @@
|
||||
alt="MAA"
|
||||
class="breadcrumb-logo"
|
||||
/>
|
||||
<img
|
||||
v-else
|
||||
src="@/assets/AUTO_MAA.png"
|
||||
alt="AUTO MAA"
|
||||
class="breadcrumb-logo"
|
||||
/>
|
||||
<img v-else src="@/assets/AUTO_MAA.png" alt="AUTO MAA" class="breadcrumb-logo" />
|
||||
编辑脚本
|
||||
</div>
|
||||
</a-breadcrumb-item>
|
||||
@@ -29,11 +22,7 @@
|
||||
</div>
|
||||
|
||||
<a-space size="middle">
|
||||
<a-button
|
||||
size="large"
|
||||
@click="handleCancel"
|
||||
class="cancel-button"
|
||||
>
|
||||
<a-button size="large" @click="handleCancel" class="cancel-button">
|
||||
<template #icon>
|
||||
<CloseOutlined />
|
||||
</template>
|
||||
@@ -55,16 +44,9 @@
|
||||
</div>
|
||||
|
||||
<div class="script-edit-content">
|
||||
<a-card
|
||||
:title="getCardTitle()"
|
||||
:loading="pageLoading"
|
||||
class="config-card"
|
||||
>
|
||||
<a-card :title="getCardTitle()" :loading="pageLoading" class="config-card">
|
||||
<template #extra>
|
||||
<a-tag
|
||||
:color="formData.type === 'MAA' ? 'blue' : 'green'"
|
||||
class="type-tag"
|
||||
>
|
||||
<a-tag :color="formData.type === 'MAA' ? 'blue' : 'green'" class="type-tag">
|
||||
{{ formData.type }}
|
||||
</a-tag>
|
||||
</template>
|
||||
@@ -150,11 +132,7 @@
|
||||
class="path-input"
|
||||
readonly
|
||||
/>
|
||||
<a-button
|
||||
size="large"
|
||||
@click="selectMAAPath"
|
||||
class="path-button"
|
||||
>
|
||||
<a-button size="large" @click="selectMAAPath" class="path-button">
|
||||
<template #icon>
|
||||
<FolderOpenOutlined />
|
||||
</template>
|
||||
@@ -345,11 +323,7 @@
|
||||
class="path-input"
|
||||
readonly
|
||||
/>
|
||||
<a-button
|
||||
size="large"
|
||||
@click="selectRootPath"
|
||||
class="path-button"
|
||||
>
|
||||
<a-button size="large" @click="selectRootPath" class="path-button">
|
||||
<template #icon>
|
||||
<FolderOpenOutlined />
|
||||
</template>
|
||||
@@ -385,11 +359,7 @@
|
||||
class="path-input"
|
||||
readonly
|
||||
/>
|
||||
<a-button
|
||||
size="large"
|
||||
@click="selectGamePath"
|
||||
class="path-button"
|
||||
>
|
||||
<a-button size="large" @click="selectGamePath" class="path-button">
|
||||
<template #icon>
|
||||
<FileOutlined />
|
||||
</template>
|
||||
@@ -592,11 +562,7 @@
|
||||
class="path-input"
|
||||
readonly
|
||||
/>
|
||||
<a-button
|
||||
size="large"
|
||||
@click="selectScriptPath"
|
||||
class="path-button"
|
||||
>
|
||||
<a-button size="large" @click="selectScriptPath" class="path-button">
|
||||
<template #icon>
|
||||
<FileOutlined />
|
||||
</template>
|
||||
@@ -623,11 +589,7 @@
|
||||
class="path-input"
|
||||
readonly
|
||||
/>
|
||||
<a-button
|
||||
size="large"
|
||||
@click="selectConfigPath"
|
||||
class="path-button"
|
||||
>
|
||||
<a-button size="large" @click="selectConfigPath" class="path-button">
|
||||
<template #icon>
|
||||
<FileOutlined />
|
||||
</template>
|
||||
@@ -696,11 +658,7 @@
|
||||
class="path-input"
|
||||
readonly
|
||||
/>
|
||||
<a-button
|
||||
size="large"
|
||||
@click="selectLogPath"
|
||||
class="path-button"
|
||||
>
|
||||
<a-button size="large" @click="selectLogPath" class="path-button">
|
||||
<template #icon>
|
||||
<FolderOpenOutlined />
|
||||
</template>
|
||||
@@ -778,19 +736,18 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import type { ScriptType, MAAScriptConfig, GeneralScriptConfig } from '@/types/script'
|
||||
import { useScriptApi } from '@/composables/useScriptApi'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { GeneralScriptConfig, MAAScriptConfig, ScriptType } from '../types/script'
|
||||
import { useScriptApi } from '../composables/useScriptApi'
|
||||
import {
|
||||
SaveOutlined,
|
||||
CloseOutlined,
|
||||
FolderOpenOutlined,
|
||||
FileOutlined,
|
||||
SettingOutlined,
|
||||
QuestionCircleOutlined
|
||||
FolderOpenOutlined,
|
||||
QuestionCircleOutlined,
|
||||
SaveOutlined,
|
||||
} from '@ant-design/icons-vue'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -803,14 +760,14 @@ const scriptId = route.params.id as string
|
||||
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
type: 'MAA' as ScriptType
|
||||
type: 'MAA' as ScriptType,
|
||||
})
|
||||
|
||||
// MAA配置
|
||||
const maaConfig = reactive<MAAScriptConfig>({
|
||||
Info: {
|
||||
Name: '',
|
||||
Path: '.'
|
||||
Path: '.',
|
||||
},
|
||||
Run: {
|
||||
ADBSearchRange: 0,
|
||||
@@ -819,13 +776,13 @@ const maaConfig = reactive<MAAScriptConfig>({
|
||||
ProxyTimesLimit: 0,
|
||||
RoutineTimeLimit: 10,
|
||||
RunTimesLimit: 3,
|
||||
TaskTransitionMethod: 'ExitEmulator'
|
||||
TaskTransitionMethod: 'ExitEmulator',
|
||||
},
|
||||
SubConfigsInfo: {
|
||||
UserData: {
|
||||
instances: []
|
||||
}
|
||||
}
|
||||
instances: [],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// General配置
|
||||
@@ -836,16 +793,16 @@ const generalConfig = reactive<GeneralScriptConfig>({
|
||||
IfForceClose: false,
|
||||
Path: '.',
|
||||
Style: 'Emulator',
|
||||
WaitTime: 0
|
||||
WaitTime: 0,
|
||||
},
|
||||
Info: {
|
||||
Name: '',
|
||||
RootPath: '.'
|
||||
RootPath: '.',
|
||||
},
|
||||
Run: {
|
||||
ProxyTimesLimit: 0,
|
||||
RunTimeLimit: 10,
|
||||
RunTimesLimit: 3
|
||||
RunTimesLimit: 3,
|
||||
},
|
||||
Script: {
|
||||
Arguments: '',
|
||||
@@ -860,18 +817,18 @@ const generalConfig = reactive<GeneralScriptConfig>({
|
||||
LogTimeFormat: '%Y-%m-%d %H:%M:%S',
|
||||
ScriptPath: '.',
|
||||
SuccessLog: '',
|
||||
UpdateConfigMode: 'Never'
|
||||
UpdateConfigMode: 'Never',
|
||||
},
|
||||
SubConfigsInfo: {
|
||||
UserData: {
|
||||
instances: []
|
||||
}
|
||||
}
|
||||
instances: [],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入脚本名称', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '请选择脚本类型', trigger: 'change' }]
|
||||
type: [{ required: true, message: '请选择脚本类型', trigger: 'change' }],
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -1006,7 +963,7 @@ const selectGamePath = async () => {
|
||||
|
||||
const path = await window.electronAPI.selectFile([
|
||||
{ name: '可执行文件', extensions: ['exe'] },
|
||||
{ name: '所有文件', extensions: ['*'] }
|
||||
{ name: '所有文件', extensions: ['*'] },
|
||||
])
|
||||
if (path) {
|
||||
generalConfig.Game.Path = path
|
||||
@@ -1031,7 +988,7 @@ const selectScriptPath = async () => {
|
||||
{ name: 'JavaScript 脚本', extensions: ['js'] },
|
||||
{ name: '批处理文件', extensions: ['bat', 'cmd'] },
|
||||
{ name: 'Shell 脚本', extensions: ['sh'] },
|
||||
{ name: '所有文件', extensions: ['*'] }
|
||||
{ name: '所有文件', extensions: ['*'] },
|
||||
])
|
||||
if (path) {
|
||||
generalConfig.Script.ScriptPath = path
|
||||
@@ -1056,7 +1013,7 @@ const selectConfigPath = async () => {
|
||||
{ name: 'YAML 文件', extensions: ['yaml', 'yml'] },
|
||||
{ name: 'INI 文件', extensions: ['ini', 'conf'] },
|
||||
{ name: 'TOML 文件', extensions: ['toml'] },
|
||||
{ name: '所有文件', extensions: ['*'] }
|
||||
{ name: '所有文件', extensions: ['*'] },
|
||||
])
|
||||
if (path) {
|
||||
generalConfig.Script.ConfigPath = path
|
||||
@@ -1145,9 +1102,6 @@ const getCardTitle = () => {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* 按钮样式 */
|
||||
.cancel-button {
|
||||
padding: 0 12px;
|
||||
@@ -1278,7 +1232,6 @@ const getCardTitle = () => {
|
||||
color: var(--ant-color-primary);
|
||||
}
|
||||
|
||||
/* 现代化输入框 */
|
||||
.modern-input {
|
||||
border-radius: 8px;
|
||||
border: 2px solid var(--ant-color-border);
|
||||
|
||||
@@ -216,33 +216,6 @@ const handleRefresh = () => {
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.add-button {
|
||||
height: 48px;
|
||||
padding: 0 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.add-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(24, 144, 255, 0.4);
|
||||
}
|
||||
|
||||
.refresh-button {
|
||||
height: 48px;
|
||||
padding: 0 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
border-radius: 12px;
|
||||
border: 2px solid var(--ant-color-border);
|
||||
background: var(--ant-color-bg-container);
|
||||
color: var(--ant-color-text);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* 脚本类型选择弹窗样式 */
|
||||
.type-select-modal :deep(.ant-modal-content) {
|
||||
border-radius: 16px;
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
"outDir": "dist-electron",
|
||||
"rootDir": "electron",
|
||||
"esModuleInterop": true,
|
||||
"types": ["node", "electron"]
|
||||
"types": ["node", "electron"],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["electron"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user