using Terminal; using DatabaseDLL; using System.Collections.Generic; using System.Threading.Tasks; using PLCS7; using System; using System.Text; using MySql.Data.MySqlClient; using System.Threading; namespace Terminal { public class Terminal : ITerminalDisplay { public static List terminalInfo = new List(); public static Dictionary idLicMap = new Dictionary(); public static bool isClosing = false; public void FeeCal() { } public void GetTerminalState() { } public List GetParkingRecords() { return null; } public List GetOrderRecords() { return null; } private object SearchPaymentScheme() { return null; } private void UpdateParkingRecords(int Object) { } /// /// 从终端结构体中获得车牌号 /// /// /// private string GetLicenseFromTerm(TerminalStru ts) { string header = Encoding.ASCII.GetString(BitConverter.GetBytes(ts.licenseCodeB)); string identityA = Encoding.ASCII.GetString(BitConverter.GetBytes(ts.licenseCodeC)); byte[] bytes = BitConverter.GetBytes(ts.licenseCodeD); List newBytes = new List(); for (int i = 0; i < bytes.Length; i++) { if (bytes[i] != 0x00) { newBytes.Add(bytes[i]); } } string identityB = Encoding.ASCII.GetString(newBytes.ToArray()); return header + identityA + identityB; } /// /// 更新所有车位信息 /// private void UpdateAllParkingSpace() { string findParkingSpace = "select parkingSpaceID from parkingspace;"; MySqlDataReader reader = Monitor.Monitor.localDBOper.Query(findParkingSpace); HashSet recordsIDSet = new HashSet(); if (reader != null) { while (reader.Read()) { if (reader.HasRows) { recordsIDSet.Add(reader.GetInt32("parkingSpaceID")); } } } List updateSpaceList = new List(); List insertSpaceList = new List(); string updateParkingSpace = ""; string insertParkingSpace = ""; for (int i = 0; i < Monitor.Monitor.parkingSpaceInfo.Count; i++) { if (recordsIDSet.Contains(Monitor.Monitor.parkingSpaceInfo[i].parkingSpace)) { updateParkingSpace = "update parkingspace set parkingSpaceX = " + Monitor.Monitor.parkingSpaceInfo[i].coordX + ",parkingSpaceY = " + Monitor.Monitor.parkingSpaceInfo[i].coordY + ",parkingSpaceZ = " + Monitor.Monitor.parkingSpaceInfo[i].floorNo + ",parkingSpaceState = " + Monitor.Monitor.parkingSpaceInfo[i].spaceStatus + " where (parkingSpaceID = " + Monitor.Monitor.parkingSpaceInfo[i].parkingSpace + ");"; updateSpaceList.Add(updateParkingSpace); } else { insertParkingSpace = "insert into parkingspace (parkingSpaceID,parkingSpaceX,parkingSpaceY,parkingSpaceZ,parkingSpaceState) values (" + Monitor.Monitor.parkingSpaceInfo[i].parkingSpace + "," + Monitor.Monitor.parkingSpaceInfo[i].coordX + "," + Monitor.Monitor.parkingSpaceInfo[i].coordY + "," + Monitor.Monitor.parkingSpaceInfo[i].floorNo + "," + Monitor.Monitor.parkingSpaceInfo[i].spaceStatus + ");"; insertSpaceList.Add(insertParkingSpace); } } try { Monitor.Monitor.localDBOper.UpdateTransaction(updateSpaceList); Monitor.Monitor.localDBOper.Insert(insertSpaceList); } catch (Exception e) { Console.WriteLine("更新本地所有车位异常" + e.Message); } } /// /// 更新车辆状态 /// /// /// private void UpdateVehicle(string lic, int state, int parkingRecordsID, bool park, bool remote) { MySqlDataReader reader; //查询车辆是否在车辆表中 string checkVehicleState = "select * from vehicle where numberPlate = '" + lic + "';"; if (!remote) { reader = Monitor.Monitor.localDBOper.Query(checkVehicleState); } else { reader = Monitor.Monitor.remoteDBOper.Query(checkVehicleState); } if (reader != null) { //更新车辆状态 string updateVehicleState = ""; if (park) { updateVehicleState = "update vehicle set vehiclepParkState = " + state + " ,parkingRecordsID = " + parkingRecordsID + " where numberPlate = '" + lic + "';"; } else { updateVehicleState = "update vehicle set vehiclepParkState = " + state + " where numberPlate = '" + lic + "';"; } List list = new List(); list.Add(updateVehicleState); if (!remote) { Monitor.Monitor.localDBOper.UpdateTransaction(list); } else { Monitor.Monitor.localDBOper.UpdateTransaction(list); } } else { //插入车辆 string insertVehicleWithState = ""; if (park) { insertVehicleWithState = "insert into vehicle (numberPlate,vehicleTypeID,vehiclepParkState,parkingRecordsID) values " + "('" + lic + "',NULL,'" + state + "'," + parkingRecordsID + ");"; } else { Console.WriteLine("明显异常,取车发现无车辆"); return; } List list = new List(); list.Add(insertVehicleWithState); if (!remote) { Monitor.Monitor.localDBOper.Insert(list); } else { Monitor.Monitor.remoteDBOper.Insert(list); } } } /// /// 停车流程,收到号牌机启动后操作过程 /// private void ParkNumSubProcess() { int numMachineLaunch = Monitor.Monitor.mainBlockInfo.numMachineLaunch; if (numMachineLaunch != 0) { for (int i = 0; i < terminalInfo.Count; i++) { //启动指令与终端id匹配 if (numMachineLaunch == terminalInfo[i].terminalID) { int numReceivedStatus = 0;//1获得,2终止 TerminalStru term = terminalInfo[i]; if (term.terminalStatus == (short)0) { string license = Monitor.Monitor.numMachineLinker.GetLicensePlate(numMachineLaunch); //未获得号牌,告知PLC终止,告诉终端提示用户重新操作 if (license == "") { MainBlockStru mb = new MainBlockStru { licenseReceived = (short)2 }; Monitor.Monitor.PLC.WriteToPLC(mb, PLCDataType.central); TerminalStru ts = new TerminalStru { paymentStatus = -1, parkingFee = -1, userType = -1, licVerification = (short)2 }; Monitor.Monitor.PLC.WriteToPLC(ts, PLCDataType.central); } else { //记录或更新当前号牌 lock (idLicMap) { if (idLicMap.ContainsKey(numMachineLaunch)) { idLicMap[numMachineLaunch] = license; } else { idLicMap.Add(numMachineLaunch, license); } } //注册 if (term.btnStatus == (short)0) { int userID = term.licenseCodeA; string userLicense = GetLicenseFromTerm(term); TerminalStru ts = new TerminalStru { paymentStatus = -1, parkingFee = -1, userType = -1 }; //与云端数据比对 string checkNetSql = "select * from user where userID=1;"; if (Monitor.Monitor.remoteDBOper.Query(checkNetSql) != null) { string userInfoCheckSql = "select * from usercarrelation where userID = '" + userID + "'and numberPlate = '" + userLicense + "';"; MySqlDataReader reader = Monitor.Monitor.remoteDBOper.Query(userInfoCheckSql); if (reader == null) { ts.licVerification = 2;//验证失败 Monitor.Monitor.PLC.WriteToPLC(ts, PLCDataType.central); numReceivedStatus = 2; } else { ts.licVerification = 1;//验证成功 Monitor.Monitor.PLC.WriteToPLC(ts, PLCDataType.central); numReceivedStatus = 1; } } else { ts.licVerification = 1;//网络异常,跳过验证 Monitor.Monitor.PLC.WriteToPLC(ts, PLCDataType.central); numReceivedStatus = 1; } } //无论是否注册,皆告知PLC,已获取号牌或比对异常、终止流程 MainBlockStru mb = new MainBlockStru { licenseReceived = (short)numReceivedStatus }; Monitor.Monitor.PLC.WriteToPLC(mb, PLCDataType.central); } } } } } } /// /// 停车流程,收到PLC停车完成信号后操作过程 /// private void ParkCompleteSubProcess() { int processAttrib = Monitor.Monitor.mainBlockInfo.parkingRunning; int processCompleted = Monitor.Monitor.mainBlockInfo.processCompleted; int currentTerm = Monitor.Monitor.mainBlockInfo.terminalID; int parkingSpaceID = 0; if (processAttrib == 1 && processCompleted == 1) { TerminalStru term; string license; //找到终端号,判断是否注册用户 for (int i = 0; i < terminalInfo.Count; i++) { //拿到号牌 if (terminalInfo[i].terminalID == currentTerm && idLicMap.TryGetValue(currentTerm, out license) && license != "") { term = terminalInfo[i]; //找到停车位置 for (int s = 0; s < Monitor.Monitor.parkingSpaceInfo.Count; s++) { if (Monitor.Monitor.parkingSpaceInfo[i].receiptNum == term.receiptNum) { parkingSpaceID = Monitor.Monitor.parkingSpaceInfo[i].parkingSpace; break; } } //无车位信息则跳出当前循环 if (parkingSpaceID == 0) break; //插入停车记录 string parkingRecordsSql = ""; if (term.licenseCodeA != 0) { parkingRecordsSql = "INSERT INTO parkingrecords (userID, numberPlate,parkingSpaceID,garageID,parkingRecordsState,realParkTime,receiptNum,parkingPrice)" + "values ('" + term.licenseCodeA + "','" + license + "','" + parkingSpaceID + "','" + Monitor.Monitor.garageID + "',3,'" + DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") + "','" + term.receiptNum + "',NULL);"; } else { parkingRecordsSql = "INSERT INTO parkingrecords (userID, numberPlate,parkingSpaceID,garageID,parkingRecordsState,realParkTime,receiptNum,parkingPrice)" + "values ('" + 1 + "','" + license + "','" + parkingSpaceID + "','" + Monitor.Monitor.garageID + "',3,'" + DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") + "','" + term.receiptNum + "',NULL);"; } List list = new List(); list.Add(parkingRecordsSql); Monitor.Monitor.localDBOper.Insert(list); //查询记录ID号 string findRecordSql = "select parkingRecordsID from parkingrecords where receiptNum = " + term.receiptNum + ";"; MySqlDataReader reader = Monitor.Monitor.localDBOper.Query(findRecordSql); int parkingRecordsID = 0; try { if (reader!=null && reader.Read()) { parkingRecordsID = reader.GetInt32("parkingRecordsID"); } } catch (Exception) { break; }; //更新本地车辆表 UpdateVehicle(license, parkingRecordsID, 1, true, false); //更新本地车位 UpdateAllParkingSpace(); //注册用户加入云端操作 if (term.btnStatus == 0) { //string //Monitor.Monitor.remoteDBOper() } } } } } /// /// 停车相关操作 /// 1.读取到号牌机启动指令,启动号牌机并根据是否注册用户进行操作 /// 非注册拿到号牌后记录并告知plc /// 注册用户,核对号牌与用户关联信息 /// 2.停车流程结束,写数据库 /// private void ParkProcess() { //1.号牌机启动 Task.Factory.StartNew(() => { while (!isClosing) { ParkNumSubProcess(); Thread.Sleep(Monitor.Monitor.plcRefreshInterval); } }); Task.Factory.StartNew(() => { while (!isClosing) { ParkCompleteSubProcess(); Thread.Sleep(Monitor.Monitor.plcRefreshInterval); } }); } private int FeeCalc(PaymentScheme scheme, DateTime parkTime, TimeSpan orderTimeLength) { try { int orderFee = scheme.bookCharge * (int)orderTimeLength.TotalHours; int parkFee = 0; int hours = (int)(DateTime.Now - parkTime).TotalHours; switch (scheme.schemeType) { //按时计费 case 1: if (hours > scheme.firstChargeTime) { parkFee = Math.Min(scheme.firstCharge + scheme.intervalCharge * hours / scheme.chargeInterval, scheme.upperBound); } else { parkFee = scheme.firstCharge; } break; //按次计费 case 2: int overnightCount = hours / 24; parkFee = scheme.eachCharge + overnightCount * scheme.overnightCharge; break; //按时间段计费 case 3: TimeSpan currentTimeOfDay = DateTime.Now.TimeOfDay; TimeSpan parkTimeOfDay = parkTime.TimeOfDay; TimeSpan startTimeOfDay = DateTime.Parse(scheme.startChargeTime).TimeOfDay; TimeSpan endTimeOfDay = DateTime.Parse(scheme.endChargeTime).TimeOfDay; double countingHoursOfDay = endTimeOfDay.TotalHours - startTimeOfDay.TotalHours; int days = (int)((DateTime.Now - parkTime).TotalHours - currentTimeOfDay.TotalHours + parkTimeOfDay.TotalHours); int previousOffset = (int)(-(Math.Max(0, parkTimeOfDay.TotalHours - startTimeOfDay.TotalHours))); int currentOffset = (int)Math.Min((currentTimeOfDay.TotalHours - startTimeOfDay.TotalHours), countingHoursOfDay); parkFee = (days * (int)countingHoursOfDay + previousOffset + currentOffset) * scheme.chargeStandard; break; } return parkFee; } catch (Exception e) { Console.WriteLine("费用计算异常"); return -1; } } /// /// 取车相关操作 /// /// private void FetchProcess() { int fetchState = Monitor.Monitor.mainBlockInfo.fetchingRunning; int receiptNum = 0; TerminalStru ts = new TerminalStru(); for (int i = 0; i < terminalInfo.Count; i++) { if (terminalInfo[i].terminalID == Monitor.Monitor.mainBlockInfo.terminalID) { ts = terminalInfo[i]; receiptNum = ts.receiptNum; break; } } //取车状态且凭证号不为空,查询数据库计费 if (fetchState == 1 && receiptNum != 0) { int userID = 0; string numberPlate = ""; string realParkTime = ""; //1.根据凭证号查询停车记录 string parkRecordsSql = "select userID,numberPlate,realParkTime from parkingrecords where receiptNum = "+ receiptNum + ";"; try { MySqlDataReader reader = Monitor.Monitor.localDBOper.Query(parkRecordsSql); if(reader!=null && reader.Read()) { object[] receiver = new object[3]; reader.GetValues(receiver); userID = (int)receiver[0]; numberPlate = (string)receiver[1]; realParkTime = (string)receiver[2]; } } catch (Exception e) { Console.WriteLine(e.Message); } //2.根据号牌查询预约记录 //3.获取停车时刻并计费发送给PLC,暂时认为皆为普通用户 DateTime parkTime = DateTime.Parse(realParkTime); if (PaymentScheme.ins != null) { int fee = FeeCalc(PaymentScheme.ins, parkTime, new TimeSpan(0)); if (Monitor.Monitor.PLC != null) { TerminalStru FeeMsg = new TerminalStru { paymentStatus = (short)-1, licVerification = (short)-1, parkingFee = (short)fee, userType = (short)1 }; Monitor.Monitor.PLC.WriteToPLC(FeeMsg,PLCDataType.central); } } } } public void Start() { //Task.Factory.StartNew(() => //{ //}); } public void Stop() { isClosing = true; } } public class PaymentScheme { public static PaymentScheme ins; public int paymentSchemeID; /// /// 策略类型。1按时,2按次,3按时间段 /// public int schemeType; /// /// 免费时间 /// public int freeTime; //******************** 按时收费 ******************* /// /// 首段收费时间 /// public int firstChargeTime; /// /// 首段费用 /// public int firstCharge; /// /// 间隔收费时间 /// public int chargeInterval; /// /// 间隔收费单价 /// public int intervalCharge; /// /// 每日停车收费上限 /// public int upperBound; //******************** 按次收费 ******************* /// /// 按次收费,每次费用 /// public int eachCharge; /// /// 按次收费,加收过夜费 /// public int overnightCharge; //******************** 按时间段收费 ******************* /// /// 按时间段收费,起始时间 /// public string startChargeTime; /// /// 按时间段收费,终止时间 /// public string endChargeTime; /// /// 按时间段收费,每小时费用 /// public int chargeStandard; //******************** VIP卡 ******************* /// /// 月卡办理价格 /// public int monthCardCharge; /// /// 季卡办理价格 /// public int seasonCardCharge; /// /// 半年卡办理价格 /// public int halfYearCardCharge; /// /// 年卡办理价格 /// public int yearCardCharge; /// /// 预约小时费用 /// public int bookCharge; public PaymentScheme() { ins = new PaymentScheme(); ins.paymentSchemeID = 0; ins.schemeType = 0; ins.freeTime = 0; ins.firstChargeTime = 0; ins.firstCharge = 0; ins.chargeInterval = 0; ins.upperBound = 0; ins.eachCharge = 0; ins.overnightCharge = 0; ins.startChargeTime = ""; ins.endChargeTime = ""; ins.chargeStandard = 0; ins.monthCardCharge = 0; ins.seasonCardCharge = 0; ins.halfYearCardCharge = 0; ins.yearCardCharge = 0; ins.bookCharge = 0; } public PaymentScheme(int pID, int type, int freeTime, int firstChargeTime, int firstCharge, int chargeInterval, int intervalCharge, int upperBound, int eachCharge, int overnightCharge, string startChargeTime, string endChargeTime, int chargeStandard, int monthCardCharge, int seasonCardCharge, int halfYearCardCharge, int yearCardCharge, int bookCharge) { ins = new PaymentScheme(); ins.paymentSchemeID = pID; ins.schemeType = type; ins.freeTime = freeTime; ins.firstChargeTime = firstChargeTime; ins.firstCharge = firstCharge; ins.chargeInterval = chargeInterval; ins.intervalCharge = intervalCharge; ins.upperBound = upperBound; ins.eachCharge = eachCharge; ins.overnightCharge = overnightCharge; ins.startChargeTime = startChargeTime; ins.endChargeTime = endChargeTime; ins.chargeStandard = chargeStandard; ins.monthCardCharge = monthCardCharge; ins.seasonCardCharge = seasonCardCharge; ins.halfYearCardCharge = halfYearCardCharge; ins.yearCardCharge = yearCardCharge; ins.bookCharge = bookCharge; } public static PaymentScheme GetCurrentPaymentScheme(int index) { string currentPaymentSchemeQuerySql = "select * from paymentScheme where paymentSchemeID = " + index + ";"; object[] paramArray = null; PaymentScheme scheme = null; try { MySqlDataReader reader = Monitor.Monitor.localDBOper.Query(currentPaymentSchemeQuerySql); if (reader != null && reader.Read()) { scheme = new PaymentScheme(); paramArray = new object[reader.FieldCount]; reader.GetValues(paramArray); scheme.paymentSchemeID = index; scheme.schemeType = (int)paramArray[1]; scheme.freeTime = (int)paramArray[2]; scheme.firstChargeTime = (int)paramArray[3]; scheme.firstCharge = (int)paramArray[4]; scheme.chargeInterval = (int)paramArray[5]; scheme.intervalCharge = (int)paramArray[6]; scheme.upperBound = (int)paramArray[7]; scheme.eachCharge = (int)paramArray[8]; scheme.overnightCharge = (int)paramArray[9]; scheme.startChargeTime = (string)paramArray[10]; scheme.endChargeTime = (string)paramArray[11]; scheme.chargeStandard = (int)paramArray[12]; scheme.monthCardCharge = (int)paramArray[13]; scheme.seasonCardCharge = (int)paramArray[14]; scheme.halfYearCardCharge = (int)paramArray[15]; scheme.yearCardCharge = (int)paramArray[16]; scheme.bookCharge = (int)paramArray[17]; } } catch (Exception e) { Console.WriteLine("读取本地计费策略," + e.Message); } return scheme; } } }