feat: allow assigning sites directly from role page

This commit is contained in:
Chris
2026-04-03 01:56:22 +08:00
parent 24aea89287
commit 9119a48c15
2 changed files with 40 additions and 1 deletions

View File

@@ -5,3 +5,4 @@ export const createRole = (data) => adminHttp.post('/admin/roles', data)
export const updateRole = (roleKey, data) => adminHttp.patch(`/admin/roles/${roleKey}`, data)
export const deleteRole = (roleKey) => adminHttp.delete(`/admin/roles/${roleKey}`)
export const getRoleSites = (roleKey) => adminHttp.get(`/admin/roles/${roleKey}/sites`)
export const setRoleSites = (roleKey, siteKeys) => adminHttp.put(`/admin/roles/${roleKey}/sites`, { site_keys: siteKeys })

View File

@@ -79,6 +79,18 @@
</el-dialog>
<el-dialog v-model="showSitesDialog" :title="`角色綁定站台:${selectedRoleLabel}`" width="980px">
<el-form label-width="120px" class="mb-4">
<el-form-item label="指派站台">
<el-select v-model="selectedSiteKeys" multiple filterable style="width: 100%" placeholder="請選擇站台">
<el-option
v-for="site in siteOptions"
:key="site.site_key"
:label="`${site.company_display_name} / ${site.display_name} (${site.site_key})`"
:value="site.site_key"
/>
</el-select>
</el-form-item>
</el-form>
<el-table :data="roleSites" border stripe v-loading="sitesLoading">
<template #empty><el-empty description="此角色尚未綁定站台" /></template>
<el-table-column prop="company_display_name" label="公司" min-width="160" />
@@ -86,6 +98,7 @@
<el-table-column prop="site_key" label="Site Key" min-width="180" />
</el-table>
<template #footer>
<el-button type="primary" :loading="savingSites" @click="handleSaveRoleSites">儲存站台綁定</el-button>
<el-button @click="showSitesDialog = false">關閉</el-button>
</template>
</el-dialog>
@@ -96,8 +109,9 @@
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { getRoles, createRole, updateRole, deleteRole, getRoleSites } from '@/api/roles'
import { getRoles, createRole, updateRole, deleteRole, getRoleSites, setRoleSites } from '@/api/roles'
import { getSystems } from '@/api/systems'
import { getSites } from '@/api/sites'
const roles = ref([])
const systems = ref([])
@@ -131,8 +145,12 @@ const rules = {
const showSitesDialog = ref(false)
const selectedRoleLabel = ref('')
const selectedRoleKey = ref('')
const roleSites = ref([])
const sitesLoading = ref(false)
const savingSites = ref(false)
const siteOptions = ref([])
const selectedSiteKeys = ref([])
async function load() {
loading.value = true
@@ -144,6 +162,8 @@ async function load() {
])
roles.value = rolesRes.data?.items || []
systems.value = systemsRes.data?.items || []
const sitesRes = await getSites({ limit: 1000, offset: 0 })
siteOptions.value = sitesRes.data?.items || []
} catch (err) {
error.value = true
errorMsg.value = err.response?.data?.detail || '載入角色失敗'
@@ -240,19 +260,37 @@ async function handleDelete(row) {
}
async function openSites(row) {
selectedRoleKey.value = row.role_key
selectedRoleLabel.value = `${row.system_name} / ${row.name}`
showSitesDialog.value = true
sitesLoading.value = true
try {
const res = await getRoleSites(row.role_key)
roleSites.value = res.data?.sites || []
selectedSiteKeys.value = roleSites.value.map(item => item.site_key)
} catch (_err) {
ElMessage.error('載入角色站台失敗')
roleSites.value = []
selectedSiteKeys.value = []
} finally {
sitesLoading.value = false
}
}
async function handleSaveRoleSites() {
if (!selectedRoleKey.value) return
savingSites.value = true
try {
await setRoleSites(selectedRoleKey.value, selectedSiteKeys.value)
const res = await getRoleSites(selectedRoleKey.value)
roleSites.value = res.data?.sites || []
ElMessage.success('角色站台綁定已更新')
} catch (err) {
ElMessage.error(err.response?.data?.detail || '儲存角色站台失敗')
} finally {
savingSites.value = false
}
}
onMounted(load)
</script>