Spring Boot 由浅入深 - 后端(电商项目)超详细 开发中...

1.项目介绍

传统的 电商 单体架构 基于SpringBoot的电商项目开发

使用技术框架: SpringBoot、SpringTask、Mybatis、Mybatis-Plus、Redis、WebSocket

2.职权明确

        管理员:店铺入驻审核、能对违规店铺进行禁用、管理员工信息、导出订单数据。

        员工:查看商品订单、配送商品、回复客户咨询,处理客户投诉,提供售后服务。

        店铺:上架商品、下架商品、查看店铺销售数据、选择开业或者停业

        用户:查看商品留下浏览记录、可以购买商品、添加购物车、将商品移除购物车、申请开店铺、关注店铺、收藏商品、投诉举报、创建订单、支付订单、查看订单状态、取消订单、退货。

        未登录用户:仅能浏览商品相关信息

3. 未登录用户模块

3.1 ProductController:(浏览商品信息)

@RestController
@RequestMapping("/product")
@RequiredArgsConstructor
public class ProductController {

    private final IProductService productService;

    //浏览商品
    @GetMapping("/browse")
    public R<ProductVO> browse(@RequestParam Long productId){
        ProductVO productVO = productService.browse(productId);
        return R.ok(productVO);
    }


}

 3.2 ProductServiceImpl:


@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    private final ProductMapper productMapper;

    private final BrowseRecordMapper browseRecordMapper;
    @Override
    public ProductVO browse(Long productId) {
        Long userId = ThreadLocalUtil.get();

        Product product = productMapper.selectById(productId);

        //如果已登录,则会在该账号添加相应的浏览记录
        if(userId != null){
            BrowseRecord browseRecord = new BrowseRecord();
            browseRecord.setUserId(userId);
            browseRecord.setProductId(productId);
            browseRecord.setLastViewTime(LocalDateTime.now());
            //添加浏览记录
            browseRecordMapper.save(browseRecord);
        }

        //返回商品信息
        return BeanUtil.copyProperties(product,ProductVO.class);
    }

}

4. 用户模块开发

4.1 用户基本的功能

(1)UserController:

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final IUserService userService;

    //登录
    @PostMapping("/login")
    public R<String> login(@RequestBody @Validated LoginDTO loginDTO){
        String token = userService.login(loginDTO);
        return R.ok(token);
    }

    //注册
    @PostMapping("/register")
    public R register(@RequestBody @Validated RegisterDTO registerDTO){
        userService.register(registerDTO);
        return R.ok();
    }

    //修改用户信息
    @PutMapping("/update")
    public R update(@RequestBody @Validated UserDTO userDTO){
        UserVO userVO = userService.updateInfo(userDTO);
        return R.ok(userVO);
    }

    //修改手机号码
    @PutMapping("/modifyPhone")
    public R modifyPhone(@RequestBody @Validated ModifyPhoneDTO modifyPhoneDTO){
        userService.modifyPhone(modifyPhoneDTO);
        return R.ok();
    }

    //获取用户信息
    @GetMapping("/info")
    public R<UserVO> info(){
        Long userId = ThreadLocalUtil.get();
        UserVO userVO = BeanUtil.copyProperties(userService.getById(userId),UserVO.class);
        return R.ok(userVO);
    }
    
}

(2)UserServiceImpl:

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements IUserService {

    private final UserMapper userMapper;

    private final RedisTemplate<String,Object> redisTemplate;

    @Override
    public String login(LoginDTO loginDTO) {
        String phone = loginDTO.getPhone();
        String password = loginDTO.getPassword();
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getPhone,phone));

        if(user != null && Md5Util.checkPassword(password,user.getPassword())){
            Map<String,Object> map = new HashMap<>();
            map.put("userId",user.getId());
            String token = JwtUtils.generateJwt(map);
            //设置token验证的有效时间
            redisTemplate.opsForValue().set(token,token,4, TimeUnit.HOURS);

            return token;
        }

        return null;
    }

    @Override
    public void register(RegisterDTO registerDTO) {

        String redisCode = (String)redisTemplate.opsForValue().get("sms:register:"+registerDTO.getPhone());
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getPhone,registerDTO.getPhone()));
        if(user==null && registerDTO.getCode().equals(redisCode)){
            User newUser = new User();
            newUser.setPhone(registerDTO.getPhone());
            //默认性别为男生
            newUser.setGender(0);

            LocalDateTime currentTime = LocalDateTime.now();
            newUser.setCreateTime(currentTime);
            newUser.setUpdateTime(currentTime);

            userMapper.insert(newUser);

        }
    }


    @Override
    public UserVO updateInfo(UserDTO userDTO) {

        Long userId = ThreadLocalUtil.get();

        User user = User.builder()
                        .id(userId)
                        .username(userDTO.getUsername())
                        .gender(userDTO.getGender())
                        .age(userDTO.getAge())
                        .address(userDTO.getAddress())
                        .email(userDTO.getEmail())
                        .avatar(userDTO.getAvatar()).build();

        userMapper.updateById(user);
        return BeanUtil.copyProperties(user,UserVO.class);
    }

    @Override
    public void modifyPhone(ModifyPhoneDTO modifyPhoneDTO) {
        Long userId = ThreadLocalUtil.get();
        String code  = modifyPhoneDTO.getCode();

        String oldPhone = userMapper.getPhoneById(userId);
        String redisCode = (String) redisTemplate.opsForValue().get("sms:modify_phone:"+ oldPhone);

        if(redisCode != null && redisCode.equals(code)){
            String newPhone = modifyPhoneDTO.getNewPhone();
            userMapper.update(new LambdaQueryWrapper<User>()
                .eq(User::getId,userId)
                .eq(User::getPhone,newPhone));
            
        }
    }
}

4.2 购买商品(购买单个商品)、收藏商品

(1)ProductController:

@RestController
@RequestMapping("/product")
@RequiredArgsConstructor
public class ProductController {

    private final IProductService productService;


    //直接购买
    @PostMapping("/purchase")
    public R purchase(@RequestBody ProductCountDTO productCountDTO){
        productService.purchase(productCountDTO);
        return R.ok();
    }

    //收藏商品
    @PostMapping("/favorite")
    public R favorite(@RequestParam Long productId){
        productService.favorite(productId);
        return R.ok();
    }

}

(2)ProductServiceImpl



@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    private final ShopMapper shopMapper;

    private final ProductMapper productMapper;

    private final OrderItemMapper orderItemMapper;

    private final OrderMapper orderMapper;

    private final UserMapper userMapper;
    
   
    @Override
    public void purchase(ProductPurchaseDTO productPurchaseDTO) {

        Product product = productMapper.selectById(productPurchaseDTO.getProductId());

        BigDecimal subtotal = product.getPrice().multiply(BigDecimal.valueOf(productPurchaseDTO.getCount()));

        //商品的库存减掉数量
        product.setStock(product.getStock() - 1);
        productMapper.updateById(product);

        OrderItem orderItem = OrderItem.builder()
                .price(product.getPrice())
                .count(productPurchaseDTO.getCount())
                .productId(product.getId())
                .subtotal(subtotal)
                .build();

        //添加订单中的单个商品
        orderItemMapper.insert(orderItem);

        List<OrderItem> list = new ArrayList<>();

        //将订单中的单个商品加入总订单中
        list.add(orderItem);

        Long userId = ThreadLocalUtil.get();

        Order order = Order.builder()
                .orderItems(list)
                .userId(userId)
                .status(OrderConstant.NOT_PAY)
                .updateTime(LocalDateTime.now())
                .createTime(LocalDateTime.now())
                .totalAmount(subtotal)
                .receiverName(productPurchaseDTO.getReceiverName())
                .receiverAddress(productPurchaseDTO.getReceiverAddress())
                .receiverPhone(productPurchaseDTO.getReceiverPhone())
                .build();

        //添加订单
        orderMapper.insert(order);

    }

    @Override
    public void favorite(Long productId) {
        Long userId = ThreadLocalUtil.get();

        User user = new User();
        user.setId(userId);
        user.setFavorite(user.getFavorite() != null ? user.getFavorite() : new ArrayList<>());
        user.getFavorite().add(productId);

        userMapper.updateById(user);
    }


}

4.3 申请开店铺、关注店铺

(1)ShopController:


@RestController
@RequestMapping("/shop")
@RequiredArgsConstructor
public class ShopController {

    private final IShopService shopService;

    //申请店铺
    @PostMapping("/applyShop")
    public R applyShop(@RequestBody ShopDTO shopDTO){
        shopService.applyShop(shopDTO);
        return R.ok();
    }



    //关注店铺
    @PostMapping("/follow")
    public R follow(@RequestParam Long shopId){
        shopService.follow(shopId);
        return R.ok();
    }

}

(2)ShopServiceImpl:


@Service
@RequiredArgsConstructor
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {

    private final ShopMapper shopMapper;

    private final UserMapper userMapper;



    @Override
    public void follow(Long shopId) {
        Long userId = ThreadLocalUtil.get();

        User user = userMapper.selectById(userId);
        user.setId(userId);
        user.setFollow(user.getFollow() != null ? user.getFollow() : new ArrayList<>());
        user.getFollow().add(shopId);

        userMapper.updateById(user);

        Shop shop = shopMapper.selectById(shopId);
        shopMapper.update(new LambdaUpdateWrapper<Shop>()
                .eq(Shop::getId,shopId)
                .set(Shop::getFansNumber,shop.getFansNumber()+1));

    }

    @Override
    public void applyShop(ShopDTO shopDTO) {
        Shop shop = BeanUtil.copyProperties(shopDTO,Shop.class);
        shop.setUserId(ThreadLocalUtil.get());
        shop.setStatus(ShopConstant.APPLY_SHOP);
        shop.setFansNumber(0);
        shopMapper.insert(shop);
    }

}

4.4 关注店铺、收藏商品

(1)UserController:

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final IUserService userService;


    //关注店铺
    @PostMapping("/follow")
    public R follow(@RequestParam Long shopId){
        userService.follow(shopId);
        return R.ok();
    }

    //收藏商品
    @PostMapping("/favorite")
    public R favorite(@RequestParam Long productId){
        userService.favorite(productId);
        return R.ok();
    }

}

(2)UserServiceImpl:

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements IUserService {

    private final ShopMapper shopMapper;

    private final UserMapper userMapper;


    @Override
    public void follow(Long shopId) {
        Long userId = ThreadLocalUtil.get();

        User user = userMapper.selectById(userId);
        user.setId(userId);
        user.setFollow(user.getFollow() != null ? user.getFollow() : new ArrayList<>());
        user.getFollow().add(shopId);

        userMapper.updateById(user);

        Shop shop = shopMapper.selectById(shopId);
        shopMapper.update(new LambdaUpdateWrapper<Shop>()
                .eq(Shop::getId,shopId)
                .set(Shop::getFansNumber,shop.getFansNumber()+1));

    }

    @Override
    public void favorite(Long productId) {
        Long userId = ThreadLocalUtil.get();

        User user = new User();
        user.setId(userId);
        user.setFavorite(user.getFavorite() != null ? user.getFavorite() : new ArrayList<>());
        user.getFavorite().add(productId);

        userMapper.updateById(user);
    }
}

4.6 添加购物车、将商品移除购物车(选择)、直接清空(从购物车中移除所有商品)、从购物车中进行购买(购买多个商品)

(1)CartController:


@RestController
@RequestMapping("/cart")
@RequiredArgsConstructor
public class CartController {

    private final ICartService cartService;

    //将商品加入购物车
    @PostMapping("/save")
    public R save(@RequestParam CartDTO cartDTO){
        cartService.saveCart(cartDTO);
        return R.ok();
    }

    //移除购物车
    @PostMapping("/remove")
    public R remove(@RequestParam List<Long> cartIds){
        cartService.removeFromCart(cartIds);
        return  R.ok();
    }

    //清空购物车
    @PostMapping("/clear")
    public R clear(@RequestParam Long userId){
        cartService.clear(userId);
        return  R.ok();
    }

    //购买
    @PostMapping("/buy")
    public R buy(@RequestParam List<Long> cartIds){
        cartService.buy(cartIds);
        return  R.ok();
    }

}

(2)CartServiceImpl:


@Service
@RequiredArgsConstructor
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {

    private final CartMapper cartMapper;

    private final OrderItemMapper orderItemMapper;

    private final OrderMapper orderMapper;

    private final ProductMapper productMapper;


    @Override
    public void clear(Long userId) {
        cartMapper.clear(userId);
    }

    @Override
    public void removeFromCart(List<Long> cartIds) {
        cartMapper.deleteBatchIds(cartIds);
    }

    @Override
    public void buy(CartBuyDTO cartBuyDTO) {

        List<Cart> carts = cartBuyDTO.getCarts();
        Long userId = ThreadLocalUtil.get();

        Order order = Order.builder()
                .receiverName(cartBuyDTO.getReceiverName())
                .receiverAddress(cartBuyDTO.getReceiverAddress())
                .receiverPhone(cartBuyDTO.getReceiverPhone())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .status(OrderConstant.NOT_PAY)
                .userId(userId)
                .build();

        List<OrderItem> orderItems = new ArrayList<>();
        carts.forEach(cart -> {

            Product product = productMapper.selectById(cart.getProductId());
            OrderItem orderItem = new OrderItem();
            orderItem.setCount(cart.getCount());
            orderItem.setPrice(product.getPrice());
            orderItem.setProductId(product.getId());
            orderItem.setSubtotal(product.getPrice().multiply(BigDecimal.valueOf(cart.getCount())));
            orderItemMapper.insert(orderItem);
            orderItems.add(orderItem);

        });
        order.setOrderItems(orderItems);

        orderMapper.insert(order);


    }

    @Override
    public void saveCart(CartDTO cartDTO) {
        Cart cart = BeanUtil.copyProperties(cartDTO,Cart.class);
        cartMapper.insert(cart);
    }
}

5. 员工权限模块开发

// 暂时没有开发员工模块

6.店铺权限模块的开发

6.1 上架商品、下架商品、更新商品信息

(1)ProductController:

@RestController
@RequestMapping("/product")
@RequiredArgsConstructor
public class ProductController {

    private final IProductService productService;

    //店铺上架商品
    @PostMapping("/save")
    public R save(@RequestBody ProductDTO productDTO){
        productService.saveProduct(productDTO);
        return R.ok();
    }

    //店铺下架商品
    @DeleteMapping("/remove")
    public R remove(@RequestParam List<Long> productIds){
        productService.removeProduct(productIds);
        return R.ok();
    }

    //店铺更新商品信息->同时更新订单对应的商品信息
    @PostMapping("/update")
    public R update(@RequestBody ProductDTO productDTO){
        productService.updateProductInfo(productDTO);
        return R.ok();
    }

}

(2)ProductServiceImpl:

6.2 改变营业状态(开业或停业)

(1)ShopController:

@RestController
@RequestMapping("/shop")
@RequiredArgsConstructor
public class ShopController {

    private final IShopService shopService;


    //对店铺进行停业和开业
    @PutMapping("/changeStatus")
    public R changeStatus(@RequestParam Long shopId){
        shopService.changeStatus(shopId);
        return R.ok();
    }

}

(2)ShopServiceImpl:

@Service
@RequiredArgsConstructor
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {

    private final ShopMapper shopMapper;

    @Override
    public void changeStatus(Long shopId) {
        shopMapper.changeStatus(shopId);
    }


}

(3)ShopMapper:

public interface ShopMapper extends BaseMapper<Shop> {

    void changeStatus(Long shopId);

}

(4)ShopMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.etc.shop.mapper.ShopMapper">

    <update id="changeStatus" parameterType="java.lang.Long">
        update shop
        <set>
            <if test="status == 1">status = 2</if>
            <if test="status == 2">status = 1</if>
        </set>
        <where>
            id = #{shopId}
        </where>
    </update>

</mapper>

6.3 导出店铺销售额数据

//导出数据功能暂时没有开发

(1)ReportController:

(2)ReportServiceImpl:

7. 管理员权限模块的开发

7.1 管理员工信息

(1)EmployeeController:

@RestController
@RequestMapping("/employee")
@RequiredArgsConstructor
public class EmployeeController {

    private final IEmployeeService employeeService;

    //员工登录
    @PostMapping("/login")
    public R<String> login(@RequestBody LoginDTO loginDTO){
        return R.ok(employeeService.login(loginDTO));
    }

    //新增员工
    @PostMapping("/save")
    public R save(@RequestBody EmployeeDTO employeeDTO){
        employeeService.saveEmployee(employeeDTO);
        return R.ok();
    }

    //删除员工
    @DeleteMapping("/remove")
    public R remove(@RequestParam Long employeeId){
        employeeService.removeById(employeeId);
        return R.ok();
    }

    //修改员工信息
    @PutMapping("/update")
    public R update(@RequestParam EmployeeDTO employeeDTO){
        employeeService.updateInfo(employeeDTO);
        return R.ok();
    }

}

(2)EmployeeServiceImpl:

@Service
@RequiredArgsConstructor
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {

    private final RedisTemplate<String,Object> redisTemplate;
    private final EmployeeMapper employeeMapper;
    @Override
    public void saveEmployee(EmployeeDTO employeeDTO) {
        Employee employee = BeanUtil.copyProperties(employeeDTO,Employee.class);
        employee.setEntryTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());
        employeeMapper.insert(employee);
    }

    @Override
    public void updateInfo(EmployeeDTO employeeDTO) {
        Employee employee = BeanUtil.copyProperties(employeeDTO,Employee.class);
        employee.setUpdateTime(LocalDateTime.now());
        employeeMapper.updateById(employee);
    }

    @Override
    public String login(LoginDTO loginDTO) {
        String phone = loginDTO.getPassword();
        String password = loginDTO.getPassword();
        Employee employee = employeeMapper.selectOne(new LambdaQueryWrapper<Employee>().eq(Employee::getPhone,phone));
        if(employee != null && Md5Util.checkPassword(password,employee.getPassword())){
            Map<String,Object> map = new HashMap<>();
            map.put("employId",employee.getId());
            String token = JwtUtils.generateJwt(map);

            redisTemplate.opsForValue().set(token,token,4, TimeUnit.HOURS);
            return token;
        }
        return null;
    }

}

7.2 对店铺进行审核、对违规的店铺进行禁用

(1)ShopController:

@RestController
@RequestMapping("/shop")
@RequiredArgsConstructor
public class ShopController {

    private final IShopService shopService;

    //审核通过入驻的店铺
    @PostMapping("/auditShop")
    public R auditShop(@RequestParam Long shopId){
        shopService.auditShop(shopId);
        return R.ok();
    }


    //对店铺进行禁用和解除禁用状态
    @PutMapping("/changeStatusByBan")
    public R changeStatusByBan(@RequestParam Long shopId){
        shopService.changeStatusByBan(shopId);
        return R.ok();
    }

}

(2)ShopServiceImpl:

@Service
@RequiredArgsConstructor
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {

    private final ShopMapper shopMapper;

    @Override
    public void changeStatusByBan(Long shopId) {
        shopMapper.changeStatusByBan(shopId);
    }

    @Override
    public void auditShop(Long shopId) {
        shopMapper.update(new LambdaUpdateWrapper<Shop>()
                .eq(Shop::getId,shopId)
                .set(Shop::getStatus,ShopConstant.OPEN_SHOP));
    }

    
}

7.3 导出订单数据

//导出数据功能暂时没有开发

(1)ReportController:

(2)ReportServiceImpl:

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
## 平台简介 可以用于所有的Web应用程序,如网站管理后台,网站会员心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。 诺寒基于hplus和inspinia两套后台系统模板开发。 http://www.zi-han.net/theme/hplus http://webapplayers.com/inspinia_admin-v2.7.1 ## 内置功能 1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现。 3. 岗位管理:配置系统用户所属担任职务。 4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 6. 字典管理:对系统经常使用的一些较为固定的数据进行维护。 7. 参数管理:对系统动态配置常用参数。 8. 通知公告:系统通知公告信息发布维护。 9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 10. 登录日志:系统登录日志记录查询包含登录异常。 11. 在线用户:当前系统活跃用户状态监控。 12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 14. 系统接口:根据业务代码自动生成相关的api接口文档。 15. 在线构建器:拖动表单元素生成相应的HTML代码。 16. 连接池监视:监视当期系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值