00:01
前面呢,我们编写了领取采购单的功能,那如果我们这个采购人员通过他的这个手机应用,他领取了采购单,那领取完了以后呢,接下来他就可以去完成这个采购单,当采购完成以后,他来点击完成我们这个采购单就完成了,那完成以后呢,我们采购单里边所有的这些需求,某一个东西,哪个仓库里边采购几个数量。那这就确认了,最终这些数量呢,就要加到库存里边去,那么接下来就来写这个完成采购功能,这个完成采购功能呢,只要一完成,它会发送这个请求,首先ID是我们采购单的ID。然后呢,我们采购单里边每一个采购项,因为我们最终采购完成的这个页面可能是这样子,我们这儿有一个页面,这画了一个采购单,我们当前采购单这里边有十个采购项,哪些都完成了,你这在这儿勾中勾中点一个确认,那我们采购单里边这些就完成了,而且没完成的,你要指定没完成的原因。
01:02
所以我们在这儿提交了相当于每一个采购项的状态。你勾上了,那就是采购完成了,以及没勾上,你还要提交这些原因等等,那这呢就算是一个完整的采购完成,那接下来编写这个功能,好我们先来postman里边来准备模拟这个功能,这个功能呢就是来模拟我们采购人员在他手机上确认我完成我们这个采购单,好我们把这个改成post,同样还是要发送我们这个JS post类型JS数据,那这个数据呢,首先确保有一个ID,这个ID呢是采购单的ID,我们刚才领了一个三号三号采购单,接下来还有一个我们这个item,那么这一块数据的类型,这是一个对象,好来写上一个对象ID,我们三号的采购单,还有一个item,四我们所有的采购,象所有采购项呢,有很多我们这个三号采购单啊,现在有两个采购项。
02:02
那我们这两个采购项呢,那都采购完成,那我们就相当于入库成功了,我们来看一下这两个采购项。这两个采购项呢,分别是四号、五号采购项,那么在这要提交的数据就是item ID status以及reason,每一个采购项呢,都要提交这几个数据,那它是四,那如果采购项完成了我们在这提交的这个状态,那就是已完成,已完成在我们页面里边采购项,我们采购需求来看一下,那就是0123,那就是三号状态,我们在这来写一个三号状态。包括reason,我们这个确认的这个原因,那已完成,那就可以不用写原因了,如果未完成,我们CTRLC我来复制到这,比如五号,它如果是未完成,那它的状态就应该是四啊原因,比如我们写一个无货,那么最终就是想要发送这个请求的,来,我们先来编写我们这个请求。
03:01
来到我们这个purchase controller里边,那现在来这有一个领取采购单,那们再来写一个叫,那么这个完成采购单,我们就叫finish,好,我们这个接口的这个路径,我们来从接口文档里面复制过来,就叫到好。我把这个路径呢,复制来啊,然后呢,我们这个数据,这个数据呢,我们还是来写一个VO,我们来收集这个数据。我们把这个VO们专门来写上一个包,之前这个VO呢,没放在我们指定的包里边,好,我点一个确定,我们再来写一个VO,我们这个VO就叫purchase,我们的finish VO我们就叫到VO,那么这个VO里边呢,需要两个数据,第一个数据是ID,我们采购单的ID private long类型的ID采购单ID,但我们要开启GSR303数据校验,比如它必须是not not不为空的等等,好,然后呢,再来写上一个。
04:06
我们所有的采购项数据,我这写一个list,但采购项里边呢,由于它是一个比较复杂的操作,所以我们在这需要再来写一个VO,封装我们这个历史的数据,就就叫item VO。这个purchase。Item到VO这个完成的这个VO,它里边呢,主要有这三个数据,我们来看一下,按照接口文档,我们要封装VO的话呢,我们需要item ID status以及。好,我们先来写第一个private long类型的item ID,这是采购项的ID和private,我们这个integer类型的,我们这个status,这是是否完成了,还有我们这个private string类型的reason,我们的这个原因。
05:05
接下来我们这个down VO里边就应该有一个list类型的,List类型的我们这个采购项purchase item down VO。那这个采购项整个它叫it复制一下,好,我们把这个VO就写好了,来到我们的controlrler,我们要收到这个请求,数据就长这样,是一个purchase down VO。我们就叫等位,那我们希望有一个project方法,我们就叫到,然后呢,它能完成我们这个采购需求,好来创建这个方法,那再来添加上它的实现,那么这个采购需求完成呢,首先第一个要做的操作就是改变我们这个采购单状态,接下来第二个就是改变采购单里边每一个采购项的状态,改变我们采购项的状态,然后第三个操作就是真的这些采购成功了,将成功的采购进行入库,将成功采购的进行入库,入库其实就给是给我们这个库存里边。
06:15
加上它相应的数量就行了,那么先来改变采购单的状态,那我们是哪个采购单呢?来看一下这个ID就是我们采购单的ID,我们这个采购单的ID呢,它最终是一个浪类型的数据,我们可以查出这个采购单的详情,然后按照ID去来更新它就行了,当这个直接更新我们可以不用查,但在这一块最复杂的操作就是采购单的状态不是完成一,它要根据采购项的状态走,如果我们所有的采购项都是成功做完的,那我们采购单的状态就是已完成,如果有一个采购项是失败的,那就采购单的状态,状态就是有异常,就像我们前端页面这一块状态呢,有一个采购单,这有一个状态叫有异常,那我们就来写一下,所以我们首先得遍历所有的采购项,点一个get items,那这个便利呢,我就用咱们正常的这个for each便利,点一个for each,我们用。
07:15
这个增强方,那在这便历的时候呢,我来分离出所有成功的采购项和不成功的采购项,包括呢,只要有人不成功了,我们就应该有一个标志位,比如我们这个Bo,我们这儿有一个flag,等于默认呢,它是处的,有一个人没有采购成功,我们就把它变成force,在这判断一下if,如果item里边点一个get letters,他这个状态呢,现在就等于我们这个采购项不成功,点一个purchase detail给它里边有一个不成功的状态叫采购失败,点get code,如果它是这个四号状态,说明它是失败了,失败的话呢,我们这个flag就应该等于false。
08:03
那否则的话就是我们这个都采购成功了,采购成功直接改它这个状态就行了,而且采购失败呢,还要添加失败的原因,但是我们在数据库设计的时候,那这张表里边缺少了采购失败的这个原因,所以我们后来大家都可以将这些进行完善,包括如果要来做细化,我们这个采购失败啊,不止是全量失败,有些有可能是十个货,我现在只采购进来了八个货,所以我们这一块的数量还应该有一个应采购数量十,实际采购数量八,我们现在的状态是未采购成功,包括它的原因等等,那我们就不设计这么复杂了,后来大家想要设计复杂,自己去来完善就行了,把这个核心功能有知道好,我们现在就来改变这些状态,那现在留给我们的就是只需要收集他们的这些状态就行了,行,我们专门来写一个新的这个list,把这个状态呢,我来收集一下,我们这些都是需要进行更新的,这些有一个a list。
09:02
我们把这个update里边,我来点一个and and一个什么呢?我现在来new一个purchase当VO,当然我不能拗这个VO。我应该new一个purchase,我们需要修改采购项的,那就是detail的这个实体类们new一个它,我们给它里边添加这个好来创建出它,那这个里边的这个数据我们来准备好,他点一个set status,首先它的这个状态如果失败了,那就应该是失败状态,我们先把这个放到上边,那失败了的失败状态我们来给它放到这,他的这个状态呢,那就应该是它点一个purchase detail.get code失败,那其实如果是不是失败了,拿这个status的值,那都是一样的,好,直接拿来进行失败判断,那如果是成功了,Else,那它的这个状态呢,我们就来重新设置,它就应该是点set status where constant,点一个purchase detail里边的这个成功已完成,点一个get cold,或者直接把它这个status拿到,这都。
10:15
是一样的,接下来呢,就是我们这个采购单的ID set ID,这是我们采购需求的ID,那么这个YVO呢,就是从它里边能拿到我们这个需求的ID,然后我们最终要更新它,我们将所有要更新的放进去,那最后来一个批量更新,好把这删除掉,然后我们在这来一个批量更新,使用我们这个detail service,点一个update be8id,我们是按照逐键更的们,这都是我们批量要更新的数据,那采购项更新完了,接下来是我们这个采购单,那采购单的这个状态改变必须是判断,我们如果是失败了,那就改失败,成功就改成功。我们使用this点一个UPDATE8ID,我们按照ID直接来改我们采购单的状态,有一个purchase实体类,这有一个entity,啊采购单呢,我们就设置两个东西,首先第一个点set它的ID,我们当前要改的采购单的ID就在这。
11:19
还有我们这个采购单的状态,Purchase entity.set status,它的这个状态要看我们这一块,如果这个flag是true,那我们就应该是采购完成点purchase status点一个,这有一个已完成点get cold,否则那我们就应该是它的这个有异常点一个,我们有一个点汉字error.get code。好,我们把它这个状态整完以后,包括我们来也给它设置上修改时间,这有个update time new,一个date,然后我们将这个进行更新,那更新完了以后,接下来我们要将所有成功采购的这些采购单要进行入库操作,所以我们呢,就在这,如果有人在这儿else进行采购成功了,我们除了改它的状态,我们还要将它进行入库,那这个入库呢,就需要用到库存的这个service,这叫v SKU service。
12:29
V squ v s ku service,我们就叫v SQ service,这个service呢,我们希望有一个方法,就是给某一个商品的ID来加上库存,我们来到我们这儿,我们看一下我们的方法呢,是在这儿改变采购项状态,来我们这个大好采购项,我们要进行入库,那这个入库呢,主要是这样子的,每一个商品啊,它有当前商品给哪个仓库入几个。
13:01
因为我们可能三个仓库都有这个商品,所以呢,我们至少需要三个参数,第一个参数是SQ的ID,第二个是当前仓库的ID,第三个是我们要入几个的ID,好,那现在呢,就来写一个方法,我们就叫andto,我们添加库存,添加库存呢我来传递三个参数,第一个参数是当前采购的商品的ID,我们从item里边我们可以拿到这个采购项。这是我们采购项的ID,但是我们怎么知道采购项的这个详细信息,你需要在data里边查出当前采购项,它有真正的SQID,还要采购几个,到哪个仓库,所以呢,我们现在要进行入库之前,还要先查出我们这个采购项。我们使用data service。点一个get,把ID方法,我们按照我们当前采购项的这个ID,我们把它点一个get item ID,我们查出当前采购项的详细信息。
14:07
我们这就叫entity,然后呢,它里边有我们要用的数据,第一个就是我们要把哪个商品,这是这个SKU的I和第二个我们要放到哪个仓库,这是where的ID和第三个点,我们要给它添加几个数量,这是有一个number,好,我们呢就希望有这么一个方法,那现在没有这个方法,我们就创建出来。然后呢,我们来添加上它的这个实现,那这个实现呢,我们希望写一个自定义的方法,那么就来this.base member,那就这就是我们YSQ的这个member,我们也可以直接自动注入它,或者用这个base,这都是一样的,来点一个autowa,好我们直接用它吧,好它点一个我们希望呢有一个方法叫andto,它呢传递这三个参数s qidd和我们仓库的ID和我们这个SQ的number,好们来添加上这个实现,当然这个方法呢,想要用实现我们就得在MY贝的这个文件里边配置上,那么在这可以有一个叫这new,一个statement,但new之前这还应该有一个叫生成PAR,我们说多个参数一定要为每一个参数指定PAR来在这一生成好,现在指定好。
15:38
以后我们再在这来直接生成我们。那我们这个statement里边,我们就应该是一个更新操作,我来写一个update。因为这个加库存啊,其实就是在这将我们原来的库存update update update哪张表呢,我们这个we SQ这张表,然后呢,Set set什么set,我们的这个最新的这个库存,库存这有一个叫to set,我们to。
16:13
等于我们这个to加上我们传过来的值,这是它的原库存,再加上我们的新址,Where s q ID等于指定的值,并且。VID等于我们指定的值。这是我们来更新库存,但是前提是如果我们要整的这个商品,入库的这个商品在这从来都没有库存,那这其实就是一个新增操作,所以我们这个方法得进行一个判断,我们先把这个修改库存拿来好,我们把这个修改库存呢放到这儿。我们要添加的这个是井号大括号,我们这有一个SQ number,这是我们这个方法里边我们要加入的新库存,然后呢,SQID直接井号大括号SQID,还有我们这有一个VID,我们是井号大括号,我们的仓库ID这都有。
17:13
这是我们添加库存的方法,当我们说如果说默认一开始还没有这个的话,所以我们在这得检查判断,如果还没有这个库存记录记录,那就是新增操作,新增如果有了,我们才是在这更新,所以我们先来进行查询v SK do.select我们进行查询list,比如我们来按照corrywaer,我们来查询我们这个条件,我们查询什么呢?我们的VRSQVRSQNT,我们是按照这个条件,哪个条件我们这有一个叫。商品的ID和仓库的ID,如果商品的ID等于我们指定的这个值,而且仓库的ID也等于我们指定的这个值,这个仓库没有这个商品的之前的这个库存信息,那我们就应该给他做一个新增操作啊,这。
18:18
我们最终会查出一个这么一个集合或者单挑记录,我们不管怎么着,我们先得判断,如果说这个集合点size是。等等零的,那前提就是如果它直接是空的,它等等,那或者它是等等零的,如果是空的,那我们就应该是一个添加,否则呢才是一个更新库存,那么这个添加呢,我们直接调用这个insert方法给它进行保存,保存呢我们就来创建一个这个SQ的n VR SQ nity。这ND里边呢,就有默认的我们这几个值,好,我把这个库存记录这儿呢,创建一条新的库存记录,库存记录的这几个值,我们设置上SQ的ID是我们指定的,包括SQn.set它的这个库存也是我们现在要加入的这个数量,包括SQN t.set它的这个仓库ID也是我们这个指定的。
19:29
那么这个添加库存就写好了,这个添加库存写好以后,我们整个的这个功能就写好了,当然他也应该是一个事物trans的。那这个事物要完成,我们一定要开事物注解,我们在这也开了,而且呢,我们看到之前这整个这个封页查询,这封页也有问题,说分页有问题,这是要做my beat蒂的配置,My beat斯得配分页插件做以我们config my beat的config,我们自己来写一个我们的这个MY贝configig,这是where这个config呢来主要以后跟数据库有关的配置,我们都配在这个config里边,我从主配置类里边将这两个拿过来,我呢放到这儿。
20:15
好,然后呢,我们来主要配一个马贝斯的分页插件,我们之前在product里边配过这个分页插件,我就直接复制过来就行了,在config里边,好,我们将这个分页插件呢引进来,CTRLC。我们直接放到我们这里边儿。这些呢,默认值想设置了设置,不想设置也可以注掉这一块,全部设置完,我们这个修改,并且这是一个事物,我们这个接收就完成了,来直接return。来看一下你现在controller来接收这个数据来进行完成,那么在这呢,来模拟请求,来模拟这一块,我们将数据格式写对,那既然是杰森,我们就来写一个正确的杰森语法格式啊。
21:00
这块也一样。我们现在呢,就是有一个是完成的,我们四号是完成的,而我们的这个五号是没有完成的。这些呢,都来写好。好,然后呢,我们来先来看一下我们这个页面,我们这个采购需求。我们新查出的这个采购需求呢,现在正式正在采购中,我们这个采购账单呢,现在是已经被领取了,领取呢正在采购,那采购完了就会有已完成或者有异常的状态,所以接下来我们来给他完成采购来模拟假设这是我们采购人员的好,这有一个叫完成采购。好,我们来选中我们这个现在是采购人员这个APP和模拟在这,好我们现在呢,假设模拟这个请求我们点一个send。
22:01
在这呢已经200了,那说明我们这个请求执行成功了,执行成功我们来看我们的这个采购单,采购单呢,说有一常我们这个采购需求,这有一个是已完成,有一个是采购失败,那已完成的这个采购数量就应该加上去,来到我们商品库存里边,那我们三号商品是SQID是一的,我们这就是110,我们来看一下我们采购需求里边这个采购单就是采购一号商品的,好我们可以新建几个采购单,比如我们现在来看商品系统里边。那么现在商品里边呢,我们为好多商品,我们都来建几个采购单,二号,四号,五号,那现在来建几个采购需求,那么新增一个采购需求采购的商品,二号我想采购十个,我们来就放到一号仓库确认这是第一个采购需求,然后呢,三号我想要采购15个,我也放到二一号仓库。
23:00
包括呢四号。我想要采购五个,我也放到这个一号仓库确认。那么这个采购需求呢,准备好了,然后我们来分配,我们将这三个呢,都分配到一个采购单上,我们这儿有一个合并整单,让他呢自己创建一个采购单,我点一个确定好,我们点一个确定,那现在创建了四号采购单,那在四号采购单里边呢,我们可可以为这个采购单来分配一个采购人员就来分配成din。那admin分配完了以后呢,Admin就可以来接收他的这个采购单。我们来到这个postman里边来领取一个采购单,好来假设领取这个四号采购单,这个是采购单,来点一个send,好,我们领取成功了,CTRLS,我们把这个请求保存一下,领取成功以后呢,我们现在来看我们这个请求点一个查询,现在已经被领取了,而且这个采购需求呢。234这三个的商品都是正在采购中,而且商品的这些库存,你现在发现只有三号是110,那我们现在给他采购完成采购单,我们采购单里边有一个四号采购单,我们去来完成它,但要完成这个采购单,采购单的状态大家都得先检查一下,好,我们现在来完成我们这个采购单,完成采购。
24:22
我们现在来完成四号采购单,那四号采购单里边呢,由我们这几个采购需求分别是678,我们假设呢,都给它做完,那我们现在就来六。七包括还有一个八。那都做完了,那就是三号状态好,我点一个send。好,我们现在这个完成了,来看页面。我来先看采购单,采购单呢现在已完成了,而采购需求里边这三个状态也已经完了,那现在看商品库存,我们就看到二号三号十实物,这就有了SK4号的好五个没问题,那如果我们刚才买了一个一号的SK,那他已经有东西了,那他就应该是给库存上给他一个进行叠加数量。而我们现在二三。
25:19
四这三个人他没有库存,那他是新增了一个库存信息。当然新增库存的时候,大家也可以将商品的这个名字也查出来,进行冗余保存,包括新增库存的时候,只要默认的锁定库存,我们也都给他写一个零,我们来改变一下。在这完成采购单,我们在这新增库存给他进行入库的时候,And sto的时候,我们在这就算要新增,我们来给它设置上一些默认,比如默认锁定的库存是零,包括呢,大家也可以在这来set SQ的name,在这呢,大家只需要来远程来查询SQ的咱们这个名字,给这一设置就行了。
26:05
把这个方法呢,就来写成一个todo。那么真的想要做它,我就来得写这个远程接口,那在这来写一个份。粪包,好,我们来写上吧,这直接来在分包里边,那创建一个商品的这个远程接口pro duck份service,我们希望呢,有一个远程接口能帮我们来查询相关的信息,好,我们一定要写一个叫FA client,我们要调用哪个远程服务,在这要写上远程服务的名字,而且呢,我们这个份功能能能要用我们在where这个库存系统里边,我们一定要开启叫enable phone cleans,好,我们在这可以来写上phone的接口都在哪个包,那我们写在主配置类上了,就不用配置那个。我们现在来写上第一个功能,假设呢,就是来远程获取我们某一个SQ的信息,好我们远程呢,我们来看product product product这里边呢,其实远程已经有这个方法了,在SQ的controller里边,那直接有一个英符SQID你传过来我就给你返回SQ信息的,好我直接复制过来,来到我们这个,我们把它一粘贴,我们说最快的办法就是复制粘贴好,我们远程接口是这个,然后呢,我们要调的这个远程服务,来我们的这个是product SQ英符把它复制来放到这。
27:37
相当于我们给这来发请求,而且呢,大家注意我们在这其实请求能写两个,这个请求路径,第一个请求路径就是我们写product SQ info,大家现在在这儿试想一下啊,我写这个跟我写这个有什么不同?他们唯一的不同就是当我们写了这个请求,他会去找到鼓励mail商品服务,然后呢,给商品服务去来发送我们这个请求,给商品服务所在的机器来发送我们的这个请求,不带API的,但如果我们写了API,我们就可以把这改成这样,我们直接给网关发请求,所以呢,我们的这个份service啊,可以有两种写法,第一个我们将所有的请求都让它过一下网关,要让所有请求过网关,我们的写法就应该是这样,首先第一个分就必须指定是给网关,它的意思就是给网关所在的机器,给他所在的机器发请求,给他所在的机器发请求,然后呢,第二个你要配置好我们这个请求路径,就是我们在这request mapping的这个路径,你给带上API。
28:57
这样呢,我们就相当于来到网关了,那我们不想过网关直接给我们后台服务发请求,那么就可以在这儿直接来写啊,我们这是第二种,直接让后台指定服务处理,那我们在这分client的写法就应该是我们直接来指定我们的后台服务,那么后台服务呢是product。
29:22
所以这两种写法呀都行,然后呢,接下来我们的请求路径,由于给后台服务发,我们不过网关,我们也不用带API,而且过网关它会截API,我们现在就过来,我们就应该是这样,给后台服务发,我们直接不应该带API发过来就行了。这样我们在这来进行测试的时候啊,我们在这添加库存的时候,我们在这呢,就可以来远程查询,我们就可以拿到这个远程的接口product份service,我们就叫product份service,那商品服务的远程调用接口,好,我拿到这个接口,我们就可以查SQ的信息。
30:04
它直接有一个方法叫info,把SQ的ID拿过来进行一个查询,而且这个查询它得成功,那R点一个get code。如果我们查的这个接口是一个成功的get code等等零,那说明它就成功了,成功了以后呢,我们就来给他设置我们这个,而且失败了,有可能我们这个远程服务啊,他现在由于各种不稳定失败,那你说就由于一个冗余字段的这个名字没保存好,保存失败了,我们让整个事物回滚,感觉也有点不合适,所以我们呢,就可以将它串一下,我们在这儿串一下,让他在这儿尝试,诶尝试如果有异常了,咱啥也不用管,你继续往下走,这是第一种办法,我们远程调用失败了,我们不用管。我们来执行,所以我们执行成功以后,我们从info里边,Info里边我们来要get get什么呢?Get data,因为我们get来的data,它是一个慢来看一下get data。
31:15
那么从info里边get出来的这个data,它是一个对象,但这个对象呢,它是一个map,所以我们可以把它强转为这个map,这个map呢,我们就来写一个string object,我们map里边所有的K都是string的值呢,我们来写一个object来创建出这个,因为我们给远程英O发请求,最终返会返回我们code message以及data这个数据,而data里边的这个数据,远程服务返回的其实就是我们来看一下啊,在info里边,哎,它还不是data,它还叫SQ info,好,那我们远程服务里边呢。会返回一个叫SQ英方,这SQ英方呢,其实就是我们这个实体类,这实体类里边呢,就应该有一个SQ name,我们就可以取出它。
32:06
所以我们真正的商品的名字,我们就点一个get,我们这SQ的name,我们给它强转为string。这是我们查询远程的SQ的名字,而且呢,如果失败,如果失败,整个事物不需要回顾,整个事物无需回滚。那无需回滚的第一种方式,我们就是在这,我们自己看齿掉异常,看吃了异常,只要我们的这个事物方法里边这有一个andto,我们这个to方法只要有异常,我们catch掉了,我们这没有把异常抛出去,我们这个。当它整个是一个事物,只要没有异常,那其他人都能成功,所以我们这个andto,那么就可以给他把异常catch掉。
33:00
当然,第二种做法我们也可以留在这偷渡,我们还可以用什么办法?让我们这个异常出现以后,异常出现以后不回滚呢,那把这个呢,就留给大家,我们也是在高级部分来给大家说,那至此我们的这个采购功能我们就完成了。
我来说两句