这是一个SpringBoot+MyBatis项目,纯后端操作。主要练习SQL语句的编写,少量的业务处理。如果时间充足,一般两三天可以完成,项目最后提交于2022-01-19。

一些说明

  1. SpringBoot项目,前端不需要改动,只写接口就行,使用MyBatis,所以基本都在写sql。
    2. 难点:商品类别-无限层级(递归实现,更好的方法是使用算法而非递归)。
    3. 写了二十来个接口才发现有很多可复用代码和接口,比如查询范围小的时候,可先查总数,在java端处理数据。
    4. 参数问题,controller无脑写就行,不用加那么多注解。ServiceImpl层有很多参数可以在这里组装,比如操作两张表时,先插入第一张表,获取自增主键,放到第二张表的实体类,然后再传到Dao层。多表操作一定加事务!
    5. 能使用join就别用子查询,最好join也别用,查两次去java组装。例如两表关联查询。
    6. 前端生成的订单号,其实已经封装到实体类中了,不必多传这个参数。
    7. new JSONObject().toJSONString:【实体类 << — >> String 】 parseArray(String, T.class)

项目启动

启动问题

可能是idea2021的问题

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-maven-plugin</artifactId>
  6. </plugin>
  7. </plugins>
  8. <resources>
  9. <resource>
  10. <directory>src/main/webapp</directory>
  11. <targetPath>META-INF/resources</targetPath>
  12. <includes>
  13. <include>**/**</include>
  14. </includes>
  15. </resource>
  16. </resources>
  17. </build>

跳过登录

1. 跳过验证码
UserServiceImpl中注释“校验图片验证码是否正确”的代码

2. 自动登录
Login.html设置value=”a”
页面加载即调用login();

3. 修改权限
如果要自己新增用户,给用户分配权限需要操作user_role表。

一、首页库存查询

  1. 驼峰命名(配置了才能使用autoMapping),分页插件(开启,查询,调用),join,模糊查询,List改数据注意覆盖问题。(可以break,获取把覆盖语句放后面)

    二、基础资料模块

    供货商管理

  2. 拿不到参数记得使用@Param注解,即使是一个参数的情况下。
    2. 实体类和其他参数一起传,出错了,这边封装到了一个实体类,其他方式暂时没测。
    3. 批量删除,前端传的String类型,使用split转换成String(当然也可以是List或者Map),使用foreach删除(也可以在实现类循环删除,记得加事务),
    ForEach写法如下,
    void delSupplier(String[] ids);
    
    可以看出来,接口上的参数名任意,因为在xml里面没有使用
    <foreach collection="array" item="supplier_id" open="(" close=")" separator=",">
     #{supplier_id}
    </foreach>
    

客户管理

  1. 刚打开页面时不会加载数据,是前端的问题,它没有传值。
    customer.js首行,自己传一个空值也行,当然还有很多方案。
    $(document).ready(function() {
       $('#dg').datagrid('load',{
          customerName: ""
    });
    });
    

商品管理

1. 无限分类(难点),Lambad+List+map的应用: b站搜谷粒学院,第45集10分钟开始,雷神带你10分钟搞懂无限分类。
https://www.bilibili.com/video/BV1np4y1C7Yf?p=45
2. 3.3查询所有商品信息,分类查询有bug,(根据分类查询)
3. 有些字段没有设置自增,并且前端也没有传值。比如说商品编号,可以在数据库查出当前最大在java上手动加一,”00” + (Integer.valueOf(goodsCode) + 1)。这里String类型的sql也可以使用max获取,暂时不知道是否有bug。
4. 3.6前端传的数据不全,比如state(状态)和inventory_quantity(库存数)
5. 3.7的删除直接sql判断,条件加一个state = 0;

三、库存管理

报损单保存

字符数组转对象

前端传的数据是[{}]格式的字符串,我们先把它转对象数组,然后取下标0;(这里错了,前端可能选则的是多个单子,所以要遍历插入,或者使用forEach)
insert返回的自增主键,Mybatis自动给我们封装到了传参的类中,而dao方法返回的是影响的行数

DamageListGoods[] damageListGoods = new Gson().fromJson(string, DamageListGoods[].class);

数据库存的日期是varchar,sql中使用DATE_FORMAT(date,’%Y-%m-%d’)格式化一下再比较,注意日期范围。
user应该从请求中获取,项目中是写死的。
这里获取的是DamageListGoods[ ],所以应该循环插入,或者批量,要加事务。

四、进货管理

进货单保存

  1. 进货单的两张表有外键关联,要开事务,获取id再添加第二个表。
    2. 获取id的坑:int res = Dao.xxx(),这里res获取的是语句是否执行成功,成功返回1。而要获取生成的主键需要调用实体类的get方法。
    3. 这里还需要更新goods表的库存,在数据库更新,字段=字段 + #{}。
    4. 退货同理

    进货单查询

    新增t_purchase_list时,没有保存user_id,导致数据查出来不全,
    新增t_purchase_list_goods时,没有保存purchase_list_id,导致数据没有。

    进货单删除

    删除时可以在mybatis操作。

    退货单删除

    退货时,如果一个单号有两件商品,而其中一件商品其他单子 也有,需要先删一个单子的,暂未处理。

    五、销售管理

    5.2.2退货

    出退货要减库存,这里没有做。

    六、供应商统计

    6.2支付结算

  2. 项目中只更换结算,直接赋固定值就行,如果需要取消,可以取反。
    2. 付款状态需要排序输出,在查询时就要做!order by state desc。
    3. 时间查询table.date between #{sTime} and #{eTime}

    6.3.1 采购统计

    这里需要查四张表,写一个实体类,取出来数据发现前端要的字段有变换,又使用HashMap装了。。。

    6.3.2 销售统计

    同采购统计,只是变动一下表,和字段。
    做steam做map映射时要注意.var收集数据,之前的没有收集,全部被覆盖了,数据只有一条。

6.4 统计分析

没有实体类可以使用map接收数据,如果只查一条直接用map,多条使用List,接口上使用注解@MapKey(id),指定一个不重复的字段做key就行。
使用steam做映射时,一定要注意new HashMap的位置,写在流外面将覆盖数据。

6.5 使用steam合并List中的数据

根据map中的某个key相同则把其他的相加。

  /**
     *
     *  将date作为去重复条件进行合并,
     *   setSaleTotal,getPurchasingTotal,setProfit 相加
     *  合并后的集合使用Java8的流进行处理输出
     *
     * @param pCount
     * @return
     */
    private List<SaleDataByMonth> merge(List<SaleDataByMonth> pCount) {
        Map<String, SaleDataByMonth> map = new HashMap<>();
        pCount.stream()
                .forEach(saleData -> {
                    SaleDataByMonth last = map.get(saleData.getDate());
                    if (null != last) {
                        saleData.setSaleTotal(saleData.getSaleTotal() + last.getSaleTotal());
                        saleData.setPurchasingTotal(saleData.getPurchasingTotal() + last.getPurchasingTotal());
                        saleData.setProfit(saleData.getSaleTotal() + last.getPurchasingTotal());
                        map.put(saleData.getDate(), saleData);
                    } else {
                        map.put(saleData.getDate(), saleData);
                    }
                });
        return map.values().stream().collect(Collectors.toList());
    }

七、总结

此项目主要练习MyBatis的使用,时间仓促,逻辑粗糙。存在许多问题,如代码冗余,重复写接口,进出货需要变动库存量,没有正确使用项目的返回工具类等问题。