大家好,最近有同学问能不能写写商城系统的实战开发,最好项目能有亮点。商城功能亮点的话可以加协同过滤算法,加沙箱支付,也可以考虑实现与商家的对话功能。
于是写了一个零食商城项目,分享下重点功能实现的过程,也录制了此商城项目实战开发视频,希望能对同学们的学习有点帮助。
角色设计
很多同学写项目仍然会选择两个角色,都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;
}
}