feat: add global manual sync button in admin header

This commit is contained in:
Chris
2026-04-03 01:25:34 +08:00
parent 561670827c
commit db00426b23

View File

@@ -12,7 +12,15 @@
<NavTab v-for="tab in adminTabs" :key="tab.to" :to="tab.to">{{ tab.label }}</NavTab> <NavTab v-for="tab in adminTabs" :key="tab.to" :to="tab.to">{{ tab.label }}</NavTab>
</nav> </nav>
<div class="flex-shrink-0 ml-4"> <div class="flex-shrink-0 ml-4 flex items-center gap-2">
<button
v-if="showManualSync"
@click="handleManualSync"
:disabled="syncing"
class="text-xs text-blue-600 border border-blue-200 hover:border-blue-300 hover:bg-blue-50 transition-colors px-2 py-1 rounded disabled:opacity-60 disabled:cursor-not-allowed"
>
{{ syncing ? '同步中...' : '手動同步' }}
</button>
<button <button
@click="logout" @click="logout"
class="text-xs text-gray-400 hover:text-gray-600 transition-colors px-2 py-1 rounded hover:bg-gray-100" class="text-xs text-gray-400 hover:text-gray-600 transition-colors px-2 py-1 rounded hover:bg-gray-100"
@@ -30,13 +38,16 @@
</template> </template>
<script setup> <script setup>
import { computed, defineComponent, h } from 'vue' import { computed, defineComponent, h, ref } from 'vue'
import { useRoute, useRouter, RouterLink } from 'vue-router' import { useRoute, useRouter, RouterLink } from 'vue-router'
import { ElMessage } from 'element-plus'
import { adminHttp } from '@/api/http'
import { useAuthStore } from '@/stores/auth' import { useAuthStore } from '@/stores/auth'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const authStore = useAuthStore() const authStore = useAuthStore()
const syncing = ref(false)
const showNav = computed(() => { const showNav = computed(() => {
const onAuthPage = route.name === 'login' || route.name === 'auth-callback' const onAuthPage = route.name === 'login' || route.name === 'auth-callback'
@@ -48,6 +59,8 @@ const userTabs = [
{ to: '/me/permissions', label: '我的角色' } { to: '/me/permissions', label: '我的角色' }
] ]
const showManualSync = computed(() => route.path.startsWith('/admin'))
const adminTabs = [ const adminTabs = [
{ to: '/admin/companies', label: '公司' }, { to: '/admin/companies', label: '公司' },
{ to: '/admin/sites', label: '站台' }, { to: '/admin/sites', label: '站台' },
@@ -78,4 +91,21 @@ function logout() {
authStore.logout() authStore.logout()
router.push('/login') router.push('/login')
} }
async function handleManualSync() {
if (syncing.value) return
syncing.value = true
try {
const res = await adminHttp.post('/admin/sync/from-provider', null, { params: { force: true } })
const data = res?.data || {}
ElMessage.success(
`同步完成: 系統+${data.systems_created || 0}/${data.systems_updated || 0}, 角色+${data.roles_created || 0}/${data.roles_updated || 0}`
)
} catch (err) {
const detail = err?.response?.data?.detail || err?.message || 'sync_failed'
ElMessage.error(`同步失敗:${detail}`)
} finally {
syncing.value = false
}
}
</script> </script>