多个后端字段对应前端单一字段的思考与解决方案
一、需求背景
最近项目有一个需求,产品要求在查询活动数据的时候,需要支持状态枚举字段的多选查询。活动状态有: 待审核、审核不通过、待投放、投放中、投放完成、已删除 这6种状态。
二、需求可行性
1、现状描述
产品要求支持多选的活动枚举状态有: 待审核、审核不通过、待投放、投放中、投放完成、已删除这6种状态。
系统的表结构现状:
审核字段: approval_state { 1:待审核 2:审核通过 3:审核不通过 }
投放字段:launch_state { 1:待投放 2:投放中 3:投放完成 }
删除字段:state { 1:正常 0:已删除 }
2、可行性分析
前端的“状态”字段是一个统一的字段。 我们不妨定义为 composedState 。
后端的“状态”字段实际上是有3个,就是上面所说的“审核字段”、“投放字段”、“删除字段”这三种。
我们可以给定composedState多个枚举状态,不妨给定:
composedState == 6 已删除
composedState == 5 投放完成
composedState == 4 投放中
composedState == 3 待投放
composedState == 2 审核不通过
composedState == 1 待审核
由此,可以满足我们的需要。
三、细节分析
关于上面几个字段,它们之间是存在一定的联系的。
首先,想要展示“审核状态”、“投放状态”,首先要保证数据是正常的,而不是已删除状态,这是一个大前提;
然后,如果想要展示“投放状态”,那么前置条件一定是,审核状态:审核通过。
换句话说,待投放、投放中、投放完成这些状态的活动,他们呢一定是审核通过的活动;
显示为待审核、审核不通过的活动,他们一定是正常的没有被删除的活动。环环相扣。
只有满足了以上两点,才是符合我们想要的业务逻辑的。
四、解决方案
1、前端逻辑
主要是下面几个枚举状态的传参约定:
composedState == 6 已删除
composedState == 5 投放完成
composedState == 4 投放中
composedState == 3 待投放
composedState == 2 审核不通过
composedState == 1 待审核
2、后端处理逻辑
f(null != creativityListDTO.getComposedStates()) //处理前端入参
{
String[] composedStates = creativityListDTO.getComposedStates().split(","); //前端的字段是一个字符串,我们对其进行切割
List<Integer> composedStatesList = new ArrayList<>();
if(0< composedStates.length)
{
for(int i=0;i<composedStates.length;i++)
{
if(!("").equals(composedStates[i]))
{
composedStatesList.add(i,Integer.valueOf(composedStates[i]));
}
}
map.put("composedStatesList",composedStatesList);
}
}
3、后端sql
<if test="null != composedStatesList and composedStatesList.size() > 0">
AND
(
(1!=1)
<foreach collection="composedStatesList" item="item">
<if test="item == 1">
OR ( a.state IN (1) AND a.approval_state IN (1) )
</if>
<if test="item == 2">
OR ( a.state IN (1) AND a.approval_state IN (3) )
</if>
<if test="item == 3">
OR ( a.state IN (1) AND a.approval_state IN (2) AND c.launch_state IN (1))
</if>
<if test="item == 4">
OR ( a.state IN (1) AND a.approval_state IN (2) AND c.launch_state IN (2) )
</if>
<if test="item == 5">
OR ( a.state IN (1) AND a.approval_state IN (2) AND c.launch_state IN (3) )
</if>
<if test="item == 6">
OR ( a.state IN (0) )
</if>
</foreach>
)
</if>
4、sql小细节—— (1!=1)
sql里面有一个条件,(1!=1) ,这是一个false,意义在哪里呢?
比如我们跟前端约定了枚举值1、2、3、4、5、6,这个时候如惨楚然冒出来一个7,那么这个时候必然是不能查询出相关数据的,因此我们需要在这里设定一个false,当如惨超出我们约定好的参数取值范围之后,查询条件必须返回false,也即这个时候是查询不到任何数据的,也是符合常理的,所以我们添加了 (1!=1) 。
五、结论
大功告成!