前言
好久没更新文章了,最近工作繁忙都快写emo了,想来也不能太颓废,记录一下最近遇到的问题吧
最近接到一个bug,有一个表单上面使用了 element的时间选择器, 用来处理年-周的选择逻辑(我们的组件库并没支持年-周)。
我们会将选中的年周发送到后端做查询,但是在选择24年某日时,发送的周数时间和后端查询出来的周数却始终不同。。。
问题排查
要排查这个问题也不难,先打开组件存在的位置,这里用显示的element的官网来模拟展示。
写法大概如下:
默认传了一个值进去,然后这个时间选择器就会显示出对应的 年数加周数
当我们重新选择一个周数时,绑定的值就会变成 该周对应的某一个日期 ,而我们实际拿到的值就是这个绑定的对应值
因此为什么我正常选中的周数,到提交的时候反而会不对呢?
原因可能是出现在提交的周数的地方,后端在接受表单的的时候也是需要接受周数,但是element只会给我们一个日期,因此在提交的时候前端实际上先进行了一次格式化,把普通的date类型数据转成了 年-周 的格式
果然,前端格式化的时候用的是:
return moment(val).format('YYYY-w')
当我选中2022年6月13日时,element展示的周数是: 2024-27
当我使用moment进行格式化时,展示的周数是: 2022-25
因此问题的原因就可以确定了,因为element 和 前端周格式化算法不一致导致提交异常。
问题修复
element 和 前端周格式化算法不一致导致提交异常
因此如果希望修复这个问题需要统一 前端格式化周的算法 和 element格式化周的算法
因为element不归属我这边,所以 将格式化方法同步到前端更实际,需要去看element的源码,源码如下:
因此更新前端格式化代码为element格式化周
const date = new Date(src.getTime());
date.setHours(0, 0, 0, 0);
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
const week1 = new Date(date.getFullYear(), 0, 4);
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
即可
坑
即便到了上面那一步还是会有问题,如果希望返回结果一致的话,必须要前端,组件,后端周格式化算法一致。
但这里只做到了前端,组件一致,而后端一致才是比较困难的,因为往往后端使用周查询时用的是数据库内置的能力,这个相对于组件库而言更难改。
因此最后的改动方案就只剩下,修改拷贝下来组件的周格式化算法,使得前端,组件周格式化算法和组件库内置一致