跳转
+
+ 代理商查询
+
查询
@@ -653,7 +666,8 @@ import {
updateUserGroup,
updateUserRealName,
getUserLoginRecord,
- getUserOperationRecord
+ getUserOperationRecord,
+ getUserByIdcAgentUid
} from '@/api/admin/user'
import { getFileDetail } from '@/api/admin/file'
import { closeAllMessage } from '../../utils/message'
@@ -663,6 +677,10 @@ const router = useRouter()
// 跳转用户ID
const jumpUserId = ref('')
+// 代理商ID查询
+const agentUid = ref('')
+const agentSearchLoading = ref(false)
+
// 查询参数
const queryParams = reactive({
key: '',
@@ -887,6 +905,33 @@ const handleJumpToUser = () => {
})
}
+// 通过代理商ID查询用户
+const handleSearchByAgentUid = async () => {
+ if (!agentUid.value || !agentUid.value.trim()) {
+ ElMessage.warning('请输入代理商ID')
+ return
+ }
+ agentSearchLoading.value = true
+ try {
+ const res = await getUserByIdcAgentUid({ uid: agentUid.value.trim() })
+ if (res?.data?.code === 200 && res?.data?.data) {
+ const userId = res.data.data.UserId
+ if (userId) {
+ router.push({ path: '/user/detail', query: { user_id: userId } })
+ } else {
+ ElMessage.warning('未找到绑定该代理商ID的用户')
+ }
+ } else {
+ ElMessage.warning(res?.data?.message || '未找到绑定该代理商ID的用户')
+ }
+ } catch (e) {
+ const msg = e?.response?.data?.message || '查询失败'
+ ElMessage.error(msg)
+ } finally {
+ agentSearchLoading.value = false
+ }
+}
+
// 选择项变化
const handleSelectionChange = (selection) => {
selectedRows.value = selection
diff --git a/src/views/virtualization/VmDetail.vue b/src/views/virtualization/VmDetail.vue
index 48b5760..8af83d4 100644
--- a/src/views/virtualization/VmDetail.vue
+++ b/src/views/virtualization/VmDetail.vue
@@ -302,7 +302,7 @@
详情
编辑
设为主IP
-
删除
+
解绑
@@ -2962,13 +2962,27 @@ const submitNetForm = () => {
}
const handleNetDetail = (row) => { netDetailData.value = row; netDetailVisible.value = true }
const handleNetDelete = (row) => {
- ElMessageBox.confirm(`确定要删除网络「${row.name}」(ID: ${row.id}) 吗?`, '删除网络', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
+ ElMessageBox.confirm(`确定从该虚拟机解绑网络「${row.name}」(ID: ${row.id}) 吗?`, '解绑网络', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
.then(async () => {
+ actionLoading.value = true
try {
- const res = await deleteNetwork({ service_id: serviceId.value, network_id: row.id, host_id: row.host_id })
- if (res?.data?.code === 200) { ElMessage.success('删除成功'); loadDetail() }
- else ElMessage.error(extractApiError(res?.data, '删除失败'))
- } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '删除失败')) }
+ const fd = new FormData()
+ fd.append('service_id', serviceId.value)
+ fd.append('vm_id', vmId.value)
+ const remainingNetworks = vmNetworks.value.filter(n => n.id !== row.id)
+ const bridgeIds = remainingNetworks.filter(n => n.type === 'bridge').map(n => n.id)
+ const natNet = remainingNetworks.find(n => n.type === 'nat')
+ bridgeIds.forEach(id => fd.append('network_ids', id))
+ if (natNet) fd.append('internet_network_id', natNet.id)
+ if (detail.value?.rx_bandwidth) fd.append('rx_bandwidth', detail.value.rx_bandwidth)
+ if (detail.value?.tx_bandwidth) fd.append('tx_bandwidth', detail.value.tx_bandwidth)
+ if (detail.value?.ssh_port) fd.append('ssh_port', detail.value.ssh_port)
+ if (vmPortGroup.value?.id) fd.append('port_group_id', vmPortGroup.value.id)
+ const res = await updateVm(fd)
+ if (res?.data?.code === 200) { ElMessage.success('解绑网络成功'); loadDetail() }
+ else ElMessage.error(extractApiError(res?.data, '解绑网络失败'))
+ } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '解绑网络失败')) }
+ finally { actionLoading.value = false }
}).catch(() => {})
}
diff --git a/src/views/virtualization/VncNodeManage.vue b/src/views/virtualization/VncNodeManage.vue
index ba53153..70310b3 100644
--- a/src/views/virtualization/VncNodeManage.vue
+++ b/src/views/virtualization/VncNodeManage.vue
@@ -39,6 +39,18 @@
{{ row.ip || '-' }}:{{ row.port || '-' }}
+
+
+ Token传参
+ 域名解析
+
+
+
+
+ 是
+ 否
+
+
{{ maskToken(row.token) }}
@@ -81,7 +93,16 @@
-
+
+
+
+
+
+
+
+
+
+
@@ -224,7 +245,7 @@ const handleSearch = () => { queryParams.page = 1; loadList() }
const formDialogVisible = ref(false)
const formType = ref('add')
const formRef = ref(null)
-const formData = reactive({ id: undefined, name: '', ip: '', port: '', token: '' })
+const formData = reactive({ id: undefined, name: '', ip: '', port: '', token: '', access_mode: 'domain', use_ssl: false })
const formRules = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
ip: [{ required: true, message: '请输入IP地址', trigger: 'blur' }],
@@ -233,14 +254,15 @@ const formRules = {
const handleAdd = () => {
formType.value = 'add'
- Object.assign(formData, { id: undefined, name: '', ip: '', port: '', token: '' })
+ Object.assign(formData, { id: undefined, name: '', ip: '', port: '', token: '', access_mode: 'domain', use_ssl: false })
formDialogVisible.value = true
}
const handleEdit = (row) => {
formType.value = 'edit'
Object.assign(formData, {
- id: row.id, name: row.name || '', ip: row.ip || '', port: row.port || '', token: row.token || ''
+ id: row.id, name: row.name || '', ip: row.ip || '', port: row.port || '', token: row.token || '',
+ access_mode: row.access_mode || 'domain', use_ssl: !!row.use_ssl
})
formDialogVisible.value = true
}
@@ -251,10 +273,12 @@ const handleSubmit = () => {
submitLoading.value = true
try {
let res
+ const payload = { service_id: serviceId.value, name: formData.name, ip: formData.ip, port: formData.port, token: formData.token, access_mode: formData.access_mode, use_ssl: formData.use_ssl }
if (formType.value === 'add') {
- res = await addVncNode({ service_id: serviceId.value, name: formData.name, ip: formData.ip, port: formData.port, token: formData.token })
+ res = await addVncNode(payload)
} else {
- res = await updateVncNode({ service_id: serviceId.value, id: formData.id, name: formData.name, ip: formData.ip, port: formData.port, token: formData.token })
+ payload.id = formData.id
+ res = await updateVncNode(payload)
}
if (res?.data?.code === 200) {
ElMessage.success(formType.value === 'add' ? '创建成功' : '修改成功')