From dc271273220312771eba21c49dd3921b5e0bd664 Mon Sep 17 00:00:00 2001 From: AoXuan Date: Mon, 25 Aug 2025 13:25:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(script):=20=E9=87=8D=E6=9E=84=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E5=88=97=E8=A1=A8=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/composables/useScriptApi.ts | 191 +++++++++++++++++++++++ frontend/src/composables/useUserApi.ts | 35 ++++- frontend/src/types/script.ts | 1 + frontend/src/views/Scripts.vue | 111 ++----------- frontend/src/views/UserEdit.vue | 92 ++++++----- 5 files changed, 289 insertions(+), 141 deletions(-) diff --git a/frontend/src/composables/useScriptApi.ts b/frontend/src/composables/useScriptApi.ts index 6482e6d..cb20990 100644 --- a/frontend/src/composables/useScriptApi.ts +++ b/frontend/src/composables/useScriptApi.ts @@ -77,6 +77,196 @@ export function useScriptApi() { } } + // 获取脚本列表及其用户数据 + const getScriptsWithUsers = async (): Promise => { + loading.value = true + error.value = null + + try { + // 首先获取脚本列表 + const scriptDetails = await getScripts() + + // 为每个脚本获取用户数据 + const scriptsWithUsers = await Promise.all( + scriptDetails.map(async (script) => { + try { + // 获取该脚本下的用户列表 + const userResponse = await Service.getUserApiScriptsUserGetPost({ + scriptId: script.uid + }) + + if (userResponse.code === 200) { + // 将用户数据转换为User格式 + const users = userResponse.index.map(userIndex => { + const userData = userResponse.data[userIndex.uid] + + if (userIndex.type === 'MaaUserConfig' && userData) { + const maaUserData = userData as any + return { + id: userIndex.uid, + name: maaUserData.Info?.Name || `用户${userIndex.uid}`, + Info: { + Name: maaUserData.Info?.Name || `用户${userIndex.uid}`, + Id: maaUserData.Info?.Id || '', + Password: maaUserData.Info?.Password || '', + Server: maaUserData.Info?.Server || '官服', + MedicineNumb: maaUserData.Info?.MedicineNumb || 0, + RemainedDay: maaUserData.Info?.RemainedDay || 0, + SeriesNumb: maaUserData.Info?.SeriesNumb || '', + Notes: maaUserData.Info?.Notes || '', + Status: maaUserData.Info?.Status !== undefined ? maaUserData.Info.Status : true, + Mode: maaUserData.Info?.Mode || 'MAA', + InfrastMode: maaUserData.Info?.InfrastMode || '默认', + Routine: maaUserData.Info?.Routine !== undefined ? maaUserData.Info.Routine : true, + Annihilation: maaUserData.Info?.Annihilation || '当期', + Stage: maaUserData.Info?.Stage || '1-7', + StageMode: maaUserData.Info?.StageMode || '刷完即停', + Stage_1: maaUserData.Info?.Stage_1 || '', + Stage_2: maaUserData.Info?.Stage_2 || '', + Stage_3: maaUserData.Info?.Stage_3 || '', + Stage_Remain: maaUserData.Info?.Stage_Remain || '', + IfSkland: maaUserData.Info?.IfSkland || false, + SklandToken: maaUserData.Info?.SklandToken || '', + }, + Task: { + IfBase: maaUserData.Task?.IfBase !== undefined ? maaUserData.Task.IfBase : true, + IfCombat: maaUserData.Task?.IfCombat !== undefined ? maaUserData.Task.IfCombat : true, + IfMall: maaUserData.Task?.IfMall !== undefined ? maaUserData.Task.IfMall : true, + IfMission: maaUserData.Task?.IfMission !== undefined ? maaUserData.Task.IfMission : true, + IfRecruiting: maaUserData.Task?.IfRecruiting !== undefined ? maaUserData.Task.IfRecruiting : true, + IfReclamation: maaUserData.Task?.IfReclamation || false, + IfAutoRoguelike: maaUserData.Task?.IfAutoRoguelike || false, + IfWakeUp: maaUserData.Task?.IfWakeUp || false, + }, + Notify: { + Enabled: maaUserData.Notify?.Enabled || false, + ToAddress: maaUserData.Notify?.ToAddress || '', + IfSendMail: maaUserData.Notify?.IfSendMail || false, + IfSendSixStar: maaUserData.Notify?.IfSendSixStar || false, + IfSendStatistic: maaUserData.Notify?.IfSendStatistic || false, + IfServerChan: maaUserData.Notify?.IfServerChan || false, + IfCompanyWebHookBot: maaUserData.Notify?.IfCompanyWebHookBot || false, + ServerChanKey: maaUserData.Notify?.ServerChanKey || '', + ServerChanChannel: maaUserData.Notify?.ServerChanChannel || '', + ServerChanTag: maaUserData.Notify?.ServerChanTag || '', + CompanyWebHookBotUrl: maaUserData.Notify?.CompanyWebHookBotUrl || '', + }, + Data: { + CustomInfrastPlanIndex: maaUserData.Data?.CustomInfrastPlanIndex || '', + IfPassCheck: maaUserData.Data?.IfPassCheck || false, + LastAnnihilationDate: maaUserData.Data?.LastAnnihilationDate || '', + LastProxyDate: maaUserData.Data?.LastProxyDate || '', + LastSklandDate: maaUserData.Data?.LastSklandDate || '', + ProxyTimes: maaUserData.Data?.ProxyTimes || 0, + }, + QFluentWidgets: { + ThemeColor: maaUserData.QFluentWidgets?.ThemeColor || 'blue', + ThemeMode: maaUserData.QFluentWidgets?.ThemeMode || 'system', + }, + } + } else if (userIndex.type === 'GeneralUserConfig' && userData) { + const generalUserData = userData as any + return { + id: userIndex.uid, + name: generalUserData.Info?.Name || `用户${userIndex.uid}`, + Info: { + Name: generalUserData.Info?.Name || `用户${userIndex.uid}`, + Id: generalUserData.Info?.Id || '', + Password: generalUserData.Info?.Password || '', + Server: generalUserData.Info?.Server || '官服', + MedicineNumb: 0, + RemainedDay: 0, + SeriesNumb: '', + Notes: generalUserData.Info?.Notes || '', + Status: generalUserData.Info?.Status !== undefined ? generalUserData.Info.Status : true, + Mode: 'General', + InfrastMode: '默认', + Routine: true, + Annihilation: '当期', + Stage: '1-7', + StageMode: '刷完即停', + Stage_1: '', + Stage_2: '', + Stage_3: '', + Stage_Remain: '', + IfSkland: false, + SklandToken: '', + }, + Task: { + IfBase: true, + IfCombat: true, + IfMall: true, + IfMission: true, + IfRecruiting: true, + IfReclamation: false, + IfAutoRoguelike: false, + IfWakeUp: false, + }, + Notify: { + Enabled: false, + ToAddress: '', + IfSendMail: false, + IfSendSixStar: false, + IfSendStatistic: false, + IfServerChan: false, + IfCompanyWebHookBot: false, + ServerChanKey: '', + ServerChanChannel: '', + ServerChanTag: '', + CompanyWebHookBotUrl: '', + }, + Data: { + CustomInfrastPlanIndex: '', + IfPassCheck: false, + LastAnnihilationDate: '', + LastProxyDate: '', + LastSklandDate: '', + ProxyTimes: 0, + }, + QFluentWidgets: { + ThemeColor: 'blue', + ThemeMode: 'system', + }, + } + } + + return null + }).filter(user => user !== null) + + return { + ...script, + users + } + } else { + // 如果获取用户失败,返回空用户列表的脚本 + return { + ...script, + users: [] + } + } + } catch (err) { + console.warn(`获取脚本 ${script.uid} 的用户数据失败:`, err) + return { + ...script, + users: [] + } + } + }) + ) + + return scriptsWithUsers + } catch (err) { + const errorMsg = err instanceof Error ? err.message : '获取脚本列表失败' + error.value = errorMsg + if (!err.message?.includes('HTTP error')) { + message.error(errorMsg) + } + return [] + } finally { + loading.value = false + } + } + // 获取单个脚本 const getScript = async (scriptId: string): Promise => { loading.value = true @@ -185,6 +375,7 @@ export function useScriptApi() { error, addScript, getScripts, + getScriptsWithUsers, getScript, deleteScript, updateScript, diff --git a/frontend/src/composables/useUserApi.ts b/frontend/src/composables/useUserApi.ts index 5137733..5362356 100644 --- a/frontend/src/composables/useUserApi.ts +++ b/frontend/src/composables/useUserApi.ts @@ -1,7 +1,7 @@ import { ref } from 'vue' import { message } from 'ant-design-vue' import { Service } from '@/api' -import type { UserInBase, UserCreateOut, UserUpdateIn, UserDeleteIn } from '@/api' +import type { UserInBase, UserCreateOut, UserUpdateIn, UserDeleteIn, UserGetIn } from '@/api' export function useUserApi() { const loading = ref(false) @@ -76,6 +76,38 @@ export function useUserApi() { } } + // 获取用户列表 + const getUsers = async (scriptId: string, userId?: string) => { + loading.value = true + error.value = null + + try { + const requestData: UserGetIn = { + scriptId, + userId: userId || null, + } + + const response = await Service.getUserApiScriptsUserGetPost(requestData) + + if (response.code !== 200) { + const errorMsg = response.message || '获取用户列表失败' + message.error(errorMsg) + throw new Error(errorMsg) + } + + return response + } catch (err) { + const errorMsg = err instanceof Error ? err.message : '获取用户列表失败' + error.value = errorMsg + if (!err.message?.includes('HTTP error')) { + message.error(errorMsg) + } + return null + } finally { + loading.value = false + } + } + // 删除用户 const deleteUser = async (scriptId: string, userId: string): Promise => { loading.value = true @@ -113,6 +145,7 @@ export function useUserApi() { loading, error, addUser, + getUsers, updateUser, deleteUser, } diff --git a/frontend/src/types/script.ts b/frontend/src/types/script.ts index ad9a1d2..1a92209 100644 --- a/frontend/src/types/script.ts +++ b/frontend/src/types/script.ts @@ -167,6 +167,7 @@ export interface ScriptDetail { type: ScriptType name: string config: MAAScriptConfig | GeneralScriptConfig + users?: User[] createTime?: string } diff --git a/frontend/src/views/Scripts.vue b/frontend/src/views/Scripts.vue index a19f1ae..2e3b219 100644 --- a/frontend/src/views/Scripts.vue +++ b/frontend/src/views/Scripts.vue @@ -80,7 +80,7 @@ import { useScriptApi } from '@/composables/useScriptApi' import { useUserApi } from '@/composables/useUserApi' const router = useRouter() -const { addScript, deleteScript, getScripts, loading } = useScriptApi() +const { addScript, deleteScript, getScriptsWithUsers, loading } = useScriptApi() const { addUser, updateUser, deleteUser, loading: userLoading } = useUserApi() const scripts = ref([]) @@ -94,108 +94,17 @@ onMounted(() => { const loadScripts = async () => { try { - const scriptDetails = await getScripts() + const scriptDetails = await getScriptsWithUsers() // 将 ScriptDetail 转换为 Script 格式(为了兼容现有的表格组件) - scripts.value = scriptDetails.map(detail => { - // 从配置中提取用户数据 - const users: User[] = [] - - // 检查配置中是否有用户数据 - if (detail.config && typeof detail.config === 'object') { - const config = detail.config as any - - // 检查 SubConfigsInfo.UserData.instances - if ( - config.SubConfigsInfo?.UserData?.instances && - Array.isArray(config.SubConfigsInfo.UserData.instances) - ) { - config.SubConfigsInfo.UserData.instances.forEach((instance: any, index: number) => { - if (instance && typeof instance === 'object' && instance.uid) { - // 从用户数据中获取实际的用户信息 - const userData = config.SubConfigsInfo.UserData[instance.uid] - if (userData) { - // 创建用户对象,使用真实的用户数据 - const user: User = { - id: instance.uid, // 使用真实的用户ID - name: userData.Info?.Name || `用户${index + 1}`, - Info: { - Name: userData.Info?.Name || `用户${index + 1}`, - Id: userData.Info?.Id || '', - Password: userData.Info?.Password || '', - Server: userData.Info?.Server || '官服', - MedicineNumb: userData.Info?.MedicineNumb || 0, - RemainedDay: userData.Info?.RemainedDay || 0, - SeriesNumb: userData.Info?.SeriesNumb || '', - Notes: userData.Info?.Notes || '', - Status: userData.Info?.Status !== undefined ? userData.Info.Status : true, - Mode: userData.Info?.Mode || 'MAA', - InfrastMode: userData.Info?.InfrastMode || '默认', - Routine: userData.Info?.Routine !== undefined ? userData.Info.Routine : true, - Annihilation: userData.Info?.Annihilation || '当期', - Stage: userData.Info?.Stage || '1-7', - StageMode: userData.Info?.StageMode || '刷完即停', - Stage_1: userData.Info?.Stage_1 || '', - Stage_2: userData.Info?.Stage_2 || '', - Stage_3: userData.Info?.Stage_3 || '', - Stage_Remain: userData.Info?.Stage_Remain || '', - IfSkland: userData.Info?.IfSkland || false, - SklandToken: userData.Info?.SklandToken || '', - }, - Task: { - IfBase: userData.Task?.IfBase !== undefined ? userData.Task.IfBase : true, - IfCombat: userData.Task?.IfCombat !== undefined ? userData.Task.IfCombat : true, - IfMall: userData.Task?.IfMall !== undefined ? userData.Task.IfMall : true, - IfMission: - userData.Task?.IfMission !== undefined ? userData.Task.IfMission : true, - IfRecruiting: - userData.Task?.IfRecruiting !== undefined ? userData.Task.IfRecruiting : true, - IfReclamation: userData.Task?.IfReclamation || false, - IfAutoRoguelike: userData.Task?.IfAutoRoguelike || false, - IfWakeUp: userData.Task?.IfWakeUp || false, - }, - Notify: { - Enabled: userData.Notify?.Enabled || false, - ToAddress: userData.Notify?.ToAddress || '', - IfSendMail: userData.Notify?.IfSendMail || false, - IfSendSixStar: userData.Notify?.IfSendSixStar || false, - IfSendStatistic: userData.Notify?.IfSendStatistic || false, - IfServerChan: userData.Notify?.IfServerChan || false, - IfCompanyWebHookBot: userData.Notify?.IfCompanyWebHookBot || false, - ServerChanKey: userData.Notify?.ServerChanKey || '', - ServerChanChannel: userData.Notify?.ServerChanChannel || '', - ServerChanTag: userData.Notify?.ServerChanTag || '', - CompanyWebHookBotUrl: userData.Notify?.CompanyWebHookBotUrl || '', - }, - Data: { - CustomInfrastPlanIndex: userData.Data?.CustomInfrastPlanIndex || '', - IfPassCheck: userData.Data?.IfPassCheck || false, - LastAnnihilationDate: userData.Data?.LastAnnihilationDate || '', - LastProxyDate: userData.Data?.LastProxyDate || '', - LastSklandDate: userData.Data?.LastSklandDate || '', - ProxyTimes: userData.Data?.ProxyTimes || 0, - }, - QFluentWidgets: { - ThemeColor: userData.QFluentWidgets?.ThemeColor || 'blue', - ThemeMode: userData.QFluentWidgets?.ThemeMode || 'system', - }, - } - users.push(user) - } - } - }) - } - } - - return { - id: detail.uid, - type: detail.type, - name: detail.name, - config: detail.config, - users, - createTime: detail.createTime || new Date().toLocaleString(), - } - }) + scripts.value = scriptDetails.map(detail => ({ + id: detail.uid, + type: detail.type, + name: detail.name, + config: detail.config, + users: detail.users || [], + createTime: detail.createTime || new Date().toLocaleString(), + })) } catch (error) { console.error('加载脚本列表失败:', error) message.error('加载脚本列表失败') diff --git a/frontend/src/views/UserEdit.vue b/frontend/src/views/UserEdit.vue index 20cd41b..21bbc9f 100644 --- a/frontend/src/views/UserEdit.vue +++ b/frontend/src/views/UserEdit.vue @@ -933,7 +933,7 @@ import { useScriptApi } from '@/composables/useScriptApi' const router = useRouter() const route = useRoute() -const { addUser, updateUser, loading: userLoading } = useUserApi() +const { addUser, updateUser, getUsers, loading: userLoading } = useUserApi() const { getScript } = useScriptApi() const formRef = ref() @@ -1115,44 +1115,8 @@ const loadScriptInfo = async () => { }) // 如果是编辑模式,加载用户数据 - if (isEdit.value && script.config) { - const config = script.config as any - if (config.SubConfigsInfo?.UserData?.instances) { - const userInstance = config.SubConfigsInfo.UserData.instances.find( - (instance: any) => instance.uid === userId - ) - - if (userInstance) { - // 从用户数据中获取实际的用户信息 - const userData = config.SubConfigsInfo.UserData[userInstance.uid] - if (userData) { - // 根据脚本类型填充用户数据 - if (scriptType.value === 'MAA') { - Object.assign(formData, { - Info: { ...getDefaultMAAUserData().Info, ...userData.Info }, - Task: { ...getDefaultMAAUserData().Task, ...userData.Task }, - Notify: { ...getDefaultMAAUserData().Notify, ...userData.Notify }, - Data: { ...getDefaultMAAUserData().Data, ...userData.Data }, - QFluentWidgets: { - ...getDefaultMAAUserData().QFluentWidgets, - ...userData.QFluentWidgets, - }, - }) - } else { - // 通用脚本 - Object.assign(formData, { - Info: { ...getDefaultGeneralUserData().Info, ...userData.Info }, - Notify: { ...getDefaultGeneralUserData().Notify, ...userData.Notify }, - Data: { ...getDefaultGeneralUserData().Data, ...userData.Data }, - }) - } - - // 同步扁平化字段 - formData.userName = formData.Info.Name - formData.userId = formData.Info.Id || '' - } - } - } + if (isEdit.value) { + await loadUserData() } } else { message.error('脚本不存在') @@ -1164,6 +1128,56 @@ const loadScriptInfo = async () => { } } +// 加载用户数据 +const loadUserData = async () => { + try { + const userResponse = await getUsers(scriptId, userId) + + if (userResponse && userResponse.code === 200) { + // 查找指定的用户数据 + const userIndex = userResponse.index.find(index => index.uid === userId) + if (userIndex && userResponse.data[userId]) { + const userData = userResponse.data[userId] as any + + // 根据脚本类型填充用户数据 + if (scriptType.value === 'MAA' && userIndex.type === 'MaaUserConfig') { + Object.assign(formData, { + Info: { ...getDefaultMAAUserData().Info, ...userData.Info }, + Task: { ...getDefaultMAAUserData().Task, ...userData.Task }, + Notify: { ...getDefaultMAAUserData().Notify, ...userData.Notify }, + Data: { ...getDefaultMAAUserData().Data, ...userData.Data }, + QFluentWidgets: { + ...getDefaultMAAUserData().QFluentWidgets, + ...userData.QFluentWidgets, + }, + }) + } else if (scriptType.value === 'General' && userIndex.type === 'GeneralUserConfig') { + Object.assign(formData, { + Info: { ...getDefaultGeneralUserData().Info, ...userData.Info }, + Notify: { ...getDefaultGeneralUserData().Notify, ...userData.Notify }, + Data: { ...getDefaultGeneralUserData().Data, ...userData.Data }, + }) + } + + // 同步扁平化字段 + formData.userName = formData.Info.Name || '' + formData.userId = formData.Info.Id || '' + + console.log('用户数据加载成功:', formData) + } else { + message.error('用户不存在') + handleCancel() + } + } else { + message.error('获取用户数据失败') + handleCancel() + } + } catch (error) { + console.error('加载用户数据失败:', error) + message.error('加载用户数据失败') + } +} + const handleSubmit = async () => { try { await formRef.value?.validate()