springboot项目中外卖用户下单业务功能之需求分析+数据模型+功能开发(详细步骤)

news/2024/4/29 7:16:04/文章来源:https://blog.csdn.net/weixin_43025151/article/details/129701587

一、需求分析

移动端用户将菜品或者套餐加入到购物车后,可以点击购物车种的 去结算 按钮,页面跳转到订单确认页面,点击 去支付 按钮则完成下单操作。

在这里插入图片描述

二、数据模型

用户下单业务对应的数据表为orders表和order_detail表:

  1. orders:订单表
CREATE TABLE `orders` (`id` bigint NOT NULL COMMENT '主键',`number` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '订单号',`status` int NOT NULL DEFAULT '1' COMMENT '订单状态 1待付款,2待派送,3已派送,4已完成,5已取消',`user_id` bigint NOT NULL COMMENT '下单用户',`address_book_id` bigint NOT NULL COMMENT '地址id',`order_time` datetime NOT NULL COMMENT '下单时间',`checkout_time` datetime NOT NULL COMMENT '结账时间',`pay_method` int NOT NULL DEFAULT '1' COMMENT '支付方式 1微信,2支付宝',`amount` decimal(10,2) NOT NULL COMMENT '实收金额',`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '备注',`phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,`user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,`consignee` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='订单表';
  1. order_detail:订单明细表
CREATE TABLE `order_detail` (`id` bigint NOT NULL COMMENT '主键',`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '名字',`image` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '图片',`order_id` bigint NOT NULL COMMENT '订单id',`dish_id` bigint DEFAULT NULL COMMENT '菜品id',`setmeal_id` bigint DEFAULT NULL COMMENT '套餐id',`dish_flavor` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '口味',`number` int NOT NULL DEFAULT '1' COMMENT '数量',`amount` decimal(10,2) NOT NULL COMMENT '金额',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='订单明细表';

三、用户下单

1. 代码开发-梳理交互过程

在开发代码之前,需要梳理一下用户下单操作时前端页面和服务端的交互过程:

  1. 在购物车中点击 去结算 按钮,页面跳转到订单确认页面

  2. 在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的默认地址

  3. 在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的购物车数据

  4. 在订单确认页面点击 去支付 按钮,发送ajax请求,请求服务端完成下单操作

开发用户下单功能 ,其实就是在服务端编写代码去处理前端页面发送的请求即可。

2. 代码开发

在开发业务功能之前,先将需要用到的类和接口基本结构创建好:

实体类 Orders:

package com.tigerhhzz.wuaimai.entity;import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;/*** 订单*/
@Data
public class Orders implements Serializable {private static final long serialVersionUID = 1L;private Long id;//订单号private String number;//订单状态 1待付款,2待派送,3已派送,4已完成,5已取消private Integer status;//下单用户idprivate Long userId;//地址idprivate Long addressBookId;//下单时间private LocalDateTime orderTime;//结账时间private LocalDateTime checkoutTime;//支付方式 1微信,2支付宝private Integer payMethod;//实收金额private BigDecimal amount;//备注private String remark;//用户名private String userName;//手机号private String phone;//地址private String address;//收货人private String consignee;
}

实体类 OrderDetail:

package com.tigerhhzz.wuaimai.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;/*** 订单明细*/
@Data
public class OrderDetail implements Serializable {private static final long serialVersionUID = 1L;private Long id;//名称private String name;//订单idprivate Long orderId;//菜品idprivate Long dishId;//套餐idprivate Long setmealId;//口味private String dishFlavor;//数量private Integer number;//金额private BigDecimal amount;//图片private String image;
}

Mapper接口 OrderMapper:

package com.tigerhhzz.wuaimai.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.tigerhhzz.wuaimai.entity.Orders;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface OrderMapper extends BaseMapper<Orders> {}

Mapper接口 OrderDetailMapper:

package com.tigerhhzz.wuaimai.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.tigerhhzz.wuaimai.entity.OrderDetail;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface OrderDetailMapper extends BaseMapper<OrderDetail> {}

业务接口OrderService:

package com.tigerhhzz.wuaimai.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.tigerhhzz.wuaimai.entity.Orders;public interface OrderService extends IService<Orders> {/*** 用户下单* @param orders*/public void submit(Orders orders);
}

业务接口OrderDetailService

package com.tigerhhzz.wuaimai.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.tigerhhzz.wuaimai.entity.OrderDetail;public interface OrderDetailService extends IService<OrderDetail> {}

业务层实现类 OrderServiceImpl:

package com.tigerhhzz.wuaimai.service.impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.tigerhhzz.wuaimai.common.BaseContext;
import com.tigerhhzz.wuaimai.common.CustomException;
import com.tigerhhzz.wuaimai.entity.*;
import com.tigerhhzz.wuaimai.mapper.OrderMapper;
import com.tigerhhzz.wuaimai.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {@Autowiredprivate ShoppingCartService shoppingCartService;@Autowiredprivate UserService userService;@Autowiredprivate AddressBookService addressBookService;@Autowiredprivate OrderDetailService orderDetailService;/*** 用户下单* @param orders*/@Override@Transactionalpublic void submit(Orders orders) {log.info("订单数据:{}", orders);//获得当前用户idLong userId = BaseContext.getCurrentId();//查询当前用户的购物车数据LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ShoppingCart::getUserId,userId);List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper);if(shoppingCarts == null || shoppingCarts.size() == 0){throw new CustomException("购物车为空,不能下单");}//查询用户数据User user = userService.getById(userId);//查询地址数据Long addressBookId = orders.getAddressBookId();AddressBook addressBook = addressBookService.getById(addressBookId);if(addressBook == null){throw new CustomException("用户地址信息有误,不能下单");}long orderId = IdWorker.getId();//订单号AtomicInteger amount = new AtomicInteger(0);List<OrderDetail> orderDetails = shoppingCarts.stream().map((item) -> {OrderDetail orderDetail = new OrderDetail();orderDetail.setOrderId(orderId);orderDetail.setNumber(item.getNumber());orderDetail.setDishFlavor(item.getDishFlavor());orderDetail.setDishId(item.getDishId());orderDetail.setSetmealId(item.getSetmealId());orderDetail.setName(item.getName());orderDetail.setImage(item.getImage());orderDetail.setAmount(item.getAmount());amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());return orderDetail;}).collect(Collectors.toList());orders.setId(orderId);orders.setOrderTime(LocalDateTime.now());orders.setCheckoutTime(LocalDateTime.now());orders.setStatus(2);orders.setAmount(new BigDecimal(amount.get()));//总金额orders.setUserId(userId);orders.setNumber(String.valueOf(orderId));orders.setUserName(user.getName());orders.setConsignee(addressBook.getConsignee());orders.setPhone(addressBook.getPhone());orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())+ (addressBook.getCityName() == null ? "" : addressBook.getCityName())+ (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())+ (addressBook.getDetail() == null ? "" : addressBook.getDetail()));//向订单表插入数据,一条数据this.save(orders);//向订单明细表插入数据,多条数据orderDetailService.saveBatch(orderDetails);//清空购物车数据shoppingCartService.remove(wrapper);}
}

业务层实现类OrderDetailServiceImpl:

package com.tigerhhzz.wuaimai.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.tigerhhzz.wuaimai.entity.OrderDetail;
import com.tigerhhzz.wuaimai.mapper.OrderDetailMapper;
import com.tigerhhzz.wuaimai.service.OrderDetailService;
import org.springframework.stereotype.Service;@Service
public class OrderDetailServiceImpl extends ServiceImpl<OrderDetailMapper, OrderDetail> implements OrderDetailService {}

控制层OrderController:

package com.tigerhhzz.wuaimai.controller;import com.tigerhhzz.wuaimai.common.R;
import com.tigerhhzz.wuaimai.entity.Orders;
import com.tigerhhzz.wuaimai.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 订单*/
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate OrderService orderService;/*** 用户下单* @param orders* @return*/@PostMapping("/submit")public R<String> submit(@RequestBody Orders orders){log.info("订单数据:{}",orders);orderService.submit(orders);return R.success("下单成功");}
}

控制层OrderDetailController:

package com.tigerhhzz.wuaimai.controller;import com.tigerhhzz.wuaimai.service.OrderDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** 订单明细*/
@Slf4j
@RestController
@RequestMapping("/orderDetail")
public class OrderDetailController {@Autowiredprivate OrderDetailService orderDetailService;}

3. 移动端查询订单

请求地址:http://localhost:8080/order/userPage?page=页数&pageSize=每页数量
请求类型:GET
请求参数:page,默认1,pageSize,默认5

OrdersService:

/*** 分页查询订单* @param page* @param pageSize* @return*/
Page<OrdersDto> userPage(Integer page, Integer pageSize);

OrdersServiceImpl:

/*** 分页查询订单* @param page* @param pageSize* @return*/
@Override
public Page<OrdersDto> userPage(Integer page, Integer pageSize) {// 分页构造器Page<Orders> ordersPage = new Page<>(page, pageSize);// 条件构造器LambdaQueryWrapper<Orders> ordersLambdaQueryWrapper = new LambdaQueryWrapper<>();ordersLambdaQueryWrapper.orderByDesc(Orders::getOrderTime);this.page(ordersPage,ordersLambdaQueryWrapper);Page<OrdersDto> ordersDtoPage = new Page<>();// 分页的ordersDtoPage,没有recordsBeanUtils.copyProperties(ordersPage, ordersDtoPage, "records");// 构造orderDetailsList<Orders> ordersList = ordersPage.getRecords();List<OrdersDto> ordersDtoList = ordersList.stream().map((item) -> {OrdersDto ordersDto = new OrdersDto();// 订单idString orderNum = item.getNumber();LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId, orderNum);BeanUtils.copyProperties(item, ordersDto);List<OrderDetail> list = orderDetailService.list(orderDetailLambdaQueryWrapper);ordersDto.setOrderDetails(list);return ordersDto;}).collect(Collectors.toList());ordersDtoPage.setRecords(ordersDtoList);return ordersDtoPage;
}

OrdersController:

/*** 分页查询订单* @param page* @param pageSize* @return*/
@GetMapping("/userPage")
public R<Page<OrdersDto>> userPage(Integer page, Integer pageSize){Page<OrdersDto> dtoPage = ordersService.userPage(page, pageSize);return R.success(dtoPage);
}

4. 再来一单

请求地址:http://localhost:8080/order/again
请求类型:POST
请求参数:{id}

/*** 再来一单* @param orders* @return*/
@PostMapping("/again")
public R<String> again(@RequestBody Orders orders){Orders temp = ordersService.getById(orders.getId());temp.setId(null);temp.setStatus(2);long orderId = IdWorker.getId(); // 订单号temp.setNumber(String.valueOf(orderId));temp.setOrderTime(LocalDateTime.now());temp.setCheckoutTime(LocalDateTime.now());ordersService.save(temp);return R.success("下单成功");
}

5. 分页多条件查询订单

请求地址:http://localhost:8080/order/page
请求类型:GET
请求参数:page页码、pageSize每页数量、number订单号、beginTime订单开始时间、endTime订单结束时间

PageQueryDto:

package cn.mu00.reggie.dto;import lombok.Data;import java.time.LocalDateTime;/*** 多条件分页查询*/
@Data
public class PageQueryDto {int page;int pageSize;String number;String beginTime;String endTime;
}

OrdersService:

/*** 分页多条件查询* @param pageQueryDto* @return*/
Page<Orders> queryPage(PageQueryDto pageQueryDto);

OrdersServiceImpl:

/*** 分页多条件查询* @param pageQueryDto* @return*/
@Override
public Page<Orders> queryPage(PageQueryDto pageQueryDto) {// 解构pageQueryDtoint page = pageQueryDto.getPage();int pageSize = pageQueryDto.getPageSize();String number = pageQueryDto.getNumber();// 订单 分页构造器Page<Orders> ordersPage = new Page<>(page, pageSize);// 订单 条件构造器LambdaQueryWrapper<Orders> ordersQueryWrapper = new LambdaQueryWrapper<>();// 根据订单时间,倒序排列ordersQueryWrapper.orderByDesc(Orders::getOrderTime);// 条件 订单号模糊查询ordersQueryWrapper.like(number != null, Orders::getNumber, number);// 判空if (pageQueryDto.getBeginTime() != null && pageQueryDto.getEndTime() != null){DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime beginTime = LocalDateTime.parse(pageQueryDto.getBeginTime(), df);LocalDateTime endTime = LocalDateTime.parse(pageQueryDto.getEndTime(), df);// 条件 时间区间ordersQueryWrapper.between(Orders::getOrderTime, beginTime, endTime);}// 执行查询this.page(ordersPage, ordersQueryWrapper);return ordersPage;
}

6. 更新订单状态

请求地址:http://localhost:8080/order
请求类型:PUT
请求参数:Orders

OrdersController:

/*** 更新订单状态* @param orders* @return*/
@PutMapping()
public R<String> toSend(@RequestBody Orders orders){log.info("派送订单:{}",orders.toString());ordersService.updateById(orders);return R.success("派送成功");
}

四、移动端效果展示

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_274529.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32-CAM 环境搭建(离线)

云盘&#xff1a;Arduino IDE链接&#xff1a;https://pan.baidu.com/s/1yk_tKH8eK8okp5z9qv1TLg 提取码&#xff1a;pz2h内含&#xff1a;IDE arduino-ide_nightly-20230322_Windows_64bit.zipSDK esp32_package_2.0.5_arduinocn.exe步骤1&#xff0c;IDE为绿色版&#xff0c;…

57、C语言程序设计谭浩强第五章习题

1、输入两个正整数m和n,求其最大公约数和最小公倍数 辗转相除法&#xff1a; #include <stdio.h>int main(){int m,n,temp;scanf("%d %d",&m,&n);if(m<n){tempm;mn;ntemp;}int dn*m;int r;while(rm%n){mn;nr;}printf("最大公因数为:%d&#…

ONES 入选北大光华 MBA 整合实践项目,推动校企合作

近日&#xff0c;ONES 旗下开源问答社区软件 Answer 入选北京大学光华管理学院 MBA 整合实践项目&#xff0c;并受邀出席项目启动会。同时入选的还有国电投清洁能源基金、京东零售、瑞尔集团、美国丹纳赫集团、大众汽车&#xff08;中国&#xff09;和贝壳找房六家国内外知名企…

队列----数据结构

队列&#x1f506;队列的概念&#x1f506;队列的结构&#x1f506;队列的实现&#x1f506;设计循环队列&#x1f506;循环队列的结构&#x1f506;循环队列的实现&#x1f506;结语&#x1f506;队列的概念 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端…

5G、工业4.0、车载以太网……TSN时间敏感网络能给我们带来哪些市场机会?

TSN是一项面向未来的新兴技术&#xff0c;它定义了以太网数据传输的时间敏感机制&#xff0c;为标准以太网增加了确定性和可靠性&#xff0c;以确保数据实时、确定和可靠地传输。这些扩展使得以太网能够应用于更加广泛的行业中&#xff0c;进而带来了更多新的市场机会。 1. 5G…

电力行业等保定级评级依据是什么?分为几个等级?

最近看到不少电力行业小伙伴在问&#xff0c;电力行业等保定级评级依据是什么&#xff1f;分为几个等级&#xff1f;今天我们小编就来给大家简单回答一下&#xff0c;仅供参考哦&#xff01; 电力行业等保定级评级依据是什么&#xff1f;分为几个等级&#xff1f; 【回答】&a…

【2023.3.18 美团校招】

文章目录1. 小美剪彩带2. 最多修改两个字符&#xff0c;生成字典序最小的回文串1. 小美剪彩带 题意&#xff1a;找出区间内不超过k种数字子数组的最大长度 使用双指针的方式&#xff0c;用哈希表来统计每个数出现次数。在双指针移动的过程中&#xff0c;动态的维护区间内不同数…

bean的作用域和生命周期和后置处理器以及作用域对生命周期的影响~

scope属性可以指定bean的作用范围&#xff1a; 在spring中可以通过配置bean标签的scope属性来指定bean的作用域范围&#xff0c;各取值含义参照表如下&#xff1a; 编写spring_test.xml文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> &…

Spring Quartz项目实现Job的动态控制

一、简单介绍 Quartz可以对job进行简单控制&#xff0c;但不支持分布式&#xff0c;也没有管理界面和任务分片&#xff0c;但使用起来比较简易。 二、创建简单Demo 我们开始简单使用一下&#xff0c;首先创建Demo&#xff0c;在pom文件中加入以下依赖。 <parent><g…

golang项目实战2023/03/21

初始化项目首先建立一个文件夹在文件夹下面建一个main.go文件执行初始化命令行go mod init page // page 为自己的项目名称 go mod tidy 安装框架 go get gorm.io/gorm // gorm go get gorm.io/driver/mysql // 这里是用的sql数据库 go get -u github.com/gin-gonic/gin // 这…

Numpy 广播域

NumPy广播(Broadcast)&#xff0c;广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式&#xff0c; 对数组的算术运算通常在相应的元素上进行。不同形状指的是&#xff0c;大小不同当然不是指的维度&#xff0c;但是要求数组各维度的长度相同例如&#xff1a;…

ICG-MAL,吲哚菁绿-马来酰亚胺,CAS:2143933-81-5,科研级别试剂

ICG-MAL,吲哚菁绿-马来酰亚胺 中文名称&#xff1a;吲哚菁绿-马来酰亚胺 英文名称&#xff1a;ICG-MAL 性状&#xff1a;粉末或固体 CAS&#xff1a;2143933-81-5 分子式&#xff1a;C51H56N4O6S 分子量&#xff1a;853.09 溶剂&#xff1a;溶于二氯甲烷等常规性有机溶…

【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(7)

目录 写在前面&#xff1a; 题目&#xff1a;P1596 [USACO10OCT]Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 解题思路&#xff1a; …

【技巧】十大深度学习技巧和经验总结

✅作者简介&#xff1a;在读博士&#xff0c;伪程序媛&#xff0c;人工智能领域学习者&#xff0c;深耕机器学习&#xff0c;交叉学科实践者&#xff0c;周更前沿文章解读&#xff0c;提供科研小工具&#xff0c;分享科研经验&#xff0c;欢迎交流&#xff01;&#x1f4cc;个人…

RocketMQ重复消费问题的原因

文章目录 概览消息发送异常时重复发送消费消息抛出异常消费者提交offset失败服务端持久化offset失败主从同步offset失败重平衡清理长时间消费的消息总结概览 消息发送异常时重复发送 首先,我们来瞅瞅RocketMQ发送消息和消费消息的基本原理。 如图,简单说一下上图中的概念: …

责任链设计模式的一次实践

业务需求 框架&#xff1a;SSH 需要对全部接口的响应体 ResponseBody 做 XSS 拦截 解决方案 在全局拦截器中检测 Response Body 是否有非法字符&#xff0c;如果有&#xff0c;就抛出异常。 实际上&#xff0c;在 struts2 的拦截器上&#xff0c;我发现 即使修改了 action…

yum安装docker以及安装指定版本docker

Docker是Docker.Inc公司开源的一个基于轻量级虚拟化技术的容器引擎项目,整个项目基于Go语言开发&#xff0c;并遵从Apache 2.0协议。通过分层镜像标准化和内核虚拟化技术&#xff0c;Docker使得应用开发者和运维工程师可以以统一的方式跨平台发布应用&#xff0c;并且以几乎没有…

在Java中,使用HttpUtils实现发送HTTP请求

HTTP请求&#xff0c;在日常开发中&#xff0c;还是比较常见的&#xff0c;今天给大家分享HttpUtils如何使用。 阅读本文&#xff0c;你将收获&#xff1a; 简单总结HTTP请求常用配置&#xff1b;JavaLib中HttpUtils如何使用&#xff1b;如何封装HTTP请求工具类。 第一部分&a…

【Unity入门】3D物体

【Unity入门】3D物体 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;物体移动旋转缩放 &#xff08;1&#xff09;物体移动 在上一篇文章【Unity入门】场景视图操作我们学会了在场景中创建3…

开源供应链管理系统 S2B2B2C系统方案及源码输出

连锁供应链的管理&#xff0c;包括供应链的仓库管理、业务员管理、门店订货管理、门店管理、门店前端拓客管理&#xff0c;相关的功能结构图如下&#xff1a; 整个方案含PC、小程序端&#xff0c;源码&#xff01; 功能列表&#xff1a; 仓库管理&#xff1a;包括仓库布局、库存…