实现nfc配对

This commit is contained in:
WindowBird 2025-11-20 11:40:31 +08:00
parent 2a58e93f96
commit 2fcaa764c8
2 changed files with 59 additions and 45 deletions

View File

@ -120,7 +120,7 @@ export function getDeceasedList(params) {
* @returns {Promise} * @returns {Promise}
*/ */
export function bindNfcCard(data) { export function bindNfcCard(data) {
return post("/bst/nfc", data, { return post("/bst/nfc/add", data, {
showLoading: false, showLoading: false,
}); });
} }

View File

@ -27,23 +27,26 @@
<view v-if="cardNo" class="text-btn" @click="resetCard" <view v-if="cardNo" class="text-btn" @click="resetCard"
>清空卡号 >清空卡号
</view> </view>
<view v-if="connectionError" class="text-btn" @click="testServerConnection" <view
v-if="connectionError"
class="text-btn"
@click="testServerConnection"
>测试服务器 >测试服务器
</view> </view>
</view> </view>
</view> </view>
<view class="form-card"> <view class="form-card">
<view class="field"> <!-- <view class="field">-->
<text class="label">设备 MAC 地址</text> <!-- <text class="label">设备 MAC 地址</text>-->
<input <!-- <input-->
v-model.trim="deviceMac" <!-- v-model.trim="deviceMac"-->
class="input" <!-- class="input"-->
maxlength="32" <!-- maxlength="32"-->
placeholder="请输入设备 MAC" <!-- placeholder="请输入设备 MAC"-->
placeholder-class="placeholder" <!-- placeholder-class="placeholder"-->
/> <!-- />-->
</view> <!-- </view>-->
<view class="field"> <view class="field">
<text class="label">NFC 卡号</text> <text class="label">NFC 卡号</text>
<input <input
@ -102,7 +105,7 @@ export default {
}, },
computed: { computed: {
canSubmit() { canSubmit() {
return !!this.deviceMac && !!this.cardNo; return !!this.cardNo;
}, },
connectionText() { connectionText() {
if (this.connectionError) { if (this.connectionError) {
@ -144,11 +147,11 @@ export default {
const isHttps = baseUrl.startsWith("https://"); const isHttps = baseUrl.startsWith("https://");
const protocol = isHttps ? "wss" : "ws"; const protocol = isHttps ? "wss" : "ws";
const host = baseUrl.replace(/^https?:\/\//, "").replace(/\/$/, ""); const host = baseUrl.replace(/^https?:\/\//, "").replace(/\/$/, "");
// token mac // token mac
const query = `?token=${encodeURIComponent(token)}&mac=${FIXED_MAC}`; const query = `?token=${encodeURIComponent(token)}&mac=${FIXED_MAC}`;
const url = `${protocol}://${host}${WS_PATH}${query}`; const url = `${protocol}://${host}${WS_PATH}${query}`;
console.log("构建 WebSocket URL:", { console.log("构建 WebSocket URL:", {
baseUrl, baseUrl,
protocol, protocol,
@ -158,7 +161,7 @@ export default {
mac: FIXED_MAC, mac: FIXED_MAC,
finalUrl: url.replace(token, "***"), // token finalUrl: url.replace(token, "***"), // token
}); });
return url; return url;
} catch (error) { } catch (error) {
console.error("构建WebSocket地址失败", error); console.error("构建WebSocket地址失败", error);
@ -176,7 +179,7 @@ export default {
} }
this.cleanupSocket(); this.cleanupSocket();
console.log("NFC配对页面发起WebSocket连接:", url); console.log("NFC配对页面发起WebSocket连接:", url);
try { try {
// //
this.connectTimeout = setTimeout(() => { this.connectTimeout = setTimeout(() => {
@ -187,7 +190,7 @@ export default {
} }
}, 10000); // 10 }, 10000); // 10
this.socketTask = uni.connectSocket({ this.socketTask = uni.connectSocket({
url, url,
success: (res) => { success: (res) => {
console.log("uni.connectSocket success:", res); console.log("uni.connectSocket success:", res);
@ -197,16 +200,16 @@ export default {
clearTimeout(this.connectTimeout); clearTimeout(this.connectTimeout);
this.connectionError = `连接失败: ${err.errMsg || "未知错误"}`; this.connectionError = `连接失败: ${err.errMsg || "未知错误"}`;
this.socketConnected = false; this.socketConnected = false;
} },
}); });
if (!this.socketTask) { if (!this.socketTask) {
clearTimeout(this.connectTimeout); clearTimeout(this.connectTimeout);
this.connectionError = "当前环境不支持WebSocket"; this.connectionError = "当前环境不支持WebSocket";
console.error("initSocket: socketTask 为 null"); console.error("initSocket: socketTask 为 null");
return; return;
} }
if (typeof this.socketTask.onOpen === "function") { if (typeof this.socketTask.onOpen === "function") {
console.log("使用 Task 级别事件绑定", this.socketTask); console.log("使用 Task 级别事件绑定", this.socketTask);
this.bindTaskSocketEvents(); this.bindTaskSocketEvents();
@ -226,7 +229,7 @@ export default {
clearTimeout(this.connectTimeout); clearTimeout(this.connectTimeout);
this.connectTimeout = null; this.connectTimeout = null;
} }
if (this.socketTask && typeof this.socketTask.close === "function") { if (this.socketTask && typeof this.socketTask.close === "function") {
try { try {
this.socketTask.close(); this.socketTask.close();
@ -276,31 +279,37 @@ export default {
clearTimeout(this.connectTimeout); clearTimeout(this.connectTimeout);
this.connectTimeout = null; this.connectTimeout = null;
} }
// //
let errorMsg = error.errMsg || error.message || "连接失败"; let errorMsg = error.errMsg || error.message || "连接失败";
let userFriendlyMsg = "连接失败"; let userFriendlyMsg = "连接失败";
// Invalid HTTP status // Invalid HTTP status
if (errorMsg.includes("Invalid HTTP status") || error.errCode === 1004) { if (
userFriendlyMsg = "服务器不支持WebSocket或路径不存在\n请检查\n1. 服务器是否正常运行\n2. WebSocket路径是否正确\n3. 服务器是否支持WebSocket协议"; errorMsg.includes("Invalid HTTP status") ||
error.errCode === 1004
) {
userFriendlyMsg =
"服务器不支持WebSocket或路径不存在\n请检查\n1. 服务器是否正常运行\n2. WebSocket路径是否正确\n3. 服务器是否支持WebSocket协议";
console.error("WebSocket握手失败可能原因", { console.error("WebSocket握手失败可能原因", {
url: this.buildSocketUrl(), url: this.buildSocketUrl(),
errorCode: error.errCode, errorCode: error.errCode,
errorMsg: errorMsg, errorMsg: errorMsg,
suggestion: "服务器可能返回了404或500错误请检查服务器日志" suggestion: "服务器可能返回了404或500错误请检查服务器日志",
}); });
} else if (errorMsg.includes("timeout")) { } else if (errorMsg.includes("timeout")) {
userFriendlyMsg = "连接超时,请检查网络连接"; userFriendlyMsg = "连接超时,请检查网络连接";
} else if (errorMsg.includes("fail")) { } else if (errorMsg.includes("fail")) {
userFriendlyMsg = "网络连接失败,请检查网络和服务器地址"; userFriendlyMsg = "网络连接失败,请检查网络和服务器地址";
} }
this.connectionError = userFriendlyMsg; this.connectionError = userFriendlyMsg;
this.socketConnected = false; this.socketConnected = false;
}); });
this.socketTask.onMessage((event) => { this.socketTask.onMessage((event) => {
this.handleSocketMessage(event); this.handleSocketMessage(event);
console.log("WebSocket <UNK>接收到事件", event);
}); });
}, },
bindGlobalSocketEvents() { bindGlobalSocketEvents() {
@ -334,26 +343,30 @@ export default {
clearTimeout(this.connectTimeout); clearTimeout(this.connectTimeout);
this.connectTimeout = null; this.connectTimeout = null;
} }
// //
let errorMsg = error.errMsg || error.message || "连接失败"; let errorMsg = error.errMsg || error.message || "连接失败";
let userFriendlyMsg = "连接失败"; let userFriendlyMsg = "连接失败";
// Invalid HTTP status // Invalid HTTP status
if (errorMsg.includes("Invalid HTTP status") || error.errCode === 1004) { if (
userFriendlyMsg = "服务器不支持WebSocket或路径不存在\n请检查\n1. 服务器是否正常运行\n2. WebSocket路径是否正确\n3. 服务器是否支持WebSocket协议"; errorMsg.includes("Invalid HTTP status") ||
error.errCode === 1004
) {
userFriendlyMsg =
"服务器不支持WebSocket或路径不存在\n请检查\n1. 服务器是否正常运行\n2. WebSocket路径是否正确\n3. 服务器是否支持WebSocket协议";
console.error("WebSocket握手失败可能原因", { console.error("WebSocket握手失败可能原因", {
url: this.buildSocketUrl(), url: this.buildSocketUrl(),
errorCode: error.errCode, errorCode: error.errCode,
errorMsg: errorMsg, errorMsg: errorMsg,
suggestion: "服务器可能返回了404或500错误请检查服务器日志" suggestion: "服务器可能返回了404或500错误请检查服务器日志",
}); });
} else if (errorMsg.includes("timeout")) { } else if (errorMsg.includes("timeout")) {
userFriendlyMsg = "连接超时,请检查网络连接"; userFriendlyMsg = "连接超时,请检查网络连接";
} else if (errorMsg.includes("fail")) { } else if (errorMsg.includes("fail")) {
userFriendlyMsg = "网络连接失败,请检查网络和服务器地址"; userFriendlyMsg = "网络连接失败,请检查网络和服务器地址";
} }
this.connectionError = userFriendlyMsg; this.connectionError = userFriendlyMsg;
this.socketConnected = false; this.socketConnected = false;
}, },
@ -394,7 +407,8 @@ export default {
this.lastMessage = parsed.msg || trimmed; this.lastMessage = parsed.msg || trimmed;
return; return;
} else { } else {
this.cardNo = trimmed; this.cardNo = trimmed.replace(/^['"]|['"]$/g, "");
console.log("接收到的卡号", this.cardNo);
this.lastMessage = "已接收卡号"; this.lastMessage = "已接收卡号";
uni.showToast({ title: "收到卡号", icon: "success" }); uni.showToast({ title: "收到卡号", icon: "success" });
return; return;
@ -426,7 +440,7 @@ export default {
try { try {
const { baseUrl } = getRequestConfig(); const { baseUrl } = getRequestConfig();
console.log("测试服务器连接:", baseUrl); console.log("测试服务器连接:", baseUrl);
const token = getToken(); const token = getToken();
if (!token) { if (!token) {
uni.showModal({ uni.showModal({
@ -436,17 +450,17 @@ export default {
}); });
return; return;
} }
// WebSocket // WebSocket
const isHttps = baseUrl.startsWith("https://"); const isHttps = baseUrl.startsWith("https://");
const protocol = isHttps ? "wss" : "ws"; const protocol = isHttps ? "wss" : "ws";
const host = baseUrl.replace(/^https?:\/\//, "").replace(/\/$/, ""); const host = baseUrl.replace(/^https?:\/\//, "").replace(/\/$/, "");
const testUrl = `${protocol}://${host}${WS_PATH}?token=${encodeURIComponent(token)}&mac=${FIXED_MAC}`; const testUrl = `${protocol}://${host}${WS_PATH}?token=${encodeURIComponent(token)}&mac=${FIXED_MAC}`;
console.log("测试 WebSocket URL:", testUrl.replace(token, "***")); console.log("测试 WebSocket URL:", testUrl.replace(token, "***"));
uni.showLoading({ title: "测试连接中...", mask: true }); uni.showLoading({ title: "测试连接中...", mask: true });
// WebSocket // WebSocket
const testSocket = uni.connectSocket({ const testSocket = uni.connectSocket({
url: testUrl, url: testUrl,
@ -463,7 +477,7 @@ export default {
}); });
}, },
}); });
// //
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
testSocket.close(); testSocket.close();
@ -474,7 +488,7 @@ export default {
showCancel: false, showCancel: false,
}); });
}, 5000); }, 5000);
testSocket.onOpen(() => { testSocket.onOpen(() => {
clearTimeout(timeout); clearTimeout(timeout);
testSocket.close(); testSocket.close();
@ -485,7 +499,7 @@ export default {
duration: 2000, duration: 2000,
}); });
}); });
testSocket.onError((err) => { testSocket.onError((err) => {
clearTimeout(timeout); clearTimeout(timeout);
uni.hideLoading(); uni.hideLoading();
@ -510,11 +524,11 @@ export default {
uni.showLoading({ title: "提交中...", mask: true }); uni.showLoading({ title: "提交中...", mask: true });
try { try {
const payload = { const payload = {
memorialMac: this.deviceMac, // memorialMac: this.deviceMac,
nfcMac: this.cardNo, nfcMac: this.cardNo,
}; };
if (this.unitId) { if (this.unitId) {
payload.unitId = this.unitId; payload.memorialId = this.unitId;
} }
const res = await bindNfcCard(payload); const res = await bindNfcCard(payload);
if (res && (res.code === 200 || res.status === 200)) { if (res && (res.code === 200 || res.status === 200)) {