前言刚进新公司没多久,运营妹子提出了一个要求。她整理了一张有400条数据记录的excel,需要进行两步操作,一是批量审核,二是批量合并。后台界面都可以操作,就是没有批处理功能。让我写一个脚本来处理它。为了给新同事树立良好的形象,我欣然接受了这个要求。对于突如其来的需求,我只能用自己多年来不断与产品运营交锋积累的技巧去应对,俗称见招拆招。整理要做的事情,首先要弄清楚整个事情需要做什么,怎么做。操作是excel表格。它包含400条具有映射关系的数据。格式如下:fieldNamenewValueoldValueKkk1112222首先是有一张record表要审核,暂且称之为check_info表。该表存储爬虫引入的400条待审核数据,对应excel中的400条数据,如:fieldNamevalue审核状态kkk111待审核,这400条数据需要批量审核,接口没有批处理功能。某条记录审核成功后,会在另一张表中生成一条数据。另外,之前已经有一条数据是旧值,一共有两条数据。我们称此表为field_detail。它看起来像:fieldNameValueKeymap_keykkk1111NullKkk2222Null222。那条数据就是oldValue对应的数据,111就是上面认可的新增数据。第二件事是执行以下语句:updatefield_detailsetmap_key=1wherefieldName='kkk'andkey=2;很简单,但是没有批处理接口,而且这个接口做的不仅仅是执行这个语句那么简单,它还做了很多缓存清理和更新相关的事情。所以只能写脚本批量调用单个接口。事情已经描述过了。下面开始工作。单次审核给出解决方案的接口是get请求,形式为:/check_info/check?id=&value=xxx。审稿接口用的是get,有点奇怪。因为审计是基于id的,所以需要在check_info表中找出id对应的excel表中的400条记录。这样可以将excel记录转换成select语句,然后用union连接400条记录。你可以找出400个id。注意这里的参数也需要传值给后台,因为这个接口的定义在review的时候可以修改重新定义的值,但是这里我们只需要传原值即可。找到后放到一个json数组中,然后用自己的身份登录后台系统。按F12打开chrome的调试工具,在sources标签下新建一个snippet,就可以在里面写js代码了。这里可以写一个for循环,400条数据通过ajax一个一个调用对应的接口。成功则继续调用下一个,失败则循环中断。下面贴出具体代码。所以第一件事就完成了。第二件事的关键是找出oldValue和newValue的key。因为有三个单一的接口参数:fieldName、oldKey、newKey。这里还是用sql处理。思路是将新旧记录合并为一条记录,属性为fieldName、oldKey、newKey,然后将400条记录并集。并将查询结果导出为json格式。也用和第一步类似的方法逐一调用接口。详细过程先根据操作提供的excel找到待审核的id。这个用excel的CONCATENATE函数非常有效。例如:=CONCATENATE("selectid,valuefromcheck_infowherefieldName=B2andvalue=C2union")B2表示取第二行第二列,C2表示取第二行第三列。最后将sql拼接起来,就可以从在线库中取出待审核记录的id和value了。幸运的是,只有400个条目,因为DMS将单个查询限制为不超过500个条目。将查询到的数据导出为json格式。开始写批量请求的脚本:幸运的是,所有400条都显示执行成功。当然,因为是直接操作线上环境,所以刚开始的时候不要批量运行,而是多试几次。接下来就是查看处理结果的时候了,可惜出了点问题。合理使用如下sql语句查看,结果应该是400条数据:select*fromfield_detailwherefieldName=kkkandvalue=111union...但是结果只有395条,为什么少了5条?通过一些sql我发现了丢失的5.发送到操作。问她这几条数据有没有问题。因为我自信地认为我的操作是没有问题的。一定是运营提供的数据有问题。操作妹子还不错,很快就摸清了这些规矩。value的内容包含一个+号。其实这几条数据已经进入了field_detail,只是+号变成了空格。在这一点上,我立即知道问题出在哪里。请求参数已经被我的encodeURI处理过了。其实我在之前的公司也遇到过这种情况。也是自己重视不够,“二次入宫”。手术妹子直截了当地说自己可以改。只需5件。但这时候,我心里有些愧疚。同一个坑我踩了两次,真的不应该。那我解释一下为什么+号变成了空格。RFC-2396标准将URI中的+号定义为保留字符,encodeURI不会对保留字符进行编码。例如:encodeURI("country+home");//%E5%9B%BD+%E5%AE%B6保留字符加号的意思是一个空格。所以传入的后端会变成空格。这个问题有两种解决方案。一种是将值放在有效负载中。改成post请求,当然现在的场景肯定不行。第二种解决方案是使用encodeURIComponent,对保留字符进行编码,例如:encodeURIComponent("country+home");//%E5%9B%BD%2B%E5%AE%B6+数字变为%2B。这样,传入的后端也会被解码为+号。百分号代码的详细解释可以参考:http://www.lmwlove.com/ac/id1030这样第一步已经被忽悠了,接下来就是批量合并了。首先使用sql查询对需要传入的参数进行处理,处理后的sql形式为:select`fieldName`,(select`key`fromfield_detailwherefieldName='kkk'andvalue='111')asnewKey,`key`asoldKeyfromfield_detailwherefieldName='kkk'andvalue='222'union...用于批量合并的脚本,例如://Pausemethodtoavoidoverloadfunctionsleep(ms){returnnewPromise(resolve=>setTimeout(resolve,ms));}//封装ajax请求constajaxGet=(url)=>newPromise(function(resolve,reject){varxhr=newXMLHttpRequest();xhr.open('GET',url);xhr.send();xhr.onload=function(){if(xhr.status==200){resolve(xhr);}else{reject("调用失败");}};});asyncfunctiondoMerge(){varmergeParamArray=[{"fieldName":"kkk","newKey":123,"oldKey":456}];//实际有400项for(vari=0;i
