java菜单的逻辑处理

陌路散爱 提交于 2020-01-01 02:13:51

1.目的:一个网站的菜单实现,存在多级关系,返回一个多级的树状结构,供前端使用。
2.整体思路 a.将所有对象查回来作为一个列表然后对他树状进行处理
b.通过vo类直接返回个树状结构
两者达成的效果一样,只是实现的地方不同
3.实现
a。根据常规场景生成一个菜单表(mysql)

CREATE TABLE `menu` (
  `menu_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单id',
  `menu_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '菜单名称',
  `menu_path` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '菜单路径',
  `menu_level` bigint(20) DEFAULT NULL COMMENT '菜单等级',
  `parent_id` bigint(20) DEFAULT NULL COMMENT '父id',
  `menu_title` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '菜单备注',
  PRIMARY KEY (`menu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

b.使用反向生成生成dao,enetity和mapper
c.建立Controller

package com.example.demo.controller;

import com.example.demo.enetity.ResponseBean;
import com.example.demo.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin
@RestController
@RequestMapping("/menu")
public class MenuController {

    @Autowired
    private MenuService menuService;


    @GetMapping(value = "/load")
    public ResponseBean loadMusicList() {
        return menuService.uploadMenu1();
    }

    @GetMapping(value = "/load/ver2")
    public ResponseBean loadMusicList2() {
        return menuService.uploadMenu2();
    }
}

e.service

package com.example.demo.service;

import com.example.demo.enetity.ResponseBean;

public interface MenuService {

    ResponseBean uploadMenu1();

    ResponseBean uploadMenu2();
}

f.
1。实现类实现

  @Autowired
    private MenuMapper menuMapper;

    @Override
    public ResponseBean uploadMenu1() {
        List<Menu> menus = menuMapper.selectAll();
        List<Map> list = treeMenu(menus);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", list);
        return CommonUtils.succssonJson(jsonObject);
    }
    private List<Map> treeMenu(List<Menu> menus) {
        List<Map> list1 = new ArrayList<>();
        Long maxLevel = 0L;
        Map mapRelation = new HashMap<>();
        Map mapObject = new HashMap<>();
        Map mapLoaction = new HashMap<>();
        for (int i = 0; i < menus.size(); i++) {
            List<Map> children = new ArrayList<>();
            Map map = new HashMap<>();
            map.put("id", Long.valueOf(menus.get(i).getMenuId()));
            map.put("menuLevel", menus.get(i).getMenuLevel());
            map.put("menuName", menus.get(i).getMenuName());
            map.put("menuPath", menus.get(i).getMenuPath());
            map.put("menuTitle", menus.get(i).getMenuTitle());
            map.put("parentId", menus.get(i).getParentId());
            map.put("children", children);
            if (menus.get(i).getMenuLevel() != null && menus.get(i).getMenuLevel() > maxLevel) {
                maxLevel = menus.get(i).getMenuLevel();
            }
            list1.add(map);
            mapRelation.put(menus.get(i).getMenuId(), menus.get(i).getParentId());
            mapObject.put(menus.get(i).getMenuId(), menus.get(i));
            mapLoaction.put(menus.get(i).getMenuId(), i);
        }
        List list = new ArrayList<>();
        //数据拼装
        for (int j = new Long(maxLevel).intValue(); j > 1; j--) {
            Set set = mapRelation.entrySet();
            Iterator iterator = set.iterator();
            while (iterator.hasNext()) {
                String s = iterator.next().toString();
                String[] split = s.split("=");
                String s1 = split[0];
                Menu menu = (Menu) mapObject.get(Long.parseLong(s1));
                if (menu.getMenuLevel() != null && menu.getMenuLevel() == j) {
                    Map mapParent = list1.get((int) mapLoaction.get(menu.getParentId()));
                    Map mapChild = list1.get((int) mapLoaction.get(menu.getMenuId()));
                    List<Map> childrenList = (List<Map>) mapParent.get("children");
                    childrenList.add(mapChild);
                    mapParent.put("children", childrenList);
                }
            }
        }
        //只取出一级标题
        for (int m = 0; m < list1.size(); m++) {
            String menuLevel = list1.get(m).get("menuLevel").toString();
            if (menuLevel.equals("1")) {
                list.add(list1.get(m));
            }
        }
        return list;
    }

对应的sql是

 <resultMap id="BaseResultMap" type="com.example.demo.enetity.Menu">
        <id column="menu_id" jdbcType="BIGINT" property="menuId"/>
        <result column="menu_name" jdbcType="VARCHAR" property="menuName"/>
        <result column="menu_path" jdbcType="VARCHAR" property="menuPath"/>
        <result column="menu_level" jdbcType="BIGINT" property="menuLevel"/>
        <result column="parent_id" jdbcType="BIGINT" property="parentId"/>
        <result column="menu_title" jdbcType="VARCHAR" property="menuTitle"/>
    </resultMap>
  <select id="selectAll" resultMap="BaseResultMap">
        select
         menu_id, menu_name, menu_path, menu_level, parent_id, menu_title
        from menu
    </select>
这种方法实现sql很简单,实现有点复杂,大概就是,盖房子一样,将第五级盖到第四级,然后第四级盖到第三级
知道第一级,然后最后取出层级为最高级的就可以啦。

2.sql实现
实现类就很简单

  @Override
    public ResponseBean uploadMenu2() {
        //需要新建一个vo类实现
        List<menuVo> menus = menuMapper.selectTreeList();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", menus);
        return CommonUtils.succssonJson(jsonObject);
    }
但是需要再新建一个vo对象,他比正常的对象多了一个children,用来存放下一级别的数据
package com.example.demo.VO;

import java.util.List;

public class menuVo {

    public List<menuVo> getChildren() {
        return children;
    }

    public void setChildren(List<menuVo> children) {
        this.children = children;
    }

    private List<menuVo> children;
    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column menu.menu_id
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    private Long menuId;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column menu.menu_name
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    private String menuName;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column menu.menu_path
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    private String menuPath;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column menu.menu_level
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    private Long menuLevel;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column menu.parent_id
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    private Long parentId;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column menu.menu_title
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    private String menuTitle;

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column menu.menu_id
     *
     * @return the value of menu.menu_id
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public Long getMenuId() {
        return menuId;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column menu.menu_id
     *
     * @param menuId the value for menu.menu_id
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public void setMenuId(Long menuId) {
        this.menuId = menuId;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column menu.menu_name
     *
     * @return the value of menu.menu_name
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public String getMenuName() {
        return menuName;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column menu.menu_name
     *
     * @param menuName the value for menu.menu_name
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public void setMenuName(String menuName) {
        this.menuName = menuName == null ? null : menuName.trim();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column menu.menu_path
     *
     * @return the value of menu.menu_path
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public String getMenuPath() {
        return menuPath;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column menu.menu_path
     *
     * @param menuPath the value for menu.menu_path
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public void setMenuPath(String menuPath) {
        this.menuPath = menuPath == null ? null : menuPath.trim();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column menu.menu_level
     *
     * @return the value of menu.menu_level
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public Long getMenuLevel() {
        return menuLevel;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column menu.menu_level
     *
     * @param menuLevel the value for menu.menu_level
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public void setMenuLevel(Long menuLevel) {
        this.menuLevel = menuLevel;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column menu.parent_id
     *
     * @return the value of menu.parent_id
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public Long getParentId() {
        return parentId;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column menu.parent_id
     *
     * @param parentId the value for menu.parent_id
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public void setParentId(Long parentId) {
        this.parentId = parentId;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column menu.menu_title
     *
     * @return the value of menu.menu_title
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public String getMenuTitle() {
        return menuTitle;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column menu.menu_title
     *
     * @param menuTitle the value for menu.menu_title
     *
     * @mbg.generated Mon Dec 30 15:20:24 CST 2019
     */
    public void setMenuTitle(String menuTitle) {
        this.menuTitle = menuTitle == null ? null : menuTitle.trim();
    }
}

sql就很多了,而且每多一个级就要加一次

 <select id="selectAll" resultMap="BaseResultMap">
        select
         menu_id, menu_name, menu_path, menu_level, parent_id, menu_title
        from menu
    </select>

    <resultMap id="treeList" type="com.example.demo.VO.menuVo">
        <id column="fir_menu_id" jdbcType="BIGINT" property="menuId"/>
        <result column="fir_menu_name" jdbcType="VARCHAR" property="menuName"/>
        <result column="fir_menu_path" jdbcType="VARCHAR" property="menuPath"/>
        <result column="fir_menu_level" jdbcType="BIGINT" property="menuLevel"/>
        <result column="fir_parent_id" jdbcType="BIGINT" property="parentId"/>
        <result column="fir_menu_title" jdbcType="VARCHAR" property="menuTitle"/>
        <collection property="children" ofType="com.example.demo.VO.menuVo">
            <id column="sec_menu_id" jdbcType="BIGINT" property="menuId"/>
            <result column="sec_menu_name" jdbcType="VARCHAR" property="menuName"/>
            <result column="sec_menu_path" jdbcType="VARCHAR" property="menuPath"/>
            <result column="sec_menu_level" jdbcType="BIGINT" property="menuLevel"/>
            <result column="sec_parent_id" jdbcType="BIGINT" property="parentId"/>
            <result column="sec_menu_title" jdbcType="VARCHAR" property="menuTitle"/>
            <collection property="children" ofType="com.example.demo.VO.menuVo">
                <id column="thi_menu_id" jdbcType="BIGINT" property="menuId"/>
                <result column="thi_menu_name" jdbcType="VARCHAR" property="menuName"/>
                <result column="thi_menu_path" jdbcType="VARCHAR" property="menuPath"/>
                <result column="thi_menu_level" jdbcType="BIGINT" property="menuLevel"/>
                <result column="thi_parent_id" jdbcType="BIGINT" property="parentId"/>
                <result column="thi_menu_title" jdbcType="VARCHAR" property="menuTitle"/>
                <collection property="children" ofType="com.example.demo.VO.menuVo">
                    <id column="four_menu_id" jdbcType="BIGINT" property="menuId"/>
                    <result column="four_menu_name" jdbcType="VARCHAR" property="menuName"/>
                    <result column="four_menu_path" jdbcType="VARCHAR" property="menuPath"/>
                    <result column="four_menu_level" jdbcType="BIGINT" property="menuLevel"/>
                    <result column="four_parent_id" jdbcType="BIGINT" property="parentId"/>
                    <result column="four_menu_title" jdbcType="VARCHAR" property="menuTitle"/>
                    <collection property="children" ofType="com.example.demo.VO.menuVo">
                        <id column="five_menu_id" jdbcType="BIGINT" property="menuId"/>
                        <result column="five_menu_name" jdbcType="VARCHAR" property="menuName"/>
                        <result column="five_menu_path" jdbcType="VARCHAR" property="menuPath"/>
                        <result column="five_menu_level" jdbcType="BIGINT" property="menuLevel"/>
                        <result column="five_parent_id" jdbcType="BIGINT" property="parentId"/>
                        <result column="five_menu_title" jdbcType="VARCHAR" property="menuTitle"/>
                    </collection>
                </collection>
            </collection>
        </collection>
    </resultMap>

h:测试
导入数据

insert  into `menu`(`menu_id`,`menu_name`,`menu_path`,`menu_level`,`parent_id`,`menu_title`) values (1,'一级菜单1','a',1,NULL,'下面有三个节点'),(2,'一级菜单2','b',1,NULL,'下面有零个节点'),(3,'一级菜单3','c',1,NULL,'下面有两个节点'),(4,'二级菜单1','d',2,1,'下面有一个节点'),(5,'二级菜单2','1',2,1,'下面有一个节点'),(6,'二级菜单3','2',2,3,'下面有0个节点'),(7,'二级菜单4','3',2,1,'下面有一个节点'),(8,'二级菜单5','4',2,3,'下面有一个节点'),(9,'三级菜单1','5',3,4,'下面有0个节点'),(10,'三级菜单2','q',3,5,'下面有0个节点'),(11,'三级菜单3','qe',3,7,'下面有2个节点'),(12,'三级菜单4','s',3,8,'下面有0个节点'),(13,'四季菜单1','s',4,11,'下面有1个节点'),(14,'四季菜单2','a',4,11,'下面有0个节点'),(15,'五级菜单','f',5,13,'下面有0个节点'),(16,'五级菜单1','11',5,14,'下面有0个节点');

然后postman发请求了localhost:8090/menu/load和localhost:8090/menu/load/ver2
然后就可以看结果了
a json数据{ "retCode": "1", "retMsg": "请求成功", "result": { "list": [ { "menuPath": "a", "children": [ { "menuPath": "d", "children": [ { "menuPath": "5", "children": [], "menuTitle": "下面有0个节点", "menuLevel": 3, "menuName": "三级菜单1", "id": 9, "parentId": 4 } ], "menuTitle": "下面有一个节点", "menuLevel": 2, "menuName": "二级菜单1", "id": 4, "parentId": 1 }, { "menuPath": "1", "children": [ { "menuPath": "q", "children": [], "menuTitle": "下面有0个节点", "menuLevel": 3, "menuName": "三级菜单2", "id": 10, "parentId": 5 } ], "menuTitle": "下面有一个节点", "menuLevel": 2, "menuName": "二级菜单2", "id": 5, "parentId": 1 }, { "menuPath": "3", "children": [ { "menuPath": "qe", "children": [ { "menuPath": "s", "children": [ { "menuPath": "f", "children": [], "menuTitle": "下面有0个节点", "menuLevel": 5, "menuName": "五级菜单", "id": 15, "parentId": 13 } ], "menuTitle": "下面有1个节点", "menuLevel": 4, "menuName": "四季菜单1", "id": 13, "parentId": 11 }, { "menuPath": "a", "children": [ { "menuPath": "11", "children": [], "menuTitle": "下面有0个节点", "menuLevel": 5, "menuName": "五级菜单1", "id": 16, "parentId": 14 } ], "menuTitle": "下面有0个节点", "menuLevel": 4, "menuName": "四季菜单2", "id": 14, "parentId": 11 } ], "menuTitle": "下面有2个节点", "menuLevel": 3, "menuName": "三级菜单3", "id": 11, "parentId": 7 } ], "menuTitle": "下面有一个节点", "menuLevel": 2, "menuName": "二级菜单4", "id": 7, "parentId": 1 } ], "menuTitle": "下面有三个节点", "menuLevel": 1, "menuName": "一级菜单1", "id": 1, "parentId": null }, { "menuPath": "b", "children": [], "menuTitle": "下面有零个节点", "menuLevel": 1, "menuName": "一级菜单2", "id": 2, "parentId": null }, { "menuPath": "c", "children": [ { "menuPath": "2", "children": [], "menuTitle": "下面有0个节点", "menuLevel": 2, "menuName": "二级菜单3", "id": 6, "parentId": 3 }, { "menuPath": "4", "children": [ { "menuPath": "s", "children": [], "menuTitle": "下面有0个节点", "menuLevel": 3, "menuName": "三级菜单4", "id": 12, "parentId": 8 } ], "menuTitle": "下面有一个节点", "menuLevel": 2, "menuName": "二级菜单5", "id": 8, "parentId": 3 } ], "menuTitle": "下面有两个节点", "menuLevel": 1, "menuName": "一级菜单3", "id": 3, "parentId": null } ] } }
b.json数据{ "retCode": "1", "retMsg": "请求成功", "result": { "list": [ { "children": [ { "children": [ { "children": [ { "children": [ { "children": null, "menuId": 15, "menuName": "五级菜单", "menuPath": "f", "menuLevel": 5, "parentId": 13, "menuTitle": "下面有0个节点" } ], "menuId": 13, "menuName": "四季菜单1", "menuPath": "s", "menuLevel": 4, "parentId": 11, "menuTitle": "下面有1个节点" }, { "children": [ { "children": null, "menuId": 16, "menuName": "五级菜单1", "menuPath": "11", "menuLevel": 5, "parentId": 14, "menuTitle": "下面有0个节点" } ], "menuId": 14, "menuName": "四季菜单2", "menuPath": "a", "menuLevel": 4, "parentId": 11, "menuTitle": "下面有0个节点" } ], "menuId": 11, "menuName": "三级菜单3", "menuPath": "qe", "menuLevel": 3, "parentId": 7, "menuTitle": "下面有2个节点" } ], "menuId": 7, "menuName": "二级菜单4", "menuPath": "3", "menuLevel": 2, "parentId": 1, "menuTitle": "下面有一个节点" }, { "children": [ { "children": [], "menuId": 9, "menuName": "三级菜单1", "menuPath": "5", "menuLevel": 3, "parentId": 4, "menuTitle": "下面有0个节点" } ], "menuId": 4, "menuName": "二级菜单1", "menuPath": "d", "menuLevel": 2, "parentId": 1, "menuTitle": "下面有一个节点" }, { "children": [ { "children": [], "menuId": 10, "menuName": "三级菜单2", "menuPath": "q", "menuLevel": 3, "parentId": 5, "menuTitle": "下面有0个节点" } ], "menuId": 5, "menuName": "二级菜单2", "menuPath": "1", "menuLevel": 2, "parentId": 1, "menuTitle": "下面有一个节点" } ], "menuId": 1, "menuName": "一级菜单1", "menuPath": "a", "menuLevel": 1, "parentId": null, "menuTitle": "下面有三个节点" }, { "children": [ { "children": [ { "children": [], "menuId": 12, "menuName": "三级菜单4", "menuPath": "s", "menuLevel": 3, "parentId": 8, "menuTitle": "下面有0个节点" } ], "menuId": 8, "menuName": "二级菜单5", "menuPath": "4", "menuLevel": 2, "parentId": 3, "menuTitle": "下面有一个节点" }, { "children": [], "menuId": 6, "menuName": "二级菜单3", "menuPath": "2", "menuLevel": 2, "parentId": 3, "menuTitle": "下面有0个节点" } ], "menuId": 3, "menuName": "一级菜单3", "menuPath": "c", "menuLevel": 1, "parentId": null, "menuTitle": "下面有两个节点" }, { "children": [], "menuId": 2, "menuName": "一级菜单2", "menuPath": "b", "menuLevel": 1, "parentId": null, "menuTitle": "下面有零个节点" } ] } }

到这里就全部做完了。
有人问我公共类方法是什么,我就分享下吧。

package com.example.demo.util;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;

public class CommonUtils {


    public static final String SUCCESS_CODE = "1";
    public static final String SUCCESS_MSG = "请求成功";

    public static ResponseBean succssonJson(JSONObject jsonObject) {
        ResponseBean responseBean = new ResponseBean();
        responseBean.setRetCode(SUCCESS_CODE);
        responseBean.setRetMsg(SUCCESS_MSG);
        responseBean.setResult(jsonObject);
        return responseBean;
    }

    public static ResponseBean succssonJson() {
        return succssonJson(new JSONObject());
    }

    public static ResponseBean errorJson(JSONObject jsonObject) {
        ResponseBean responseBean = new ResponseBean();
        responseBean.setRetCode("0");
        responseBean.setRetMsg("请求失败");
        return responseBean;
    }

    public static ResponseBean errorJson() {
        return errorJson(new JSONObject());
    }
}

公共的实体类

package com.example.demo.enetity;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.util.ErrorEnum;

public class ResponseBean {
    private String retCode;
    private String retMsg;
    private JSONObject result;

    public  ResponseBean(){

    }

    public ResponseBean(String retCode, String retMsg, JSONObject result) {
        this.retCode = retCode;
        this.retMsg = retMsg;
        this.result = result;
    }

    public ResponseBean(String retCode, String retMsg) {
        this.retCode = retCode;
        this.retMsg = retMsg;

    }

    public ResponseBean(ErrorEnum errorEnum) {
        this.retCode = errorEnum.getErrorCode();
        this.retMsg = errorEnum.getErrorMsg();
        this.result = new JSONObject();
    }


    public String getRetCode() {
        return retCode;
    }

    public String getRetMsg() {
        return retMsg;
    }

    public void setRetMsg(String retMsg) {
        this.retMsg = retMsg;
    }

    public JSONObject getResult() {
        return result;
    }

    public void setResult(JSONObject result) {
        this.result = result;
    }

    public void setRetCode(String retCode) {
        this.retCode = retCode;
    }
}

方法一是自己实现的,需要对逻辑很清楚,循环也比较多比较慢,但是一劳永逸了,写一次这个方法只要保证数据没问题就不会报错。
方法二通过vo接收,实现类就很简单但是sql就多表联了,而且层级是写死的,每次加一个级别的时候就需要改下sql了,但是代码看起来很清楚,各有优劣吧。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!