微信小程序实现lot开发08 项目主体业务前后端实现

主体业务:订座位,下单,时间过期之后自动回收座位,控制座位灯与插座,控制门禁。

微信小程序页面图片:

 实现逻辑主体在springboot后端代码:

直接挂代码:有不理解和需要帮助的评论区留言,我会及时回复。

实体层:

import lombok.Data;

@Data
public class Device {
    private String Id;
    private boolean State;
    private boolean Lock;
    private String Info;
    /*输出口号*/
    private int outSign;
    /*设备配置端口号*/
    private int hostPort;
    /*设备电源状态*/
    private boolean power;
    /*区号*/
    private char areaCode;
}

@Data
public class DeviceUsePrice {

    private String deviceId;
    private Integer receipt;
    private Integer deviceTime;
    private String  info;
}

@Data
public class Door {
    private int Id;
    private int outSign;
    private int serverPort;
}

@Data
public class FromInfo {
    private String info;
    private Date date;
}

@Data
public class User {
    private String Id;
    private String Name;
    private Integer Amount;
    private String Phone;
    private String password;
}

@Data
public class UserDevice {
    private String userId;
    private Integer useTime;
    private String deviceId;
    private Integer receipt;
    private String orderTime;
    private boolean orderState;
}

 mapper层

import com.hlc.entity.Device;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

@Mapper
public interface DeviceMapper {

    @Select("select * from getmsqlconnection.device where areaCode=#{areaCode}")
    List<Device> findDeviceByArea(@Param("areaCode") char areaCode);

    @Update("update getmsqlconnection.device set `State` = 0 , `Lock` = 1 where `Id`=#{Id}")
    boolean updateDeviceStateByDeviceId(@Param("Id") String Id);

    @Update("update getmsqlconnection.device set `State` = 1 , `Lock` = 0 where `Id`=#{Id}")
    boolean freeDeviceByDeviceId(@Param("Id") String Id);

    @Select("select `Lock` from getmsqlconnection.device where `Id`=#{Id}")
    boolean findDeviceLockByDeviceId(@Param("Id")String Id);

    @Select("select outSign from getmsqlconnection.device where Id=#{Id}")
    int findOutSignByDeviceId(@Param("Id")String Id);

    @Select("select hostPort from getmsqlconnection.device where Id=#{Id}")
    int findHostPortByDeviceId(@Param("Id")String Id);

    @Update("update getmsqlconnection.device set power = 1 where Id=#{Id}")
    boolean openDevicePowerByDeviceId(@Param("Id")String Id);

    @Update("update getmsqlconnection.device set power = 0 where Id=#{Id}")
    boolean downDevicePowerByDeviceId(@Param("Id")String Id);

    @Select("select power from getmsqlconnection.device where Id=#{Id}")
    boolean findDevicePowerByDeviceId(@Param("Id")String Id);
}


@Mapper
public interface DeviceUsePriceMapper {
    
    @Select("select * from getmsqlconnection.device_use_price where deviceId=#{deviceId}")
    List<DeviceUsePrice> findDeviceUsePriceByDeviceId(@Param("deviceId")String deviceId);

}

@Mapper
public interface DoorMapper {
    @Select("select * from getmsqlconnection.door where Id=1 ")
    Door findDoor();
}


@Mapper
public interface FromInfoMapper {

    @Select("select date,info from getmsqlconnection.from_info")
    List<FromInfo> findAllFromInfo();

}

@Mapper
public interface UserDeviceMapper {

    @Insert("insert into getmsqlconnection.user_device values (#{userDevice.userId},#{userDevice.useTime},#{userDevice.deviceId},#{userDevice.receipt},#{userDevice.orderTime},#{userDevice.orderState})")
    boolean InsertUserDevice(@Param("userDevice")UserDevice userDevice);

    @Select("select * from getmsqlconnection.user_device where userId=#{userId}")
    List<UserDevice> findUserDeviceByUserId(@Param("userId")String userId);

    @Update("update getmsqlconnection.user_device set useTime = 0 where useTime!=0 and deviceId=#{deviceId}")
    boolean updateExOrder(@Param("deviceId")String deviceId);
//  用户使用时间在缓存过期时会被设置为0;所以当前不为0的使用时间就是用户可以使用设备的凭证
    @Select("select deviceId from getmsqlconnection.user_device where useTime != 0 and userId=#{userId}")
    String findDeviceIdByUserId(@Param("userId")String userId);
}

@Mapper
public interface UserMapper {

    //    登录
    @Select("select password from getmsqlconnection.user where Id=#{Id}")
    String login(@Param("Id") String Id,@Param("password") String password);
    //    注册
    @Insert("insert into getmsqlconnection.user values(#{user.Id},#{user.Name},#{user.Phone},#{user.Amount},#{user.password})")
    Boolean register(@Param("user") User user);
    //    修改密码
    @Update("update getmsqlconnection.user set password=#{password} where Id=#{Id}")
    Boolean updatePassword(@Param("Id") String Id,@Param("password") String password);
}

 Servcie层(无非是mapper层的注入语接口的重塑,便于解耦与业务的拓展)

controller层(嵌套工具组件)

deviceController

package com.hlc.controller;/*
    User: 黄林春
    Date: 2022/7/13
    Time: 周三
    Project_Name: springDemo712
    */

import com.hlc.common.R;
import com.hlc.entity.Device;
import com.hlc.service.DeviceService;
import com.hlc.service.UserDeviceService;
import com.hlc.utils.NetAndIoController;
import com.hlc.utils.NetFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import java.util.List;

@RestController(value = "DeviceController")
public class DeviceController {

    @Autowired
    private DeviceService deviceService;

    /**
     * --------------------------------------------查询全部设备信息------------------------------------------------------/
     */

    @GetMapping("/findDeviceByArea")
    @ResponseBody
    public R<Object> findDeviceByArea(@RequestParam("areaCode") char areaCode) {
        List<Device> deviceList = deviceService.findDeviceByArea(areaCode);
        R<Object> r = new R<>();
        r.setCode(1);
        r.setData(deviceList);
        r.setMsg("查询全部设备信息成功!");
        return r;
    }

    /***
     * ---------------------------------查询设备锁状态(锁为false就是可读不可写)-------------------------------------------/
     */

    @GetMapping("/findDeviceLockByDeviceId")
    @ResponseBody
    public R<Boolean> findDeviceLockByDeviceId(@RequestParam("deviceId") String deviceId) {
        try {
            /*异常只有可能在这里发生*/
            boolean lock = deviceService.findDeviceLockByDeviceId(deviceId);
            if (lock) {
                return R.error("设备已被使用,现在不可下单");
            }
            return R.success(true);
        } catch (Exception e) {
            return R.error("设备锁无法查询");
        }
    }

    /**
     * --------------------------------------------电源控制-------------------------------------------------------------/
     */

    @Autowired
    private NetFactory netFactory;
    @Autowired
    private UserDeviceService userDeviceService;

    @GetMapping("/updateDevicePower")
    @ResponseBody
    public R<Boolean> updateDevicePower(@RequestParam("deviceId") String deviceId, @RequestParam("userId") String userId) {
        R<Boolean> r = new R<>();
        /**查询当前用户是否具备未过期订单*/
        String V = userDeviceService.findDeviceIdByUserId(userId);
        try {
            if (V != null) {
                NetAndIoController netAndIoController = netFactory.getNetAndIoController();
                /**将当前设备对应的输出口号赋值给out口标识*/
                netAndIoController.outSign = deviceService.findOutSignByDeviceId(deviceId);
                /**将分配的主机端口赋值给port标识*/
                netAndIoController.serverPort = deviceService.findHostPortByDeviceId(deviceId);
                /**查询当前设备的电源通断标识power*/
                boolean power = deviceService.findDevicePowerByDeviceId(deviceId);
                if (power) {
                    netAndIoController.TcpConnection();
                    /**如果电源状态为通电true,则执行关闭电源的指令方法*/
                    netAndIoController.sendDownControllerMsg();
                    deviceService.downDevicePowerByDeviceId(deviceId);
                } else {
                    netAndIoController.TcpConnection();
                    /**如果电源状态为false,则执行开电源的指令方法*/
                    netAndIoController.sendOpenControllerMsg();
                    deviceService.openDevicePowerByDeviceId(deviceId);
                }
//            因为开关座位电源的频率比开门禁的概率高
//            netAndIoController.shutClient();
                return R.success(true);
            }
            return R.error("当前用户订单过期");
        } catch (Exception e) {
            return R.error("TCP连接失败");
        }
    }

}

DeviceUsePriceController

package com.hlc.controller;/*
    User: 黄林春
    Date: 2022/7/14
    Time: 周四
    Project_Name: springDemo712
    */

import com.hlc.common.R;
import com.hlc.entity.DeviceUsePrice;
import com.hlc.service.DeviceUsePriceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController(value = "DeviceUsePriceController")
public class DeviceUsePriceController {
    @Autowired
    private DeviceUsePriceService deviceUsePriceService;

    /**
     * 查询某一号设备的设备价格表
     * @param deviceId
     * @return
     */
    @RequestMapping("/findDeviceUsePriceByDeviceId")
    @ResponseBody
    public R<Object> findDeviceUsePriceByDeviceId(@RequestParam("deviceId")String deviceId){
        R<Object> r = new R<>();
        try{
            List<DeviceUsePrice> priceList = deviceUsePriceService.findDeviceUsePriceByDeviceId(deviceId);
            r.setData(priceList);
            r.setCode(1);
            r.setMsg("价格表查询成功");
            return r;
        }catch (Exception e){
            r.setCode(0);
            r.setMsg("价格表查询错误");
            return r;
        }
    }
}

 DoorController

package com.hlc.controller;/*
    User: 黄林春
    Date: 2022/7/21
    Time: 周四
    Project_Name: springDemo712
    */

import com.hlc.common.R;
import com.hlc.entity.Door;
import com.hlc.service.DoorService;
import com.hlc.service.UserDeviceService;
import com.hlc.utils.NetAndIoController;
import com.hlc.utils.NetFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DoorController {

    @Autowired
    private DoorService doorService;
    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private NetFactory netFactory;

    @GetMapping("/doorController")
    @ResponseBody
    public R<Boolean> doorController(@RequestParam("userId")String userId){
        R<Boolean> r = new R<>();
        try {
            System.out.println("----------查询该用户是否可以使用门禁------");
            String deviceId = userDeviceService.findDeviceIdByUserId(userId);
            System.out.println("---------拥有订单"+deviceId+"可以使用门禁--------");
            if (deviceId != null){
                NetAndIoController netAndIoController = netFactory.getNetAndIoController();
                System.out.println("---------门禁控制类实现成功-----------");
                Door door = doorService.findDoor();
                netAndIoController.outSign = door.getOutSign();
                netAndIoController.serverPort = door.getServerPort();
                System.out.println("----------开始尝试连接门禁TCP----------------");
                netAndIoController.TcpConnection();
                netAndIoController.sendDelayOpenControllerMsg();
                System.out.println("-------------开门成功-----------------");
                netAndIoController.shutClient();
                r.setMsg("开门成功");
                r.setCode(1);
                return r;
            }
            return R.error("开门失败");
        }catch (Exception e){
            System.out.println("----------------开门异常---------------");
            return R.error("开门失败");
        }
    }

}

 FromInfoController

package com.hlc.controller;/*
    User: 黄林春
    Date: 2022/7/15
    Time: 周五
    Project_Name: springDemo712
    */

import com.hlc.common.R;
import com.hlc.entity.FromInfo;
import com.hlc.service.FromInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class FromInfoController {

    @Autowired
    private FromInfoService fromInfoService;

    /***
     * 查询全部公告
     * @return
     */
    @GetMapping("/findAllFromInfo")
    @ResponseBody
    public R<Object> findAllFromInfo() {
        R<Object> r = new R<>();
        try {
            List<FromInfo> fromInfoList = fromInfoService.findAllFromInfo();
            r.setData(fromInfoList);
            r.setCode(1);
            r.setMsg("查询公告成功");
            return r;
        } catch (Exception e) {
            return R.error("查询公告失败");
        }
    }
}

usercontroller

package com.hlc.controller;/*
    User: 黄林春
    Date: 2022/7/12
    Time: 周二
    Project_Name: springDemo712
    */

import com.hlc.common.R;
import com.hlc.entity.User;
import com.hlc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import java.sql.SQLException;


@RestController(value = "UserController")
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 登录
     * @param Id
     * @param password
     * @return
     */
    @RequestMapping("/login")
    public R<Boolean> userLogin(@RequestParam("Id")String Id, @RequestParam("password")String password){
//        System.out.println("-------------"+Id+"||"+password+"--------------------");
        if (Id == null || password == null){
            return R.error("输入完整的账号密码!");
        }
        try {
            String userLogin = userService.userLogin(Id, password);
//            System.out.println("-------------"+userLogin+"----------");
            if (!userLogin.equals(password)){
                throw new SQLException("账号密码错误!");
            }
            return R.success(true);
        }catch (Exception e){
            return R.error("登录失败!");
        }
    }

    /**
     * 注册
     * @param Id
     * @param Name
     * @param Phone
     * @param password
     * @return
     */
    @RequestMapping("/register")
    @ResponseBody
    public R<Boolean> UserRegister(@RequestParam("Id") String Id,@RequestParam("Name")String Name,@RequestParam("Phone")String Phone,@RequestParam("password")String password){
        System.out.println("-----------微信小程序访问------------");
        if (Id == null || password == null)
            return R.error("请填写完整的用户信息!");
        String password1 = null;
        try {
            password1 = userService.userLogin(Id,password);
        }catch (Exception e){
            System.out.println("该账户没有注册过!");
            throw e;
        }
        try{
            if (password1 != null)
                throw new Exception("该账户名已经被使用!");
            User user = new User();
            user.setId(Id);
            user.setName(Name);
            user.setAmount(0);
            user.setPhone(Phone);
            user.setPassword(password);
            boolean userRegister = userService.UserRegister(user);
            if (!userRegister){
                throw new Exception("注册失败!");
            }
            return R.success(true);
        }catch (Exception e){
            return R.error("注册失败!");
        }
    }
}

UserDeviceController

package com.hlc.controller;/*
    User: 黄林春
    Date: 2022/7/14
    Time: 周四
    Project_Name: springDemo712
    */

import com.hlc.common.R;
import com.hlc.entity.UserDevice;
import com.hlc.service.DeviceService;
import com.hlc.service.UserDeviceService;
import com.hlc.utils.JedisUtil;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController(value = "UserDeviceController")
public class UserDeviceController {

    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private JedisUtil jedisUtil;

    /**
     * 用户支付后回调
     * 修改设备信息以及在订单记录中插入一条记录
     *
     * @param receipt
     * @param deviceId
     * @param userId
     * @param useTime
     * @return
     */
    @RequestMapping("/insertUserDevice")
    @ResponseBody
    /**设置事务回滚(一般用于多表操作,单表使用异常捕获就可以实现)*/
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> InsertUserDevice(@Param("receipt") Integer receipt, @Param("deviceId") String deviceId,
                                       @Param("userId") String userId, @Param("useTime") Integer useTime, @Param("orderTime") String orderTime) {
        try {
            System.out.println("-------------生成订单对象---------------");
            UserDevice userDevice = new UserDevice();
            userDevice.setDeviceId(deviceId);
            userDevice.setUserId(userId);
            userDevice.setUseTime(useTime);

            /**
             * 此时应该在插入这条用户使用记录的地方设置redis缓存键值对,
             * key是用户id+设备id,value是时间。
             * */
            System.out.println("--------------插入缓存------------------");
            jedisUtil.InsertOrderServerListener(deviceId,userId,useTime);
            System.out.println("--------缓存成功,继续装箱--------");
            userDevice.setReceipt(receipt);
            userDevice.setOrderTime(orderTime);
            userDevice.setOrderState(true);
            System.out.println("-----------装箱完毕,校验成功后缓存记录------------");
            boolean insertUserDevice = userDeviceService.InsertUserDevice(userDevice);
            boolean updateDeviceState = deviceService.updateDeviceStateByDeviceId(deviceId);
            if (!insertUserDevice || !updateDeviceState) {
                throw new Exception("插入订单记录失败");
            }
            return R.success(true);
        } catch (Exception e) {
            /**回滚支持*/
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("添加新的订单失败");
        }
    }

    /***
     * 查询某一用户的全部使用记录
     * 用户可查看自己的消费记录
     * @param userId
     * @return
     */
    @RequestMapping("/findUserDeviceByUserId")
    @ResponseBody
    public R<Object> findUserDeviceByUserId(@RequestParam("userId") String userId) {
        R<Object> r = new R<>();
        try{
            List<UserDevice> userDeviceList = userDeviceService.findUserDeviceByUserId(userId);
            r.setData(userDeviceList);
            r.setCode(1);
            r.setMsg("查询消费记录成功");
            return r;
        }catch (Exception e){
            return R.error("查询失败");
        }
    }

    /**
     * 校验用户订单是否过期
     * @param userId
     * @return deviceId
     */
    @GetMapping("/findUserTime")
    @ResponseBody
    public R<String> findUserTime(@RequestParam("userId")String userId){
        R<String> r = new R<>();
        try{
            String deviceId= userDeviceService.findDeviceIdByUserId(userId);
            System.out.println("--------查询用户是否具备使用权-----------");
            r.setData(deviceId);
            r.setMsg("查询成功");
            r.setCode(1);
            return r;
        }catch (Exception e){
            return  R.error("该用户没有可用订单");
        }
    }
}

通用响应对象

package com.hlc.common;

/*
    User: 黄林春
    Date: 2022/7/12
    Time: 周二
    Project_Name: springDemo712
    */

import lombok.Data;


import java.util.HashMap;
import java.util.Map;

/**组件返回通用类,设定返回码与消息与返回结果的封装*/
@Data
public class R<T> {

//响应码
    private Integer code;
//响应消息
    private String msg;
    private T data;
    private Map map = new HashMap();

    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }

    public static <T> R<T> error(String msg) {
        R<T> r = new R<T>();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }

}

redis控制组件(缓存实现的目的主要是过期监听,普通活动限期的实现,也可以自加缓存登录减少数据库压力)

单例jedispool的创建

package com.hlc.utils;/*
    User: 黄林春
    Date: 2022/7/19
    Time: 周二
    Project_Name: springDemo712
    */

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Component
public class JedisFactory {

    private static JedisPool jedisPool = null;

    public static JedisPool getJedisPool() {

        if (jedisPool == null) {
            synchronized (JedisFactory.class) {
                if (jedisPool == null) {
                    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                    jedisPoolConfig.setMaxIdle(150);
                    jedisPoolConfig.setMaxTotal(200);
                    jedisPoolConfig.setTestOnBorrow(false);
                    jedisPoolConfig.setBlockWhenExhausted(true);

                    jedisPool = new JedisPool(jedisPoolConfig, "192.168.100.150", 6379);
                }
            }
        }
        return jedisPool;
    }

    public void release(Jedis jedis, JedisPool jedisPool) {
        if (jedisPool != null) {
            jedis.close();
        }
    }

}

jedisuntil对缓存数据库实现插入一对时效性键值对

package com.hlc.utils;/*
    User: 黄林春
    Date: 2022/7/19
    Time: 周二
    Project_Name: springDemo712
    */

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Component
public class JedisUtil {

     static JedisPool jedisPool = JedisFactory.getJedisPool();
     static Jedis jedis = jedisPool.getResource();

    /*用户下单对应的时间与用户的Id与设备Id, key:设备Id , value: 用户Id*/
    public void InsertOrderServerListener(String deviceId,String userId,Integer time){
        jedis.auth("hlc");
        try {
            System.out.println("--------------" + deviceId + "订单开始计时----------------");
            /**向缓存中插入这一对订单键值对,以秒为单位计时*/
            jedis.setex(deviceId, time*60*60 , userId);
        }catch (Exception e){
            System.out.println("------------------缓存异常---------------");
        }
        jedis.close();
    }

}
    

缓存远程监听配置

package com.hlc.utils;/*
    User: 黄林春
    Date: 2022/7/19
    Time: 周二
    Project_Name: springDemo712
    */

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
/**redis缓存配置类*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }

}

缓存监听,键值过期出发业务

package com.hlc.utils;/*
    User: 黄林春
    Date: 2022/7/19
    Time: 周二
    Project_Name: springDemo712
    */

import com.hlc.service.DeviceService;
import com.hlc.service.UserDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

@Component
public class RedisListener extends KeyExpirationEventMessageListener {

    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private NetFactory netFactory;

    public RedisListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 针对redis数据失效事件,进行数据处理
     *
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        /**当名为expiredKey的键值对过期了,会把key返回,而不会将value返回*/
        String expiredKey = message.toString();
        try {
            /**首先修改订单使用时间为0*/
            boolean updateExOrder = userDeviceService.updateExOrder(expiredKey);
            /**其次将设备的锁装置与设备状态释放掉*/
            deviceService.freeDeviceByDeviceId(expiredKey);
            /**最后向设备查询设备电源状态,如果状态为开则发送关闭指令*/
            boolean power = deviceService.findDevicePowerByDeviceId(expiredKey);
            if (power) {
                NetAndIoController netAndIoController = netFactory.getNetAndIoController();
                netAndIoController.outSign = deviceService.findOutSignByDeviceId(expiredKey);
                netAndIoController.serverPort = deviceService.findHostPortByDeviceId(expiredKey);
                netAndIoController.TcpConnection();
                netAndIoController.sendDownControllerMsg();
                /**由于订单过期,现在关闭端口电源通断*/
                netAndIoController.shutClient();
                /**由于数据库里记录的电源还开着,所以我们需要将数据库表中的电源关掉**/
                boolean downDevicePowerByDeviceId = deviceService.downDevicePowerByDeviceId(expiredKey);
                if (!downDevicePowerByDeviceId)
                    throw new Exception("数据库power更改异常");
            }
            if (!updateExOrder) {
                throw new Exception("订单过期处理失败");
            }
        } catch (Exception e) {
            System.out.println("---------处理过期订单业务失效---------");
        }
        System.out.println(expiredKey + "订单过期--------------------");
    }
}

继电器控制类(实现电源的通断)

package com.hlc.utils;/*
    User: 黄林春
    Date: 2022/7/18
    Time: 周一
    Project_Name: springDemo712
    */


import java.io.*;
import java.net.*;

/***
 * 控制继电器吸合辅助工具类
 */
public class NetAndIoController {
    /*读写缓冲区*/
    private   BufferedReader reader;
    private   BufferedWriter writer;
    private   Socket client;
    private ServerSocket server;
    /*控制电源输出端口号*/
    public    int outSign;
    /*控制主机端口号:0~65535 去掉主要的计算机运行接口 */
    public    int serverPort;
    public  void TcpConnection(){
        try{
            /*主机所使用的端口,需要在硬件配置里设置好主机的目的IP与端口号*/
            server = new ServerSocket(serverPort);
            /*连接服务*/
            client = server.accept();
            System.out.println("连接成功");
            String clientAddress = client.getRemoteSocketAddress().toString().substring(1);
            String[] clientAddresses = clientAddress.split(":");
            System.out.println("客户端IP"+clientAddresses[0]+"端口"+clientAddresses[1]);
            reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
        }catch (IOException e) {
//            e.printStackTrace();
            System.out.println("----------------------目前的TCP链接并没有断开,依旧使用旧链接-------------------------");
        }
    }

    /*这里的输出口号outSign决定我们去控制那个口的常开吸合*/
    public  void sendOpenControllerMsg(){
        System.out.println("控制继电器通道常开吸合发送:AT+STACHn=1\\r\\n");
        String msg = "AT+STACH"+outSign+"=1\r\n";
        try {
            /*发送数据(主机输出信息口等于继电器的网口输入口)*/
            System.out.println("主机发送控制常开指令"+msg);
            writer.write(msg);
            writer.flush();
            /*读数据(继电器收到指令会做出应答,如果应答OK就是执行正常)*/
            msg = reader.readLine();
            msg = msg.replace("\r\n","\\r\\n");
            System.out.println("网络继电器应答"+msg);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*这里的输出口号决定我们控制那个口的常关吸合*/
    public  void sendDownControllerMsg(){
        System.out.println("控制继电器通道常关吸合发送:AT+STACHn=0\\r\\n");
        String msg = "AT+STACH"+outSign+"=0\r\n";
        try{
            System.out.println("主机发送控制常开指令"+msg);
            writer.write(msg);
            writer.flush();
            msg =  reader.readLine();
            msg = msg.replace("\r\n","\\r\\n");
            System.out.println("网络继电器应答"+msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /*控制开关限时吸合*/
    public void sendDelayOpenControllerMsg(){
        System.out.println("控制继电器通道开启后延时关闭发送:AT+STACHn=3,10\\r\\n");
        String msg = "AT+STACH"+outSign+"=3,10\r\n";
        try{
            System.out.println("主机发送控制常开指令"+msg);
            writer.write(msg);
            writer.flush();
            msg =  reader.readLine();
            msg = msg.replace("\r\n","\\r\\n");
            System.out.println("网络继电器应答"+msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public  void shutClient(){
        try{
            System.out.println("关闭客户端连接");
            if (reader != null)
                reader.close();
            if (writer != null)
                writer.close();
            if (client != null)
                client.close();
            if (server != null)
                server.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


神生成控制继电器类的创建工厂,单例模式,避免浪费

package com.hlc.utils;/*
    User: 黄林春
    Date: 2022/7/18
    Time: 周一
    Project_Name: springDemo712
    */

import org.springframework.stereotype.Component;

/**
 * 代理生成控制继电器类的实例化工厂
 */
@Component
public class NetFactory {

    private NetAndIoController netAndIoController = null;

    public NetAndIoController getNetAndIoController(){
        if (netAndIoController == null){
            synchronized (NetFactory.class){
                if (netAndIoController == null){
                    netAndIoController = new NetAndIoController();
                    return netAndIoController;
                }
                return netAndIoController;
            }
        }
        return netAndIoController;
    }
}

前端微信小程序代码,需要的私聊!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ForestSpringH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值