这次我们要去完成规格参数的显示代码。
可以看到规格参数,这里的前端代码是发送这样一条请求路径,加上商品的id,
可以看到下面它有个Data数据,我们可以找一下这个Data对应的是什么
最终找到了data的forEach,这个forEach是什么意思呢?这个是遍历的意思,它用在这里是解构表达式,我们可以看到这个红框里面的属性名是对应什么呢?
可以看到,它是对应数据库里面的部分属性的。data肯定是个集合,因为forEach是一个遍历对象,它里面的每个元素都在遍历,所以forEach肯定是个集合。
我们再来看看后台哪个模块截取了这个参数分类
但是看看下图中传入的是一个gid,浏览器是传入cid,那该怎么办呢?
本来下图这个方法只是传了gid这个参数,但是我们该如何传入cid这个参数呢?我们可以这样,直接在参数方法中加入其他参数,为什么可以这样做呢?加入其他参数不就等于要传入四个参数吗?其实不是的,在传入参数这一块,你写可以传入四个参数,但是我这边可以只传一个参数,假如我要传gid,你这边也只能接收到gid,而不会接收到其他的,为什么我们要传入四个参数呢?因为这四个参数对我们来说都有用,我们如果到时候需要用哪个功能,我们就传入哪个参数。最后我们还需要在Service方法里面传入这几个参数。
我们下面的这个方法是什么作用呢?我们下面的方法是根据商品的条件去查询他的规格参数,然而规格参数有很多,这四个参数就是它的规格参数。
Service里面的方法是一样的,你如果传入,它就接收,你如果不传入,它也不会做出反应,看你传入哪个参数,哪个方法就会去响应。
来测试一下,启动服务后,我们看看“新增商品”中的规格参数是什么变化,选择好一个商品分类为手机,然后选择品牌后。
第二步的时候直接选择下一步,然后到了第三步,可以看到,我们的参数发生了变化,像是型号,机身重量,机身材质工艺,操作系统这些只有手机这种商品才会有这种规格参数,我们输入商品分类的id,也就是cid后,它会在Mapper方法(我们之前写好的通过商品分类查询规格参数方法)传入cid或者其他参数,然后在Mapper里面调用方法查询数据库对应的规格参数并且进行返回。
我们来到第四步,填一下SKU属性,可以看到,我们先填两个机身颜色。
内存我们写两个参数上去,其他属性也差不多,就是写两个参数上去那种
可以看到我们最终生成的商品参数有这么多条,这是为什么呢?原来,我们的手机颜色,内存,容量,都是选了两个,那就是2乘2乘2的关系,也就是这里有三个组,每组两个,三个组之间互相匹配,得出来这个结果。
然后你可以去选择启用哪个组合。
我们最终就可以去保存商品信息。
但是却出现了保存失败。
看到浏览器这里,有两个请求,一个是跨域请求,为什么说他是跨域请求呢?可以看他的请求方式是OPTIONS,而不是GET或者POST。
另外一个才是真正的请求,为什么说他是真正的请求呢?因为他有一个POST,POST请求指的是你把一些数据发送到服务器,像这里新增商品,我们是把商品的规格,参数,信息等等发送到服务器。
但是方法我们还没写好,所以出现了错误。
而且你可以看到他传的是一个json对象,我们应该要用RequestBody来接收,而且是要用一个对象来接收。这句话是什么意思呢?也就是你后台要去接收这个json对象的时候,这个json对象是一个整体,你不能只接收单个参数,因为如果只接收当个参数的话,其他的规格参数你没办法接收到,所以我们只能用一个完整的对象去接收这一个完整的json。
可以看到我们要接收这个json对象,可以用spu进行接收,但是这个json对象里面有几个spu的pojo方法里面没有封装的对象,因此我们需要去进行一个扩展。
但是我们看到skus里面有个集合,这个又要怎么去接收它呢?
因此,我们需要加入这个sku对象。如果下次遇到同样的情况,也就是我们的pojo里面没有这种浏览器里面显示的json对象的集合的,我们可以自己进行创建一个对象
引入对象,这个注解选择上面的。
在数据库里面打开sku看一看,是对应这些字段
我们来看看这个库存字段,表里面根本就没有
库存字段只在库存表里面才会有。
所以这个注解的意思就是忽略这个字段的意思。
因为通过上面的步骤,我们已经把skus建好了,然后我们取的名字建议要和浏览器里面的名字是一样的。不然以后会接收不到。
我们要注意的是,这里还有个库存的字段,我们也要建立对应的类,去写入这个库存的pojo。而这个不需要写进spuBo里面,因为他在sku里面
然后我们去创建SkuMapper
库存的Mapper
然后我们不需要创建多一个Service,可以方便一点,直接在Goods的Service里面和controller里面进行编写。
如果我们要保存商品信息,该怎么保存呢?我们可以打开这个,然后找到保存商品对应的按钮。
可以看到,这里有个保存按钮。
我们可以去method去找找submit方法,
它会进行一个校验,校验不通过就执行上面的方法,校验通过就执行下面的方法。
最终提交请求在这个地方。如果是新增的话就是post,编辑的话就是put
这个就是请求参数,请求参数是什么呢?
这些就是请求参数。
如果我们点击了保存,最终并不需要返回什么结果,可以看到括号里面是空的,代表没有返回结果,我们只需要输出一个字段给用户看是否保存成功了就可以了。
可以看到它的路径是这个,因为item是我们在网关配的微服务路径名,所以我们不需要写进controller,所以只需要截取goods就可以了。
我们的controller方法如下,最后是返回一个已经build了的状态码,另外说明一下这是在Goodscontroller里面的。
再去编写Service里面的方法的时候,我们要清楚,我们要新增的表示哪几个表,首先spu的表肯定要新增的,也就是基本参数表。
别忘了这里还有spuDetail的表也是需要新增的。
所以spu_detail也是需要新增进去的。
sku也是需要添加进去,而且有两个组
而且还有一个库存信息
下面是sku表
这是库存信息表
总共就是新增这些表,但是新增这些表有没有先后顺序呢?如果先新增库存表的话,skuid从哪里来,对吧?
如果先新增sku表,那spuid从哪来,
而且spu_detail表也是需要spu_id,所以你需要先去新增spu表。
新增完后我们就有spu_id,然后就可以去新增spu_detail和sku表。
然后sku表也有sku_id了,然后就可以传给库存表
编写Service方法,Service方法在GoodsService里面进行编写,下面的Mapper方法能使用第一个就使用第一个,因为第一个效率更高,这种情况针对于插入数据到数据库的情况。
我们看看数据库,spu这张表,右边红框圈住的地方都是没有编写对应的参数方法,那我们该如何进行对他们的操作呢?
这里进行一个小插曲,我们要进行下面的设置:
为什么要设置为null呢?如果你不设置为null,别人可以通过专业软件,写和你一样的请求地址,同一样的请求方式,然后就可以随便上传一个文件上来,如果是上传病毒,那就有危险。
可以看到,数据库真的接收到了数据。
上面讲到数据表后面那几个属性名该怎么设置,我们可以自己去添加,首先Saleable是是否上架,我们选择true,setValid是是否可用,商品新增后肯定是上架了而且是可用的。然后创建时间是当前系统时间,其实更新时间有人也会用new Date,但是这里最好不要用,为什么呢?如果你去new两个Date,可能时间会有延迟,相差几毫秒,所以我们最好是用回刚刚new的时间。
我们来测试一下,点击保存
可以看到我们的数据,如果找不到路径的话可以先清空一下控制台信息,再点击保存商品信息
,对应的控制台信息就会出来了。
我们可以对比一下浏览器的值,还有数据库里面的,可以看到,除了spu_id这个值在浏览器上面没有之外,其他的都有。也就是说浏览器并没有把spu_id传进来,所以我们要自己在后台输入这个spu_id,然后传进数据库。
我们从spuBo那里拿到id,然后传进spu,可以看到spuBo是没有去设置它的id的,因为它传进了数据库里面的话,数据库会自动给它加上id,所以我们不需要给它加上id,但是可以把它的id拿过来赋值给Spu的id。
然后我们记得把spuDetail注入进来,然后我们要去新增sku,却发现没有sku的Mapper
顺便把库存的Mapper也加入进去,注意这两个都要加Autowired注解。
我们skuMapper的方法如下,但是有点要注意的是,我们传进来的东西不是一个参数这么简单,它是一个集合。
所以我们要一个个传入,那就需要遍历方法,我们可以用以下的遍历方法去传,传的sku进去的那个insertSelective方法是最终返回的方法,我们在上面要编写一个个数据怎么传进去的方法,可以对照数据库,需要传入哪些数据。
我们可以看到浏览器信息并没有传入spu_id,所以我们要自己去获取。
注意那个sku的id为什么设为null,上面也解释过,而且我们也不需要去设置它,因为它会自动生成。
然后我们还需要去修改这些数值就行,和上面修改Detail方法一样,但是我们不是有其他参数吗?为什么不传进来了?首先说明一下,spuBo是spu的扩展类,它包括了一切接收新增商品参数的封装方法,包括sku的,所以用户输入的数据在传入到controller被输入到spuBo里面,我们就可以通过spuBo拿到sku数据,这时候的sku就已经有了浏览器传给它的基本数据了,但是它还有一些数据没有,就是spu的id,创建时间,还有最后一次更新时间,这些数据却是数据库所需要的数据,所以我们需要手动在后端方法中去设置它,就行了,它原来的sku就已经包含了用户输入给它的数据,我们只是再添加几个属性而已,最终传入到sku。为什么要写成遍历的方式呢?因为你可以看看上面浏览器的图,上面写着sku不止一个数组,有第0组和第1组,每个组我们都需要去增加刚刚说的那些数据库的额外属性,所以我们需要用到遍历的方法。这里要说明一下下面的sku的含义,下面的sku代表的是每一个spuBo.getSkus()的元素,spuBo.getSkus()是什么呢?它代表的是sku的全部列表(如下面图中的第二张图所示),全部sku被传进去了,我们就取每一个sku元素出来,然后进行增加属性
还有stock呢?该怎么写,我们对照数据库的表发现它需要这几个参数。可以看到我们需要加入两个字段,一个是id,一个是stock。
这是我们需要加入的,id和Stock,为什么在sku里面拿Stock呢?我们可以看看浏览器,它在里面是传了一个Stock
可以看到是传了一个Stock
最后有没有发现一个问题,就是如果新增这些东西的过程中出现了问题怎么办,如果出现了问题,会出现一堆的垃圾信息,那我们数据库就会崩溃,所以我们需要添加事务,如果出错了,事务会帮助我们进行回滚。
重新启动一下微服务后,我们试试点击保存
数据也有了
其他表就不一一展示了。