t
后台地址
http://zzsh.bhsc.cc:5500
通信地址
http://zzsh.bhsc.cc:5600
微信公众号
http://zzsh.bhsc.cc/default.html?type=scan&deviceno=JUDT062207071514
http://zzsh.bhsc.cc/swagger/index.html
后台地址
http://42.194.142.223:5500
扫码租借
http://42.194.142.223/default.html?type=scan&deviceno=WSTD088888888888&testflg=1
一 web管理后台
1、登录管理后台
2、首页
3. 设备管理
3.1 设备 & 卡口 & 电池自动注册
3.2 设备日志
4、电池管理
5、代理管理
6、店铺管理(可批量绑定设备)
7、系统用户管理
二、通信后台
三 扫码租借
预先充值
店铺信息
我的订单 (使用中 & 已完成)
我的流水
四 运维管理
添加店铺
绑定设备
设备维护
五 充电宝模拟程序
模拟注册
模拟租借
模拟归还
设备通信协议
使用redis+mysql方式,当设备定时上传注册,心跳,机柜信息时,采用redis查缓存数据,有变化再更新mysql数据,以增强并发能力
using PBCommon;
using PBCommon.db.model;
using PBCommon.redis;
using PBService.Utility;
using PBService.Utilty.db;
using System;
namespace PBService.Utilty
{
///
/// 业务处理类
///
public class Business
{
///
/// 添加设备日志
///
public static void InsertDeviceLog(string deviceno, int logtype, string logcontent)
{
FreeSqlHelper.InsertDeviceLog(new DeviceLog() { LogTime = DateTime.Now, DeviceNo = deviceno, LogType = logtype, LogContent = logcontent });
}
///
/// 添加电池日志
///
public static void InsertBatteryLog(string deviceno, int slotid, string batteryno, string orderno, int logtype, string logcontent)
{
FreeSqlHelper.InsertDeviceLog(new DeviceLog() { LogTime = DateTime.Now, DeviceNo = deviceno, SlotId = slotid, BatteryNo = batteryno, OrderNo = orderno, LogType = logtype, LogContent = logcontent });
}
///
/// 设备注册
///
public static void Reg(string deviceno, int devicetype, string serverip, int port, int slotcount)
{
// query -> redis&&mysql
var key_device = RedisKey.ExistDevice(deviceno);
var device = RedisHelper.Get(key_device);
if (null == device)
{
device = FreeSqlHelper.GetDevice(deviceno);
if (null == device)
{
device = new Device() { DeviceNo = deviceno, DeviceType = devicetype, OnTime = DateTime.Now, OffTime = null, ShopId = 0, BorrowUrl = Program.Domain + deviceno, ServerIp = serverip, ServerPort = port };
FreeSqlHelper.InsertDevice(device);
}
RedisHelper.Set(key_device, device);// 添加redis默认数据
}
// datachange update -> redis&&mysql
if (device.OnLine != BaseEnum.Statue_ON || device.ServerIp != serverip || device.ServerPort != port || device.SlotCount != slotcount)
{
device.OnLine = BaseEnum.Statue_ON;
device.ServerIp = serverip;
device.ServerPort = port;
device.SlotCount = slotcount;
RedisHelper.Set(key_device, device);
FreeSqlHelper.UpdateDeviceOnLine(deviceno, serverip, port, slotcount);
InsertDeviceLog(deviceno, BaseEnum.DeviceLog_ON, "设备上线");
}
}
///
/// 设备注销
///
public static void UnReg(string deviceno)
{
var key_device = RedisKey.ExistDevice(deviceno);
var device = RedisHelper.Get(key_device);
if (null != device)
{
device.OnLine = BaseEnum.Statue_OFF;
RedisHelper.Set(key_device, device);
}
FreeSqlHelper.UpdateDeviceOFFLine(deviceno);
InsertDeviceLog(deviceno, BaseEnum.DeviceLog_OFF, "设备离线");
}
///
/// 更新固件版本信息
///
public static void Version(string deviceno, string ver)
{
var key_device = RedisKey.ExistDevice(deviceno);
var device = RedisHelper.Get(key_device); if (null == device) return;
// datachange update -> redis&&mysql
if (device.Version != ver)
{
device.Version = ver;
RedisHelper.Set(key_device, device);
FreeSqlHelper.UpdateDeviceVersion(deviceno, ver);
InsertDeviceLog(deviceno, BaseEnum.DeviceLog_Control, $"变更固件版本:{ver}");
}
}
///
/// 更新设备充电宝公开数量
///
public static void SlotPublishCount(string deviceno, int canborrow, int[] arrSlotId)
{
var key_device = RedisKey.ExistDevice(deviceno);
var device = RedisHelper.Get(key_device); if (null == device) return;
//if (device.CanBorrow != canborrow) // redis数据有变更时才更新mysql数据
//{
device.CanBorrow = canborrow; if (device.SlotCount == 0) device.SlotCount = device.CanBorrow;
device.CanReturn = device.SlotCount - device.CanBorrow; if (device.CanReturn < 0) device.CanReturn = 0;
RedisHelper.Set(key_device, device);
FreeSqlHelper.UpdateDeviceSlotPublishCount(deviceno, device.SlotCount, device.CanBorrow, device.CanReturn);
if (arrSlotId.Length > 0)
{
// 卡口内没有电池的数据置空
var items = FreeSqlHelper.GetSlotWithoutBattery(deviceno, arrSlotId);
foreach (var item in items)
{
item.BatteryNo = string.Empty;
RedisHelper.Set(RedisKey.ExistSlot(deviceno, item.SlotId), item);
}
FreeSqlHelper.ClearSlotWithoutBattery(deviceno, arrSlotId);
}
//InsertDeviceLog(deviceno, BaseEnum.DeviceLog_Control, $"变更设备充电宝数量:{count}");
//}
}
///
/// 更新机柜信息
///
public static void Info(string deviceno, int slotid, string batteryno, int level)
{
if (string.IsNullOrEmpty(deviceno)) return;
// query -> redis&&mysql
var key_slot = RedisKey.ExistSlot(deviceno, slotid);
var slot = RedisHelper.Get(key_slot);
if (null == slot)
{
slot = FreeSqlHelper.GetSlot(deviceno, slotid);
if (null == slot)
{
slot = new Slot() { DeviceNo = deviceno, SlotId = slotid, BatteryNo = batteryno, LockStatus = BaseEnum.Statue_OFF };
FreeSqlHelper.InsertSlot(slot);
}
RedisHelper.Set(key_slot, slot);// 添加redis默认数据
}
// datachange update -> redis&&mysql
if (slot.DeviceNo != deviceno || slot.SlotId != slotid || slot.BatteryNo != batteryno)
{
slot.DeviceNo = deviceno; slot.SlotId = slotid; slot.BatteryNo = batteryno;
RedisHelper.Set(key_slot, slot);
FreeSqlHelper.UpdateSlot(deviceno, slotid, batteryno);
}
// query -> redis&&mysql
var key_battery = RedisKey.ExistBattery(batteryno);
var battery = RedisHelper.Get(key_battery);
if (null == battery)
{
battery = FreeSqlHelper.GetBattery(batteryno);
if (null == battery)
{
battery = new Battery() { BatteryNo = batteryno, Level = level, UseStatus = BaseEnum.UseStatus_Free };
FreeSqlHelper.InsertBattery(battery);
}
RedisHelper.Set(key_battery, battery);// 添加redis默认数据
}
// datachange update -> redis&&mysql
if (battery.Level != level)
{
battery.Level = level;
RedisHelper.Set(key_battery, battery);
FreeSqlHelper.UpdateBatteryLevel(batteryno, level);
}
// 在仓标识空闲
if (battery.UseStatus != BaseEnum.UseStatus_Free)
{
battery.UseStatus = BaseEnum.UseStatus_Free;
RedisHelper.Set(key_battery, battery);
FreeSqlHelper.UpdateBatteryFreeStatus(batteryno);
}
// 离线归还,结算计费
var key_order = RedisKey.GetBorrowBattery(batteryno);
var order = RedisHelper.Get(key_order);
if (null != order)
{
if (FreeSqlHelper.IsOffReturnOrder(batteryno))
{
ReturnResult(deviceno, slotid, batteryno, "离线归还");
}
}
}
///
/// 更新出的设备信息
///
public static void HandleOut(bool result, string deviceno, int slotid, string batteryno, string orderno, int logtype, string logcontent)
{
if (result)
{
UpdateDeviceSlotInfo(deviceno, -1);// 数量-1
UpdateSlotBattery(deviceno, slotid, string.Empty);
UpdateBatteryStatus(batteryno, BaseEnum.UseStatus_Use);
}
InsertBatteryLog(deviceno, slotid, batteryno, orderno, logtype, logcontent);
}
///
/// 更新入的设备信息
///
public static void HandleIn(string deviceno, int slotid, string batteryno, string orderno, int logtype, string logcontent)
{
UpdateDeviceSlotInfo(deviceno, 1);// 数量+1
UpdateSlotBattery(deviceno, slotid, batteryno);
UpdateBatteryStatus(batteryno, BaseEnum.UseStatus_Free);
InsertBatteryLog(deviceno, slotid, batteryno, orderno, logtype, logcontent);
}
///
/// 更新设备可借数量(mysql+resid)
///
public static void UpdateDeviceSlotInfo(string deviceno, int num)
{
var key_device = RedisKey.ExistDevice(deviceno);
var device = RedisHelper.Get(key_device); if (null == device) { device = FreeSqlHelper.GetDevice(deviceno); RedisHelper.Set(key_device, device); }
device.CanBorrow = device.CanBorrow + num;
device.CanReturn = device.SlotCount - device.CanBorrow; if (device.CanReturn < 0) device.CanReturn = 0;
RedisHelper.Set(key_device, device);
FreeSqlHelper.UpdateDeviceSlotPublishCount(deviceno, device.SlotCount, device.CanBorrow, device.CanReturn);
}
///
/// 更新卡口电池(mysql+resid)
///
public static void UpdateSlotBattery(string deviceno, int slotid, string batteryno)
{
var key_slot = RedisKey.ExistSlot(deviceno, slotid);
var slot = RedisHelper.Get(key_slot); if (null == slot) { slot = FreeSqlHelper.GetSlot(deviceno, slotid); RedisHelper.Set(key_slot, slot); }
slot.DeviceNo = deviceno;
slot.SlotId = slotid;
slot.BatteryNo = batteryno;
RedisHelper.Set(key_slot, slot);
FreeSqlHelper.UpdateSlotBattery(deviceno, slotid, batteryno);
}
///
/// 更新电池状态(mysql+resid)
///
public static void UpdateBatteryStatus(string batteryno, int usestatus)
{
var key_battery = RedisKey.ExistBattery(batteryno);
var battery = RedisHelper.Get(key_battery); if (null == battery) { battery = FreeSqlHelper.GetBattery(batteryno); RedisHelper.Set(key_battery, battery); }
battery.BatteryNo = batteryno;
battery.UseStatus = usestatus;
RedisHelper.Set(key_battery, battery);
FreeSqlHelper.UpdateBatteryStatus(batteryno, usestatus);
}
///
/// 强制弹出结果
///
public static void PopUpResult(string deviceno, int slotid, string batteryno, bool result)
{
HandleOut(result, deviceno, slotid, batteryno, "", BaseEnum.DeviceLog_Force, result ? "强制弹出成功" : "强制弹出失败");
}
///
/// 借充电宝结果
///
public static void BorrowResult(string deviceno, int slotid, string batteryno, bool result)
{
var time = DataHelper.GetNowTimeEntity(); string orderno = string.Empty;
if (result)
{
var key_device = RedisKey.GetBorrowDevice(deviceno, slotid, batteryno);
var order = RedisHelper.Get(key_device);
if (null == order)
{
order = FreeSqlHelper.GetBorrowOrder(deviceno, slotid, batteryno, BaseEnum.OrderStatus_BorrowStart);
}
orderno = order.OrderNo;
order.BorrowTime = time.Time;
order.BorrowTimeStamp = time.TimeStamp;
order.OrderStatus = BaseEnum.OrderStatus_BorrowSuccess;
RedisHelper.Set(RedisKey.GetBorrowBattery(order.BatteryNo), order);
}
// 更新数据库租借信息
FreeSqlHelper.UpdateOrderBorrowStatus(deviceno, slotid, batteryno, time.Time, time.TimeStamp, (result ? BaseEnum.OrderStatus_BorrowSuccess : BaseEnum.OrderStatus_BorrowFail));
HandleOut(result, deviceno, slotid, batteryno, orderno, BaseEnum.DeviceLog_Brrow, result ? "租借成功" : "租借失败");
}
///
/// 归还电宝结果
///
public static void ReturnResult(string deviceno, int slotid, string batteryno, string note)
{
bool exist_order = true;
var time = DataHelper.GetNowTimeEntity();
// 根据batteryno查询订单信息(redis && mysql)
var key_order = RedisKey.GetBorrowBattery(batteryno);
var order = RedisHelper.Get(key_order);
if (null == order)
{
order = FreeSqlHelper.GetBorrowOrder("", -1, batteryno, BaseEnum.OrderStatus_BorrowSuccess);
if (null == order)
{
exist_order = false;
}
}
HandleIn(deviceno, slotid, batteryno, (exist_order ? order.OrderNo : string.Empty), BaseEnum.DeviceLog_Return, (exist_order ? $"{note}成功" : $"{note}失败,未找到租借订单"));
if (!exist_order) return;// 不存在订单则跳出
// 根据deviceno查询店铺信息(redis && mysql)
var key_shop = RedisKey.ExistShop(deviceno);
var shop = RedisHelper.Get(key_shop);
if (null == shop)
{
shop = FreeSqlHelper.GetShop(deviceno); if (null != shop) RedisHelper.Set(key_shop, shop);
}
// 计算费用
decimal moneyTotal = 0; string timeTotal = string.Empty;
PayMoney.GetMoney(time.TimeStamp, order.BorrowTimeStamp, shop, ref moneyTotal, ref timeTotal);
// 费用入账
var dtNow = DateTime.Now;
var timestamp = DataHelper.GetTimestamp(dtNow);
var player = FreeSqlHelper.GetPlayer(order.OpenId);
var openid = player.OpenId;
// 添加交易日志
// 用户扣款 + 更新账户余额
if (0 != moneyTotal)
{
int excute_result = FreeSqlHelper.freeSql.Ado.ExecuteNonQuery($"update player set Money=Money-{moneyTotal} where OpenId='{openid}'");
if (0 == excute_result)
{
Logger.Info($"用户扣款失败,orderno={order.OrderNo},openid={openid},moneyTotal={moneyTotal},excute_result={excute_result}");
}
else
{
Logger.Info($"用户扣款成功,orderno={order.OrderNo},openid={openid},moneyTotal={moneyTotal},excute_result={excute_result}");
FreeSqlHelper.InstertFundLog(new FundLog() { TradeNo = "", Account = openid, LogTimeStamp = timestamp, LogTime = dtNow, FundMoney = moneyTotal, FundType = BaseEnum.FundLog_Customer_Remove });
if (null == shop)
{
// 钱直接进平台
excute_result = FreeSqlHelper.freeSql.Ado.ExecuteNonQuery($"update player set Money=Money+{moneyTotal} where Account='{BaseEnum.PlatformAccount}'");
if (0 == excute_result)
{
Logger.Info($"平台收益失败,orderno={order.OrderNo},Account={BaseEnum.PlatformAccount},moneyTotal={moneyTotal},excute_result={excute_result},分成比例=10");
}
else
{
Logger.Info($"平台收益成功,orderno={order.OrderNo},Account={BaseEnum.PlatformAccount},moneyTotal={moneyTotal},excute_result={excute_result},分成比例=10");
FreeSqlHelper.InstertFundLog(new FundLog() { TradeNo = "", Account = BaseEnum.PlatformAccount, LogTimeStamp = timestamp, LogTime = dtNow, FundMoney = moneyTotal, FundType = BaseEnum.FundLog_Platform_Add });
}
}
else
{
// 跟商户分
var moneyTotal1 = Math.Round(moneyTotal * Convert.ToDecimal(shop.Ratio / 10.0), 2);
excute_result = FreeSqlHelper.freeSql.Ado.ExecuteNonQuery($"update player set Money=Money+{moneyTotal1} where Account='{shop.Account}'");
if (0 == excute_result)
{
Logger.Info($"商户收益失败,orderno={order.OrderNo},Account={shop.Account},moneyTotal={moneyTotal1},excute_result={excute_result}");
}
else
{
Logger.Info($"商户收益成功,orderno={order.OrderNo},Account={shop.Account},moneyTotal={moneyTotal1},excute_result={excute_result},分成比例={shop.Ratio}");
FreeSqlHelper.InstertFundLog(new FundLog() { TradeNo = "", Account = shop.Account, LogTimeStamp = timestamp, LogTime = dtNow, FundMoney = moneyTotal1, FundType = BaseEnum.FundLog_Shop_Add });
}
var moneyTotal2 = Convert.ToDecimal(moneyTotal) - moneyTotal1;
excute_result = FreeSqlHelper.freeSql.Ado.ExecuteNonQuery($"update player set Money=Money+{moneyTotal2} where Account='{BaseEnum.PlatformAccount}'");
if (0 == excute_result)
{
Logger.Info($"平台收益失败,orderno={order.OrderNo},Account={BaseEnum.PlatformAccount},moneyTotal={moneyTotal2},excute_result={excute_result},分成比例={ 10 - shop.Ratio }");
}
else
{
Logger.Info($"平台收益成功,orderno={order.OrderNo},Account={BaseEnum.PlatformAccount},moneyTotal={moneyTotal2},excute_result={excute_result},分成比例={ 10 - shop.Ratio }");
FreeSqlHelper.InstertFundLog(new FundLog() { TradeNo = "", Account = BaseEnum.PlatformAccount, LogTimeStamp = timestamp, LogTime = dtNow, FundMoney = moneyTotal2, FundType = BaseEnum.FundLog_Platform_Add });
}
}
}
}
// 清除redis中的订单数据
RedisHelper.Remove(RedisKey.GetBorrowBattery(batteryno));
// 更新数据库归还信息
long shopid = 0; string shopname = ""; if (null != shop) { shopid = shop.Id; shopname = shop.ShopName; }
FreeSqlHelper.UpdateOrderReturn(batteryno, deviceno, slotid, shopid, shopname, time.Time, time.TimeStamp, moneyTotal, moneyTotal, timeTotal);
}
///
/// 是否能租借
///
public static string IsCanBorrow(string deviceno, string openid)
{
var key_shop = RedisKey.ExistShop(deviceno);
var shop = RedisHelper.Get(key_shop);
if (null == shop)
{
shop = FreeSqlHelper.GetShop(deviceno); if (null != shop) RedisHelper.Set(key_shop, shop);
}
if (null == shop) return "";// 店铺未绑定设备,可免费使用
if (null != shop && BaseEnum.Statue_OFF == shop.IsPremium) return "";// 店铺设置免费
// 收费需要用户注册
var player = FreeSqlHelper.GetPlayer(openid);
if (null == player) return "未找到用户信息";
if (player.Money < shop.Pledge) return "用户余额不足";
return "";
}
}
}