Mybatis框架学习笔记(5) ---[多表关联查询 连接到前端页面显示]

之前在第四次笔记中完成了;对于关联查询的情况
Mybatis框架学习笔记(4)

当然,之前的数据基本都在控制台显示,那么我想让它显示到前端的页面,怎么去完成呢;

1.首先解决一个问题;之前忘记创建web项目;怎么把普通的文件夹标记为能被识别的web文件夹

首先得去找存放web文件的文件夹了;

啊这,之前创建这个项目的时候,没有选择是web项目,忘记了…

在这里插入图片描述

那么,就得手动添加创建了;
在这里添加创建

在这里插入图片描述

在这里插入图片描述

但是,目前它没在src目录下的main目录
在这里插入图片描述

手动,搬过去,怎么说;
它的标记好像没了,变成了一个普通文件夹;
在这里插入图片描述

当然,为了让它和标准创建的web项目相同,我把文件夹web的名字改为webapp;也用不到jsp文件,那就删掉;
在这里插入图片描述

那么,首先得让它恢复标记;
在文件处点击项目结构;

在这里插入图片描述

这两处的路径需要手动改一下;双击文件,进行修改;

在这里插入图片描述

在这里插入图片描述

结束

在这里插入图片描述

这时,发现项目就已经被标记好了;

在这里插入图片描述

当然,要部署web项目,先去配置服务器
在这里插入图片描述

在这里插入图片描述

然后,先去pom.xml文件导入需要的依赖jar坐标

<dependencies>
        <!--需要的mybatis依赖jar包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!--数据库驱动连接的jar包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>

        <!--log4j日志包-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!--junit单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <!--这里的test标识,即表示它不会被打包-->
            <scope>test</scope>
        </dependency>

        <!--导入json需要的依赖-->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>

        <!--servlet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
</dependencies>

xiaozhi包下创建servlet包;
在前几次的整理测试时,注意到,调用公共类的这部分代码;以及调用持久层的方法;还是比较多的,
若是直接放在servlet层中去直接写的话;也是可行的;;但是在项目的整体架构上来看,这个耦合度就比较高;那么为了能尽量降低耦合度;就得在持久层(dao数据交互访问层)servlet(控制层)之间加一层(服务层service层);就是说,让持久层和控制层尽量不要直接接触,
比如说你要去租房子;一般来说;你不会直接去和房东进行沟通的;而是去找中介,然后中介在你和房东之间进行沟通;那么,添加的这个服务层就相当于一个中介;

在这里插入图片描述

xiaozhi包下创建service包;

2.员工查询展示,以及在搜索框输入Id后根据Id查询员工信息

OK,查询员工的话,展示比较简单;那就先做员工的查询展示;
mapper层的接口和配置文件这里就不重复去写了;
Mybatis框架学习笔记(4)–>之中有整理

先在webapp文件夹下创建一个js文件夹;把jquery.1.8.3.min.js文件放入;

当然,先去创建一个简易的字符编码过滤器;
xiaozhi包下创建filter包,创建EncodingFilter,进行字符编码过滤;

package com.xiaozhi.filter;

import javax.servlet.*;
import java.io.IOException;

/**
 * @author by CSDN@小智RE0
 * @date 2021-10-30 15:20
 */
public class EncodingFilter implements Filter{
    String encode;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //接收初始化参数;
        encode = filterConfig.getInitParameter("encode");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("字符编码过滤中.......................");
        servletRequest.setCharacterEncoding(encode);
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
    }
}

webapp下的WEB-INFweb.xml中配置过滤器;

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--配置过滤器-->
    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.xiaozhi.filter.EncodingFilter</filter-class>
        <!--初始化参数-->
        <init-param>
            <param-name>encode</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/do/*</url-pattern>
    </filter-mapping>
</web-app>

service包下创建EmployeeService;员工类的服务层;

package com.xiaozhi.service;

import com.xiaozhi.mapper.EmployeeMapper;
import com.xiaozhi.pojo.Employee;
import com.xiaozhi.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
/**
 * @author by CSDN@小智RE0
 * @date 2021-10-29 21:55
 * 员工类的服务层
 */
public class EmployeeService {

    //查询所有的员工;
    public List<Employee> getAllEmployees(){
        //调用工具类;
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //获取代理对象;
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        //调用方法;
        List<Employee> allEmp = mapper.getAllEmp();
        //关闭;
        sqlSession.close();
        //传递到控制层;
        return allEmp;
    }

    //根据Id查询员工;
    public Employee getEmpById(Integer id){
        //调用工具类;
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //获取代理对象;
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        //调用方法;
        Employee employee = mapper.getEmpById(id);
        //关闭sqlSession;
        sqlSession.close();
        return employee;
    }

}

servlet包下创建EmployeeServlet,获取前端的参数;这里会调用服务层的方法进行处理,

package com.xiaozhi.servlet;

import com.google.gson.Gson;
import com.xiaozhi.pojo.Employee;
import com.xiaozhi.service.EmployeeService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @author by CSDN@小智RE0
 * @date 2021-10-29 21:56
 * 员工管理的servlet处理
 */
public class EmployeeServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("-----在员工管理请求数据---");
        PrintWriter out=null;

        //获取到标记参数;
        String mark = req.getParameter("mark");
        //查询所有的员工
        if(mark.equals("empList")){
            try {
                //请求编码;响应解码;
                resp.setContentType("text/html;charset=utf-8");
                //会以流的方式返回;
                out = resp.getWriter();

                //这里会调用服务层进行处理;
                EmployeeService employeeService = new EmployeeService();
                List<Employee> allEmployees = employeeService.getAllEmployees();
                //控制台输出测试;
                allEmployees.forEach(System.out::println);
                //不为空就发出去;
                if(!allEmployees.isEmpty()){
                    //以json格式发送到前端页面进行响应;
                    out.print(new Gson().toJson(allEmployees));
                }else {
                    out.print(0);//-->抱歉,暂时没有员工
                }
            } catch (IOException e) {
                e.printStackTrace();
                out.print(500);
            }
        }

        //根据Id查询员工;
        else if(mark.equals("getEmpById")){
            try{
                //请求编码;响应解码;
                resp.setContentType("text/html;charset=utf-8");
                //会以流的方式返回;
                out = resp.getWriter();

                //获取传递的Id;
                String empId = req.getParameter("empId");

                //这里会调用服务层进行处理;
                EmployeeService employeeService = new EmployeeService();
                //根据ID查询员工;
                Employee emp = employeeService.getEmpById(Integer.parseInt(empId));

                //控制台输出测试;
                System.out.println(emp);
                //不为空才发出去;
                if(emp!=null){
                    //以Json字符串格式返回;
                    out.print(new Gson().toJson(emp));
                }else {
                    out.print(0);//-->抱歉,员工不存在
                }
            }catch (Exception e){
                e.printStackTrace();
                out.print(500);
            }
        }
    }
}

当然,还要在webapp下的WEB-INFweb.xml中配置servlet;

<!--配置员工servlet-->
<servlet>
    <servlet-name>empServlet</servlet-name>
    <servlet-class>com.xiaozhi.servlet.EmployeeServlet</servlet-class>
</servlet>
<!--servlet映射-->
<servlet-mapping>
    <servlet-name>empServlet</servlet-name>
    <url-pattern>/do/emp</url-pattern>
</servlet-mapping>

webapp文件夹下创建index.html,一个简易的跳转首页;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>简易首页</title>
</head>
<body>
  <a href="employee.html">员工列表</a>
  <a href="dept.html">部门列表</a>
</body>
</html>

员工的展示页面;

webapp新建的employee.html作为员工的展示页面

这个页面就比较粗糙了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>员工列表</title>
    <!--部署jquery-->
    <script src="js/jquery.1.8.3.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        //页面打开时发送请求;
        $(function () {
            $.get("do/emp", {mark: "empList"}, function (res) {
                //测试获取的数据;
                //console.log(res)
                if(res==500){
                    alert("抱歉,服务器出了点问题");
                }else if(res==0){
                    //弹框提示;
                    alert("抱歉,暂时没有员工!")
                }else {
                    //拼接存入表格;
                    var str2="";
                    for (var i = 0; i < res.length; i++) {
                        str2+="<tr class='allEmpClass' align='center'>";
                        str2+="<td>"+(i+1)+"</td>";
                        str2+="<td>"+res[i].name+ "</td>";
                        str2+="<td>"+res[i].sex+ "</td>";
                        str2+="<td>"+res[i].dept.name+ "</td>";
                        str2+="<td>"+res[i].user.account+ "</td>";
                        str2+="</tr>";
                    }
                    $("#table").append(str2);
                }

            }, "json");
        });

        //点击搜索时,查询员工;
        function getEmp(){
            //先判断是否输入了;
            var idVal = $("input[name='id']").val();
            if((idVal.trim()).length==0){
                alert("请输入要查询的员工Id.");
            }else {
                //发送请求;进行查询;
                $.get("do/emp",{mark:"getEmpById",empId:idVal},function (res){
                    if(res==500){
                        alert("抱歉,服务器出了点问题");
                    }else if(res==0){
                        //清除上一次的查询信息;
                        $(".oneEmpClass").empty();
                        //弹框提示;
                        alert("该员工不存在!!!");
                    }else {
                        //同样地,先清除全部的信息;
                        $(".allEmpClass").empty();
                        //清除上一次的查询信息;
                        $(".oneEmpClass").empty();
                        //拼接显示数据; 注意,携带的Class为 oneEmpClass
                        var str4="";
                        str4+="<tr class='oneEmpClass' align='center'>";
                        str4+="<td>"+1+"</td>";
                        str4+="<td>"+res.name+ "</td>";
                        str4+="<td>"+res.sex+ "</td>";
                        str4+="<td>"+res.dept.name+ "</td>";
                        str4+="<td>"+res.user.account+ "</td>";
                        str4+="</tr>";
                        $("#table").append(str4);
                    }
                },"json")
            }
        }

        //点击全部员工,刷新页面;
        function getAll(){
            location.reload();
        }

    </script>
</head>
<body>
<form style="width: 1080px" id="form">
    <label>
        <input type="text" name="id" placeholder="请输入要查询的Id:"/>
    </label>
    <input  type="button" value="搜索" onclick="getEmp()"/>
    <!--当然为了能够调回之前的全部员工,再次加载一次这个页面-->
    <input type="button" value="显示全部员工" onclick="getAll()">
</form>
<br/>
<!--显示的表格-->
<table width="100%" border="1" cellspacing="0" id="table">
    <th>编号</th>
    <th>员工姓名</th>
    <th>员工性别</th>
    <th>所属部门</th>
    <th>操作人</th>
</table>
</body>
</html>

展示效果;
我在做这个显示列表时,给tr标签都加了一个类名allEmpClass

在这里插入图片描述

点击搜索时,会把之前的全部内容给清空;也就是说,会把类名class为allEmpClass的行清空;然后还在这时给查询到的显示的指定员工那行的tr标签携带定义了一个类名class为 oneEmpClass;

所以还要考虑到还想看全部的员工;那么我就添加了一个显示全部员工的按钮,比较粗糙了;
直接用location的刷新函数reload()把页面重新刷新了一次,然后再次请求查询全部的员工;

在这里插入图片描述

然后,在查不到员工的情况的时候;

当时做的时候,考虑的是,

  • 删除所有显示的员工;就是清空定义了类名class为allEmpClasstr标签;
  • 删除之前已经查询到的信息;也就是说,我要把之前可能查到的员工那一行信息删除掉 ;也就是类名class为oneEmpClasstr标签;
  • 然后在表格上显示提示信息的字符串;

但是,经过频繁的测试;(先查询能查到的,然后查询查不到的;…往返试试有什么bug;)就是数据会覆盖;
暂时没想到怎么解决;

所以,就先用alert("该员工不存在!!!");的弹框进行提示;
然后效果就是,弹框提示;
还可以删除之前查询的存在的员工数据信息;

在这里插入图片描述

在这里插入图片描述

然后,这个刷新按钮就比较普通了;哈哈

在这里插入图片描述


3.部门信息查询(查询显示所有部门,且显示员工信息);(根据输入框的Id查询部门的信息)

先在service包下创建DeptService部门类服务层;

package com.xiaozhi.service;

import com.xiaozhi.mapper.DeptMapper;
import com.xiaozhi.pojo.Dept;
import com.xiaozhi.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.List;
/**
 * @author by CSDN@小智RE0
 * @date 2021-10-29 21:54
 * 部门类的服务层
 */
public class DeptService {
    //查询所有的部门;会包括部门的员工;
    public List<Dept> getAllDept(){
        //调用工具类;
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //获取代理类对象;
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        //调用方法;
        List<Dept> allDept = mapper.getAllDept();
        //关闭sqlSession;
        sqlSession.close();
        return allDept;
    }

    //根据Id查询部门;
    public Dept getDeptById(Integer id){
        //调用工具类;
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //获取代理类对象;
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        //调用方法;
        Dept deptById = mapper.getDeptById(id);
        //关闭sqlSession;
        return deptById;
    }
}

servlet包下创建DeptServlet,处理数据;

package com.xiaozhi.servlet;

import com.google.gson.Gson;
import com.xiaozhi.pojo.Dept;
import com.xiaozhi.service.DeptService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @author by CSDN@小智RE0
 * @date 2021-10-29 21:55
 * 部门类的servlet层处理
 */
public class DeptServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out=null;
        //获取到标记参数;
        String mark = req.getParameter("mark");
        //查询所有的部门;
        if(mark.equals("deptList")){
            try{
                //请求编码;响应解码;
                resp.setContentType("text/html;charset=utf-8");
                //会以流的方式返回;
                out = resp.getWriter();
                //调用;
                DeptService deptService = new DeptService();
                List<Dept> allDept = deptService.getAllDept();

                //控制台输出;
                allDept.forEach(System.out::println);

                //不为空就响应;
                if(!allDept.isEmpty()){
                    //以json格式的字符串返回;
                    out.print(new Gson().toJson(allDept));
                }else {
                    out.print(0);//->抱歉,部门不存在;
                }
            }catch (Exception e){
                e.printStackTrace();
                out.print(500);
            }
        }

        //根据ID查询部门;
        else if(mark.equals("getDeptById")){
            try {
                //请求编码;响应解码;
                resp.setContentType("text/html;charset=utf-8");
                //会以流的方式返回;
                out = resp.getWriter();

                //获取传递的Id,
                String deptId = req.getParameter("deptId");

                System.out.println("--测试->"+deptId);

                //调用;
                DeptService deptService = new DeptService();
                Dept deptById = deptService.getDeptById(Integer.parseInt(deptId));

                //若存在就响应数据;
                if(deptById!=null){
                    //以JSon字符串的格式返回;
                    out.print(new Gson().toJson(deptById));
                }else {
                    out.print(0);//->抱歉,没有部门;
                }
            }catch (Exception e){
                e.printStackTrace();
                out.print(500);
            }
        }
    }
}

需要在WEB-INF下的web.xml配置servlet

<!--配置部门servlet-->
<servlet>
    <servlet-name>deptServlet</servlet-name>
    <servlet-class>com.xiaozhi.servlet.DeptServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>deptServlet</servlet-name>
    <url-pattern>/do/dept</url-pattern>
</servlet-mapping>

刚才的员工查询是单个数据;而部门查询的话,还需要显示部门下的员工姓名;
所以在前端表格页面需要两层循环存放数据;

webapp文件夹下创建dept.html,作为部门展示页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>部门列表</title>
    <!--部署JQuery-->
    <script src="js/jquery.1.8.3.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        //页面加载时,就会显示所有的信息;
        $.get("do/dept",{mark:"deptList"},function (res){
            //测试;
            //console.log(res)

            if(res==500){
                alert("抱歉,服务器出了点问题");
            }else if(res==0){
                //弹框提示;
                alert("抱歉,暂时没有部门!")
            }else{
                //拼接字符串; 这里会为这些行加上类名信息;
                //需要两层循环取到员工的姓名信息;
                var str="";
                for (var i = 0; i < res.length; i++) {
                    str+="<tr class='allDeptClass'>";
                    str+="<td>"+(i+1)+"</td>";
                    str+="<td>"+res[i].name+"</td>";
                    str+="<td>"+res[i].user.account+"</td>";
                    //遍历员工;
                    str+="<td>";
                    for (var j = 0; j < res[i].employees.length; j++) {
                        str+=res[i].employees[j].name +"  ";
                    }
                    str+="</td>";
                    str+="</tr>";
                }
                //拼接到表格;
                $("#table").append(str);
            }
        },"json");

        //根据Id查询部门;
        function  getDeptById(){
            //先看输入框有没有东西;
            var idVal = $("input[name='id']").val();
            if((idVal.trim()).length==0){
                alert("请输入ID后查询")
            }else {
                //发送请求;包括ID;
                $.get("do/dept",{mark: "getDeptById",deptId:idVal},function (res){
                    //测试;
                    console.log(res)

                    if(res==500){
                        alert("抱歉,服务器出了点问题");
                    }else if(res==0){
                        //清除上一次查询的结果;
                        $(".oneDeptClass").empty();
                        //弹框提示;
                        alert("抱歉,当前部门不存在");
                    }else{
                        //先清空原先的全部信息;
                        $(".allDeptClass").empty();
                        //清除上一次查询的信息;
                        $(".oneDeptClass").empty();

                        //拼接字符串; 这里赋予类名为oneDeptClass
                        var str2="";
                            str2+="<tr class='oneDeptClass'>";
                            str2+="<td>"+1+"</td>";
                            str2+="<td>"+res.name+"</td>";
                            str2+="<td>"+res.user.account+"</td>";
                            str2+="<td>";
                        for (var i = 0; i < res.employees.length; i++) {
                            str2+=res.employees[i].name +"  ";
                        }
                            str2+="</td>";
                        str2+="</tr>";
                        $("#table").append(str2);
                    }
                },"json");
            }
        }

        //点击显示所有部门;刷新一次页面;
        function getAll(){
            location.reload();
        }

    </script>
</head>
<body>
<form style="width: 1080px" id="form">
    <label>
        <input type="text" name="id" placeholder="请输入要查询的Id:"/>
    </label>
    &nbsp; &nbsp; &nbsp;
    <input type="button" value="搜索" onclick="getDeptById()"/>
    &nbsp; &nbsp; &nbsp; &nbsp;
    <!--当然为了能够调回之前的全部部门,再次加载一次这个页面-->
    <input type="button" value="显示全部部门" onclick="getAll()">
</form>
<br/>
<table  width="100%" border="1" cellspacing="0" id="table">
    <th>编号</th>
    <th>部门名称</th>
    <th>操作人</th>
    <th>部门员工</th>
</table>
</body>
</html>

显示页面

同样地,我在拼接这些表格行的时候,给他们的tr标签定义共同的class类名为allDeptClass;
方便统一操作;
然后,由于一次性的查询到的部门对象中包含有员工的集合;所以要双层循环取到里面的员工姓名;

在这里插入图片描述

然后就是这个搜索框;
先说能查到部门的情况;

在显示数据之前,会清空class类名为allDeptClasstr标签行;也就是清空数据;
当然还要考虑到用户在连续查询两次或多次的情况;
所以还要清除之前查询的数据;
那么,在显示这个查询数据的时候,我就给他定义了class类名为oneDeptClass;
查询的时候还会清除class类名为oneDeptClasstr标签行

为啥要定义类名呢?;这个;我试过定义Id,但是;这个所谓的清空其实不是清空所有,而是清空里面的内容;也就是说结构还在;要是定义Id的话,我去调用empty()函数清空,由于Id是唯一的;它就只能清除出现的第一个;看起来只是一行数据,其实已经不知不觉存了多行tr标签;

在这里插入图片描述

其实,只是清空数据,结构还在;

在这里插入图片描述

多查询几次试试;
比如说我查询了三次,他那个结构就出现了三行;之前的会被存起来;

在这里插入图片描述

查询不到的情况;会清除之前可能查询的class类名为oneDeptClasstr标签行

在这里插入图片描述

显示全部部门;location对象的reload()函数刷新页面

在这里插入图片描述

查询这部分暂时结束;很多地方还需要优化的;
比如说我在查询时的 清空;都是调用了 empty()函数 ;去完成清空的;
这要是数据量大的话,或者被大量地查询,会不会出现一些问题;
还有弹框的使用确实不太美观;
所以说,还要继续学习,努力提升自己的技能

OK,终于找到办法去删除表格中之前的数据了;而且不会在页面中产生冗余的类名代码;

只需要;在发出请求之前;清除页面的表格第一行之外的所有<tr>标签内容即可

$("tr:gt(0)").remove();

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小智RE0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值