Trouble Shooting -- 绕弯解决EVE无$unset问题

本周,在Fix bug的过程中遇到了一个非常有意思的问题,解决了三天之久。在不停的探索,刨根问底地寻求帮助后,终于使用很投机取巧的方式解决了这个问题,以下就是对这个问题的描述以及解决的过程。

问题描述:

需要修改的项目某页面如下图所示:


Trouble Shooting -- 绕弯解决EVE无$unset问题_第1张图片
需修改的页面

当用户点击橙色的“选择文件”按钮将正确的SROI模板上传至系统,系统会自动解析上传的SROI模板,并将解析后的数据显示在“区域1”,与其同时,上传的Excel文件名显示在区域2。

当用户点击“删除”button时,区域2中的文件会被删除,区域1中的数据不会被删除。我们期望的结果是:当点击“删除”button后,区域1和区域2的数据可以一同被删除。


代码中的解决方式及问题定位:

既然会发生点击“删除”按钮后,一处删除掉了,一处没有删除掉的情况,肯定是代码中出现了问题。现在就开始分析代码的写法。


Trouble Shooting -- 绕弯解决EVE无$unset问题_第2张图片
现有代码

通过代码72--77行,我们可以看到,在点击“删除”按钮后,会弹出提示框,然后执行deleteAttachment function。Attachment.delete具体实现如下:


Attachment.delete

PS:项目使用的数据库是mongo,使用EVE对数据库进行操作。EVE官方文档上写着:Eve is an open source Python REST API framework designed for human beings. It allows to effortlessly build and deploy highly customizable, fully featured RESTful Web Services.

当触发删除操作后,会直接发送delete请求至EVE,然后删除数据库里的数据。那到底删除了数据库的什么数据呢?

数据库的结构大致是这样的:一个attachment的collection,专门存放各种附加Excel、图片等信息;一个project的collection,存放项目的基本信息。当触发delete操作后,前端发送了“$http.delete('/api/doc/files/attachment/projectId')”,对数据库中attachment进行了删除。与此同时,页面上区域2的数据,也就是attachment也被删除掉。而上传的Excel经过后台代码解析后,会将Excel中的数据存入project collection的sroi filed中,而页面上区域1的信息正是根据project collection的sroi filed显示的。所以,只需要把project collection中的sroi filed删除掉,就可以解决最初的问题。

解决思路:

方法一:


Trouble Shooting -- 绕弯解决EVE无$unset问题_第3张图片
project collection存储结构


由于只想删除一个collection中的某个字段,很自然的想到了mongo中的unset方法,用法如下。


使用unset前project


使用unset后project

可以看到使用unset方法可以很方便的把project collection中的sroi和sroi_result字段删除掉并且不影响其他的字段。但是!项目中不是单纯的操作mongo,而是通过EVE对数据库进行操作,并且EVE对unet方法不!支!持!不支持!不支持!没办法,只能放弃unset这条路,继续探索新方法。

方法二:

既然不能直接删除,那就间接删除吧。

先通过get请求把project信息都取到,通过代码手动将sroi字段删除,再用update把新project更新到数据库中。


Trouble Shooting -- 绕弯解决EVE无$unset问题_第4张图片
get project



Trouble Shooting -- 绕弯解决EVE无$unset问题_第5张图片
get project response

可以发现response里比mongo里多了一些我们不想要的字段,(所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果),即使通过操作把sroi和sroi_result删除,也会在update的时候把多余字段加入到数据库中,从而引入脏数据。这个方式又被排除。

方法三:

直接删除和间接删除都不行,那就采取软删除的方式吧。

在数据库中加上一个isDelete字段,当需要使用project sroi时,先判断isDelete是否为true,为true表示已经被删除,数据就不可用了。看起来这种方式是可行的,但是!!关键是!!并不知道具体有多少地方使用到了sroi,从而不能确定需要改动哪些地方,改动量可能会非常非常大。

所以这种方式也被排除。

方法四:

Trouble Shooting -- 绕弯解决EVE无$unset问题_第6张图片
upload 前端


Trouble Shooting -- 绕弯解决EVE无$unset问题_第7张图片
deal sroi file api


第一次上传Excel表后,数据库project里已经存在了sroi字段,当第二次再上传Excel表,第二次表的内容会将第一次的数据覆盖掉。我们可以看到,当前端发送upload request后,后端会接收到Excel表并对其进行处理和保存,91,92和94行就是使用EVE将数据存入数据库。

从这个思路中,我们想到了另外一种解决方式:当点击“delete button”时,使用同upload相同的套路,只不过将result、formatData数据置空,同时使用put方式将数据update至数据库。


Trouble Shooting -- 绕弯解决EVE无$unset问题_第8张图片
测试 method4 代码

在代码中,先发送post请求将Excel信息save到数据库中,再使用put方式变相清除数据。看似没有问题的测试代码,但是结果却是这样的。╮(╯▽╰)╭


Trouble Shooting -- 绕弯解决EVE无$unset问题_第9张图片
result

不仅仅把sroi删除了,还把project中其他字段也删除了。 (`皿´) 好吧,put方法是全部更新,此时应该用patch方法更新部分信息。

于是乎,又开始看代码中httpClient部分的发送请求,然而我看到了什么。。。。


Trouble Shooting -- 绕弯解决EVE无$unset问题_第10张图片
httpclient

默默的在风中凌乱了。。。_(:з」∠)_似乎已经把路走绝了。。

方法五:

在方法一中说到,没办法用unset将指定字段删除掉,但是它不能阻止我把指定字段替换掉啊。如果我把sroi中的内容用[ ]替换掉,只需要在前端显示的时候判断sroi内容是否为[ ]即可了 。

Trouble Shooting -- 绕弯解决EVE无$unset问题_第11张图片
patch sroi to [ ]


Trouble Shooting -- 绕弯解决EVE无$unset问题_第12张图片
result

看样子似乎成功了,可以成功替换为空。下面只需要考虑两个问题:改前端有sroi的部分,加上判断条件;再次上传Excel是否能成功。

第一个问题工作量大但是挺简单,先来看第二个吧。彡(-_-;)彡不能上传成功!不能!不!!!

当然把[ ]换成了null,string依旧不能保证第二次上传成功,好吧。You win!

方法。。。。

直接上可以work的解决方法吧。。。

Trouble Shooting -- 绕弯解决EVE无$unset问题_第13张图片
right

既然[ ], string都不能保证第二次上传Excel成功,肯定是因为类型的原因,那如果我把sroi改为空的{ }就可以保证第二次Excel上传成功了。所以,首先把sroi字段置为null,再次置为{ }。。。好吧,接下来只添加前端显示部分的判断就好了。

(´థ౪థ)σ

你可能感兴趣的:(Trouble Shooting -- 绕弯解决EVE无$unset问题)