springboot vue零食商城实战开发教程 实现websocket对话功能

大家好,最近有同学问能不能写写商城系统的实战开发,最好项目能有亮点。商城功能亮点的话可以加协同过滤算法,加沙箱支付,也可以考虑实现与商家的对话功能。

于是写了一个零食商城项目,分享下重点功能实现的过程,也录制了此商城项目实战开发视频,希望能对同学们的学习有点帮助。

角色设计

很多同学写项目仍然会选择两个角色,都2025年了,大家可以多去参考目前的商城系统,如某宝,某东,两个角色目前来说太单调了,可以在管理员,用户的基础上添加一个商家的角色,有不同的店铺信息,功能也会丰富一点。

商品功能

基于三个角色,功能也比较清晰了,商家管理商品,商品在添加时可以做以下两点调整。

很多同学商品名称依然使用简短的几个字如【可乐】,【雪碧】等,但在真实电商平台中没有这样写名称的,真实使用的名称是【可乐原味碳酸饮料整箱批发24罐330ml特价爆款无糖汽水】。

鼠标放上去能直接显示文字,这个用element ui 中标签实现。

ini 复制代码
<el-tooltip :content="item.name" placement="top-start" >
  <p  class="name">{{item.name}}</p>
</el-tooltip>

在商品详情页部分,很多项目直接不写,或者几个字,但在真实平台中介绍的很详细,多张图文形式显示,可以考虑使用富文本编辑器

实现的效果也会好很多。

富文本编辑器怎么使用呢?可以去看看wangeditor编辑器官网看看,网上也有很多视频教程,初始化编辑器代码如下。

kotlin 复制代码
// 初始化编辑器
    initWangEditor(content) { //用户输入的文本作为参数传进函数。
      this.$nextTick(() => { //1.dom元素加载好后,先判断editor是否已经完成初始化,如果已经完成初始化,那么把editor销毁,清空。
        if (this.editor){
          this.editor.destroy();
          this.editor = null;
        }
        this.editor = new E('#editor') //2.新建一个editor,赋值给我们一开始定义的editor,并渲染在iD为#editor的元素里
        this.editor.config.placeholder = '请输入内容' // 配置编辑器默认展示的文本
        this.editor.config.uploadFileName = 'file' //配置编辑器文件上传的名称
        this.editor.config.uploadImgServer = 'http://localhost:9090/files/wang/upload'  //配置编辑器文件上传的接口
        this.editor.create() //执行创建编辑器
        setTimeout(() => { //延时函数,这里没有设置延时时间,即为实时获取编辑器的文本给到this.editor.txt.html()。
          this.editor.txt.html(content)
        })
      })
    },

商品详情

这一部分也是参考真实平台写的,比只有两三个字段的商品界面是不是会好些呢?数量这一部分使用的是element ui中的计数器。element ui框架也比较好用,能比html减少很多代码。

个人中心功能

可以将个人的很多功能放在个人中心部分,购物车功能,收藏功能,收货地址,订单功能。

websocket对话功能

websocket功能是一种不同于http的通信方式,websocket使用最多的是两人聊天,多人聊天,前端就模仿某宝pc端写的,界面与核心代码如下。

typescript 复制代码
package com.example.springboot.common.config;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;

import com.example.springboot.entity.Chat;
import com.example.springboot.service.ChatService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket服务 - 单聊
 */
@ServerEndpoint(value = "/chatWebsocket")
@Component
public class WebSocketServer implements InitializingBean {
    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    /**
     * 记录当前在线连接数
     */
    public static final Map<String, Session> sessionMap = new ConcurrentHashMap<>();
    @Resource
    ChatService chatService;
    static ChatService staticChatService;
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        sessionMap.put(session.getId(), session);
    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        sessionMap.remove(session.getId());
    }
    /**
     * 收到客户端消息后调用的方法
     * 后台收到客户端发送过来的消息
     * onMessage 是一个消息的中转站
     * 接受 浏览器端 socket.send 发送过来的 json数据
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session fromSession) {
        log.info("服务端收到消息:{}", message);
        Chat chat = JSONUtil.toBean(message, Chat.class);//字符串转为java对象
        chat.setTime(DateUtil.now());
        chat.setIsRead(0);//0 表示未读 1 表示已读
        // 存储数据到数据库
           staticChatService.saveChat(chat);
        String jsonStr = JSONUtil.toJsonStr(chat);  // 处理后的消息体
        this.sendAllMessage(jsonStr);
        log.info("[onMessage] 发送消息:{}", jsonStr);
    }
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("[onError] 发生错误", error);
    }
    /**
     * 服务端发送消息给除了自己的其他客户端
     */
    private void sendMessage(Session fromSession, String message) {
        sessionMap.values().forEach(session -> {
            if (fromSession != session) {
                log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
                try {
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    log.error("服务端发送消息给客户端异常", e);
                }
            }
        });
    }
    /**
     * 服务端发送消息给所有客户端
     */
    private void sendAllMessage(String message) {
        try {
            for (Session session : sessionMap.values()) {
                log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败", e);
        }
    }
    @Override
    public void afterPropertiesSet() {
              staticChatService = chatService;
    }
}
相关推荐
AQin10121 小时前
IP 🆚 MAC,你分得清吗?
后端·网络协议
天涯学馆1 小时前
Solidity 中的高级模式匹配:提升代码的可读性和可维护性
后端·区块链·solidity
郝学胜-神的一滴2 小时前
Spring Boot Actuator 保姆级教程
java·开发语言·spring boot·后端·程序人生
剪刀石头布啊2 小时前
数据口径
前端·后端·程序员
剪刀石头布啊2 小时前
http状态码大全
前端·后端·程序员
jiangxia_10243 小时前
面试系列:什么是JAVA并发编程中的JUC并发工具类
java·后端
用户1512905452203 小时前
踩坑与成长:WordPress、MyBatis-Plus 及前端依赖问题解决记录
前端·后端
A_氼乚3 小时前
JVM运行时数据区相关知识,这篇文档会勘正你的许多理解!(本周会补上更详细的图式)
后端
斜月3 小时前
Springboot 项目加解密的那些事儿
spring boot·后端
汤姆yu4 小时前
基于springboot的快递分拣管理系统
java·spring boot·后端