整体架构流程
一:先展示前端效果图
二:要求后端给前端返回的json数据结构
三:最终json返回结构图
简单解释下吧:
这个 JSON 结构表示一个包含不同会员级别及其相应权益的数据。以下是对 JSON 结构中各部分的解释:
-
"msg": "操作成功"
:这是一个消息字段,表示操作成功的信息。 -
"headers"
:这是一个包含表头信息的数组,描述了数据表的列名和属性。- 每个表头对象都包括以下属性:
"prop"
:属性名称,用于标识列。"levelId"
:级别 ID,表示会员级别的唯一标识符。"label"
:标签,用于表示列的显示名称。
- 每个表头对象都包括以下属性:
-
"code": 200
:这是一个状态码,表示操作成功的状态码(通常 200 表示成功)。 -
"data"
:这是一个包含数据的数组,描述了不同会员级别的权益信息。- 每个数据对象都包括以下属性:
"right"
:会员权益的描述或名称。"tourist"
、"common"
、"vip"
、"svip"
、"enterprise-vip"
:这些属性对应不同会员级别下的权益或具体数值。每个属性的值表示该会员级别下的具体权益,例如金额、权限、咨询等。
- 每个数据对象都包括以下属性:
这个 JSON 结构似乎用于描述不同会员级别的权益以及它们的具体内容。通常,这种结构在网站或应用程序中用于展示会员级别和权益的信息,以帮助用户选择适合他们需求的会员级别。
四: 先了解下数据库吧,主要涉及到三个数据库表
五: 先看看我的需要的实体类和Vo吧
**JskjMemberLevel**
//会员等级对象 - JskjMemberLevel
/** 会员ID */
private Long levelId;
/** 会员名称 */
@Excel(name = "会员名称")
private String levelName;
/** 会员权限字符串 */
@Excel(name = "会员权限字符串")
private String levelKey;
/** 显示顺序 */
@Excel(name = "显示顺序")
private Integer levelSort;
/** 会员状态(0正常 1停用) */
@Excel(name = "会员状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
private Long[] menuIds;
private Long[] deptIds;
MemberDetail
//会员权益信息对象 -
/** 主键权益id */
@Field("right_id")
private Integer id;
/** 权益名称 */
@Field("right_name")
private String rightName;
/** 父类id */
@Field("parent_id")
private Integer parentId;
/** 层级 */
@Field("level")
private Integer level;
/** 状态 */
@Field("status")
private Integer status;
/** 是否有子导航栏 */
@Field("has_children")
private Integer hasChildren;
/** 子部门 */
private List<MemberDetail> children = new ArrayList<MemberDetail>();
主要是这两种实体类了,其他还是用Map<String,Object>来接受数据库的数据
六: Controller的代码块
@GetMapping("/detailListSecond")
public AjaxResult selectDetailListSecond()
{
AjaxResult ajax = AjaxResult.success();
// 获取会员等级列表
// 查询会员等级列表
List<JskjMemberLevel> memberLevels = jskjMemberLevelService.selectJskjMemberLevelList(new JskjMemberLevel());
// 获取会员等级详细信息列表
List<Map<String, Object>> detailVoList = memberDetailNavService.selectMemberLevelDetailVoList();
// 获取会员详细信息的父列表
List<String> MemberDetailParentList = memberDetailNavService.selectMemberDetailParentList();
// 创建一个用于存储转换后的会员等级信息的列表
List<Map<String, Object>> memberLevelList = new ArrayList<>();
List<Map<String, Object>> memberLevelDetailList = memberDetailNavService.getFinalMemberLevelDetailVo(memberLevels, detailVoList, MemberDetailParentList, memberLevelList);
ajax.put("headers", memberLevelList);
ajax.put("data",memberLevelDetailList);
return ajax;
}
这段代码是一个 Spring Boot 控制器方法,使用 @GetMapping
注解来处理 HTTP GET 请求,路径为 “/detailListSecond”。下面是对这段代码的总结:
-
首先,创建了一个名为
ajax
的AjaxResult
对象,用于准备响应数据。 -
通过调用服务层方法
jskjMemberLevelService.selectJskjMemberLevelList(new JskjMemberLevel())
,获取会员等级列表并存储在memberLevels
列表中。 -
通过调用服务层方法
memberDetailNavService.selectMemberLevelDetailVoList()
,获取会员等级详细信息列表并存储在detailVoList
列表中。 -
通过调用服务层方法
memberDetailNavService.selectMemberDetailParentList()
,获取会员详细信息的父列表并存储在MemberDetailParentList
列表中。 -
创建一个名为
memberLevelList
的空列表,用于存储经过转换后的会员等级信息。 -
调用
memberDetailNavService.getFinalMemberLevelDetailVo(...)
方法,将获取的会员等级列表memberLevels
、会员等级详细信息列表detailVoList
、会员详细信息的父列表MemberDetailParentList
和空的memberLevelList
传递给该方法,以获取最终的会员等级详细信息列表,并将结果存储在memberLevelDetailList
列表中。 -
最后,将
memberLevelList
和memberLevelDetailList
放入ajax
对象中,并返回该对象作为 HTTP 响应。这个响应包含了会员等级列表和会员等级详细信息列表。
总的来说,这段代码的作用是获取和组装会员等级相关的数据,然后将这些数据作为 JSON 响应返回给客户端。在响应中,headers
包含会员等级列表的表头信息,而 data
包含会员等级详细信息的具体数据。这种设计通常用于在前端页面中展示会员等级和其详细信息的表格或列表。
七: 来看看service和serviceImpl的代码块
service
List<Map<String,Object>> selectMemberLevelDetailVoList();
List<String> selectMemberDetailParentList();
List<Map<String, Object>> getFinalMemberLevelDetailVo(List<JskjMemberLevel> memberLevels,
List<Map<String, Object>> detailVoList,
List<String> MemberDetailParentList, List<Map<String, Object>> memberLevelList);
serviceImpl
@Override
public List<Map<String,Object>> selectMemberLevelDetailVoList() {
return memberDetailNavMapper.selectMemberLevelDetailVoList();
}
@Override
public List<String> selectMemberDetailParentList() {
return memberDetailNavMapper.selectMemberDetailParentList();
}
接下来是最核心的代码:
public List<Map<String, Object>> getFinalMemberLevelDetailVo(List<JskjMemberLevel> memberLevels, List<Map<String, Object>> detailVoList, List<String> MemberDetailParentList, List<Map<String, Object>> memberLevelList) {
// 遍历会员等级列表并将其转换为Map形式
memberLevels.forEach(item -> {
// 创建一个新的Map用于存储会员等级信息
Map<String, Object> map = new HashMap<>();
// 添加会员等级的显示名称到Map中
map.put("label", item.getLevelName());
// 添加会员等级的属性键值到Map中
map.put("prop", item.getLevelKey());
// 添加会员等级的唯一标识(ID)到Map中
map.put("levelId", item.getLevelId());
// 将转换后的Map添加到会员等级列表中
memberLevelList.add(map);
});
// 创建一个用于存储会员等级详细信息的列表
List<Map<String, Object>> memberLevelDetailList = new ArrayList<>();
// 创建一个有序的Map用于存储数据
Map<String, Object> map = new LinkedHashMap<>();
// 初始化索引
int index = 0;
// 创建一个用于存储会员等级详细信息的 Map
map.put("right", MemberDetailParentList.get(index));
// 判断标志
int flag = 0;
// 遍历会员等级详细信息列表
for (Map<String, Object> item : detailVoList) {
// 遍历会员等级列表
for (Map<String, Object> item2 : memberLevelList) {
// 如果会员等级详细信息的ID与会员等级的ID匹配
if (item.get("id").equals(item2.get("levelId"))) {
//判断是否是最后一个会员等级
if (item2.get("prop").equals(memberLevelList.get(memberLevelList.size()-1).get("prop"))){
flag = 1;
}
// 将会员等级的属性键值与其显示名称添加到 Map 中
map.put(item.get("level_key").toString(), item.get("right_name"));
// 跳出内部循环
break;
}
}
// 如果计数器等于会员等级列表的大小
if ( flag == 1) {
flag = 0;
// 将填充好的 Map 添加到会员等级详细信息列表中
memberLevelDetailList.add(map);
// 创建一个新的有序 Map 用于下一轮循环
map = new LinkedHashMap<>();
// 增加索引
index++;
// 如果索引超过了阈值(12),跳出外部循环
if (index >= MemberDetailParentList.size())
break;
// 更新新的 Map 的 "right" 属性
map.put("right", MemberDetailParentList.get(index));
}
}
// 创建一个新的 HashMap 对象,用于存储会员级别信息
Map<String, Object> firstMap = new HashMap<>();
// 向 firstMap 中添加标签(label)、属性(prop)和级别ID(levelId)信息
firstMap.put("label", "会员级别");
firstMap.put("prop", "right");
firstMap.put("levelId", 0);
// 将 firstMap 插入到 memberLevelList 的开头(索引 0 处)
memberLevelList.add(0, firstMap);
return memberLevelDetailList;
}
这段代码实现了将会员等级信息和其详细信息进行转换和组装的功能。以下是对该代码的总结:
-
getFinalMemberLevelDetailVo
方法接受四个参数:memberLevels
(会员等级列表)、detailVoList
(会员等级详细信息列表)、MemberDetailParentList
(会员详细信息的父列表)、memberLevelList
(用于存储转换后的会员等级信息的列表)。 -
代码首先遍历
memberLevels
列表,将每个会员等级对象转换为一个包含显示名称、属性键值和级别ID的 Map,并将这些 Map 添加到memberLevelList
中。 -
然后,创建一个新的列表
memberLevelDetailList
用于存储会员等级详细信息。 -
创建一个有序的
Map
对象map
用于存储数据,并初始化一个索引index
。 -
在循环中,遍历
detailVoList
(会员等级详细信息列表),然后再内部循环中遍历memberLevelList
(会员等级列表)。 -
如果会员等级详细信息的ID与会员等级的ID匹配,将该信息添加到
map
中,同时检查是否是最后一个会员等级,如果是则设置flag
为 1。 -
如果
flag
为 1(表示已经处理完一个会员等级的详细信息),则将map
添加到memberLevelDetailList
中,创建一个新的map
用于下一轮循环,增加索引,同时检查索引是否超过阈值(12),如果是则跳出外部循环。 -
最后,创建一个新的
HashMap
对象firstMap
用于表示会员级别的初始信息,将其插入到memberLevelList
的开头。 -
返回
memberLevelDetailList
,其中包含了已转换和组装的会员等级详细信息。
总的来说,该方法用于将会员等级信息和其详细信息进行组装,最终返回一个包含了会员等级详细信息的列表。这个过程包括了遍历、匹配、转换和组装数据。
八: 最后看看Dao层的sql语句,虽然比较简单
<select id="selectMemberLevelDetailVoList" resultType="java.util.Map">
select level_key, right_name ,ml.level_id as id, lr.parent_id as parentId
from jskj_level_right lr ,jskj_member_level ml,jsky_level_right_relation lrr
where lr.right_id = lrr.right_id and ml.level_id = lrr.level_id
and lr.parent_id != 0
order by lr.right_id, ml.level_sort asc
</select>
<select id="selectMemberDetailParentList" resultType="java.lang.String">
select lr.right_name
from jskj_level_right lr
where lr.parent_id = 0
order by lr.right_id
</select>
这两个 SQL 查询是 MyBatis 映射文件中的两个查询语句,用于从数据库中检索会员等级详细信息和会员详细信息的父列表。以下是对这两个查询的总结:
-
selectMemberLevelDetailVoList
查询:-
该查询从三个表中检索数据:
jskj_level_right
表(别名lr
)、jskj_member_level
表(别名ml
)和jsky_level_right_relation
表(别名lrr
)。 -
查询的结果类型是
java.util.Map
。 -
查询的字段包括
level_key
、right_name
、ml.level_id
(别名为id
)和lr.parent_id
(别名为parentId
)。 -
查询条件包括以下条件:
lr.right_id = lrr.right_id
:连接jskj_level_right
表和jsky_level_right_relation
表,以获取相关的权益信息。ml.level_id = lrr.level_id
:连接jskj_member_level
表和jsky_level_right_relation
表,以获取相关的会员等级信息。lr.parent_id != 0
:筛选出jskj_level_right
表中parent_id
不等于 0 的记录。
-
结果集根据
lr.right_id
和ml.level_sort
进行升序排序。
-
-
selectMemberDetailParentList
查询:-
该查询仅从
jskj_level_right
表(别名lr
)中检索数据。 -
查询的结果类型是
java.lang.String
。 -
查询的字段包括
right_name
,表示会员详细信息的父级名称。 -
查询条件包括以下条件:
lr.parent_id = 0
:筛选出jskj_level_right
表中parent_id
等于 0 的记录,这些记录表示会员详细信息的父级。
-
结果集根据
lr.right_id
进行升序排序。
-
总的来说,这两个查询用于检索与会员等级和会员详细信息相关的数据。第一个查询获取会员等级详细信息,包括权益键(level_key
)、权益名称(right_name
)、会员等级的唯一标识(id
)、以及父级的唯一标识(parentId
)。第二个查询获取会员详细信息的父级名称。这些查询语句通常用于构建会员等级和权益信息的数据结构,以便在应用程序中展示或处理。
小结
怎么说呢,逻辑很重要,算法本人还是十分欠缺,没刷过力扣的小白。