服务端代码 端口默认8080
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* WebSocket配置
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter () {
return new ServerEndpointExporter();
}
}
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
@Component
@ServerEndpoint(value = "/ws")
public class WebSocketServer {
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private static final AtomicInteger OnlineCount = new AtomicInteger(0);
private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<>();
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
SessionSet.add(session);
this.session = session;
int cnt = OnlineCount.incrementAndGet(); // 在线数加1
System.out.println("有连接加入,当前连接数为:" + cnt);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
SessionSet.remove(this.session);
int cnt = OnlineCount.decrementAndGet();
System.out.println("有连接关闭,当前连接数为:" + cnt);
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println(message);
BroadCastInfo(message);
}
/**
* 出现错误
* @param error
*/
@OnError
public void onError(Throwable error) {
error.printStackTrace();
}
/**
* 发送消息
*
* @param session
* @param message
*/
public static void SendMessage(Session session, String message) {
try {
if (session.isOpen()) {
session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 群发消息
*
* @param message
* @throws IOException
*/
public static void BroadCastInfo(String message) {
for (Session session : SessionSet) {
SendMessage(session, message);
}
}
/**
* 指定Session发送消息
*
* @param sessionId
* @param message
* @throws IOException
*/
public static void SendMessage(String message, String sessionId) {
Session session = null;
for (Session s : SessionSet) {
if (s.getId().equals(sessionId)) {
session = s;
break;
}
}
if (session != null) {
SendMessage(session, message);
}
}
}
前端代码
链接: jquery仿外卖点餐购物车页面代码.
下载下来,代码覆盖index.html和add.js文件即可
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>商品</title>
<link rel="stylesheet" type="text/css" href="css/aui.css">
<link rel="stylesheet" href="css/classify.css">
<style>
html,body{height: 100%;max-width: 640px;margin:0 auto;}
.aui-bar-nav{border:none;background: #f5f5f5;}
.main{height: calc(100% - 4.5rem);}
#tab1-con1{padding-bottom: 3rem;}
#tab1-con1,#tab1-con2{height: 100%;}
.aui-tab{border-bottom: solid 1px #eee;background: #f5f5f5;height: 2.25rem;}
.aui-tab-item{font-size: .75rem;color: #666;width: 25%;}
.aui-tab-item.aui-active{border:none;color: #000;position: relative;}
.aui-tab-item.aui-active:after{position: absolute;left: 40%;width: 20%;height: 2px;background: #00ae66;content: '';bottom:0;}
</style>
</head>
<body>
<header class="aui-bar aui-bar-nav">
<a class="aui-pull-left aui-btn">
<span class="aui-iconfont aui-icon-left"></span>
</a>
<div class="aui-title">商品</div>
<div class="aui-pull-right"></div>
</header>
<div class="aui-tab" id="tab">
<div class="aui-tab-item aui-active">点菜</div>
<div class="aui-tab-item">商家</div>
</div>
<div class="main">
<div class="aui-item" id="tab1-con1">
<div class="left-menu" id="left">
<ul>
<li><span>营养套餐</span></li>
</ul>
</div>
<div class="con">
<div class="right-con con-active" style="display: none;">
<ul>
</ul>
</div>
</div>
<div class="up1"></div>
<div class="shopcart-list fold-transition">
<div class="list-header">
<h1 class="title">购物车</h1>
<span class="empty">清空所有</span>
</div>
<div class="list-content">
<ul></ul>
</div>
</div>
<div class="footer">
<div class="left">
<div class="count_num"><span id="totalcountshow">0</span></div>
<span id="cartN" class="nowrap">总计:<span id="totalpriceshow">0</span>元</span>
</div>
<div class="right">
<a id="btnselect" class="xhlbtn disable">去结算</a>
</div>
</div>
</div>
<div class="aui-item aui-hide" id="tab1-con2">
2
</div>
</div>
<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script type="text/javascript" src="script/add.js"></script>
<script type="text/javascript" src="script/aui-tab.js" ></script>
<script type="text/javascript">
apiready = function() {
api.parseTapmode();
}
var tab = new auiTab({
element: document.getElementById("tab"),
}, function(ret) {
if (ret) {
//定义获取对象的所有兄弟节点的函数,
function siblings(elm) {
var a = [];
var p = elm.parentNode.children;
for (var i = 0, pl = p.length; i < pl; i++) {
if (p[i] !== elm) a.push(p[i]);
}
return a;
}
var index = ret.index;
var activeC = document.getElementById("tab1-con" + index);
activeC.className = "";
for (var i = 0; i < siblings(activeC).length; i++) {
siblings(activeC)[i].className = "aui-hide";
}
}
});
</script>
</body>
</html>
var ws = null;
// 菜单信息
var menuArr = [{"name":"珍珠奶茶","sale":"月销量:123","price":2.00,"num":0},
{"name":"辣子鸡","sale":"月销量:333","price":3.00,"num":0}];
var shoppingCarArr = [];
function setMenu(obj){
menuArr.forEach((elem, index) => {
if(elem.name == obj.name){
if(obj.operation == 'add'){
elem.num = parseInt(elem.num) + 1;
}else if(obj.operation == 'remove'){
elem.num = parseInt(elem.num) - 1;
}
$('#num'+index ).html(parseInt(elem.num));
if(elem.num != 0){
$('.minus').css('display','inline-block');
$('#num'+index).css('display','inline-block');
}else{
$('.minus').css('display','none');
$('#num'+index).css('display','none');
}
}
if(obj.operation == 'clear'){
elem.num = 0;
$('.minus').css('display','none');
$('#num'+index).css('display','none');
}
});
}
function setShoppingCar(){
var totalprices = 0;
var totalcount = 0;
var delIndex;
delflag = false;
shoppingCarArr.forEach((elem, index) => {
flag = true;
$(".list-content ul li").each(function(){
if ($(this).find("span.accountName").html() == elem.accountName) {
$(this).find(".li_acount").html(parseInt(elem.num)); //对商品的数量进行重新赋值
$(this).find(".accountPrice").html((elem.num*elem.price).toFixed(2));//对商品的价格进行重新赋值
flag = false;
if(elem.num == 0){
$(this).remove();
delIndex = index;
delflag = true;
}
}
})
if(flag){
var addtr = '<li class="food">';
addtr += '<div><span class="accountName">'+elem.accountName+'</span></div>';
addtr += '<div><span>¥</span><span class="accountPrice">'+(elem.num*elem.price).toFixed(2)+'</span></div>' ;
addtr += '<div class="btn">';
addtr += '<button class="ms2" style="display: inline-block;"></button>';
addtr += '<i class="li_acount">'+elem.num+'</i>';
addtr += '<button class="ad2"></button>';
addtr += '<i class="price" style="display: none;">'+elem.price+'</i>';
addtr += '</div>';
addtr += '</li>';
$(".list-content ul").append(addtr);
}
totalprices = (parseInt(totalprices) + (parseInt(elem.num)*parseInt(elem.price))).toFixed(2) ;
totalcount = parseInt(totalcount + elem.num) ;
if(totalcount == 0){
$(".up1").hide();
}
});
if(delflag){
shoppingCarArr.splice(delIndex,delIndex+1);
}
console.log(shoppingCarArr);
$("#totalpriceshow").html(totalprices); //计算当前所选总价
$("#totalcountshow").html(totalcount); //计算当前总数量
if(parseFloat($("#totalcountshow").text())==0){
$(".shopcart-list").hide();
}
jss(); //改变按钮样式
}
// 构建菜单
function menu(){
menuArr.forEach((elem, index) => {
var addtr = '<li>';
addtr += '<div class="menu-img"><img src="image/img.jpg"></div>';
addtr += '<div class="menu-txt">';
addtr += '<h4 data-icon="'+ index +'">'+ elem.name +'</h4>';
addtr += '<p class="list1">'+ elem.sale +'</p>';
addtr += '<p class="list2">';
addtr += '<b>¥</b><b>'+ elem.price +'</b>';
addtr += '</p>';
addtr += '<div class="btn">';
addtr += '<button class="minus"></button>';
addtr += '<i id=num'+ index + '>'+ elem.num +'</i>';
addtr += '<button class="add"></button>';
addtr += '<i class="price">'+ elem.price +'</i>';
addtr += '</div>';
addtr += '</div>';
addtr += '</li>';
$(".right-con ul").append(addtr);
});
}
function jss() {
var m = $("#totalcountshow").html();
if (m > 0) {
$(".right").find("a").removeClass("disable");
} else {
$(".right").find("a").addClass("disable");
}
};
$(function () {
$("#left li:first-child").addClass("active");
$(document).ready(function(){
// 初始化菜单
menu();
// 连接webSocket
webSocketTest();
});
function webSocketTest(){
if ("WebSocket" in window){
// 打开一个 web socket
ws = new WebSocket("ws://localhost:8080/ws");
ws.onopen = function() {
};
ws.onmessage = function (evt){
var received_msg = evt.data;
var obj = JSON.parse(received_msg);
setMenu(obj);
if(obj.operation == 'add'){
addShoppingCar(obj.name,obj.price);
}else if(obj.operation == 'remove'){
removeShoppingCar(obj.name);
}else if(obj.operation == 'clear'){
clearShoppingCar();
}
};
ws.onclose = function(){
alert("连接已关闭...");
};
}else{
alert("您的浏览器不支持 WebSocket!");
}
}
function sendMsg(name,operation,price){
var Obj = new Object();
Obj.name = name;
Obj.operation = operation;
Obj.price = price;
var json = JSON.stringify(Obj);
ws.send(json);
}
function addShoppingCar(name,price){
var flag = true;
shoppingCarArr.forEach((elem, index) => {
if(name == elem.accountName){
elem.num = elem.num + 1;
flag = false;
}
});
if(flag){
var Obj = new Object();
Obj.accountName = name;
Obj.price = price;
Obj.num = 1;
shoppingCarArr.push(Obj);
}
setShoppingCar();
}
function removeShoppingCar(name){
shoppingCarArr.forEach((elem, index) => {
if(name == elem.accountName){
elem.num = elem.num - 1;
}
});
setShoppingCar();
}
function clearShoppingCar(){
shoppingCarArr = [];
$(".list-content>ul").html("");
$("#totalcountshow").text("0");
$("#totalpriceshow").text("0");
$(".minus").next().text("0");
$(".minus").hide();
$(".minus").next().hide();
$(".shopcart-list").hide();
$(".up1").hide();
jss();//改变按钮样式
}
$(document).on('click','.add',function(){
var parent = $(this).parent();
var m = parent.parent().children("h4").text(); //当前商品名称
var p = $(this).next().text(); //获取单价
sendMsg(m,"add",p);
});
$(document).on('click','.minus',function(){
$('.shopcart-list,.up1').show();
});
//购物车 - 加
$(document).on('click','.ad2',function(){
var m = $(this).parent().parent().find(".accountName").text(); //当前商品名字
var p = parseFloat($(this).next().text()); //隐藏的价格
sendMsg(m,"add",p);
});
//购物车 - 减
$('.list-content').on('click','.ms2',function(){
var m = $(this).parent().parent().find(".accountName").text(); //当前商品名字
sendMsg(m,"remove",0);
});
//选项卡
$(".con>div").hide();
$(".con>div:eq(0)").show();
$(".left-menu li").click(function(){
$(this).addClass("active").siblings().removeClass("active");
var n = $(".left-menu li").index(this);
$(".left-menu li").index(this);
$(".con>div").hide();
$(".con>div:eq("+n+")").show();
});
$(".footer>.left").click(function(){
var content = $(".list-content>ul").html();
if(content!=""){
$(".shopcart-list.fold-transition").toggle();
$(".up1").toggle();
}
});
$(".up1").click(function(){
$(".up1").hide();
$(".shopcart-list.fold-transition").hide();
})
//清空购物车
$(".empty").click(function(){
sendMsg(0,"clear",0);
});
});
实现效果
当然要实现美团和二维火那种多人点餐还要很多逻辑,这只是最简单的demo
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/133935.html