小程序服务、启动充电流程

This commit is contained in:
yuyang 2021-08-12 15:54:28 +08:00
parent 892528576b
commit 4377939cb7
23 changed files with 794 additions and 285 deletions

View File

@ -16,6 +16,7 @@
<module>xhpc-user</module>
<module>xhpc-payment</module>
<module>xhpc-order</module>
<module>xhpc-wxma</module>
</modules>
<artifactId>xhpc-modules</artifactId>

View File

@ -69,7 +69,7 @@ public class XhpcChargingPileServiceImpl implements IXhpcChargingPileService {
Long chargingPileId = xhpcChargingPile.getChargingPileId();
if (xhpcChargingPile.getGunNumber() > 0) {
for (int i = 0; i < xhpcChargingPile.getGunNumber(); i++) {
for (int i = 1; i <= xhpcChargingPile.getGunNumber(); i++) {
XhpcTerminal xhpcTerminal = new XhpcTerminal();
xhpcTerminal.setChargingStationId(chargingStationId);
xhpcTerminal.setChargingPileId(chargingPileId);

View File

@ -1,30 +0,0 @@
package com.xhpc.order.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* @author yuyang
* @date 2021/8/9 20:31
*/
@Component
@Lazy(false)
public class ApplicationContextRegister implements ApplicationContextAware {
private static ApplicationContext APPLICATION_CONTEXT;
/**
* 设置spring上下文 * * @param applicationContext spring上下文 * @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
APPLICATION_CONTEXT = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return APPLICATION_CONTEXT;
}
}

View File

@ -73,5 +73,13 @@ public class HxpcChargeOrderController extends BaseController {
return iHxpcChargeOrderService.stopUp(userId, serialNumber,chargingOrderId);
}
/**
* 桩回调接口
* @return
*/
@GetMapping("/pileStatus")
public AjaxResult pileStatus(String orderNo,Integer status,String remark){
iHxpcChargeOrderService.pileStatus(orderNo, status,remark);
return null;
}
}

View File

@ -1,152 +0,0 @@
package com.xhpc.order.controller;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.order.config.ApplicationContextRegister;
import com.xhpc.order.service.IHxpcChargeOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.SpringConfigurator;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/**
* @author yuyang
* @date 2021/8/9 14:33
*/
@Component
@ServerEndpoint(value = "/websocket/{userId}")
public class WebSocketController {
/**
* 静态变量用来记录当前在线连接数应该把它设计成线程安全的
*/
private static int onlineCount = 0;
/**
* concurrent包的线程安全Set用来存放每个客户端对应的MyWebSocket对象若要实现服务端与单一客户端通信的话可以使用Map来存放其中Key可以为用户标识
*/
private static CopyOnWriteArraySet<WebSocketController> webSocketSet = new CopyOnWriteArraySet<WebSocketController>();
/**
* 与某个客户端的连接会话需要通过它来给客户端发送数据
*/
private Session session;
//连接用户id
private Long userId;
/**
* 连接建立成功调用的方法
*
* @param session 可选的参数session为与某个客户端的连接会话需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(@PathParam("userId") Long userId, Session session) {
this.userId = userId;
this.session = session;
System.out.println("userId:" + userId);
System.out.println("session:" + session);
webSocketSet.add(this); //加入set中
addOnlineCount(); //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
try {
this.session.getBasicRemote().sendText("推送消息");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("收到:" + this.userId + "的消息");
System.out.println("来自客户端的消息:" + message);
try {
message = "{\n" +
" \"msg\": \"操作成功\",\n" +
" \"code\": 200,\n" +
" \"data\": {\n" +
" \"amountCharged\": 50.0,\n" +
" \"gunNumber\": \"1\",\n" +
" \"balance\": 10.00,\n" +
" \"chargingOrderId\": 3,\n" +
" \"soc\": \"12\",\n" +
" \"chargingTime\": \"21\",\n" +
" \"realTimeOrderId\": 8,\n" +
" \"electricCurrent\": 1.0,\n" +
" \"power\": null,\n" +
" \"chargingDegree\": 10.25,\n" +
" \"voltage\": 45.0,\n" +
" \"remainingTime\": \"45\"\n" +
" }\n" +
"}";
//终端编号订单信息需要获取
ApplicationContext act = ApplicationContextRegister.getApplicationContext();
RedisService redisService = act.getBean(RedisService.class);
Object cacheObject = redisService.getCacheObject("gun:1472583698524602.seqdec");
System.out.println("cacheObject:" + cacheObject);
this.session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发生错误时调用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketController.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketController.onlineCount--;
}
}

View File

@ -13,6 +13,8 @@ import java.util.Map;
*/
public interface HxpcChargeOrderMapper {
/**
* 实时订单
* @param userId
@ -20,6 +22,8 @@ public interface HxpcChargeOrderMapper {
*/
int getHistotyChargeOrderMessage(@Param("userId") Long userId);
Map<String,Object> getMessage(@Param("userId") Long userId);
/**
* 异常订单
* @param userId
@ -54,12 +58,34 @@ public interface HxpcChargeOrderMapper {
* @param hxpcChargeOrder
* @return
*/
int addXhpcTerminalSerial(HxpcChargeOrder hxpcChargeOrder);
int addXhpcChargeOrder(HxpcChargeOrder hxpcChargeOrder);
/**
* 修改充电订单
* @param hxpcChargeOrder
* @return
*/
int updateXhpcTerminalSerial(HxpcChargeOrder hxpcChargeOrder);
int updateXhpcChargeOrder(HxpcChargeOrder hxpcChargeOrder);
/**
* 获取充电订单数据
* @param serialNumber 订单编号
* @return
*/
HxpcChargeOrder getSerialNumberMessage(@Param("serialNumber") String serialNumber);
/**
* 判断用户是第几次充电
* @param userId
* @return
*/
int getCount(@Param("userId") Long userId);
/**
* 活动
* @return
*/
Map<String,Object> getPromotion();
}

View File

@ -1,6 +1,8 @@
package com.xhpc.order.mapper;
import com.xhpc.order.domain.XhpcChargeOrderCurrent;
import com.xhpc.order.domain.XhpcChargeOrderSoc;
import com.xhpc.order.domain.XhpcChargeOrderVoltage;
import com.xhpc.order.domain.XhpcRealTimeOrder;
import org.apache.ibatis.annotations.Param;
@ -29,6 +31,20 @@ public interface XhpcRealTimeOrderMapper {
*/
int addSOC(XhpcChargeOrderSoc xhpcChargeOrderSoc);
/**
* 添加订单实时电流
* @param XhpcChargeOrderCurrent
* @return
*/
int addCurrent(XhpcChargeOrderCurrent XhpcChargeOrderCurrent);
/**
* 添加订单实时电流
* @param XhpcChargeOrderVoltage
* @return
*/
int addVoltage(XhpcChargeOrderVoltage xhpcChargeOrderVoltage);
/**
* 实时订单接口

View File

@ -40,4 +40,15 @@ public interface IHxpcChargeOrderService {
* @return
*/
AjaxResult stopUp(Long userId,String serialNumber,Long chargingOrderId);
/**
* 桩回调接口
* @param orderNo 订单编号
* @param status 订单状态 (启动状态 1成功 2失败 实时订单状态 3充电中 4 桩充电完成 5 用户停止充电 6桩异常停止充电 )
* @param remark 失败的备注
*/
void pileStatus(String orderNo,Integer status,String remark);
}

View File

@ -1,6 +1,7 @@
package com.xhpc.order.service;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.order.domain.XhpcHistoryOrder;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@ -27,4 +28,12 @@ public interface IXhpcHistoryOrderService {
* @return
*/
AjaxResult gethistotyOrderMessage(Long userId,Long historyOrderId,Integer type,Long chargingOrderId);
/**
* 新增 历史订单信息
*
* @param xhpcHistoryOrder 历史订单信息
* @return 结果
*/
void insert(XhpcHistoryOrder xhpcHistoryOrder);
}

View File

@ -1,6 +1,8 @@
package com.xhpc.order.service.impl;
import cn.hutool.core.date.DateUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.xhpc.common.api.PowerPileService;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.web.domain.AjaxResult;
@ -9,10 +11,14 @@ import com.xhpc.common.data.redis.SeqUtil;
import com.xhpc.common.domain.XhpcTerminal;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.order.domain.HxpcChargeOrder;
import com.xhpc.order.domain.XhpcHistoryOrder;
import com.xhpc.order.mapper.HxpcChargeOrderMapper;
import com.xhpc.order.service.IHxpcChargeOrderService;
import com.xhpc.order.service.IXhpcHistoryOrderService;
import com.xhpc.order.util.ConnectionRabbitMQUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
@ -35,9 +41,14 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
@Autowired
private HxpcChargeOrderMapper hxpcChargeOrderMapper;
@Autowired
private IXhpcHistoryOrderService xhpcHistoryOrderService;
@Autowired
private PowerPileService powerPileService;
@Autowired
private RedisService redisService;
//队列名称
private final static String NAME = "webSocket";
@PostConstruct
public void init(){
REDIS =redisService;
@ -50,6 +61,7 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
return AjaxResult.success();
}
return AjaxResult.error(1201,"无实时数据");
//return AjaxResult.success(hxpcChargeOrderMapper.getMessage(userId));
}
@Override
@ -58,6 +70,7 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
}
@Override
@Transactional
public AjaxResult startUp(Long userId, String serialNumber,Integer type) {
String pattern = "^([0-9]{16})";
Pattern compile = Pattern.compile(pattern);
@ -87,10 +100,21 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
}
//终端状态是否空闲
//是否插枪
// R r = powerPileService.terminalStatus(serialNumber);
// if(r.getCode() !=200){
// return AjaxResult.error(r.getMsg());
// }
Map<String, Object> cacheMap = REDIS.getCacheMap("gun:" + serialNumber);
if(cacheMap==null){
return AjaxResult.error(1105, "未注册的终端,请选择其他终端充电");
}else{
if(cacheMap.get("status") ==null){
return AjaxResult.error(1106, "未知的终端状态,请选择其他终端充电");
}else{
String status = cacheMap.get("status").toString();
//不同的状态
if("离线".equals(status)||"故障".equals(status) ||"充电".equals(status)){
return AjaxResult.error(1107, "此终端"+status+"中,请选择其他终端充电");
}
}
}
//终端信息
XhpcTerminal xhpcTerminal = hxpcChargeOrderMapper.getXhpcTerminalSerialNumber(serialNumber);
if (xhpcTerminal == null || xhpcTerminal.getTerminalId() == null || xhpcTerminal.getChargingPileId() == null || xhpcTerminal.getPileSerialNumber() == null) {
@ -104,12 +128,8 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
Date date = new Date();
String format = DateUtil.format(date, "yyMMddHHmmss");
//自增
String number = "number:" + serialNumber;
String cacheObject = REDIS.getCacheObject(number);
String gunSerialNumber=serialNumber+format;
gunSerialNumber = getString(number, cacheObject, gunSerialNumber);
String orderNo = serialNumber + format + SeqUtil.seqDec("gun:" + serialNumber + ".seqdec");
String orderNo = SeqUtil.seqDec("gun:" + gunSerialNumber + ".seqdec");
startChargingData.setOrderNo(orderNo);
startChargingData.setPileNo(xhpcTerminal.getPileSerialNumber());
startChargingData.setGunId(xhpcTerminal.getSerialNumber());
@ -119,15 +139,14 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
if(r1.getCode() !=200){
return AjaxResult.error(r1.getMsg());
}
//创建充电订单(充电启动soc初始值结束是获取,并修改状态)
HxpcChargeOrder hxpcChargeOrder = new HxpcChargeOrder();
hxpcChargeOrder.setChargingStationId(xhpcTerminal.getChargingStationId());
hxpcChargeOrder.setUserId(userId);
hxpcChargeOrder.setTerminalId(xhpcTerminal.getTerminalId());
hxpcChargeOrder.setSerialNumber(gunSerialNumber);
hxpcChargeOrder.setSerialNumber(orderNo);
hxpcChargeOrder.setSource(0);
hxpcChargeOrder.setStatus(0);
hxpcChargeOrder.setStatus(-1);
hxpcChargeOrder.setRateModelId(xhpcTerminal.getRateModelId());
if(type ==1){
hxpcChargeOrder.setChargingMode("小华充电微信");
@ -135,58 +154,11 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
hxpcChargeOrder.setChargingMode("小华充电支付宝");
}
hxpcChargeOrder.setStartTime(date);
hxpcChargeOrderMapper.addXhpcTerminalSerial(hxpcChargeOrder);
hxpcChargeOrderMapper.addXhpcChargeOrder(hxpcChargeOrder);
return AjaxResult.success();
}
private String getString(String number, String cacheObject, String gunSerialNumber) {
if(cacheObject !=null){
if(cacheObject.length()==4){
if("9999".equals(cacheObject)){
REDIS.setCacheObject(number,1,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +"0001";
}else{
int value = Integer.parseInt(cacheObject)+1;
REDIS.setCacheObject(number,value,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +value;
}
}else if(cacheObject.length()==3){
if("999".equals(cacheObject)){
REDIS.setCacheObject(number,1000,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +"1000";
}else{
int value = Integer.parseInt(cacheObject)+1;
REDIS.setCacheObject(number,value,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +value;
}
}else if(cacheObject.length()==2){
if("99".equals(cacheObject)){
REDIS.setCacheObject(number,100,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +"100";
}else{
int value = Integer.parseInt(cacheObject)+1;
REDIS.setCacheObject(number,value,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +value;
}
}else{
if("9".equals(cacheObject)){
REDIS.setCacheObject(number,10,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +"10";
}else{
int value = Integer.parseInt(cacheObject)+1;
REDIS.setCacheObject(number,value,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +value;
}
}
}else{
REDIS.setCacheObject(number,1,24L, TimeUnit.HOURS);
gunSerialNumber = gunSerialNumber +"0001";
}
return gunSerialNumber;
}
@Override
public AjaxResult stopUp(Long userId, String serialNumber,Long chargingOrderId) {
@ -208,4 +180,116 @@ public class HxpcChargeOrderServiceImpl implements IHxpcChargeOrderService {
return AjaxResult.success();
}
/**
* 桩回调接口
* @param orderNo 订单编号
* @param status 订单状态 (启动状态 1成功 2失败 实时订单状态 3充电中 4 桩充电完成 5 用户停止充电 6桩异常停止充电 )
* @param remark 失败的备注
*/
@Override
public void pileStatus(String orderNo, Integer status,String remark) {
//解析订单编号
String s = orderNo.split("\\.")[0];
String s1 = s.split(":")[1];
if(status ==1){
update(orderNo,0, 0,null, s1,0);
}else if(status ==2){
update(orderNo,-1, 1,remark, s1,0);
}else{
if(status == 3){
//发送实时数据
}
if(status == 4 || status==5){
//发送实时订单结束状态并修改订单状态生成一条历史订单
update(orderNo,1, 0,null, s1,status);
}
if(status ==6){
//订单异常修改订单状态
update(orderNo,2, 0,remark, s1,status);
}
}
//消息对了内容
String message="";
rabbimt(message);
}
private void update(String orderNo,Integer status,Integer delFlag, String remark, String serialNumber,Integer type) {
HxpcChargeOrder hxpcChargeOrder = hxpcChargeOrderMapper.getSerialNumberMessage(serialNumber);
hxpcChargeOrder.setStatus(status);
hxpcChargeOrder.setDelFlag(delFlag);
hxpcChargeOrder.setRemark(remark);
Long userId = hxpcChargeOrder.getUserId();
if(type==4 ||type ==5){
Date date = new Date();
//获取实时订单
REDIS.getCacheObject(orderNo);
//用户第几次充电
int count = hxpcChargeOrderMapper.getCount(userId);
String state ="";
String discount ="";
if(count==0){
//活动折扣
Map<String, Object> promotion = hxpcChargeOrderMapper.getPromotion();
if(promotion !=null){
//state 1.总金额 2.金额 3.服务费 discount 折扣率
state = promotion.get("state").toString();
discount = promotion.get("discount").toString();
}
}
//生成一条历史订单
XhpcHistoryOrder xhpcHistoryOrder =new XhpcHistoryOrder();
xhpcHistoryOrder.setChargeOrderId(hxpcChargeOrder.getChargeOrderId());
xhpcHistoryOrder.setChargingStationId(hxpcChargeOrder.getChargingStationId());
xhpcHistoryOrder.setUserId(userId);
xhpcHistoryOrder.setTerminalId(hxpcChargeOrder.getTerminalId());
xhpcHistoryOrder.setSerialNumber(hxpcChargeOrder.getSerialNumber());
xhpcHistoryOrder.setStartSoc(hxpcChargeOrder.getStartSoc());
xhpcHistoryOrder.setReconciliationStatus(0);
xhpcHistoryOrder.setSortingStatus(0);
xhpcHistoryOrder.setType(1);
xhpcHistoryOrder.setStatus(0);
xhpcHistoryOrder.setDelFlag(0);
xhpcHistoryOrder.setCreateTime(date);
//订单总价---运维服务费抽成
//结束时soc
xhpcHistoryOrderService.insert(xhpcHistoryOrder);
//充电订单 --结束soc充电时长充电度数
hxpcChargeOrder.setEndTime(date);
if(type ==4){
hxpcChargeOrder.setType(0);
}else{
hxpcChargeOrder.setType(2);
}
//实时数据存入MYsqlsoc电流电压
}
hxpcChargeOrderMapper.updateXhpcChargeOrder(hxpcChargeOrder);
}
private void rabbimt(String message) {
//发送消息队列
try{
// 1获取到连接
Connection connection = ConnectionRabbitMQUtil.getConnection();
// 2从连接中创建通道使用通道才能完成消息相关的操作
Channel channel = connection.createChannel();
// 3声明创建队列
channel.queueDeclare(NAME, false, false, false, null);
// 4消息内容
channel.basicPublish("", NAME, null, message.getBytes());
channel.close();
connection.close();
}catch (Exception e){
}
}
}

View File

@ -1,6 +1,7 @@
package com.xhpc.order.service.impl;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.order.domain.XhpcHistoryOrder;
import com.xhpc.order.mapper.XhpcHistoryOrderMapper;
import com.xhpc.order.service.IXhpcHistoryOrderService;
import org.apache.poi.ss.formula.functions.T;
@ -29,4 +30,9 @@ public class XhpcHistoryOrderServiceImpl implements IXhpcHistoryOrderService {
return AjaxResult.success(xhpcHistoryOrderMapper.gethistotyOrderMessage(userId,historyOrderId,type,chargingOrderId));
}
@Override
public void insert(XhpcHistoryOrder xhpcHistoryOrder) {
xhpcHistoryOrderMapper.insert(xhpcHistoryOrder);
}
}

View File

@ -56,27 +56,27 @@
where user_id = #{userId} and status=0 and del_flag =0
</select>
<!-- <select id="getHistotyChargeOrderMessage" resultType="map">-->
<!-- select-->
<!-- rto.real_time_order_id as realTimeOrderId,-->
<!-- rto.charging_order_id as chargingOrderId,-->
<!-- rto.voltage as voltage,-->
<!-- rto.electric_current as electricCurrent,-->
<!-- (select power from xhpc_charging_pile where charging_pile_id=-->
<!-- (select charging_pile_id from xhpc_terminal where serial_number=rto.pile_number and del_flag=0 LIMIT 1))power,-->
<!-- rto.soc as soc,-->
<!-- rto.gun_number as gunNumber,-->
<!-- rto.charging_degree as chargingDegree,-->
<!-- rto.charging_time as chargingTime,-->
<!-- rto.remaining_time as remainingTime,-->
<!-- rto.amount_charged as amountCharged,-->
<!-- au.balance as balance-->
<!-- from xhpc_real_time_order as rto-->
<!-- LEFT JOIN xhpc_app_user as au on au.app_user_id = rto.user_id-->
<!-- where rto.charging_order_id =(select charge_order_id from xhpc_charge_order where status =0 and source = 0 ORDER BY create_time desc LIMIT 1)-->
<!-- and rto.user_id=#{userId}-->
<!-- </select>-->
<select id="getMessage" resultType="map">
select
rto.real_time_order_id as realTimeOrderId,
rto.charging_order_id as chargingOrderId,
rto.voltage as voltage,
rto.gun_number as seriaNumber,
rto.electric_current as electricCurrent,
(select power from xhpc_charging_pile where charging_pile_id=
(select charging_pile_id from xhpc_terminal where serial_number=rto.pile_number and del_flag=0 LIMIT 1))power,
rto.soc as soc,
rto.gun_number as gunNumber,
rto.charging_degree as chargingDegree,
rto.charging_time as chargingTime,
rto.remaining_time as remainingTime,
rto.amount_charged as amountCharged,
au.balance as balance
from xhpc_real_time_order as rto
LEFT JOIN xhpc_app_user as au on au.app_user_id = rto.user_id
where rto.charging_order_id =(select charge_order_id from xhpc_charge_order where status =0 and source = 0 ORDER BY create_time desc LIMIT 1)
and rto.user_id=#{userId}
</select>
<select id="getUserMessage" resultType="map">
select
@ -87,10 +87,7 @@
where del_flag=0
</select>
<select id="countXhpcRealTimeOrder" resultType="int">
select
count(charge_order_id)
from xhpc_charge_order
where user_id =#{userId} and status=0
select count(charge_order_id) from xhpc_charge_order where user_id =#{userId} and status=0 and del_flag =0
</select>
<select id="countXhpcChargeOrder" resultType="int">
@ -98,13 +95,10 @@
</select>
<select id="getXhpcTerminalSerialNumber" resultMap="BaseResultMap">
select
*
from xhpc_terminal
where serial_number=#{serialNumber} and del_flag=0 limit 1
select * from xhpc_terminal where serial_number=#{serialNumber} and del_flag=0 limit 1
</select>
<insert id="addXhpcTerminalSerial" parameterType="com.xhpc.order.domain.HxpcChargeOrder" useGeneratedKeys="true"
<insert id="addXhpcChargeOrder" parameterType="com.xhpc.order.domain.HxpcChargeOrder" useGeneratedKeys="true"
keyProperty="chargeOrderId">
insert into xhpc_charge_order
<trim prefix="(" suffix=")" suffixOverrides=",">
@ -203,11 +197,12 @@
</trim>
</insert>
<update id="updateXhpcTerminalSerial" parameterType="com.xhpc.order.domain.HxpcChargeOrder">
<update id="updateXhpcChargeOrder" parameterType="com.xhpc.order.domain.HxpcChargeOrder">
update xhpc_charge_order
<trim prefix="SET" suffixOverrides=",">
<if test="chargingStationId != null">end_soc = #{chargingStationId},</if>
<if test="endSoc != null">end_soc = #{endSoc},</if>
<if test="status != null">status = #{status},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="endTime != null">end_time = #{endTime},</if>
<if test="chargingTime != null">charging_time = #{chargingTime},</if>
<if test="chargingDegree != null">charging_degree = #{chargingDegree},</if>
@ -236,4 +231,15 @@
order by cor.update_time desc
</select>
<select id="getSerialNumberMessage" resultMap="HxpcChargeOrderResult">
select * from xhpc_charge_order where serial_number=#{serialNumber} limit 1
</select>
<select id="getCount" resultType="int">
select count(charge_order_id) from xhpc_charge_order where user_id=#{userId} and del_flag =1
</select>
<select id="getPromotion" resultType="map">
select discount,state from xhpc_promotion where del_flag=0 and status=0 and type=0 and start_time &lt;= now() and end_time &gt;=now() order by update_time desc
</select>
</mapper>

View File

@ -199,6 +199,64 @@
</trim>
</insert>
<insert id="addSOC" parameterType="com.xhpc.order.domain.XhpcRealTimeOrder" useGeneratedKeys="true"
keyProperty="chargeOrderSocId">
insert into xhpc_charge_order_soc
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="null != chargeOrderId ">
charge_order_id,
</if>
<if test="null != soc ">
soc,
</if>
<if test="null != status ">
status,
</if>
<if test="null != createTime ">
create_time,
</if>
<if test="null != createBy ">
create_by,
</if>
<if test="null != updateTime ">
update_time,
</if>
<if test="null != updateBy ">
update_by,
</if>
<if test="null != remark ">
remark
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="null != chargeOrderId ">
#{chargeOrderId},
</if>
<if test="null != soc ">
#{soc},
</if>
<if test="null != status ">
#{status},
</if>
<if test="null != createTime ">
#{createTime},
</if>
<if test="null != createBy ">
#{createBy},
</if>
<if test="null != updateTime ">
#{updateTime},
</if>
<if test="null != updateBy ">
#{updateBy},
</if>
<if test="null != remark ">
#{remark}
</if>
</trim>
</insert>
<select id="list" resultType="map">
select

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xhpc-modules</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xhpc-wxma</artifactId>
<description>
小程序服务
</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.1</version>
</dependency>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
</dependency>
<!-- RuoYi Common DataScope -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datascope</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>xhpc-common</artifactId>
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>xhpc-order</artifactId>
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,32 @@
package com.xhpc;
import com.xhpc.common.security.annotation.EnableCustomConfig;
import com.xhpc.common.security.annotation.EnableRyFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author yuyang
* @date 2021/8/11 17:08
*/
@EnableCustomConfig
@EnableRyFeignClients
@EnableFeignClients
@SpringBootApplication
public class WxmaApplication {
public static void main(String[] args) {
SpringApplication.run(WxmaApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 小程序启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}

View File

@ -1,20 +1,17 @@
package com.xhpc.order.config;
package com.xhpc.wxma.config;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author yuyang
* @date 2021/8/9 17:13
* @date 2021/8/11 17:12
*/
@Component
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

View File

@ -0,0 +1,22 @@
package com.xhpc.wxma.controller;
import com.xhpc.wxma.socket.OrderNotificationWebSocket;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author yuyang
* @date 2021/8/11 17:47
*/
@RestController
@RequestMapping("/orderWebSocket")
public class OrderNotificationWebSocketController {
@GetMapping("/test")
public void test(@RequestParam String userId){
OrderNotificationWebSocket.sendMessage(userId,"有新订单啦");
}
}

View File

@ -0,0 +1,37 @@
package com.xhpc.wxma.domain;
import javax.websocket.Session;
/**
* @author yuyang
* @date 2021/8/11 17:44
*/
public class WebSocketClient {
// 与某个客户端的连接会话需要通过它来给客户端发送数据
private Session session;
//连接的uri
private String uri;
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
}

View File

@ -0,0 +1,52 @@
package com.xhpc.wxma.rabbitm;
import com.rabbitmq.client.*;
import com.xhpc.order.util.ConnectionRabbitMQUtil;
import com.xhpc.wxma.socket.OrderNotificationWebSocket;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* @author yuyang
* @date 2021/8/11 20:58
*/
@Component
public class RabbitmConsumer implements ApplicationRunner {
//队列名称
private final static String NAME="webSocket";
@Override
public void run(ApplicationArguments args) throws Exception {
try {
// 获取到连接
Connection connection = ConnectionRabbitMQUtil.getConnection();
// 2从连接中创建通道使用通道才能完成消息相关的操作
Channel channel = connection.createChannel();
// 3声明创建队列
channel.queueDeclare(NAME, false, false, false, null);
//实现消费方法
DefaultConsumer consumer = new DefaultConsumer(channel){
// 获取消息并且处理这个方法类似事件监听如果有消息的时候会被自动调用
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String exchange = envelope.getExchange();
//消息idmq在channel中用来标识消息的id可用于确认消息已接收
//long deliveryTag = envelope.getDeliveryTag();
// body 即消息体
String msg = new String(body,"utf-8");
String[] split = msg.split("##");
OrderNotificationWebSocket.sendMessage(split[0],split[1]);
}
};
channel.basicConsume(NAME, true, consumer);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,85 @@
package com.xhpc.wxma.socket;
import com.xhpc.wxma.domain.WebSocketClient;
import org.springframework.stereotype.Component;
import java.util.List;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author yuyang
* @date 2021/8/11 17:15
*/
@Component
@ServerEndpoint(value = "/websocket/{userId}")
public class OrderNotificationWebSocket {
static final ConcurrentHashMap<String, List<WebSocketClient>> webSocketClientMap= new ConcurrentHashMap<>();
/**
* 连接建立成功时触发绑定参数
* @param session 与某个客户端的连接会话需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId){
WebSocketClient client = new WebSocketClient();
client.setSession(session);
client.setUri(session.getRequestURI().toString());
List<WebSocketClient> webSocketClientList = webSocketClientMap.get(userId);
if(webSocketClientList == null){
webSocketClientList = new ArrayList<>();
}
webSocketClientList.add(client);
webSocketClientMap.put(userId, webSocketClientList);
}
/**
* 连接关闭时触发注意不能向客户端发送消息了
* @param userId
*/
@OnClose
public void onClose(@PathParam("userId") String userId){
webSocketClientMap.remove(userId);
}
/**
* 通信发生错误时触发
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
/**
* 向客户端发送消息
* @param userId
* @param message
*/
public static void sendMessage(String userId,String message){
try {
List<WebSocketClient> webSocketClientList = webSocketClientMap.get(userId);
if(webSocketClientList!=null){
for(WebSocketClient webSocketServer:webSocketClientList){
webSocketServer.getSession().getBasicRemote().sendText(message);
}
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}

View File

@ -0,0 +1,9 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
,--. ,--.
,--. ,--. | ,---. ,---. ,---. ,---. ,--.--. ,-| | ,---. ,--.--.
\ `' / | .-. | | .-. | | .--' | .-. | | .--' ' .-. | | .-. : | .--'
/ /. \ | | | | | '-' ' \ `--. ' '-' ' | | \ `-' | \ --. | |
'--' '--' `--' `--' | |-' `---' `---' `--' `---' `----' `--'
`--'

View File

@ -0,0 +1,27 @@
# Tomcat
server:
port: 9811
# Spring
spring:
application:
# 应用名称
name: xhpc-wxma
profiles:
# 环境配置
active: dev
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/xhpc-wxma"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.xhpc" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</configuration>