| <script setup lang="ts"> |
| import { ref, onMounted, onUnmounted, watch } from 'vue'; |
| import { MessagePlugin } from 'tdesign-vue-next'; |
| import { accountApi } from '../services/accountApi'; |
| import { useAccountStore } from '../stores/accountStorage'; |
| import MonacoEditor from '../components/MonacoEditor.vue'; |
| const accountStore = useAccountStore(); |
| const accountsText = ref<string>(''); |
| const loading = ref(false); |
| const showDiff = ref(false); |
| const originalText = ref(''); |
| |
| const fetchAccounts = async (force: boolean) => { |
| try { |
| loading.value = true; |
| accountsText.value = ""; |
| await accountStore.fetchAccounts(force); |
| const formattedData = JSON.stringify(accountStore.accounts, null, 2); |
| accountsText.value = formattedData; |
| originalText.value = formattedData; |
| } catch (error) { |
| MessagePlugin.error('获取账号数据失败'); |
| } finally { |
| loading.value = false; |
| } |
| }; |
| |
| |
| const handleSave = async () => { |
| loading.value = true; |
| try { |
| if (accountsText.value === '') { |
| MessagePlugin.error('账号数据不能为空'); |
| return; |
| } |
| if (originalText.value === accountsText.value) { |
| MessagePlugin.success('数据未修改'); |
| return; |
| } |
| const accounts = JSON.parse(accountsText.value); |
| const result = await accountApi.post(accounts); |
| if (result.error) { |
| MessagePlugin.error(`${result.error}`); |
| return; |
| } |
| accountStore.updateAccounts(accounts || []); |
| MessagePlugin.success('保存成功'); |
| } catch (error) { |
| if (error instanceof SyntaxError) { |
| MessagePlugin.error('JSON格式错误'); |
| } else { |
| MessagePlugin.error('保存失败'); |
| } |
| } finally { |
| loading.value = false; |
| } |
| }; |
| |
| const handleReload = async () => { |
| loading.value = true; |
| try { |
| await fetchAccounts(true); |
| MessagePlugin.success('重新加载成功'); |
| } catch (error) { |
| MessagePlugin.error('重新加载失败'); |
| } finally { |
| loading.value = false; |
| } |
| }; |
| |
| |
| const handleKeyDown = (e: KeyboardEvent) => { |
| if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') { |
| e.preventDefault(); |
| handleSave(); |
| } |
| }; |
| |
| |
| |
| const toggleDiff = () => { |
| showDiff.value = !showDiff.value; |
| |
| if (showDiff.value) { |
| |
| if (originalText.value === '') { |
| originalText.value = accountsText.value; |
| } |
| } |
| }; |
| |
| watch(showDiff, (newVal) => { |
| if (newVal && originalText.value === accountsText.value) { |
| |
| MessagePlugin.info('当前没有差异可以显示'); |
| } |
| }, { immediate: true }); |
| |
| onMounted(async () => { |
| |
| window.addEventListener('keydown', handleKeyDown); |
| await fetchAccounts(false); |
| }); |
| |
| onUnmounted(() => { |
| |
| window.removeEventListener('keydown', handleKeyDown); |
| }); |
| </script> |
|
|
| <template> |
| <div class="account-container h-full p-2 md:p-5"> |
| <t-card bordered class="h-full"> |
| <template #content> |
| <div class=" flex flex-col h-full"> |
| <div class="flex justify-end items-center mb-4 gap-4"> |
| <div class="flex gap-2"> |
| <t-button variant="outline" @click="handleReload"> |
| 重新加载 |
| </t-button> |
| <t-button variant="outline" @click="toggleDiff"> |
| {{ showDiff ? '隐藏对比' : '显示对比' }} |
| </t-button> |
| <t-button theme="primary" @click="handleSave" :loading="loading"> |
| 保存账号 |
| </t-button> |
| </div> |
| </div> |
|
|
| <div class="editor-container flex-1"> |
| <MonacoEditor v-model:value="accountsText" :original-value="showDiff ? originalText : undefined" |
| language="json" :options="{ tabSize: 2 }" /> |
| </div> |
| </div> |
| </template> |
| </t-card> |
| </div> |
| </template> |
|
|
| <style scoped> |
| .account-container { |
| width: 100%; |
| } |
| |
| :deep(.t-card__body) { |
| height: 100%; |
| } |
| |
| .editor-container { |
| border: 1px solid var(--td-component-border); |
| } |
| </style> |
|
|