Преглед изворни кода

Merge remote-tracking branch 'origin/master'

2545307760@qq.com пре 3 месеци
родитељ
комит
65a47e8665

+ 2 - 2
server/api/v1/vehicle/shortlist.go

@@ -45,7 +45,7 @@ func (sa *ShortlistApi) CreateShortlist(c *gin.Context) {
 	var shortlist dao.Shortlist
 	err := c.ShouldBindJSON(&shortlist)
 	if err != nil {
-		response.FailWithMessage("参数错误", c)
+		response.FailWithMessage("参数错误"+err.Error(), c)
 		return
 	}
 	err = shortlistService.CreateShortlist(shortlist)
@@ -60,7 +60,7 @@ func (sa *ShortlistApi) UpdateShortlist(c *gin.Context) {
 	var shortlist dao.Shortlist
 	err := c.ShouldBindJSON(&shortlist)
 	if err != nil {
-		response.FailWithMessage("参数错误", c)
+		response.FailWithMessage("参数错误"+err.Error(), c)
 		return
 	}
 	err = shortlistService.UpdateShortlist(shortlist)

+ 2 - 1
server/config.yaml

@@ -125,7 +125,8 @@ mysql:
     config: charset=utf8mb4&parseTime=True&loc=Local
     db-name: lc_garage
     username: root
-    password: 123456
+    password: root
+
     path: 127.0.0.1
     engine: ""
     log-mode: error

+ 1 - 1
server/dao/vehicle.go

@@ -8,7 +8,7 @@ import (
 type Vehicle struct {
 	global.GVA_MODEL
 	PlateNumber   string       `gorm:"size:20;not null;uniqueIndex" json:"plate_number"` // 车牌号
-	RFIDTag       string       `gorm:"size:20;" json:"rfid_tag"`                         // 电子标签
+	RFIDTag       string       `gorm:"size:40;" json:"rfid_tag"`                         // 电子标签
 	VehicleTypeID uint         `gorm:"not null" json:"vehicle_type_id"`                  // 车辆类型ID
 	VehicleType   *VehicleType `gorm:"foreignKey:VehicleTypeID" json:"vehicle_type"`     // 车辆类型关联
 	VehicleBrand  string       `gorm:"size:50" json:"vehicle_brand"`                     // 车辆品牌

+ 1 - 1
server/dao/vehicle_record.go

@@ -8,7 +8,7 @@ import (
 type VehicleRecord struct {
 	global.GVA_MODEL
 	PlateNumber    string     `gorm:"size:20;" json:"plate_number"`                   // 车牌号
-	RFIDTag        string     `gorm:"size:20;column:rfid_tag" json:"rfid_tag"`        // 标签
+	RFIDTag        string     `gorm:"size:40;column:rfid_tag" json:"rfid_tag"`        // 标签
 	EntryTime      time.Time  `json:"entry_time" gorm:"default:null"`                 // 入场时间
 	ExitTime       *time.Time `json:"exit_time" gorm:"default:null"`                  // 出场时间
 	StayTime       int64      `json:"stay_time"`                                      // 停留时间(分钟)

+ 26 - 34
server/service/uhf/reader.go

@@ -212,7 +212,9 @@ func parseReportData(deviceCode string, buf []byte) (*ReportData, error) {
 
 	rssi := int(buf[6])
 	antenna := int(buf[22])
-	epc := hex.EncodeToString(buf[11:21])
+	epc := hex.EncodeToString(buf[11:23])
+
+	fmt.Printf(hex.EncodeToString(buf))
 
 	return &ReportData{
 		DeviceCode: deviceCode,
@@ -239,20 +241,22 @@ func handleReportData(report *ReportData) {
 	}
 
 	epc := report.Epcs[0]
-
 	fmt.Println("<UNK>", epc)
 	now := time.Now().Unix()
 
+	// ===================== 【修复】锁只包防抖,绝不包业务!=====================
 	epcMutex.Lock()
-	defer epcMutex.Unlock()
-
-	// ===================== 修复:3秒防抖 =====================
+	// 3秒防抖
 	if lastTime, ok := epcLastTime[epc]; ok && now-lastTime < debounceSecond {
+		epcMutex.Unlock()
 		return
 	}
+	epcLastTime[epc] = now
+	epcMutex.Unlock()
+	// ===================== 锁已释放,后面逻辑不会阻塞 =====================
 
 	// 获取设备处理器
-	handler, exists := DeviceManager.Get(report.DeviceCode)
+	_, exists := DeviceManager.Get(report.DeviceCode)
 	if !exists {
 		return
 	}
@@ -276,7 +280,6 @@ func handleReportData(report *ReportData) {
 	if err != nil || vehicle.ID == 0 {
 		isTempVehicle = true
 	} else {
-		// ===================== 修复:防止空指针panic =====================
 		if vehicle.VehicleType != nil {
 			isTempVehicle = (vehicle.VehicleTypeID == 1)
 		} else {
@@ -290,7 +293,6 @@ func handleReportData(report *ReportData) {
 	// ===================== 3. 黑名单优先判断 =====================
 	if isBlack {
 		fmt.Printf("🚫 禁止通行 | 车辆在黑名单中 | 设备:%s EPC:%s\n", report.DeviceCode, epc)
-		epcLastTime[epc] = now
 		return
 	}
 
@@ -298,62 +300,52 @@ func handleReportData(report *ReportData) {
 	if isTempVehicle {
 		if !allowTemporary && !isWhite {
 			fmt.Printf("🚫 禁止通行 | 临时车不允许此通道且不在白名单 | 设备:%s EPC:%s\n", report.DeviceCode, epc)
-			epcLastTime[epc] = now
 			return
 		}
 		if !isWhite {
 			fmt.Printf("🚫 禁止通行 | 临时车不在白名单 | 设备:%s EPC:%s\n", report.DeviceCode, epc)
-			epcLastTime[epc] = now
 			return
 		}
 	}
 
 	// ===================== 5. 入口 =====================
 	if direction == "in" {
-		// 关键:只要状态是 false 就允许进入
-		if !epcStatus[epc] {
-			fmt.Printf("🟢 入口开闸 | 设备:%s EPC:%s 临时车:%v 白名单:%v\n", report.DeviceCode, epc, isTempVehicle, isWhite)
-			handler.reader.CloseRelay1(2)
+		epcMutex.Lock()
+		canIn := !epcStatus[epc]
+		epcMutex.Unlock()
+
+		if canIn {
+			fmt.Printf("🟢 入口开闸 | 设备:%s EPC:%s\n", report.DeviceCode, epc)
+			//handler.reader.CloseRelay1(2)
 
-			// 记录入场
 			var vehicleEntry request.VehicleEntry
 			vehicleEntry.RFIDTag = epc
 			vehicleEntry.ParkingLotID = channel.ParkingLotID
 			_, err := vehicleService.VehicleEntry(vehicleEntry)
 
-			if err != nil {
-				fmt.Printf("❌ 入场记录失败:%v | EPC:%s\n", err, epc)
-				// 关键:不设置 epcStatus[epc] = true
-				// 让下一次刷卡可以继续进入
-			} else {
-				// ✅ 只有成功才修改状态
+			if err == nil {
+				epcMutex.Lock()
 				epcStatus[epc] = true
+				epcMutex.Unlock()
 			}
-		} else {
-			fmt.Printf("⚠️  已在场内,禁止重复入场 | EPC:%s\n", epc)
 		}
 	}
 
 	// ===================== 6. 出口 =====================
 	if direction == "out" {
-		fmt.Printf("🔴 出口开闸 | 设备:%s EPC:%s 临时车:%v 白名单:%v\n", report.DeviceCode, epc, isTempVehicle, isWhite)
-		handler.reader.CloseRelay1(2)
+		fmt.Printf("🔴 出口开闸 | 设备:%s EPC:%s\n", report.DeviceCode, epc)
+		//handler.reader.CloseRelay1(2)
 
-		// 记录出场
 		var vehicleExit request.VehicleExit
 		vehicleExit.RFIDTag = epc
 		_, err := vehicleService.VehicleExit(vehicleExit)
-		if err != nil {
-			fmt.Printf("❌ 出场记录失败:%v | EPC:%s\n", err, epc)
-			// 关键:不设置 epcStatus[epc] = false
-		} else {
-			// ✅ 只有成功才重置状态
+
+		if err == nil {
+			epcMutex.Lock()
 			epcStatus[epc] = false
+			epcMutex.Unlock()
 		}
 	}
-
-	// 更新最后读卡时间
-	epcLastTime[epc] = now
 }
 
 // ===================== 手动重置离场 =====================

+ 2 - 3
web/src/view/parking/roster.vue

@@ -174,7 +174,6 @@
             type="datetime"
             placeholder="不选则永久有效"
             style="width:100%"
-            value-format="YYYY-MM-DD HH:mm:ss"
           />
         </el-form-item>
       </el-form>
@@ -218,7 +217,7 @@ const form = reactive({
   ID: 0,
   list_type: '白名单',
   vehicle_id: '',
-  expiration_time: ''
+  expiration_time: null
 })
 
 // 时间格式化
@@ -258,7 +257,7 @@ const add = () => {
   form.ID = 0
   form.list_type = '白名单'
   form.vehicle_id = ''
-  form.expiration_time = ''
+  form.expiration_time = null
   dialogVisible.value = true
 }