人员管理增加修改
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"appid" : "__UNI__5A0A7D6",
|
"appid" : "__UNI__5A0A7D6",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "1.2.5",
|
"versionName" : "1.2.5",
|
||||||
"versionCode" : 114,
|
"versionCode" : 116,
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
/* 5+App特有相关 */
|
/* 5+App特有相关 */
|
||||||
"app-plus" : {
|
"app-plus" : {
|
||||||
|
|||||||
+6
-3
@@ -603,17 +603,19 @@ export default {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.page{
|
.page{
|
||||||
/* padding: 10px; */
|
/* padding: 10px; */
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.content{
|
.content{
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
.block {
|
.block {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
@@ -713,7 +715,8 @@ export default {
|
|||||||
.column{
|
.column{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -379,10 +379,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
temp() {
|
temp() {
|
||||||
this.RS485.sendDataString(cmd.getTemp())
|
this.RS485.sendDataString('020300000002C438')
|
||||||
},
|
},
|
||||||
pressure() {
|
pressure() {
|
||||||
this.RS485.sendDataString(cmd.getPressure())
|
this.RS485.sendDataString('01030001000295CB')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+120
-4
@@ -16,8 +16,8 @@
|
|||||||
<th>工号</th>
|
<th>工号</th>
|
||||||
<th>卡号</th>
|
<th>卡号</th>
|
||||||
<th>卡号2</th>
|
<th>卡号2</th>
|
||||||
|
<th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="ant-table-tbody">
|
<tbody class="ant-table-tbody">
|
||||||
<tr v-for="(item, index) in list" :key="index">
|
<tr v-for="(item, index) in list" :key="index">
|
||||||
@@ -27,6 +27,12 @@
|
|||||||
<td>{{ item.number }}</td>
|
<td>{{ item.number }}</td>
|
||||||
<td>{{ item.ic }}</td>
|
<td>{{ item.ic }}</td>
|
||||||
<td>{{ item.ic2 }}</td>
|
<td>{{ item.ic2 }}</td>
|
||||||
|
<td>
|
||||||
|
<view class="action-btns">
|
||||||
|
<view class="ant-btn edit-btn" @click="edit(item)">编辑</view>
|
||||||
|
<!-- <view class="ant-btn delete-btn" @click="remove(item)">删除</view> -->
|
||||||
|
</view>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -102,7 +108,7 @@
|
|||||||
<uni-row>
|
<uni-row>
|
||||||
<uni-col>
|
<uni-col>
|
||||||
<view class="form-btn">
|
<view class="form-btn">
|
||||||
<view class="ant-btn" @click="submit">保存</view>
|
<view class="ant-btn" @click="submit">{{ isEdit ? '更新' : '保存' }}</view>
|
||||||
<view class="ant-btn" style="margin-left: 20px;" @click="close">取消</view>
|
<view class="ant-btn" style="margin-left: 20px;" @click="close">取消</view>
|
||||||
</view>
|
</view>
|
||||||
</uni-col>
|
</uni-col>
|
||||||
@@ -134,6 +140,8 @@ export default {
|
|||||||
],
|
],
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPage: 0,
|
totalPage: 0,
|
||||||
|
isEdit: false,
|
||||||
|
editId: null,
|
||||||
form: {
|
form: {
|
||||||
name: '',
|
name: '',
|
||||||
ic: '',
|
ic: '',
|
||||||
@@ -149,6 +157,8 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
|
this.isEdit = false
|
||||||
|
this.editId = null
|
||||||
this.$refs.popup.open()
|
this.$refs.popup.open()
|
||||||
this.form = {
|
this.form = {
|
||||||
name: '',
|
name: '',
|
||||||
@@ -167,8 +177,53 @@ export default {
|
|||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$refs.popup.close()
|
this.$refs.popup.close()
|
||||||
|
this.isEdit = false
|
||||||
|
this.editId = null
|
||||||
uni.$off('ic')
|
uni.$off('ic')
|
||||||
},
|
},
|
||||||
|
edit(item) {
|
||||||
|
this.isEdit = true
|
||||||
|
this.editId = item.id
|
||||||
|
this.form = {
|
||||||
|
name: item.name,
|
||||||
|
ic: item.ic,
|
||||||
|
ic2: item.ic2 || '',
|
||||||
|
number: item.number || '',
|
||||||
|
type: item.type || ''
|
||||||
|
}
|
||||||
|
this.$refs.popup.open()
|
||||||
|
uni.$on('ic', (val) => {
|
||||||
|
if (!this.form.ic) {
|
||||||
|
this.form.ic = val
|
||||||
|
} else if (!this.form.ic2) {
|
||||||
|
this.form.ic2 = val
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async remove(item) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '确认删除',
|
||||||
|
content: `确定要删除 ${item.name} 吗?`,
|
||||||
|
success: async (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
try {
|
||||||
|
await db.deleteInformationType('user', { id: item.id })
|
||||||
|
uni.showToast({
|
||||||
|
title: '删除成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
this.getList()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
uni.showToast({
|
||||||
|
title: '删除失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
async submit() {
|
async submit() {
|
||||||
if (this.form.name == '' || this.form.ic == '') {
|
if (this.form.name == '' || this.form.ic == '') {
|
||||||
return false
|
return false
|
||||||
@@ -179,17 +234,33 @@ export default {
|
|||||||
await db.addUserTable()
|
await db.addUserTable()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
if (this.isEdit) {
|
||||||
|
// 编辑模式
|
||||||
|
await db.updateSQL(tableName, {
|
||||||
|
name: this.form.name,
|
||||||
|
ic: this.form.ic,
|
||||||
|
ic2: this.form.ic2,
|
||||||
|
number: this.form.number,
|
||||||
|
type: this.form.type
|
||||||
|
}, 'id', this.editId)
|
||||||
|
uni.showToast({
|
||||||
|
title: '更新成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 新增模式
|
||||||
await db.addTabItem(tableName, { ...this.form })
|
await db.addTabItem(tableName, { ...this.form })
|
||||||
this.$refs.popup.close()
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '保存成功',
|
title: '保存成功',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
this.$refs.popup.close()
|
||||||
this.getList()
|
this.getList()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '保存失败',
|
title: this.isEdit ? '更新失败' : '保存失败',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -295,4 +366,49 @@ export default {
|
|||||||
.form-btn{
|
.form-btn{
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
|
.action-btns{
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.edit-btn{
|
||||||
|
/* background: #1890ff;
|
||||||
|
border-color: #1890ff; */
|
||||||
|
width: 60px;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 32px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.delete-btn{
|
||||||
|
/* background: #ff4d4f;
|
||||||
|
border-color: #ff4d4f; */
|
||||||
|
width: 60px;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 32px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.edit-btn:hover{
|
||||||
|
/* background: #40a9ff;
|
||||||
|
border-color: #40a9ff; */
|
||||||
|
}
|
||||||
|
.delete-btn:hover{
|
||||||
|
/* background: #ff7875;
|
||||||
|
border-color: #ff7875; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格内容自动换行 */
|
||||||
|
.ant-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
.ant-table th,
|
||||||
|
.ant-table td {
|
||||||
|
padding: 10px 8px;
|
||||||
|
text-align: center;
|
||||||
|
word-wrap: break-word;
|
||||||
|
word-break: break-all;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
max-width: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
+35
-64
@@ -55,7 +55,6 @@ export default {
|
|||||||
RS232: undefined,
|
RS232: undefined,
|
||||||
timer: null, // 定时器读取485接口数据
|
timer: null, // 定时器读取485接口数据
|
||||||
taskTimer: null,
|
taskTimer: null,
|
||||||
leftDoorCycleTimer: null, // 左门循环定时器
|
|
||||||
last485DataTime: null, // 上次收到485数据的时间戳
|
last485DataTime: null, // 上次收到485数据的时间戳
|
||||||
heartbeatTimer: null, // 心跳检测定时器
|
heartbeatTimer: null, // 心跳检测定时器
|
||||||
reconnectCount: 0, // 重连次数计数器
|
reconnectCount: 0, // 重连次数计数器
|
||||||
@@ -119,9 +118,9 @@ export default {
|
|||||||
|
|
||||||
uni.$on('closeDoor', async (data) => {
|
uni.$on('closeDoor', async (data) => {
|
||||||
try {
|
try {
|
||||||
cmd.LeftDoor(false)
|
await cmd.LeftDoor(false)
|
||||||
await delay(100)
|
await delay(200)
|
||||||
cmd.RightDoor(false)
|
await cmd.RightDoor(false)
|
||||||
this.addLog('门', '触摸屏关门')
|
this.addLog('门', '触摸屏关门')
|
||||||
// 触发关门事件
|
// 触发关门事件
|
||||||
this.closeDoorEvent()
|
this.closeDoorEvent()
|
||||||
@@ -163,11 +162,6 @@ export default {
|
|||||||
clearInterval(this.taskTimer)
|
clearInterval(this.taskTimer)
|
||||||
this.taskTimer = null
|
this.taskTimer = null
|
||||||
}
|
}
|
||||||
// 清理左门循环定时器
|
|
||||||
if (this.leftDoorCycleTimer) {
|
|
||||||
clearInterval(this.leftDoorCycleTimer)
|
|
||||||
this.leftDoorCycleTimer = null
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init() {
|
init() {
|
||||||
@@ -519,10 +513,13 @@ export default {
|
|||||||
this.timer = null
|
this.timer = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 重置时间戳
|
// 4. 清空RS485队列中积压的失效指令
|
||||||
|
cmd.clearRS485Queue()
|
||||||
|
|
||||||
|
// 5. 重置时间戳
|
||||||
this.last485DataTime = null
|
this.last485DataTime = null
|
||||||
|
|
||||||
// 5. 重新启动RS485通信
|
// 6. 重新启动RS485通信
|
||||||
this.startRS485()
|
this.startRS485()
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -531,7 +528,23 @@ export default {
|
|||||||
// 失败后延迟重试
|
// 失败后延迟重试
|
||||||
await delay(5000)
|
await delay(5000)
|
||||||
if (this.reconnectCount < this.maxReconnect) {
|
if (this.reconnectCount < this.maxReconnect) {
|
||||||
|
// 还有重连机会,继续重连
|
||||||
this.resetRS485()
|
this.resetRS485()
|
||||||
|
} else {
|
||||||
|
// 重连次数耗尽,自动重启应用(彻底恢复native层状态)
|
||||||
|
this.addLog('485通信', `重连${this.maxReconnect}次均失败,即将自动重启...`)
|
||||||
|
|
||||||
|
uni.showToast({
|
||||||
|
title: '通信异常,3秒后重启',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
plus.runtime.restart()
|
||||||
|
// #endif
|
||||||
|
}, 3000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -592,7 +605,7 @@ export default {
|
|||||||
if (data.action == 'door' && data.status == 'closed') {
|
if (data.action == 'door' && data.status == 'closed') {
|
||||||
try {
|
try {
|
||||||
await cmd.LeftDoor(false)
|
await cmd.LeftDoor(false)
|
||||||
await delay(100)
|
await delay(200)
|
||||||
await cmd.RightDoor(false)
|
await cmd.RightDoor(false)
|
||||||
// 触发关门事件
|
// 触发关门事件
|
||||||
await this.closeDoorEvent()
|
await this.closeDoorEvent()
|
||||||
@@ -678,50 +691,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// handle232HexData(hex) {
|
|
||||||
// // 处理232接口上报的数据
|
|
||||||
// let data = cmd.parse232dData(hex)
|
|
||||||
// if (data == {}) return
|
|
||||||
// if (data.action == 'leave' && data.type == 'internal') {
|
|
||||||
// // 更新内镜数据
|
|
||||||
// let key = data.address - 1
|
|
||||||
// uni.$emit('notice', { title: data.address, content: '内镜取出'})
|
|
||||||
// this.updateScope(key, 'leave', '')
|
|
||||||
// // 添加日志数据
|
|
||||||
// this.addLog('位置'+key, '内镜取出')
|
|
||||||
// }
|
|
||||||
// if (data.action == 'enter' && data.type == 'internal') {
|
|
||||||
// // 验证内镜信息
|
|
||||||
// this.checkEndoCard(data.number).then(res => {
|
|
||||||
// if (res) {
|
|
||||||
// uni.$emit('notice', { title: data.number, content: '内镜存入'})
|
|
||||||
// // 更新内镜数据
|
|
||||||
// let key = data.address - 1
|
|
||||||
// this.updateScope(key, 'enter', data.number)
|
|
||||||
// // 添加日志数据
|
|
||||||
// this.addLog(data.number, '内镜存入')
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// uni.$emit('ic', data.number)
|
|
||||||
// }
|
|
||||||
// if (data.action == 'enter' && data.type == 'person') {
|
|
||||||
// // 验证人员信息
|
|
||||||
// this.checkPersonCard(data.number).then(res => {
|
|
||||||
// if (res) {
|
|
||||||
// // 开门事件
|
|
||||||
// cmd.Door(true)
|
|
||||||
// // this.openDoorEvent()
|
|
||||||
// uni.$emit('notice', { title: data.number, content: '刷卡开门'})
|
|
||||||
// // 添加日志数据
|
|
||||||
// this.addLog(data.number, '刷卡开门')
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// uni.$emit('ic', data.number)
|
|
||||||
// }
|
|
||||||
// if (data.action == 'door') {
|
|
||||||
// cmd.Door(false)
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// 密码框提交
|
// 密码框提交
|
||||||
inputModalSubmit(val) {
|
inputModalSubmit(val) {
|
||||||
let password = this.$store.state.base.screenPw
|
let password = this.$store.state.base.screenPw
|
||||||
@@ -803,20 +773,21 @@ export default {
|
|||||||
// 开门事件
|
// 开门事件
|
||||||
async openDoorEvent() {
|
async openDoorEvent() {
|
||||||
// 关闭真空泵和消毒,打开照明,打开门锁,打开风机
|
// 关闭真空泵和消毒,打开照明,打开门锁,打开风机
|
||||||
cmd.Vacuum(false)
|
|
||||||
await delay(300)
|
|
||||||
cmd.Light(true)
|
cmd.Light(true)
|
||||||
await delay(300)
|
await delay(500)
|
||||||
|
cmd.Vacuum(false)
|
||||||
|
await delay(500)
|
||||||
cmd.Wind(true)
|
cmd.Wind(true)
|
||||||
},
|
},
|
||||||
// 关门事件
|
// 关门事件
|
||||||
async closeDoorEvent() {
|
async closeDoorEvent() {
|
||||||
// 关闭照明,打开真空泵、消毒
|
// 关闭照明,打开真空泵、消毒
|
||||||
cmd.Light(false) // 照明关闭指令
|
await delay(500)
|
||||||
await delay(300)
|
await cmd.Light(false) // 照明关闭指令
|
||||||
cmd.Vacuum(true) //真空泵开启指令
|
await delay(500)
|
||||||
await delay(300)
|
await cmd.Vacuum(true) //真空泵开启指令
|
||||||
cmd.Wind(true)
|
await delay(500)
|
||||||
|
await cmd.Wind(true)
|
||||||
},
|
},
|
||||||
// 验证人员卡是否可以开门
|
// 验证人员卡是否可以开门
|
||||||
async checkPersonCard(ic) {
|
async checkPersonCard(ic) {
|
||||||
|
|||||||
+44
-9
@@ -38,7 +38,7 @@ const enqueueTask = (task) => {
|
|||||||
// 规则1: 去重 - 已存在相同cmd的任务则丢弃
|
// 规则1: 去重 - 已存在相同cmd的任务则丢弃
|
||||||
const isDuplicate = rs485Queue.some(t => t.cmd === task.cmd)
|
const isDuplicate = rs485Queue.some(t => t.cmd === task.cmd)
|
||||||
if (isDuplicate) {
|
if (isDuplicate) {
|
||||||
console.warn('[RS485队列] 丢弃重复任务:', task.cmd)
|
// console.warn('[RS485队列] 丢弃重复任务:', task.cmd)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,16 +54,16 @@ const enqueueTask = (task) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lastLowIndex !== -1) {
|
if (lastLowIndex !== -1) {
|
||||||
console.warn('[RS485队列] 高优挤掉低优:', rs485Queue[lastLowIndex].cmd)
|
// console.warn('[RS485队列] 高优挤掉低优:', rs485Queue[lastLowIndex].cmd)
|
||||||
rs485Queue.splice(lastLowIndex, 1)
|
rs485Queue.splice(lastLowIndex, 1)
|
||||||
} else {
|
} else {
|
||||||
// 没有低优先级可挤,踢掉队首最老的
|
// 没有低优先级可挤,踢掉队首最老的
|
||||||
console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd)
|
// console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd)
|
||||||
rs485Queue.shift()
|
rs485Queue.shift()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 低优先级:直接踢掉队首最老的
|
// 低优先级:直接踢掉队首最老的
|
||||||
console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd)
|
// console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd)
|
||||||
rs485Queue.shift()
|
rs485Queue.shift()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,10 +80,41 @@ const enqueueTask = (task) => {
|
|||||||
rs485Queue.push(task)
|
rs485Queue.push(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[RS485队列] 入队成功, 长度:${rs485Queue.length}, cmd:${task.cmd}`)
|
// console.log(`[RS485队列] 入队成功, 长度:${rs485Queue.length}, cmd:${task.cmd}`)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== RS485 发送超时保护 ==========
|
||||||
|
const RS485_SEND_TIMEOUT = 2000 // 发送超时2秒
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带超时的RS485发送封装
|
||||||
|
* 防止底层串口驱动卡死导致Promise永久pending,造成队列死锁
|
||||||
|
*/
|
||||||
|
const sendWithTimeout = (rs485Instance, cmd) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
console.warn(`[RS485] 发送超时(${RS485_SEND_TIMEOUT}ms), cmd: ${cmd}`)
|
||||||
|
reject(new Error('RS485发送超时'))
|
||||||
|
}, RS485_SEND_TIMEOUT)
|
||||||
|
|
||||||
|
const result = rs485Instance.sendDataString(cmd)
|
||||||
|
if (result && typeof result.then === 'function') {
|
||||||
|
result.then(res => {
|
||||||
|
clearTimeout(timer)
|
||||||
|
resolve(res)
|
||||||
|
}).catch(err => {
|
||||||
|
clearTimeout(timer)
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
clearTimeout(timer)
|
||||||
|
resolve(result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// ========== RS485 发送超时保护 END ==========
|
||||||
|
|
||||||
const processRS485Queue = async () => {
|
const processRS485Queue = async () => {
|
||||||
if (isRS485Sending || rs485Queue.length === 0) {
|
if (isRS485Sending || rs485Queue.length === 0) {
|
||||||
return
|
return
|
||||||
@@ -95,10 +126,8 @@ const processRS485Queue = async () => {
|
|||||||
if (!RS485) {
|
if (!RS485) {
|
||||||
throw new Error('RS485 not initialized')
|
throw new Error('RS485 not initialized')
|
||||||
}
|
}
|
||||||
const result = RS485.sendDataString(task.cmd)
|
// 使用带超时的发送封装,防止Promise永久pending导致队列死锁
|
||||||
if (result && typeof result.then === 'function') {
|
await sendWithTimeout(RS485, task.cmd)
|
||||||
await result
|
|
||||||
}
|
|
||||||
// 发送后延迟,确保总线空闲再发下一条
|
// 发送后延迟,确保总线空闲再发下一条
|
||||||
await new Promise(r => setTimeout(r, RS485_SEND_DELAY))
|
await new Promise(r => setTimeout(r, RS485_SEND_DELAY))
|
||||||
task.resolve()
|
task.resolve()
|
||||||
@@ -132,6 +161,7 @@ const clearRS485Queue = () => {
|
|||||||
const task = rs485Queue.shift()
|
const task = rs485Queue.shift()
|
||||||
task.reject(new Error('RS485队列已清空(重连中)'))
|
task.reject(new Error('RS485队列已清空(重连中)'))
|
||||||
}
|
}
|
||||||
|
isRS485Sending = false // 强制释放发送锁,防止队列死锁
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,6 +253,11 @@ export default {
|
|||||||
clearRS485Queue,
|
clearRS485Queue,
|
||||||
getRS485QueueSize,
|
getRS485QueueSize,
|
||||||
|
|
||||||
|
// 重置RS485队列锁(供外部重连时调用)
|
||||||
|
resetRS485Lock() {
|
||||||
|
clearRS485Queue() // 内部已包含清队列 + 释放锁
|
||||||
|
},
|
||||||
|
|
||||||
// 解析门卡数据,返回卡号
|
// 解析门卡数据,返回卡号
|
||||||
parse232dData: (hexString) => {
|
parse232dData: (hexString) => {
|
||||||
// IC卡 20 01 00 08 04 00 00 00 0e 26 fe ab 8f 03
|
// IC卡 20 01 00 08 04 00 00 00 0e 26 fe ab 8f 03
|
||||||
|
|||||||
Reference in New Issue
Block a user