关于前端:程序员日常之见招拆招

7次阅读

共计 3699 个字符,预计需要花费 10 分钟才能阅读完成。

前言

刚入职新公司不久,经营妹子提了个需要,她整顿了一份 400 条数据记录的 excel,须要执行两步操作,一个是批量审核,一个是批量合并。后盾界面都是能够操作的,但都没有批量性能。让我能不能写个脚本解决下。本着给新共事建立一个良好形象的目标,我欣然接受了这个需要。对于从天而降的需要,只能拿出本人多少年与产品经营一直交锋,攒下来的本事进行应答了,俗称见招拆招。

梳理要做的事件

首先对整个事件要弄清楚本人须要干什么,怎么干。经营给的是一份 excel 表格。外面是它整顿的 400 条具备映射关系的数据格式形如:

fieldName newValue oldValue
Kkk 111 2222

第一件事件是有一张待审核记录表,权且叫做 check_info 表吧,这张表里寄存的是 400 条爬虫引入的待审核数据,对应的正是 excel 里的 400 条数据,形如:

fieldName value 审核状态
kkk 111 待审核

须要将这 400 条数据,批量审核通过,界面是没有批量性能的。某条记录审核胜利后,就会在另外一个表生成一条数据,加上之前旧的值曾经存在一条数据,一共两条数据,这张表权且叫作 field_detail 吧,形如:

fieldName Value Key map_key
kkk 111 1 Null
Kkk 222 2 Null

222那条数据是 oldValue 对应的数据,111是下面审核通过新加的数据。

第二件要做的事件就是,执行上面这条语句:

update field_detail set map_key = 1 where fieldName='kkk' and key=2;

很简略,然而同样没有批量接口,另外这个接口做的事件不止执行这条语句这么简略,还做了许多和缓存清理,更新无关的事件。所以只能写脚本批量调用单条的接口。事件曾经形容完了。上面就是开干了。

给出解决方案

单条审核的接口是 get 申请,形如:/check_info/check?id=&value=xxx,审核的接口应用 get,有点奇怪呀。因为是依据id 进行审核的,所以必须找出 excel 表里 400 条记录对应在 check_info 表的 id。这个能够把 excel 记录转化为 select 语句,而后 400 条应用 union 连贯一下。就能够把 400 条 id 找进去了。留神此处的参数外面还须要把 value 传给后盾,因为这个接口的定义是能够在审核的时候批改本人从新定义的 value,然而此处咱们只有把原值传过来即可。找进去之后放到一个json 数组外面,而后应用本人的身份登录到后盾零碎。按 F12 关上 chrome 的调试工具,在 sources 这个 tab 下新建一个 snippet,这个外面就能够写 js 代码了。此处能够写个for 循环,400 条数据一一 ajax 调用相应的接口。胜利持续调用下一条,失败就中断循环。具体代码上面会贴出来。这样第一件事件就算实现了。第二件事件要害就是把 oldValuenewValue的 key 找进去。因为单条的接口参数有三个别离是:fieldNameoldKeynewKey。此处还是应用 sql 解决。思路就是将新的和老的合并成一条记录,属性有 fieldNameoldKeynewKey,而后将 400 条记录再union 起来。并将查问后果导出成 json 格局。同样应用相似第一步的形式一一调用接口。

具体过程

首先依据经营提供的 excel 找出待审核的 id,这个用 excel 的CONCATENATE 函数很灵。形如:

=CONCATENATE("select id,value from check_info where fieldName= B2 and value= C2 union")

B2 示意取第二行第二列,C2 示意取第二行第三列。最初将 sql 拼接起来,就能够将待审核的记录的 idvalue从线上库里捞进去。庆幸就 400 条,因为 DMS 限度单次查问不大于 500 条。将查问的数据导出成 json 格局。

开始写批量申请的脚本:

庆幸 400 条都显示执行胜利了。当然因为是间接操作线上环境,开始不要批量跑,弄几条试试是很有必要的。而后是查看处理结果,然而可怜的是出问题了。按情理应用形如上面的 sql 语句查看,后果应该是 400 条数据:

select * from field_detail where fieldName=kkk and value = 111 union 
...

然而后果就 395 条,为什么少了 5 条呢?通过一些 sql 我找出了缺失的那 5 条。发给了经营。询问她这几条数据是不是有什么问题。因为我自信的认为我的操作是没问题的。肯定是经营给的数据有问题。经营妹子也不赖,迅速找出了这几条的法则。value的内容都蕴含了 + 号。理论这几条数据曾经进入了 field_detail,只不过+ 号变成了空格。此时我立马晓得问题出在哪了。申请参数被我 encodeURI 解决过了。其实在上家公司遇到过这种状况。也是本人不够器重,” 二进宫 ” 了。经营妹子痛快的说她本人改下就能够了。就 5 条嘛。但此时我的心里是有点自责的。同样的坑踩了两次,实属不应该啊。那我来解释下为什么 + 号会变成空格吧。

RFC-2396这个规范定义了 URI 中 + 号为保留字符,encodeURI不会对保留字符进行编码。比方:

encodeURI("国 + 家");
//%E5%9B%BD+%E5%AE%B6

而加号这个保留字符的含意就是空格。所以传入后端会变成空格。要解决这个问题有两个计划,一是将 value 放到 payload 中。改成 post 申请,当然以后这个场景必定是不行的。第二个计划就是应用encodeURIComponent,这个函数会对保留字符进行编码,比方:

encodeURIComponent("国 + 家");
//%E5%9B%BD%2B%E5%AE%B6

+号变成了 %2B。这样传入后端还会解码为+ 号了。

对于百分号编码具体解释请参考:http://www.lmwlove.com/ac/id1030

就这样第一步算蒙混过关了,接下来须要进行批量合并了。首先还是把须要传入的参数应用 sql 查询处理,解决的 sql 形如:

select `fieldName`,(select `key` from field_detail where fieldName = 'kkk' and value = '111') as newKey,`key` as oldKey from field_detail where  fieldName = 'kkk' and value = '222' union
...

批量合并的脚本,形如:

// 进展办法,防止过载
function sleep(ms) {return new Promise(resolve => setTimeout(resolve, ms));
}
// 封装 ajax 申请
const ajaxGet = (url)=>new Promise(function(resolve,reject){var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.send();
    xhr.onload = function() {if(xhr.status == 200) {resolve(xhr);
                }else{reject("调用失败");
                }
    };
});

async function doMerge(){var mergeParamArray = [{"fieldName":"kkk","newKey":123,"oldKey":456}];// 理论有 400 条
    for(var i=0;i< mergeParamArray.length;i++){
       // 调用合并接口
       var mergeParam = mergeParamArray[i];
       var url = "/field_detail/merge?field="+mergeParam.fieldName+"&oldKey="+mergeParam.oldKey+"&newKey="+mergeParam.newKey;
       await ajaxGet(url);
       console.log("merge field",JSON.stringify(mergeParam),"success");
       await sleep(1000);
    }
}

doMerge();

庆幸 400 条都胜利了。经营妹子示意了感激。

总结与反思

下面这种案例只能解一时之需,真正迷信的方法还是增加性能。满足日常经营需要。整个过程下来,兴许是本人的确做过许多相似的事件吧,简直没有什么卡顿。然而有几个中央还是做得不够好,比方下面那个百分号编码问题,还有整个过程本人和经营确认的环节也没做好。实践上这种需要都须要本人执行一步,经营确认一步。如果经营确认的时候不够认真,本人也须要把要害信息传递给她。表明本人执行完当某个操作执行,成果是什么样的。还有一点也是要值得思考的,毕竟是批量调用接口,难保某次调用有问题,导致整个执行中断。此时须要记录下以后的进度。找出出错的是哪条记录,便于下次复原执行。还有一点也很要害,就是假如执行过程中发现问题了,为了及时止损,须要中断工作执行。此时能够思考强制敞开以后标签页。这样 for 循环的 js 也会终止执行。总之胆子要大,但心要细。

正文完
 0