返回顶部
首页 > 资讯 > 数据库 >SpringBoot+Mybatis+Mysql+Netty+Redis+Uni-app开发的充电桩小程序管理后台
  • 584
分享到

SpringBoot+Mybatis+Mysql+Netty+Redis+Uni-app开发的充电桩小程序管理后台

springbootmybatis汽车uni-app 2023-10-28 08:10:58 584人浏览 独家记忆
摘要

由于之前用PHP+WorkMan开发的新能源汽车充电管理系统,(有兴趣的可以查看这里),公司说这技术淘汰了,需要用java重新架构一套,适应市场需求。 毕竟入职时候,说自己php、java都能撸出冒火星,这个任务无可厚非放在我的身上了。 经

由于之前用PHP+WorkMan开发的新能源汽车充电管理系统,(有兴趣的可以查看这里),公司说这技术淘汰了,需要用java重新架构一套,适应市场需求。

毕竟入职时候,说自己php、java都能撸出冒火星,这个任务无可厚非放在我的身上了。

经过小组讨论,决定架构用:SpringBoot+mybatis+Mysql+Netty+Redis+Uni-app

有什么不明白地方,大家一起交流:150-5606-9927

技术解决方案

硬件跟服务器通讯

硬件厂商提供的充电桩和充电运营管理系统之间的通信接口采用基于 tcp/IP Socket 的通信方式实现,按照长连接工作模式。

我们使用Netty跟硬件桩子(TCP/IP)通讯

应用层报文桢格式

  1. 应用层数据结构

起始标志

数据长度

序列号域

加密标志

桢类型标志

消息体

桢校验域

1字节

1字节

2字节

1字节

1字节

N字节

2字节

数据结构定义说明:

  1. 起始标识符代表一数据的开始,固定为0x68。
  2. 数据域字节数,数据域长度不超过200字节。不加密时为原数据长度,加密时,为加密后数据长度。其值为“序列号域+加密标志+桢类型标志+消息体”字节数之和。
  3. 序列号域即为数据包的发送顺序号,从 0 开始顺序增加,如是应答数据包,则与询问数据包序号保持一致,当桩与平台网络断开重新建立连接或者溢出归0。
  4. 加密标志只针对消息体(数据单元)。0x00:不加密,0x01:3DES
  5. 桢类志定了上下行数据

校验域:从序列号域到数据域的 CRC 校验,校验多项式为 0x180D,低字节在前,高字节在后,

  1. 数据格式定义

数据格式包括BCD码、BIN码、ASCII,BIN码均为低位在前高位在后。协议中小数值均乘倍率(保留小数点位数)上送平台(例如:电压为225.1,保留一位小数,上送到平台值为2251,即0x8CB)。CP56Time2a格式如下:

Miliseconds(D7-D0)

Miliseconds(D15-D8)

IV(D7)

RES1

Minutes(D5-D0)

SU(D7)

RES2

Hours(D4-D0)

DAY of WEEK

DAY of MONTH(D4-D0)

RES3

Month(D3-D0)

RES4

Years(D6-D0)

有了充电桩硬件厂商提供的数据协议,

我们开始写Netty服务器端,贴出核心代码

package com.icojoo.chargeNetty.tcpIp;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.NIO.NioEventLoopGroup;import io.netty.channel.socket.nio.NiOServerSocketChannel;import io.netty.util.concurrent.Future;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;@Slf4j@Componentpublic class NettyTcpServer {        private EventLoopGroup boss = new NioEventLoopGroup(1);        private EventLoopGroup worker = new NioEventLoopGroup();    @Autowired    ServerChannelInitializer serverChannelInitializer;    @Value("${netty.tcp.client.port}")    private Integer port;        private Channel channel;        public static Map map = new ConcurrentHashMap();        public ChannelFuture start() {        // 启动类        ServerBootstrap serverBootstrap = new ServerBootstrap();        //组配置,初始化ServerBootstrap的线程组        serverBootstrap.group(boss, worker)                //构造channel通道工厂 bossGroup的通道,只是负责连接                .channel(NioServerSocketChannel.class)                //设置通道处理者ChannelHandlerWorkerGroup的处理器                .childHandler(serverChannelInitializer)                //socket参数,当服务器请求处理程全满时,用于临时存放已完成三次握手请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。                .option(ChannelOption.SO_BACKLOG, 1024)                //启用心跳保活机制,tcp,默认2小时发一次心跳                .childOption(ChannelOption.SO_KEEPALIVE, true);        //Future:异步任务的生命周期,可用来获取任务结果        // 绑定端口 开启监听 同步等待        ChannelFuture channelFuture1 = serverBootstrap.bind(port).syncUninterruptibly();        if (channelFuture1 != null && channelFuture1.isSuccess()) {            // 获取通道            channel = channelFuture1.channel();            log.info("Netty tcp server start success,port={}",port);        }else {            log.error("Netty tcp server start fail");        }        return channelFuture1;    }        public void destroy(){        if (channel != null) {            channel.close();        }        try {            Future future = worker.shutdownGracefully().await();            if (!future.isSuccess()) {                log.error("netty tcp workerGroup shutdown fail,{}",future.cause());            }        } catch (InterruptedException e) {            log.error(e.toString());        }        log.info("Netty tcp server shutdown success");    }}
package com.icojoo.chargeNetty.tcpIp;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.bytes.ByteArrayDecoder;import io.netty.handler.codec.bytes.ByteArrayEncoder;import io.netty.handler.timeout.IdleStateHandler;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Componentpublic class ServerChannelInitializer extends ChannelInitializer {    @Autowired    ServerChannelHandler serverChannelHandler;    @Override    protected void initChannel(SocketChannel socketChannel) throws Exception {        ChannelPipeline pipeline = socketChannel.pipeline();        //IdleStateHandler心跳机制,如果超时触发Handle中userEventTrigger()方法        pipeline.addLast("idleStateHandler",                new IdleStateHandler(15,0,0, TimeUnit.MINUTES));        // 字符串编解码器        pipeline.addLast(                new ByteArrayDecoder(),                new ByteArrayEncoder()        );        // 自定义Handler        pipeline.addLast("serverChannelHandler",serverChannelHandler);    }}
package com.icojoo.chargeNetty.tcpIp;import com.icojoo.chargeNetty.service.ITBookService;import com.icojoo.chargeNetty.utils.Crc3Util;import com.icojoo.chargeNetty.utils.JuDianUtil;import com.icojoo.chargeNetty.utils.RedisUtil;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.timeout.IdleState;import io.netty.handler.timeout.IdleStateEvent;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Slf4j@Component@ChannelHandler.Sharablepublic class ServerChannelHandler extends SimpleChannelInboundHandler {    @Autowired    private ITBookService itBookService;    @Autowired    RedisUtil redisUtil;        @Override    protected void channelRead0(ChannelHandlerContext channelHandlerContext, byte[]  msg) throws Exception {        String vv=JuDianUtil.bytesToHexString(msg);      log.info("Netty tcp server receive--- message: {}",  vv);//      效验//String nn="000000010361002001101300020a3232303432320000011920168010203000000000";      byte[] bb= JuDianUtil.hexStringToBytes(nn);      log.info("Netty tcp server receive message------: {}", Crc3Util.getCRC3(bb,null));//        String cmd = JuDianUtil.getMsGCmd(msg);//        String pileCode = JuDianUtil.getPileNum(msg);////        log.info("Netty tcp: {}", cmd);//        log.info("Netty tcp: {}", pileCode);//        itBookService.save(new TBook("1231", (String) msg));//        redisUtil.set("123",new TBook(1,"1231", (String) msg),60);//       channelHandlerContext.writeAndFlush(JuDianUtil.hexStringToBytes("680c000000020361002001101300c17f")).syncUninterruptibly();    }        @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        super.channelActive(ctx);        log.info("tcp client "+getRemoteAddress(ctx)+" connect success");        NettyTcpServer.map.put(getIPString(ctx),ctx.channel());    }        @Override    public void channelInactive(ChannelHandlerContext ctx) throws Exception {        // 删除Channel Map中失效的Client        log.info("tcp client "+getRemoteAddress(ctx)+" 删除Channel");        NettyTcpServer.map.remove(getIPString(ctx));        ctx.close();    }掉线移除//    @Override//    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {////        log.info("tcp client "+getRemoteAddress(ctx)+" handlerRemoved");//        NettyTcpServer.map.remove(getIPString(ctx));//        ctx.close();//    }        @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        super.exceptionCaught(ctx, cause);        // 发生异常 关闭连接        log.error("引擎{}的通道发生异常,断开连接",getRemoteAddress(ctx));        ctx.close();    }        @Override    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {        String socketString = ctx.channel().remoteAddress().toString();        if (evt instanceof IdleStateEvent) {            IdleStateEvent event = (IdleStateEvent) evt;            if (event.state()== IdleState.READER_IDLE) {                log.info("Client: "+socketString+" READER_IDLE读超时");                ctx.disconnect();            }else if (event.state()==IdleState.WRITER_IDLE){                log.info("Client: "+socketString+" WRITER_IDLE写超时");                ctx.disconnect();            }else if (event.state()==IdleState.ALL_IDLE){                log.info("Client: "+socketString+" ALL_IDLE总超时");                ctx.disconnect();            }        }    }        public String getRemoteAddress(ChannelHandlerContext channelHandlerContext){        String socketString = "";        socketString = channelHandlerContext.channel().remoteAddress().toString();        return socketString;    }        public String getIPString(ChannelHandlerContext channelHandlerContext){        String ipString = "";        String socketString = channelHandlerContext.channel().remoteAddress().toString();        int colonAt = socketString.indexOf(":");        ipString = socketString.substring(1,colonAt);        return ipString;    }}

 CRC 校验工具

package com.icojoo.chargeNetty.utils;public class Crc3Util {        public static String getCRC3(byte[] data,String order) {        byte[] crc16_h = {                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,                (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40        };        byte[] crc16_l = {                (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04,                (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8,                (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC,                (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10,                (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4,                (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38,                (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C,                (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0,                (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4,                (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68,                (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C,                (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0,                (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54,                (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98,                (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C,                (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40        };        int crc = 0x0000ffff;        int ucCRCHi = 0x00ff;        int ucCRCLo = 0x00ff;        int iIndex;        for (int i = 0; i < data.length; ++i) {            iIndex = (ucCRCLo ^ data[i]) & 0x00ff;            ucCRCLo = ucCRCHi ^ crc16_h[iIndex];            ucCRCHi = crc16_l[iIndex];        }        crc = ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;        //高低位互换,输出符合相关工具对Modbus CRC16的运算        if("H".equals(order)) {            crc = ( (crc & 0xFF00) >> 8) | ( (crc & 0x00FF ) << 8);        }        return String.fORMat("%04X", crc);    }}

ui界面重新设计了

 

 

 

 

 

 

 

 

2.5.1、总后台管理

权限管理、管理员管理、角色管理、系统基本管理、互联互通管理、支付管理、短信通知管理。

2.5.2、用户管理

APP、小程序会员管理、代理商管理、商户管理、公司账户管理。

2.5.3、设备管理

站场网站管理、设备管理、功率监控、故障管理、告警管理、摄像头管理。

2.5.4、订单管理

充电订单、充值订单、卡充电单、退款订单等

2.5.5、财务管理

平台流水、代理商流水、代理商提现、商户流水、商户提现、会员流水、电子发票自助开票管理

2.5.6、数据分析

订单分析、会员分析、财务分析、运营数据分析

2.6、App、小程序端功能点

2.6.1、首页

充电站列表、导航、当前价格、距离远近、设备是否有空闲、是否有停车位、停车收费标准等。

2.6.2、充电

扫码充电、插枪充电、刷卡充电、充满推送、远程停充、占位费计算、充电订单等。

2.6.3、会员中心

显示余额、充值、充电卡、积分、优惠券、每日签到、故障申报、发票申领、联系客服。

代理商或商户:收益统计、佣金查看、提现、收支流水等

2.7、数据大屏

可视化数据大屏数据 通过地图、柱状图、折线图、饼图把场站位置、场站数量。充电桩的类型、充电桩状态、当月/当日充值金额,当月/当日充电金额,电站告警等相对复杂、抽象的数据通过可视的方式以一种人们更容易理解的、更直观的方式来展示出来,将数据转换成图或表等。将业务的关键指标以可视化的方式展示到一个或多个LED屏幕上,不仅使业务人员能够从复杂的业务数据中快速、直接地找到重要数据,而且能对决策者起到辅助作用。

 

来源地址:https://blog.csdn.net/jiyehang/article/details/128786810

您可能感兴趣的文档:

--结束END--

本文标题: SpringBoot+Mybatis+Mysql+Netty+Redis+Uni-app开发的充电桩小程序管理后台

本文链接: https://www.lsjlt.com/news/518293.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作