前言
上周接手了另一个项目的同事需求,简单看了下设计原型,感觉还行,就和产品简简单单的过了一遍,产品说做的和之前一样就行and这个功能另一个页面有,想想有做过就ok,也就没太深入了解,最不济cv后修改一下。
但是真的有点被这两句话伤害到。开发过程中,遇到了不少问题,整个开发过程甚为艰难,总结反思一下,所以写了这篇文章,同时在复盘一下需求。
遇到的问题(反思)
- 业务需求没了解清楚,算是中途接手(更应该主动去了解)
- 盲目相信那两句话,导致功能没有完成实现,即使我cv了之前的功能(了解需求)
- 技术不够,看了下tapd上测试提的Bug单,陷入怀疑,虽然有部分需求不清晰(这可能是最主要原因了,学习永不停息)
- 开发时间不足,虽然给的时间也没几天,测试的过程中也在开发
- 第一次遇到产品上线,整体氛围紧张,导致整个人逻辑精神状态不太对,到了最后改了bug还是错
- 没有认真检查代码及功能,很重要(看到简单的错误,有点羞愧)
- 将要做事情的记录下来,否则一旦被其中一件耽误,其他也就忘记了
虽然最后还是完成的功能需求开发,这可能是我职业生涯第一次遇到的困难,即使是刚开始,离不开同事的帮助,帮我提供方案滤清思路,想想如果没有,我肯定非常焦虑。
正文
主要复盘整个需求中最难的功能点,不过现在感觉开发方向对之后,逻辑理解起来就很清晰。途中遇到的苦和泪,不言而喻,先看功能,难点主要集中在提交给后端的数据上,我们需要对输入的数据进行校验及数据处理。
我们可以通过点击$股票搜索我们想要的股票消息,点击上方的tag获取想要的股票。那么输入框中就会出现以下几种情况:
文案:普通输入的文本,在移动端显示为正常文本
股票:通过搜索点击得到的股票$xxx$
(以$开头和结尾),在移动端是下划线高亮,可点击跳转
情况:文案、股票、文案+股票、股票+文案、文案+股票+文案、文案+股票+文案+股票、股票+文案+股票
那么后端需要我们提交的格式,属于文案的type为1,text存放文案;输入股票的type为3,其他参数则是股票的其他信息,最终一起提交是一个数组类型
那么怎么样可以分别获取文案和股票呢,大致思路就是通过$xxx$
来分割,获取文案,而$$里面的内容我们可以之前点击股票获取,我们前面搜索点击的股票也会被push进一个数组quoteList(下图),那么遍历获取$xxx$
。一开始是这么想的,但是,产品说希望复制点击过的股票也可以高亮(下图,前一个是搜索点击获得,后一个是复制前一个),那么quoteList只保存一个元素,就无法实现识别两个(也许有其他方案)但是后期我们还要验证输入的是否与quoteList相同,以防输入后期被修改了,所以遍历quoteList这个方案不行。
正则
另一个方案大致就是通过正则表达式匹配整个输入内容,但是这个最开始我是拒绝的,麻烦要写正则表达式(主要这方面知识忘光光了),所以花了不少时间去想quoteList咋做。不过最后我妥协了,还是得正则,被迫重新捡起知识。
总结规则:$10303.HK 納指摩通二九購B$
,后面对应正则
- 以
$
开头\$[^\$]
只出现一次 - 5位数的数字
\d{5}
- .
\.
- HK或US
HK|US
- 空格
\s
- 任意文字、字母及数量
.{3,}
3个任意字符及以上 - 以
$
结尾\$
最终结合为\$[^\$](\d{5}(\.HK|\.US)\s.{3,}?)\$
,可以看到最后有一个?,如果不加上?,只能实现匹配最后一个字符是$,所以会出现$$结尾也会被包括(下图),?是尽可能少匹配
正则验证地址,有兴趣可以试试c.runoob.com/front-end/8…
我们有了正则,就可以直接去匹配输入框中的$xxx$
let messageContentTemp = this.content //内容
var reg = RegExp(/\$(\d{5}(\.HK|\.US)\s[\s\S]{3,}?)\$/g)
const arr = messageContentTemp.match(reg) || [] //match返回数组,数组存放匹配成功的元素
console.log(arr)
具体代码
如果我们没有通过$股票来进行获取股票,那么即使手动输入正确的股票也只能默认为文本,因为前端无法校验他是否输入正确,需要后端配合,目前不支持。如果他只输入了文案,那type就为1
if (quoteList?.length) {
...xxx
} else {
richTextList.push({
type: 1,
text: this.content
})
}
我们遍历match来的数组,对其进行以下一系列的处理
for (const i of arr) {
const stockStr = i.slice(1, i.length - 1)
const splitArr = stockStr.split('.')
// const code = splitArr[0]
// const market = splitArr[1]
// const exchange = marketInfo[market]
// 以上当type=3时,需要提交的字段
const idx = messageContentTemp.indexOf(i)
const strOne = messageContentTemp.slice(0, idx) // 前一段
messageContentTemp = idx + i.length !== messageContentTemp.length
&& messageContentTemp.slice(idx + i.length) || '' // 后一段
}
indexOf(i)可以获取第一个股票的位置下标idx,那么从字符串(0,idx)就是文案,如果idx也是0,那证明股票前面没有文案。而剩下的后半段会在复制给messageContentTemp,下次循环找到新的股票,前提是i的长度不等于messageContentTemp的长度,如果相同,那也就证明messageContentTemp只有股票,就没有后半段,messageContentTemp为空
if (strOne.length !== '') {
richTextList.push({
type: 1,
text: strOne
})
}
文案在前,先将其push进数组,不仅要实现匹配识别,也要保证整体的文案顺序正确。
const trueArr = this.quoteList.filter(item => item.code === code) || []
// 验证输入的股票是否与接口返回的相同,不相同则变成文案
if (trueArr.length && trueArr[0]?.stockSymbol === stockStr) {
//richTextList.push({
// type: 3,
// stockSymbol: stockStr,
// stockCode: code,
// market: market,
// exchange: exchange,
// })
// 本来是使用上面获取的参数的,但是有个问题就是我是通过符号点(.)去做分割的,如果用户把点给删除了
// 那还怎么拿数据,所有上面声明的就没用了。好在,可以获取到quoteList里的股票数据且一定不会错。
richTextList.push({
type: 3,
stockSymbol: trueArr[0].stockSymbol,
stockCode: trueArr[0].code,
market: trueArr[0].market,
exchange: trueArr[0].exchange,
categoryType: trueArr[0].categoryType,
})
} else {
richTextList.push({
type: 1,
text: stockStr,
})
}
// 当messageContentTemp后一段匹配不到股票$xxx$,证明剩下都是文案
const msgReg = messageContentTemp.match(reg) || []
!msgReg.length && richTextList.push({
type: 1,
text: messageContentTemp
})
这里还有一种情况,就是原本有一个股票,arr里面也存放后,但是后来我把股票删除了,arr就没有股票了,只剩下文案的情况,所以需要加上一个判断arr.length是否为0
if (arr.length) {
for (const i of arr) {
...xxxx
// 当只有一个股票,且股票在前,文案在后的情况
const msgReg = messageContentTemp.match(reg) || []
!msgReg.length && richTextList.push({
type: 1,
text: messageContentTemp
})
}
} else {
// 原本有股票,后面删除了只剩文本
richTextList.push({
type: 1,
text: this.content
})
}
到此,我们基本就把所有的情况处理完毕,当输入以下,查看处理结果,达到预期
还有就是当我们打开已经存在过的数据,我们需要再处理数据,将其转会我们能用的,例如我们得把type=3的股票保存到quoteList、把股票和文案按我们输入的顺序展示。
最后
昨天说股票要兼容美股,自己忘记了,那么正则表达式又需要再修改
如果在开发的紧张时刻,一定要保持(强迫)自己冷静,滤清代码和业务逻辑思路,可以写在本子上,可以有一个更好的逻辑方向。
这一块前前后后出了不少错误,这几天还在修复存在的bug,到今天可能算是结束了,看着自己写的代码和情况,说实话有些沮丧,很多很基本的检查都没有做,存在简单的错误,没有最开始的谨慎仔细了。
有一个事情挺可笑,看了许多想学的技术,想想自己掌握的样子,很兴奋,可是到现在也只是在收藏夹吃灰罢了,没啥行动,即使有也断断续续。
如果可以,告诉自己请按时离开自己的舒适区。