引 言
作为一个职场新人,项目经验少,工作总也干不好,最后薪资还挺少;
如果是在校生,毕业设计往往无从下手,实战经验少,设计总是做不好;
面对用户,总会遇到一些项目需求很多,同时业务经验少的窘境;
在这里,根据我们多年的开发与实战经验,对项目设计与开发,特别是Java项目的开发做一个完整的分析与总结,主要从以下几个方面着手解析:
六大应用场景: 电商销售、旅游健康、金融办公、酒店物业、租赁政务 、工程电信
架构体系:JavaEE原生、SSM经典、Springboot微服务、大数据与AI预测模型未来服务
开发模式:前后端一体开发、前后端分离开发
用户模式:前台管理 、后台管理
下面,我们来看一下基于Springboot+Vue易购电商应用项目实战吧!
一、项目简介
本款电商App实现了时下热门的电商应用效果。系统分为系统管理员和普通商家用户两个角色,管理员登录能管理商品的上下架和订单功能,用户管理等,普通商家和用户登录能浏览商品,上传商品,添加购物车和下单等功能。
此应用满足商家出售商品需求,亦能满足用户购买需求。
二、产品优势
随着时代的发展,社会生产力迅速发展,科学技术突飞猛进,人们对购物的需求不断增长。
对于商家来说,大量信息需要发布,订单需要生成并管理;对于顾客来说,如何快速找到自己需求的商品并且快速购买是一个考量。
易购电商应用项目搭建了一个商家和顾客之间交互的平台,改平台能提供商品,购物车和订单等等服务,满足商家和顾客双方需求。
三、技术体系
四、功能列表
五、项目架构
前台用户管理:
业务流程:
六、效果展示
首页效果:
商家列表:
商家详情:
订单列表:
在线支付:
七、部分源码参考
全局跨域配置:
@Configuration
public class CrossConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("*")
.allowedHeaders("*")
//Access-Control-Allow-Credentials允许跨域
//是否允许cookie
.allowCredentials(true)
.maxAge(3600);
}
}
全局异常管理:
@ControllerAdvice
public class GlobalAdvice {
/**
* 空指针异常
* @return
*/
@ExceptionHandler(NullPointerException.class)
public String nullPointer(){
//直接转发到static根下
return "forward:null.html";
}
/**
* 数组越界
* @return
*/
@ExceptionHandler(ArrayIndexOutOfBoundsException.class)
public String arrayOutof(){
//直接转发到static根下
return "forward:out.html";
}
/**
* 文件未找到
* @return
* 传入反射对象
*/
@ExceptionHandler(FileNotFoundException.class)
public String notFind(){
//跳到/static/not.html
return "forward:not.html";
}
@ExceptionHandler(SqlSessionException.class)
@ResponseBody//返回json字符串
public ResultVo mysqlException(){
//跟前端约定好接口的标准
return new ResultVo(3001,null,"数据更新异常 ");
}
}
自定义全局拦截器:
/**
* 自定义拦截器
*/
@Slf4j
public class MyInterception implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object us=request.getSession().getAttribute("username");
log.info("后端us:"+us);
if(us==null){//用户名为空,转发一定要用request携带
request.setAttribute("error","请先登录");
//这里要写映射的地址
request.getRequestDispatcher("/login").forward(request,response);
return false;
}
//正常执行
return true;
}
}
订单服务类:
@Service
public class OrdersServiceImpl implements OrdersService {
//订单基本管理
@Resource
private OrdersMapper ordersMapper;
//订单详情管理
@Resource
private OrderDetailsMapper orderDetailsMapper;
//购物车管理
@Resource
private CartMapper cartMapper;
/**
* 生成订单:同步添加订单表orders与订单详情表
* 要使用事务管理:多表与多sql操作
* @param orders
* @return
*/
@Transactional
@Override
public ResultVo addOrders(Orders orders) {
//拿到当前的时间
LocalDate localDate = LocalDate.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String date = localDate.format(dateTimeFormatter);
//存入当前日期
orders.setOrderDate(date);
//存入当前状态,未支付
orders.setOrderState(0);
int n = ordersMapper.insertOrders(orders);
Integer orderId=orders.getOrderId();
//声明订单详情集合
List<OrderDetails> orderDetails = new ArrayList<>();
if (n > 0) {
//同时执行订单详情操作
List<Cart> list = cartMapper.selectByUserIdAndBusinessId(orders.getUserId(), orders.getBusinessId());
//批量存订单详情信息,并删除用户对应的购物车信息
for (Cart temp : list) {
OrderDetails od = new OrderDetails();
//订单id
od.setOrderId(orderId);
//食品id
od.setFoodId(temp.getFoodId());
//食品数量
od.setQuantity(temp.getQuantity());
//存入订单详情集合
orderDetails.add(od);
}//for
int num = orderDetailsMapper.insertOrderDetailsBatch(orderDetails);
删除当前用户的购物车信息
if (num > 0) {//直接遍历删除
for (Cart temp : list){
cartMapper.deleteCart(temp);
}//for
}
将生成的订单id传到前端
return new ResultVo(1000, orders.getOrderId(), "订单已生成");
}
return new ResultVo(1001, null, "订单生成失败");
}
/**
* 通过用户id查询订单
*
* @param userId,使用包装类对象,可以判断前端是否传了空对象
* @return
*/
@Override
public ResultVo queryOrdersByUserId(Integer userId) {
if (userId == null) {
return new ResultVo(1001, null, "用户Id为空");
} else {
List<Orders> list = ordersMapper.selectByUserId(userId);
if (list != null) {
return new ResultVo(1000, list, "订单查询成功");
}
return new ResultVo(1001, null, "订单查询失败");
}
}
/**
* 通过订单id查询订单,并关联查询
* @param orderId
* @return
*/
@Override
public ResultVo queryOrdersByOrderId(Integer orderId) {
Orders orders =ordersMapper.selectByOrderId(orderId);
if(orders!=null){
return new ResultVo(1000,orders,"订单查询成功");
}
return new ResultVo(1001,null,"订单查询失败");
}
/**
* 修改订单状态:0未支付,1已支付,2已取消
* 使用包装类对象,可以判断前端是否传了空对象
*
* @param orderId
* @param orderState
* @return
*/
@Override
public ResultVo updateOrdersState(Integer orderId, Integer orderState) {
if (orderId == null || orderState == null) {
return new ResultVo(1001, null, "传入的为空数据");
} else {
int n = ordersMapper.updateStatus(orderId, orderState);
if (n > 0) {
return new ResultVo(1000, null, "订单状态更新成功");
}
return new ResultVo(1001, null, "订单状态更新失败");
}
}
}
订单控制器层,实现接口映射:
@RestController
@RequestMapping("/Orders")
public class OrdersController {
@Resource
private OrdersService ordersService;
/**
* 生成订单
* @param orders
* @return
*/
@PostMapping("/add")
public ResultVo addOrders(Orders orders){
return ordersService.addOrders(orders);
}
/**
* 通过用户id查询订单
* @param userId
* @return
*/
@GetMapping("/query")
public ResultVo queryOrders(int userId){
return ordersService.queryOrdersByUserId(userId);
}
/**
* @param orderId
* @return
*/
@GetMapping("/orderId")
@CrossOrigin
public ResultVo queryOrdersByOrderId(int orderId){
return ordersService.queryOrdersByOrderId(orderId);
}
/**
* 更新订单状态:0未支付,1已支付
* @param orderId
* @param orderState
* @return
*/
@PostMapping("/update")
public ResultVo updateOrders(int orderId,int orderState){
return ordersService.updateOrdersState(orderId,orderState);
}
}