|
@@ -77,26 +77,35 @@
|
|
|
/>
|
|
/>
|
|
|
</a-card>
|
|
</a-card>
|
|
|
|
|
|
|
|
- <a-card title="读卡号" style="margin-top: 16px">
|
|
|
|
|
- <a-form layout="vertical">
|
|
|
|
|
- <a-form-item label="选择天线 (1-24)">
|
|
|
|
|
- <a-space>
|
|
|
|
|
- <a-input-number v-model:value="cardAntenna" :min="1" :max="24" style="width: 120px" />
|
|
|
|
|
- <a-button type="primary" @click="readCardNumber" :loading="readingCard" :disabled="!canControl">
|
|
|
|
|
- 读取卡号
|
|
|
|
|
- </a-button>
|
|
|
|
|
- </a-space>
|
|
|
|
|
- </a-form-item>
|
|
|
|
|
- </a-form>
|
|
|
|
|
|
|
+ <a-card title="读卡号(V4 批量 24 路)" style="margin-top: 16px">
|
|
|
|
|
+ <a-button type="primary" @click="readAllCards" :loading="readingCard" :disabled="!canControl">
|
|
|
|
|
+ 读取全部卡号
|
|
|
|
|
+ </a-button>
|
|
|
|
|
|
|
|
- <div v-if="cardResult" class="card-result">
|
|
|
|
|
- <a-descriptions bordered size="small" :column="1">
|
|
|
|
|
- <a-descriptions-item label="天线位置">{{ cardResult.antenna }}</a-descriptions-item>
|
|
|
|
|
- <a-descriptions-item label="卡号">{{ formatUid(cardResult.card_number_str) }}</a-descriptions-item>
|
|
|
|
|
- <a-descriptions-item label="原始数据">{{ cardResult.raw_data }}</a-descriptions-item>
|
|
|
|
|
- </a-descriptions>
|
|
|
|
|
- </div>
|
|
|
|
|
- <a-empty v-else-if="!readingCard" description="点击「读取卡号」查看结果" />
|
|
|
|
|
|
|
+ <a-table
|
|
|
|
|
+ v-if="cardList.length > 0"
|
|
|
|
|
+ :data-source="cardList"
|
|
|
|
|
+ :columns="cardColumns"
|
|
|
|
|
+ :pagination="false"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ row-key="antenna"
|
|
|
|
|
+ style="margin-top: 12px"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #bodyCell="{ column, record }">
|
|
|
|
|
+ <template v-if="column.key === 'antenna'">
|
|
|
|
|
+ P{{ record.antenna }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else-if="column.key === 'present'">
|
|
|
|
|
+ <a-tag :color="record.present ? 'green' : 'default'">
|
|
|
|
|
+ {{ record.present ? '有卡' : '无卡' }}
|
|
|
|
|
+ </a-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else-if="column.key === 'card_str'">
|
|
|
|
|
+ <span class="card-uid">{{ record.present ? formatUid(record.card_str) : '-' }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </a-table>
|
|
|
|
|
+ <a-empty v-else-if="!readingCard" description="点击「读取全部卡号」查看 24 路卡号" style="margin-top: 16px" />
|
|
|
</a-card>
|
|
</a-card>
|
|
|
</a-col>
|
|
</a-col>
|
|
|
|
|
|
|
@@ -115,7 +124,7 @@
|
|
|
:key="n"
|
|
:key="n"
|
|
|
class="led-cell"
|
|
class="led-cell"
|
|
|
:class="{ active: selectedLed === n || selectedLed === 0 }"
|
|
:class="{ active: selectedLed === n || selectedLed === 0 }"
|
|
|
- @click="selectedLed = n; cardAntenna = n"
|
|
|
|
|
|
|
+ @click="selectedLed = n"
|
|
|
>
|
|
>
|
|
|
<div
|
|
<div
|
|
|
class="led-dot"
|
|
class="led-dot"
|
|
@@ -167,9 +176,13 @@ const feedbackMsg = ref('')
|
|
|
const feedbackType = ref('success')
|
|
const feedbackType = ref('success')
|
|
|
// LED 状态按设备地址组织: { deviceAddress: { portId: color } }
|
|
// LED 状态按设备地址组织: { deviceAddress: { portId: color } }
|
|
|
const ledStates = ref({})
|
|
const ledStates = ref({})
|
|
|
-const cardAntenna = ref(1)
|
|
|
|
|
const readingCard = ref(false)
|
|
const readingCard = ref(false)
|
|
|
-const cardResult = ref(null)
|
|
|
|
|
|
|
+const cardList = ref([])
|
|
|
|
|
+const cardColumns = [
|
|
|
|
|
+ { title: '端口', key: 'antenna', dataIndex: 'antenna', width: 70 },
|
|
|
|
|
+ { title: '状态', key: 'present', dataIndex: 'present', width: 90 },
|
|
|
|
|
+ { title: '卡号', key: 'card_str', dataIndex: 'card_str' }
|
|
|
|
|
+]
|
|
|
let pollTimer = null
|
|
let pollTimer = null
|
|
|
|
|
|
|
|
const ledColors = { 0: '#d9d9d9', 1: '#ff4d4f', 2: '#52c41a', 3: '#1890ff' }
|
|
const ledColors = { 0: '#d9d9d9', 1: '#ff4d4f', 2: '#52c41a', 3: '#1890ff' }
|
|
@@ -259,16 +272,24 @@ async function loadTerminals() {
|
|
|
} catch (e) { console.error(e) }
|
|
} catch (e) { console.error(e) }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-async function readCardNumber() {
|
|
|
|
|
|
|
+async function readAllCards() {
|
|
|
readingCard.value = true
|
|
readingCard.value = true
|
|
|
- cardResult.value = null
|
|
|
|
|
|
|
+ cardList.value = []
|
|
|
try {
|
|
try {
|
|
|
- const res = await apiService.modbus.readAntenna({
|
|
|
|
|
- device_address: selectedDevice.value,
|
|
|
|
|
- antenna: cardAntenna.value
|
|
|
|
|
|
|
+ const res = await apiService.modbus.readAllCards({
|
|
|
|
|
+ device_address: selectedDevice.value
|
|
|
})
|
|
})
|
|
|
- if (res.data.success && res.data.data) {
|
|
|
|
|
- cardResult.value = res.data.data
|
|
|
|
|
|
|
+ if (res.data.success && res.data.data && res.data.data.cards) {
|
|
|
|
|
+ cardList.value = res.data.data.cards.map(c => ({
|
|
|
|
|
+ key: c.antenna,
|
|
|
|
|
+ antenna: c.antenna,
|
|
|
|
|
+ present: !!c.present,
|
|
|
|
|
+ card_str: c.card_str || '',
|
|
|
|
|
+ uid: c.uid || ''
|
|
|
|
|
+ }))
|
|
|
|
|
+ const has = cardList.value.filter(c => c.present).length
|
|
|
|
|
+ feedbackMsg.value = `读取成功,24 路中 ${has} 路有卡`
|
|
|
|
|
+ feedbackType.value = 'success'
|
|
|
} else {
|
|
} else {
|
|
|
feedbackMsg.value = '读卡失败: ' + (res.data.message || '未知错误')
|
|
feedbackMsg.value = '读卡失败: ' + (res.data.message || '未知错误')
|
|
|
feedbackType.value = 'error'
|
|
feedbackType.value = 'error'
|
|
@@ -278,7 +299,7 @@ async function readCardNumber() {
|
|
|
feedbackType.value = 'error'
|
|
feedbackType.value = 'error'
|
|
|
} finally {
|
|
} finally {
|
|
|
readingCard.value = false
|
|
readingCard.value = false
|
|
|
- setTimeout(() => { if (!cardResult.value) feedbackMsg.value = '' }, 3000)
|
|
|
|
|
|
|
+ setTimeout(() => { feedbackMsg.value = '' }, 3000)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -374,4 +395,10 @@ onUnmounted(() => {
|
|
|
border-radius: 50%;
|
|
border-radius: 50%;
|
|
|
border: 1px solid rgba(0,0,0,0.1);
|
|
border: 1px solid rgba(0,0,0,0.1);
|
|
|
}
|
|
}
|
|
|
|
|
+.card-uid {
|
|
|
|
|
+ font-family: 'Monaco', 'Menlo', monospace;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ word-break: break-all;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|