({
+ url: '/device/amt/getInfo',
+ method: 'post',
+ data
+ });
+}
diff --git a/src/typings/api/device.d.ts b/src/typings/api/device.d.ts
index 687c52a..f73e9a1 100644
--- a/src/typings/api/device.d.ts
+++ b/src/typings/api/device.d.ts
@@ -51,5 +51,29 @@ declare namespace Api {
/** 备注 */
remark?: string;
}
+
+ /** AMT 测试请求 */
+ interface AmtTestRequest {
+ /** IP地址 */
+ ipAddress: string;
+ /** 用户名 */
+ username?: string;
+ /** 密码 */
+ password?: string;
+ /** 凭证ID */
+ credentialId?: number;
+ }
+
+ /** AMT 设备信息 */
+ interface AmtDeviceInfo {
+ /** 设备名称 */
+ deviceName: string;
+ /** 设备编号 */
+ deviceCode: string;
+ /** IP地址 */
+ ipAddress: string;
+ /** MAC地址 */
+ macAddress: string;
+ }
}
}
diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts
index de84222..4b8f039 100644
--- a/src/typings/components.d.ts
+++ b/src/typings/components.d.ts
@@ -49,6 +49,7 @@ declare module 'vue' {
IconMdiIp: typeof import('~icons/mdi/ip')['default']
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
+ IconMdiLanConnect: typeof import('~icons/mdi/lan-connect')['default']
IconMdiMagnify: typeof import('~icons/mdi/magnify')['default']
IconMdiMapMarker: typeof import('~icons/mdi/map-marker')['default']
IconMdiMemory: typeof import('~icons/mdi/memory')['default']
@@ -188,6 +189,7 @@ declare global {
const IconMdiIp: typeof import('~icons/mdi/ip')['default']
const IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
const IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
+ const IconMdiLanConnect: typeof import('~icons/mdi/lan-connect')['default']
const IconMdiMagnify: typeof import('~icons/mdi/magnify')['default']
const IconMdiMapMarker: typeof import('~icons/mdi/map-marker')['default']
const IconMdiMemory: typeof import('~icons/mdi/memory')['default']
diff --git a/src/views/device/list/index.vue b/src/views/device/list/index.vue
index abaa334..a0c4c65 100644
--- a/src/views/device/list/index.vue
+++ b/src/views/device/list/index.vue
@@ -93,8 +93,88 @@
v-model:show="modalVisible"
:title="modalTitle"
preset="card"
- class="w-700px"
+ class="w-800px"
>
+
+
+
+ 手动添加
+ AMT 自动添加
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 使用已保存凭证
+ 手动输入
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 测试连接
+
+
+
+ 连接成功
+
+
+
+
+
+
+ 设备信息
+
+
+
@@ -148,7 +231,14 @@
取消
- 确定
+
+ 确定
+
@@ -187,8 +277,11 @@ import {
fetchCreateDevice,
fetchUpdateDevice,
fetchDeleteDevice,
- fetchBatchDeleteDevice
+ fetchBatchDeleteDevice,
+ fetchTestAmtConnection,
+ fetchAmtDeviceInfo
} from '@/service/api/device';
+import { fetchAllActiveCredentials, type AmtCredential } from '@/service/api/amt';
defineOptions({
name: 'DeviceList'
@@ -353,6 +446,22 @@ const modalTitle = ref('');
const isEdit = ref(false);
const submitLoading = ref(false);
const formRef = ref();
+
+// 添加方式:manual(手动)、amt(AMT自动)
+const addMode = ref<'manual' | 'amt'>('manual');
+
+// AMT 相关
+const amtFormData = reactive({
+ ipAddress: '',
+ username: '',
+ password: '',
+ credentialId: null as number | null,
+ useCredential: false
+});
+const amtCredentials = ref([]);
+const amtTesting = ref(false);
+const amtTestSuccess = ref(false);
+
const formData = reactive({
id: null as number | null,
deviceName: '',
@@ -421,6 +530,8 @@ function handleCheck(keys: number[]) {
function handleAdd() {
isEdit.value = false;
modalTitle.value = '新增设备';
+ addMode.value = 'manual';
+ amtTestSuccess.value = false;
Object.assign(formData, {
id: null,
deviceName: '',
@@ -430,7 +541,15 @@ function handleAdd() {
macAddress: '',
remark: ''
});
+ Object.assign(amtFormData, {
+ ipAddress: '',
+ username: '',
+ password: '',
+ credentialId: null,
+ useCredential: false
+ });
modalVisible.value = true;
+ loadAmtCredentials();
}
// 编辑
@@ -506,4 +625,105 @@ async function handleBatchDelete() {
onMounted(() => {
loadData();
});
+
+// 加载 AMT 凭证列表
+async function loadAmtCredentials() {
+ try {
+ const { data } = await fetchAllActiveCredentials();
+ amtCredentials.value = data || [];
+ } catch (error) {
+ console.error('加载 AMT 凭证失败:', error);
+ }
+}
+
+// 测试 AMT 连接
+async function handleTestAmtConnection() {
+ // 验证必填项
+ if (!amtFormData.ipAddress) {
+ window.$message?.warning('请输入 IP 地址');
+ return;
+ }
+
+ if (!amtFormData.useCredential && (!amtFormData.username || !amtFormData.password)) {
+ window.$message?.warning('请输入用户名和密码,或选择已保存的凭证');
+ return;
+ }
+
+ if (amtFormData.useCredential && !amtFormData.credentialId) {
+ window.$message?.warning('请选择 AMT 凭证');
+ return;
+ }
+
+ amtTesting.value = true;
+ amtTestSuccess.value = false;
+
+ try {
+ const requestData: Api.Device.AmtTestRequest = {
+ ipAddress: amtFormData.ipAddress
+ };
+
+ if (amtFormData.useCredential && amtFormData.credentialId) {
+ requestData.credentialId = amtFormData.credentialId;
+ } else {
+ requestData.username = amtFormData.username;
+ requestData.password = amtFormData.password;
+ }
+
+ const { data } = await fetchTestAmtConnection(requestData);
+
+ if (data) {
+ amtTestSuccess.value = true;
+ window.$message?.success('AMT 连接测试成功');
+
+ // 自动获取设备信息
+ await handleGetAmtDeviceInfo();
+ } else {
+ window.$message?.error('AMT 连接测试失败');
+ }
+ } catch (error: any) {
+ window.$message?.error(error?.message || 'AMT 连接测试失败');
+ } finally {
+ amtTesting.value = false;
+ }
+}
+
+// 获取 AMT 设备信息
+async function handleGetAmtDeviceInfo() {
+ try {
+ const requestData: Api.Device.AmtTestRequest = {
+ ipAddress: amtFormData.ipAddress
+ };
+
+ if (amtFormData.useCredential && amtFormData.credentialId) {
+ requestData.credentialId = amtFormData.credentialId;
+ } else {
+ requestData.username = amtFormData.username;
+ requestData.password = amtFormData.password;
+ }
+
+ const { data } = await fetchAmtDeviceInfo(requestData);
+
+ // 填充表单数据
+ formData.deviceName = data.deviceName;
+ formData.deviceCode = data.deviceCode;
+ formData.ipAddress = data.ipAddress;
+ formData.macAddress = data.macAddress;
+
+ window.$message?.success('设备信息获取成功');
+ } catch (error: any) {
+ window.$message?.error(error?.message || '获取设备信息失败');
+ }
+}
+
+// 切换凭证使用方式
+function handleCredentialToggle(value: boolean) {
+ if (value) {
+ amtFormData.username = '';
+ amtFormData.password = '';
+ } else {
+ amtFormData.credentialId = null;
+ }
+ amtTestSuccess.value = false;
+}
+
diff --git a/test_amt_api.bat b/test_amt_api.bat
index 5735eaf..298856e 100644
--- a/test_amt_api.bat
+++ b/test_amt_api.bat
@@ -1,16 +1,43 @@
@echo off
-chcp 65001 >nul
echo ========================================
-echo 测试 AMT API 接口
+echo 测试 AMT API 是否正常
echo ========================================
echo.
-echo 测试获取凭证列表...
-curl -X GET "http://localhost:8080/api/amt/credential/list?page=1&size=10" -H "Content-Type: application/json"
+echo [测试 1] 检查后端是否运行...
+curl -s http://localhost:8080/device/statistics >nul 2>&1
+if %ERRORLEVEL% NEQ 0 (
+ echo 后端未运行或无法连接!
+ echo 请先启动后端服务。
+ pause
+ exit /b 1
+)
+echo 后端正常运行 ✓
+
+echo.
+echo [测试 2] 检查模拟模式状态...
+curl -s http://localhost:8080/device/amt/mockStatus
+echo.
+
+echo.
+echo [测试 3] 测试 AMT 连接 API(使用模拟数据)...
+echo.
+echo 发送测试请求...
+curl -X POST http://localhost:8080/device/amt/test ^
+ -H "Content-Type: application/json" ^
+ -d "{\"ipAddress\":\"192.168.1.100\",\"username\":\"admin\",\"password\":\"admin\"}"
echo.
echo.
echo ========================================
echo 测试完成
echo ========================================
+echo.
+echo 如果看到成功响应,说明 API 正常工作。
+echo 如果看到错误,请检查:
+echo 1. 后端是否正常启动
+echo 2. 端口 8080 是否被占用
+echo 3. 查看后端控制台日志
+echo.
+
pause
diff --git a/test_amt_connection.bat b/test_amt_connection.bat
new file mode 100644
index 0000000..2a4bdd1
--- /dev/null
+++ b/test_amt_connection.bat
@@ -0,0 +1,43 @@
+@echo off
+echo ========================================
+echo AMT 连接测试工具
+echo ========================================
+echo.
+
+set /p AMT_IP="请输入 AMT 设备 IP 地址: "
+set /p AMT_USER="请输入 AMT 用户名 (默认: admin): "
+if "%AMT_USER%"=="" set AMT_USER=admin
+
+echo.
+echo 正在测试连接到 %AMT_IP%...
+echo.
+
+REM 测试端口 16992 是否开放
+echo [1/4] 测试端口 16992 (HTTP)...
+powershell -Command "Test-NetConnection -ComputerName %AMT_IP% -Port 16992 -InformationLevel Detailed"
+
+echo.
+echo [2/4] 测试端口 16993 (HTTPS)...
+powershell -Command "Test-NetConnection -ComputerName %AMT_IP% -Port 16993 -InformationLevel Detailed"
+
+echo.
+echo [3/4] 尝试 HTTP 连接...
+curl -v -u %AMT_USER% http://%AMT_IP%:16992/wsman -H "Content-Type: application/soap+xml;charset=UTF-8" -d ""
+
+echo.
+echo [4/4] 尝试 HTTPS 连接...
+curl -v -k -u %AMT_USER% https://%AMT_IP%:16993/wsman -H "Content-Type: application/soap+xml;charset=UTF-8" -d ""
+
+echo.
+echo ========================================
+echo 测试完成
+echo ========================================
+echo.
+echo 提示:
+echo - 如果端口不通,请检查防火墙设置
+echo - 如果返回 401,请检查用户名和密码
+echo - 如果返回 404,AMT 可能未启用
+echo - HTTP 端口: 16992, HTTPS 端口: 16993
+echo.
+
+pause