fea: 前端完成动态ip与动态mac的适配
This commit is contained in:
parent
0f4386457d
commit
80b6dfb38d
|
@ -10,6 +10,7 @@ import {
|
||||||
TutorialClient,
|
TutorialClient,
|
||||||
UDPClient,
|
UDPClient,
|
||||||
LogicAnalyzerClient,
|
LogicAnalyzerClient,
|
||||||
|
NetConfigClient,
|
||||||
} from "@/APIClient";
|
} from "@/APIClient";
|
||||||
|
|
||||||
// 支持的客户端类型联合类型
|
// 支持的客户端类型联合类型
|
||||||
|
@ -24,7 +25,8 @@ type SupportedClient =
|
||||||
| RemoteUpdateClient
|
| RemoteUpdateClient
|
||||||
| TutorialClient
|
| TutorialClient
|
||||||
| LogicAnalyzerClient
|
| LogicAnalyzerClient
|
||||||
| UDPClient;
|
| UDPClient
|
||||||
|
| NetConfigClient;
|
||||||
|
|
||||||
export class AuthManager {
|
export class AuthManager {
|
||||||
// 存储token到localStorage
|
// 存储token到localStorage
|
||||||
|
@ -157,6 +159,10 @@ export class AuthManager {
|
||||||
return AuthManager.createAuthenticatedClient(LogicAnalyzerClient);
|
return AuthManager.createAuthenticatedClient(LogicAnalyzerClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static createAuthenticatedNetConfigClient(): NetConfigClient {
|
||||||
|
return AuthManager.createAuthenticatedClient(NetConfigClient);
|
||||||
|
}
|
||||||
|
|
||||||
// 登录函数
|
// 登录函数
|
||||||
public static async login(
|
public static async login(
|
||||||
username: string,
|
username: string,
|
||||||
|
|
|
@ -74,8 +74,6 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
|
||||||
// 新增板卡(管理员权限)
|
// 新增板卡(管理员权限)
|
||||||
async function addBoard(
|
async function addBoard(
|
||||||
name: string,
|
name: string,
|
||||||
ipAddr: string,
|
|
||||||
port: number,
|
|
||||||
): Promise<{ success: boolean; error?: string; boardId?: string }> {
|
): Promise<{ success: boolean; error?: string; boardId?: string }> {
|
||||||
try {
|
try {
|
||||||
// 验证管理员权限
|
// 验证管理员权限
|
||||||
|
@ -86,19 +84,19 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证输入参数
|
// 验证输入参数
|
||||||
if (!name || !ipAddr || !port) {
|
if (!name) {
|
||||||
console.error("参数验证失败", { name, ipAddr, port });
|
console.error("参数验证失败", { name });
|
||||||
return { success: false, error: "参数不完整" };
|
return { success: false, error: "参数不完整" };
|
||||||
}
|
}
|
||||||
|
|
||||||
const client = AuthManager.createAuthenticatedDataClient();
|
const client = AuthManager.createAuthenticatedDataClient();
|
||||||
const boardId = await client.addBoard(name, ipAddr, port);
|
const boardId = await client.addBoard(name);
|
||||||
|
|
||||||
if (boardId) {
|
if (boardId) {
|
||||||
console.log("新增板卡成功", { boardId, name, ipAddr, port });
|
console.log("新增板卡成功", { boardId, name});
|
||||||
// 刷新板卡列表
|
// 刷新板卡列表
|
||||||
await getAllBoards();
|
await getAllBoards();
|
||||||
return { success: true};
|
return { success: true };
|
||||||
} else {
|
} else {
|
||||||
console.error("新增板卡失败:返回ID为空");
|
console.error("新增板卡失败:返回ID为空");
|
||||||
return { success: false, error: "新增板卡失败" };
|
return { success: false, error: "新增板卡失败" };
|
||||||
|
@ -116,7 +114,9 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除板卡(管理员权限)
|
// 删除板卡(管理员权限)
|
||||||
async function deleteBoard(boardId: string): Promise<{ success: boolean; error?: string }> {
|
async function deleteBoard(
|
||||||
|
boardId: string,
|
||||||
|
): Promise<{ success: boolean; error?: string }> {
|
||||||
try {
|
try {
|
||||||
// 验证管理员权限
|
// 验证管理员权限
|
||||||
const hasAdminAuth = await AuthManager.verifyAdminAuth();
|
const hasAdminAuth = await AuthManager.verifyAdminAuth();
|
||||||
|
@ -198,7 +198,10 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (downloadResult != cnt) {
|
if (downloadResult != cnt) {
|
||||||
console.error("固化比特流失败", { expected: cnt, actual: downloadResult });
|
console.error("固化比特流失败", {
|
||||||
|
expected: cnt,
|
||||||
|
actual: downloadResult,
|
||||||
|
});
|
||||||
return { success: false, error: "固化比特流失败" };
|
return { success: false, error: "固化比特流失败" };
|
||||||
} else {
|
} else {
|
||||||
console.log("固化比特流成功", { count: downloadResult });
|
console.log("固化比特流成功", { count: downloadResult });
|
||||||
|
@ -213,7 +216,7 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
|
||||||
// 热启动位流
|
// 热启动位流
|
||||||
async function hotresetBitstream(
|
async function hotresetBitstream(
|
||||||
board: BoardData,
|
board: BoardData,
|
||||||
bitstreamNum: number
|
bitstreamNum: number,
|
||||||
): Promise<{ success: boolean; error?: string }> {
|
): Promise<{ success: boolean; error?: string }> {
|
||||||
try {
|
try {
|
||||||
console.log("开始热启动比特流", { boardIp: board.ipAddr, bitstreamNum });
|
console.log("开始热启动比特流", { boardIp: board.ipAddr, bitstreamNum });
|
||||||
|
@ -253,7 +256,11 @@ const [useProvideBoardManager, useBoardManager] = createInjectionState(() => {
|
||||||
const file = target.files?.[0];
|
const file = target.files?.[0];
|
||||||
if (file) {
|
if (file) {
|
||||||
(board as any)[fileKey] = file;
|
(board as any)[fileKey] = file;
|
||||||
console.log(`文件选择成功`, { boardIp: board.ipAddr, fileKey, fileName: file.name });
|
console.log(`文件选择成功`, {
|
||||||
|
boardIp: board.ipAddr,
|
||||||
|
fileKey,
|
||||||
|
fileName: file.name,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,61 +3,73 @@
|
||||||
<div class="modal-box w-96 max-w-md">
|
<div class="modal-box w-96 max-w-md">
|
||||||
<h3 class="text-lg font-bold mb-4">新增实验板</h3>
|
<h3 class="text-lg font-bold mb-4">新增实验板</h3>
|
||||||
|
|
||||||
<form @submit.prevent="handleSubmit" class="space-y-4">
|
<!-- 步骤1: 输入板卡名称 -->
|
||||||
<!-- 实验板名称 -->
|
<div v-if="currentStep === 'input'" class="space-y-4">
|
||||||
<div class="form-control">
|
<form @submit.prevent="handleSubmit">
|
||||||
<label class="label">
|
<!-- 实验板名称 -->
|
||||||
<span class="label-text">实验板名称 <span class="text-error">*</span></span>
|
<div class="form-control">
|
||||||
</label>
|
<label class="label">
|
||||||
<input
|
<span class="label-text"
|
||||||
v-model="form.name"
|
>实验板名称 <span class="text-error">*</span></span
|
||||||
type="text"
|
>
|
||||||
placeholder="请输入实验板名称"
|
</label>
|
||||||
class="input input-bordered"
|
<input
|
||||||
:class="{ 'input-error': errors.name }"
|
v-model="form.name"
|
||||||
required
|
type="text"
|
||||||
/>
|
placeholder="请输入实验板名称"
|
||||||
<label v-if="errors.name" class="label">
|
class="input input-bordered"
|
||||||
<span class="label-text-alt text-error">{{ errors.name }}</span>
|
:class="{ 'input-error': errors.name }"
|
||||||
</label>
|
required
|
||||||
</div>
|
/>
|
||||||
|
<label v-if="errors.name" class="label">
|
||||||
|
<span class="label-text-alt text-error">{{ errors.name }}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- IP 地址 -->
|
<!-- 操作按钮 -->
|
||||||
<div class="form-control">
|
<div class="modal-action">
|
||||||
<label class="label">
|
<button
|
||||||
<span class="label-text">IP 地址 <span class="text-error">*</span></span>
|
type="button"
|
||||||
</label>
|
class="btn btn-ghost"
|
||||||
<input
|
@click="handleCancel"
|
||||||
v-model="form.ipAddr"
|
:disabled="isSubmitting"
|
||||||
type="text"
|
>
|
||||||
placeholder="例如:192.168.1.100"
|
取消
|
||||||
class="input input-bordered"
|
</button>
|
||||||
:class="{ 'input-error': errors.ipAddr }"
|
<button
|
||||||
required
|
type="submit"
|
||||||
/>
|
class="btn btn-primary"
|
||||||
<label v-if="errors.ipAddr" class="label">
|
:class="{ loading: isSubmitting }"
|
||||||
<span class="label-text-alt text-error">{{ errors.ipAddr }}</span>
|
:disabled="isSubmitting"
|
||||||
</label>
|
>
|
||||||
</div>
|
{{ isSubmitting ? "添加中..." : "确认添加" }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 端口号 -->
|
<!-- 步骤2: 等待配对 -->
|
||||||
<div class="form-control">
|
<div v-else-if="currentStep === 'pairing'" class="space-y-4">
|
||||||
<label class="label">
|
<div class="text-center">
|
||||||
<span class="label-text">端口号 <span class="text-error">*</span></span>
|
<div class="alert alert-info">
|
||||||
</label>
|
<div class="flex items-center">
|
||||||
<input
|
<svg
|
||||||
v-model.number="form.port"
|
class="w-5 h-5 mr-2"
|
||||||
type="number"
|
fill="none"
|
||||||
placeholder="例如:1234"
|
stroke="currentColor"
|
||||||
min="1"
|
viewBox="0 0 24 24"
|
||||||
max="65535"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="input input-bordered"
|
>
|
||||||
:class="{ 'input-error': errors.port }"
|
<path
|
||||||
required
|
stroke-linecap="round"
|
||||||
/>
|
stroke-linejoin="round"
|
||||||
<label v-if="errors.port" class="label">
|
stroke-width="2"
|
||||||
<span class="label-text-alt text-error">{{ errors.port }}</span>
|
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
</label>
|
/>
|
||||||
|
</svg>
|
||||||
|
<span>请打开实验板配对模式</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
|
@ -65,21 +77,82 @@
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-ghost"
|
class="btn btn-ghost"
|
||||||
@click="handleCancel"
|
@click="handleCancelPairing"
|
||||||
:disabled="isSubmitting"
|
:disabled="isConfiguring"
|
||||||
>
|
>
|
||||||
取消
|
取消
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="button"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
:class="{ 'loading': isSubmitting }"
|
@click="handlePairingConfirm"
|
||||||
:disabled="isSubmitting"
|
:disabled="isConfiguring"
|
||||||
>
|
>
|
||||||
{{ isSubmitting ? '添加中...' : '确认添加' }}
|
已开启
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
|
|
||||||
|
<!-- 步骤3: 配置网络 -->
|
||||||
|
<div v-else-if="currentStep === 'configuring'" class="space-y-4">
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="loading loading-spinner loading-sm mr-2"></div>
|
||||||
|
<span>正在分配网络...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 步骤4: 显示配置结果 -->
|
||||||
|
<div v-else-if="currentStep === 'result'" class="space-y-4">
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<svg
|
||||||
|
class="w-5 h-5 mr-2"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M5 13l4 4L19 7"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span>实验板配置成功</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 网络配置信息 -->
|
||||||
|
<div v-if="networkConfig" class="space-y-2">
|
||||||
|
<h4 class="font-semibold">网络配置信息:</h4>
|
||||||
|
<div class="bg-base-200 p-3 rounded">
|
||||||
|
<div class="text-sm space-y-1">
|
||||||
|
<div><span class="font-medium">主机IP:</span> {{ networkConfig.hostIP }}</div>
|
||||||
|
<div><span class="font-medium">板卡IP:</span> {{ networkConfig.boardIP }}</div>
|
||||||
|
<div><span class="font-medium">主机MAC:</span> {{ networkConfig.hostMAC }}</div>
|
||||||
|
<div><span class="font-medium">板卡MAC:</span> {{ networkConfig.boardMAC }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<div class="modal-action">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="handleSuccess"
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 点击背景关闭 -->
|
<!-- 点击背景关闭 -->
|
||||||
|
@ -90,8 +163,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, watch } from 'vue';
|
import { ref, reactive, watch } from "vue";
|
||||||
import { useBoardManager } from '../../utils/BoardManager';
|
import { AuthManager } from "../../utils/AuthManager";
|
||||||
|
import { useAlertStore } from "../../components/Alert";
|
||||||
|
import type { NetworkConfigDto } from "../../APIClient";
|
||||||
|
|
||||||
// Props 和 Emits
|
// Props 和 Emits
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -99,75 +174,53 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:visible', value: boolean): void;
|
(e: "update:visible", value: boolean): void;
|
||||||
(e: 'success'): void;
|
(e: "success"): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
// 使用 BoardManager
|
// 使用 Alert
|
||||||
const boardManager = useBoardManager()!;
|
const alertStore = useAlertStore();
|
||||||
|
|
||||||
|
// 当前步骤
|
||||||
|
const currentStep = ref<'input' | 'pairing' | 'configuring' | 'result'>('input');
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: 'Board1',
|
name: "Board1",
|
||||||
ipAddr: '169.254.103.0',
|
|
||||||
port: 1234
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 表单错误
|
// 表单错误
|
||||||
const errors = reactive({
|
const errors = reactive({
|
||||||
name: '',
|
name: "",
|
||||||
ipAddr: '',
|
|
||||||
port: ''
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 提交状态
|
// 状态
|
||||||
const isSubmitting = ref(false);
|
const isSubmitting = ref(false);
|
||||||
|
const isConfiguring = ref(false);
|
||||||
|
|
||||||
// IP地址验证正则
|
// 添加的板卡信息
|
||||||
const IP_REGEX = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
const addedBoardId = ref<string>("");
|
||||||
|
const networkConfig = ref<NetworkConfigDto | null>(null);
|
||||||
|
|
||||||
// 验证表单
|
// 验证表单
|
||||||
function validateForm(): boolean {
|
function validateForm(): boolean {
|
||||||
// 清空之前的错误
|
// 清空之前的错误
|
||||||
errors.name = '';
|
errors.name = "";
|
||||||
errors.ipAddr = '';
|
|
||||||
errors.port = '';
|
|
||||||
|
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
|
|
||||||
// 验证名称
|
// 验证名称
|
||||||
if (!form.name.trim()) {
|
if (!form.name.trim()) {
|
||||||
errors.name = '请输入实验板名称';
|
errors.name = "请输入实验板名称";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
} else if (form.name.trim().length < 2) {
|
} else if (form.name.trim().length < 2) {
|
||||||
errors.name = '实验板名称至少需要2个字符';
|
errors.name = "实验板名称至少需要2个字符";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
} else if (form.name.trim().length > 50) {
|
} else if (form.name.trim().length > 50) {
|
||||||
errors.name = '实验板名称不能超过50个字符';
|
errors.name = "实验板名称不能超过50个字符";
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证IP地址
|
|
||||||
if (!form.ipAddr.trim()) {
|
|
||||||
errors.ipAddr = '请输入IP地址';
|
|
||||||
isValid = false;
|
|
||||||
} else if (!IP_REGEX.test(form.ipAddr.trim())) {
|
|
||||||
errors.ipAddr = '请输入有效的IP地址格式';
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证端口号
|
|
||||||
if (!form.port) {
|
|
||||||
errors.port = '请输入端口号';
|
|
||||||
isValid = false;
|
|
||||||
} else if (form.port < 1 || form.port > 65535) {
|
|
||||||
errors.port = '端口号必须在1-65535之间';
|
|
||||||
isValid = false;
|
|
||||||
} else if (!Number.isInteger(form.port)) {
|
|
||||||
errors.port = '端口号必须是整数';
|
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,18 +229,17 @@ function validateForm(): boolean {
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
function resetForm() {
|
function resetForm() {
|
||||||
form.name = 'Board1';
|
form.name = "Board1";
|
||||||
form.ipAddr = '169.254.103.0';
|
errors.name = "";
|
||||||
form.port = 1234;
|
currentStep.value = 'input';
|
||||||
errors.name = '';
|
addedBoardId.value = "";
|
||||||
errors.ipAddr = '';
|
networkConfig.value = null;
|
||||||
errors.port = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理取消
|
// 处理取消
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
if (!isSubmitting.value) {
|
if (!isSubmitting.value && !isConfiguring.value) {
|
||||||
emit('update:visible', false);
|
emit("update:visible", false);
|
||||||
resetForm();
|
resetForm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,29 +253,120 @@ async function handleSubmit() {
|
||||||
isSubmitting.value = true;
|
isSubmitting.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const success = await boardManager.addBoard(
|
// 通过 AuthManager 获取认证的 DataClient
|
||||||
form.name.trim(),
|
const dataClient = AuthManager.createAuthenticatedDataClient();
|
||||||
form.ipAddr.trim(),
|
|
||||||
form.port
|
|
||||||
);
|
|
||||||
|
|
||||||
if (success) {
|
// 添加板卡到数据库
|
||||||
emit('success');
|
const boardId = await dataClient.addBoard(form.name.trim());
|
||||||
resetForm();
|
|
||||||
|
if (boardId) {
|
||||||
|
addedBoardId.value = boardId;
|
||||||
|
currentStep.value = 'pairing';
|
||||||
|
alertStore?.success("板卡添加成功,请开启配对模式");
|
||||||
|
} else {
|
||||||
|
alertStore?.error("板卡添加失败");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('添加实验板失败:', error);
|
console.error("添加实验板失败:", error);
|
||||||
|
alertStore?.error("添加实验板失败");
|
||||||
} finally {
|
} finally {
|
||||||
isSubmitting.value = false;
|
isSubmitting.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听对话框显示状态,重置表单
|
// 处理取消配对
|
||||||
watch(() => props.visible, (newVisible) => {
|
async function handleCancelPairing() {
|
||||||
if (newVisible) {
|
if (!addedBoardId.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 通过 AuthManager 获取认证的 DataClient
|
||||||
|
const dataClient = AuthManager.createAuthenticatedDataClient();
|
||||||
|
|
||||||
|
// 删除添加的板卡
|
||||||
|
await dataClient.deleteBoard(addedBoardId.value);
|
||||||
|
|
||||||
|
alertStore?.info("已取消添加实验板");
|
||||||
|
emit("update:visible", false);
|
||||||
resetForm();
|
resetForm();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("删除板卡失败:", error);
|
||||||
|
alertStore?.error("删除板卡失败");
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// 处理配对确认
|
||||||
|
async function handlePairingConfirm() {
|
||||||
|
if (!addedBoardId.value) return;
|
||||||
|
|
||||||
|
isConfiguring.value = true;
|
||||||
|
currentStep.value = 'configuring';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 通过 AuthManager 获取认证的客户端
|
||||||
|
const dataClient = AuthManager.createAuthenticatedDataClient();
|
||||||
|
const netConfigClient = AuthManager.createAuthenticatedNetConfigClient();
|
||||||
|
|
||||||
|
// 获取数据库中对应分配的板卡信息
|
||||||
|
const boardInfo = await dataClient.getBoardByID(addedBoardId.value);
|
||||||
|
|
||||||
|
if (!boardInfo) {
|
||||||
|
throw new Error("无法获取板卡信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新主机IP和主机MAC
|
||||||
|
await netConfigClient.updateHostIP();
|
||||||
|
await netConfigClient.updateHostMAC();
|
||||||
|
|
||||||
|
// 设置板卡IP和MAC
|
||||||
|
await netConfigClient.setBoardIP(boardInfo.ipAddr);
|
||||||
|
await netConfigClient.setBoardMAC(boardInfo.macAddr);
|
||||||
|
|
||||||
|
// 获取实验板网络信息
|
||||||
|
const networkInfo = await netConfigClient.getNetworkConfig();
|
||||||
|
|
||||||
|
if (networkInfo) {
|
||||||
|
networkConfig.value = networkInfo;
|
||||||
|
currentStep.value = 'result';
|
||||||
|
alertStore?.success("实验板配置成功");
|
||||||
|
} else {
|
||||||
|
throw new Error("无法获取网络配置信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("配置实验板失败:", error);
|
||||||
|
alertStore?.error("配置实验板失败");
|
||||||
|
|
||||||
|
// 配置失败,删除数据库中的板卡信息
|
||||||
|
try {
|
||||||
|
const dataClient = AuthManager.createAuthenticatedDataClient();
|
||||||
|
await dataClient.deleteBoard(addedBoardId.value);
|
||||||
|
} catch (deleteError) {
|
||||||
|
console.error("删除板卡失败:", deleteError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回输入步骤
|
||||||
|
currentStep.value = 'input';
|
||||||
|
} finally {
|
||||||
|
isConfiguring.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理成功
|
||||||
|
function handleSuccess() {
|
||||||
|
emit("success");
|
||||||
|
emit("update:visible", false);
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听对话框显示状态,重置表单
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(newVisible) => {
|
||||||
|
if (newVisible) {
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="postcss">
|
<style scoped lang="postcss">
|
||||||
|
@ -248,4 +391,20 @@ watch(() => props.visible, (newVisible) => {
|
||||||
.loading {
|
.loading {
|
||||||
@apply opacity-50 cursor-not-allowed;
|
@apply opacity-50 cursor-not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
@apply rounded-lg p-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-info {
|
||||||
|
@apply bg-blue-50 text-blue-800 border border-blue-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-warning {
|
||||||
|
@apply bg-yellow-50 text-yellow-800 border border-yellow-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-success {
|
||||||
|
@apply bg-green-50 text-green-800 border border-green-200;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -37,7 +37,9 @@ const [useProvideBoardTableManager, useBoardTableManager] =
|
||||||
port: false,
|
port: false,
|
||||||
id: false,
|
id: false,
|
||||||
status: false,
|
status: false,
|
||||||
version: false,
|
firmVersion: false,
|
||||||
|
macAddr: false,
|
||||||
|
occupiedUserName: false,
|
||||||
});
|
});
|
||||||
const rowSelection = ref({});
|
const rowSelection = ref({});
|
||||||
const expanded = ref<ExpandedState>({});
|
const expanded = ref<ExpandedState>({});
|
||||||
|
@ -88,20 +90,12 @@ const [useProvideBoardTableManager, useBoardTableManager] =
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "devAddr",
|
accessorKey: "ipAddr",
|
||||||
header: "IP 地址",
|
header: "IP 地址",
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const device = row.original;
|
const device = row.original;
|
||||||
return isEditMode.value
|
// IP地址设置为不可更改
|
||||||
? h("input", {
|
return h("span", { class: "font-mono" }, device.ipAddr);
|
||||||
type: "text",
|
|
||||||
class: "input input-sm w-full",
|
|
||||||
value: device.ipAddr,
|
|
||||||
onInput: (e: Event) => {
|
|
||||||
device.ipAddr = (e.target as HTMLInputElement).value;
|
|
||||||
},
|
|
||||||
})
|
|
||||||
: h("span", { class: "font-medium" }, device.ipAddr);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -109,16 +103,28 @@ const [useProvideBoardTableManager, useBoardTableManager] =
|
||||||
header: "端口",
|
header: "端口",
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const device = row.original;
|
const device = row.original;
|
||||||
return isEditMode.value
|
// 端口设置为不可更改
|
||||||
? h("input", {
|
return h("span", { class: "font-mono" }, device.port.toString());
|
||||||
type: "number",
|
},
|
||||||
class: "input input-sm w-full",
|
enableHiding: true,
|
||||||
value: device.port,
|
},
|
||||||
onInput: (e: Event) => {
|
{
|
||||||
device.port = parseInt((e.target as HTMLInputElement).value);
|
accessorKey: "macAddr",
|
||||||
},
|
header: "MAC 地址",
|
||||||
})
|
cell: ({ row }) => {
|
||||||
: h("span", { class: "font-mono" }, device.port.toString());
|
const device = row.original;
|
||||||
|
return h("span", { class: "font-mono text-sm" }, device.macAddr);
|
||||||
|
},
|
||||||
|
enableHiding: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "occupiedUserName",
|
||||||
|
header: "占用用户",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const device = row.original;
|
||||||
|
const userName = device.occupiedUserName || "未占用";
|
||||||
|
const userClass = device.occupiedUserName ? "text-warning" : "text-success";
|
||||||
|
return h("span", { class: `font-medium ${userClass}` }, userName);
|
||||||
},
|
},
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
},
|
},
|
||||||
|
@ -134,9 +140,27 @@ const [useProvideBoardTableManager, useBoardTableManager] =
|
||||||
header: "状态",
|
header: "状态",
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const device = row.original;
|
const device = row.original;
|
||||||
const statusText = device.status === 0 ? "忙碌" : "可用";
|
let statusText = "";
|
||||||
const statusClass =
|
let statusClass = "";
|
||||||
device.status === 0 ? "badge-warning" : "badge-success";
|
|
||||||
|
switch (device.status) {
|
||||||
|
case 0: // Disabled
|
||||||
|
statusText = "禁用";
|
||||||
|
statusClass = "badge-error";
|
||||||
|
break;
|
||||||
|
case 1: // Busy
|
||||||
|
statusText = "忙碌";
|
||||||
|
statusClass = "badge-warning";
|
||||||
|
break;
|
||||||
|
case 2: // Available
|
||||||
|
statusText = "可用";
|
||||||
|
statusClass = "badge-success";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
statusText = "未知";
|
||||||
|
statusClass = "badge-neutral";
|
||||||
|
}
|
||||||
|
|
||||||
return h(
|
return h(
|
||||||
"span",
|
"span",
|
||||||
{
|
{
|
||||||
|
@ -148,10 +172,11 @@ const [useProvideBoardTableManager, useBoardTableManager] =
|
||||||
enableHiding: true,
|
enableHiding: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "version",
|
accessorKey: "firmVersion",
|
||||||
header: "版本号",
|
header: "固件版本",
|
||||||
cell: ({ row }) =>
|
cell: ({ row }) =>
|
||||||
h("span", { class: "font-mono" }, row.original.firmVersion),
|
h("span", { class: "font-mono text-sm" }, row.original.firmVersion),
|
||||||
|
enableHiding: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "defaultBitstream",
|
accessorKey: "defaultBitstream",
|
||||||
|
@ -248,7 +273,7 @@ const [useProvideBoardTableManager, useBoardTableManager] =
|
||||||
class: "btn btn-error btn-sm",
|
class: "btn btn-error btn-sm",
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
const confirmed = confirm(
|
const confirmed = confirm(
|
||||||
`确定要删除设备 ${device.ipAddr} 吗?`,
|
`确定要删除设备 ${device.boardName || device.ipAddr} 吗?`,
|
||||||
);
|
);
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
await deleteBoard(device.id);
|
await deleteBoard(device.id);
|
||||||
|
@ -378,8 +403,8 @@ const [useProvideBoardTableManager, useBoardTableManager] =
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增板卡
|
// 新增板卡
|
||||||
async function addBoard(name: string, ipAddr: string, port: number): Promise<boolean> {
|
async function addBoard(name: string): Promise<boolean> {
|
||||||
const result = await boardManager.addBoard(name, ipAddr, port);
|
const result = await boardManager.addBoard(name);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
dialog?.info("新增板卡成功");
|
dialog?.info("新增板卡成功");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue