SSM框架的搭建及项目开发的步骤

第一阶段:

1、用PowerDesign建数据模型,并导出SQL文件;

2、将SQL文件导入到MySQL客户端,建立表格;

  MySQL数据远程访问:GRANT ALL PRIVILEGES ON . TO ‘root’@’%’IDENTIFIED BY ‘mypassword’ WITH GRANT OPTION;

如果是固定IP:grant all privileges on . to ‘root’@’192.168.41.100’identified by ‘123456’ with grant option;

//推送设置到内存或重启服务器也行
mysql>FLUSH PRIVILEGES

3、使用MyBatis框架,搭建DAO层:——————————-Mybatis—————————————

  1)数据库连接的信息:驱动类、连接地址、用户名、密码

  2)targetPackage=”com.softjx.model”

  3)把表名与类名对应

  4)运行GeneratorSqlmap.java生成dao和model

第二阶段:

1、在MyEclipse上新建一个Web项目,并导入ssm所需的jar包,放在WEB-INF/lib目录下;

2、将第一阶段通过Mybatis框架生成的model和dao复制到当前项目;—————–Dao层—————-

3、搭建Service层:建com.softjx.service与com.softjx,service,impl包;————-spring层—————

4、将需要相关的配置文件
(mybatisconfig.xml,dbconfig.properties,applicationContext.xml,log4j.properties)放到src目录下;

  1)修改dbconfig.properties文件,ip,数据库,用户名,密码

  2)修改applicationContext.xml中的包名,目录名

5、在com.softjx.service包中写接口,在com.softjx.service.impl写接口的实现。
  注意:com.softjx.service.impl写接口的实现,
  @Service(“studentService”)
  @Transactional

  
  类中注入
  @Autowired
  private StudentMapper studentMapper;

7.单元测试:
  要注意mysql数据库中主键要自增,这一步要我们去mysql中设置。
  studentService = (StudentService) context.getBean(“studentService”);
  这个”studentService”是从@Service(“studentService”)

第三阶段:

1、修改WebRoot目录下的web.xml如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 7   <display-name></display-name>
 8   
 9   
10   
11     <!-- 配置启动 Spring IOC 容器的 Listener,启动spring容器 -->
12     <context-param>
13         <param-name>contextConfigLocation</param-name>
14         <param-value>classpath:applicationContext.xml</param-value>
15     </context-param>
16 
17     <listener>
18         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
19     </listener>
20 
21 
22     <!-- 表单提交controller获得中文参数后乱码解决方案 注意: jsp页面编码设置为UTF-8 form表单提交方式为必须为post,get方式下面spring编码过滤器不起效果 -->
23 
24     <filter>
25         <filter-name>characterEncodingFilter</filter-name>
26         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
27         <init-param>
28             <param-name>encoding</param-name>
29             <param-value>UTF-8</param-value>
30         </init-param>
31         <init-param>
32             <param-name>forceEncoding</param-name>
33             <param-value>true</param-value>
34         </init-param>
35     </filter>
36     <filter-mapping>
37         <filter-name>characterEncodingFilter</filter-name>
38         <url-pattern>/*</url-pattern>
39     </filter-mapping>
40 
41 
42     <!-- 可以把 POST 请求转为 DELETE 或 PUT 请求 -->
43 
44     <filter>
45         <filter-name>HiddenHttpMethodFilter</filter-name>
46         <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
47     </filter>
48 
49     <filter-mapping>
50         <filter-name>HiddenHttpMethodFilter</filter-name>
51         <url-pattern>/*</url-pattern>
52     </filter-mapping>
53 
54 
55 
56     <!-- 配置 DispatcherServlet -->
57     <servlet>
58         <servlet-name>dispatcherServlet</servlet-name>
59         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
60 
61         <init-param>
62             <param-name>contextConfigLocation</param-name>
63             <param-value>classpath:springmvc.xml</param-value>
64         </init-param>
65 
66         <load-on-startup>1</load-on-startup>
67 
68     </servlet>
69 
70     <servlet-mapping>
71         <servlet-name>dispatcherServlet</servlet-name>
72         <url-pattern>/</url-pattern>
73     </servlet-mapping>
74   
75   
76   
77   
78   
79       
80   <welcome-file-list>
81     <welcome-file>index.jsp</welcome-file>
82   </welcome-file-list>
83 </web-app>

2、在src目录下建立springmvc.xml文件,文件内容如下:———-SpringMVC层—————-

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <!-- 配置自定扫描的包 -->
    <context:component-scan base-package="com.softjx" use-default-filters="false">
        <context:include-filter type="annotation" 
            expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>


    <!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>


    <!-- 处理静态资源 -->
    <mvc:default-servlet-handler/>


    <!-- 默认配置方案。
    并提供了:数据绑定支持,@NumberFormatannotation支持,
    @DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),
    读写JSON的支持(Jackson)。
          后面,我们处理响应ajax请求时,就使用到了对json的支持。
     -->
    <mvc:annotation-driven></mvc:annotation-driven>




</beans>

3、在src目录下新建com.softjx.action包,在包里建Action类;

注意:1)@Controller
@RequestMapping(“/student”)

  2)每个方法:
@RequestMapping(“/studentAddInput”)

  3) 类中注入
  @Autowired
  private StudentService studentService;//通过studentService调用Service里的方法调用Dao层

4、在WEB-INF目录下创建views文件,用来放置所有.jsp文件,这个jsp文件名是作为Action中方法 return的值。;

注意:1)在WEB-INF目录下的jsp页面只能通过程序来访问,外部访问不到。(安全)

    2)添加页面的jsp,要注意控件的属性名是javabean的属性名。 

———————–第四阶段—————————
1.dao层(mybatis)
2.service层(spring)
3.单元测试
4.action(springmvc)
5.jsp html,htm (界面)

1)查询所有数据

2)单条件查询

3)多条件查询

4)分页查询

5) 单条件分页查询

6)多添加分页查询

7) 修改(先查询单个实体)

8)删除(先查询单个实体)

———————–第五阶段—————————
1)文件上传
a.要导入commons-fileupload-1.2.1.jar,commons-io-2.0.jar这两个包

b.

<!-- 配置 MultipartResolver 上传文件-->        
      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"></property>
        <property name="maxUploadSize" value="10240000"></property> 
      </bean>   

c.在WEB-INF同一层目录中建一个upload目录

d.上传文件的jsp界面

<form action="student/checkFileUpload" method="POST" enctype="multipart/form-data">
        文件: <input type="file" name="file"/>
                描述: <input type="text" name="desc"/>
        <input type="submit" value="上传数据"/>
   </form>

e.编写上传文件的action

2)文件下载
a.在WEB-INF同一层目录中建一个upload目录
b.下载的url:
通过 文件流 的方式下载文件hibernate1.jpg
c.编写下载文件的action

———————–第六阶段—————————
1.把数据库中数据导出到excel
1)导入包poi-3.2-FINAL-20081019.jar
2)在action中写代码
3)注意excel表格中的各种格式

———————–第七阶段(两个表查询,有关系)—————————
一.根据条件查询
1).掌握多表查询


select a.*,b.* from student a,school b where a.t_sid=b.t_id

select a.t_id,a.t_name,a.t_age,a.t_enterdate,b.t_name as t_name1 from student a,school b where a.t_sid=b.t_id

select a.t_id,a.t_name,a.t_age,a.t_enterdate,b.t_name as t_name1 from student a LEFT JOIN school b on a.t_sid=b.t_id

2).设计实体类中要关联类,在Student类中有School类的引用。

private School school;
    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

3)在StudentMapper.xml编写sql语句

<!-- 返回多表查询的字段名 -->
  <resultMap id="WithSchoolResultMap" type="com.softjx.model.Student" >
    <id column="t_id" property="tId" jdbcType="INTEGER" />
    <result column="t_name" property="tName" jdbcType="VARCHAR" />
    <result column="t_age" property="tAge" jdbcType="INTEGER" />
    <result column="t_enterdate" property="tEnterdate" jdbcType="TIMESTAMP" />
    <result column="t_sid" property="tSid" jdbcType="INTEGER" />
     <!-- 指定联合查询出的学校字段-->
    <association property="school" javaType="com.softjx.model.School">
        <id column="t_id1" property="tId"/>
        <result column="t_name1" property="tName"/>
    </association>
  </resultMap>


  <!-- 多表查询的字段名 -->
   <sql id="Student_School_Column_List">
    a.t_id, a.t_name, a.t_age, a.t_enterdate, a.t_sid,b.t_id as t_id1,b.t_name as t_name1
   </sql>


  <!-- 查询学生同时带学校信息 -->
  <select id="selectByExampleWithSchool" resultMap="WithSchoolResultMap">
       select
        <if test="distinct">
          distinct
        </if>
        <include refid="Student_School_Column_List" />
        FROM student a
        left join school b on a.t_sid=b.t_id
        <if test="_parameter != null">
          <include refid="Example_Where_Clause" />
        </if>
        <if test="orderByClause != null">
          order by ${orderByClause}
        </if>
  </select>

4).在dao中编写一个接口
//多表查询
List selectByExampleWithSchool(StudentExample example);

5).在service层编写接口与接口的实现

//多表查询
     public List<Student> getStudentWithSchool(StudentExample studentExample);

         public List<Student> getStudentWithSchool(StudentExample studentExample) {

        return studentMapper.selectByExampleWithSchool(studentExample);
    }

6)编写单元测试多表查询。

二.根据主键查询两个表
1) .select a.t_id,a.t_name,a.t_age,a.t_enterdate,b.t_name as t_name1 from student a LEFT JOIN school b on a.t_sid=b.t_id where a.t_id=3

2).设计实体类中要关联类,在Student类中有School类的引用。

 private School school;
    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

3).在StudentMapper.xml编写sql语句

<!-- 返回多表查询的字段名 -->
  <resultMap id="WithSchoolResultMap" type="com.softjx.model.Student" >
    <id column="t_id" property="tId" jdbcType="INTEGER" />
    <result column="t_name" property="tName" jdbcType="VARCHAR" />
    <result column="t_age" property="tAge" jdbcType="INTEGER" />
    <result column="t_enterdate" property="tEnterdate" jdbcType="TIMESTAMP" />
    <result column="t_sid" property="tSid" jdbcType="INTEGER" />
     <!-- 指定联合查询出的学校字段-->
    <association property="school" javaType="com.softjx.model.School">
        <id column="t_id1" property="tId"/>
        <result column="t_name1" property="tName"/>
    </association>
  </resultMap>


  <!-- 多表查询的字段名 -->
   <sql id="Student_School_Column_List">
    a.t_id, a.t_name, a.t_age, a.t_enterdate, a.t_sid,b.t_id as t_id1,b.t_name as t_name1
   </sql>


  <!-- 主键查询多表数据 -->
   <select id="selectByPrimaryKeyWithSchool" resultMap="WithSchoolResultMap">
    select 
    <include refid="Student_School_Column_List" />
    FROM student a
        left join school b on a.t_sid=b.t_id
    where a.t_id = #{tId,jdbcType=INTEGER}
  </select>

4).在dao中编写一个接口
Student selectByPrimaryKeyWithSchool(Integer tId);

5)在service层编写接口与接口的实现

 public Student selectByPrimaryKeyWithSchool(Integer tId);

    public Student selectByPrimaryKeyWithSchool(Integer tId) {

        return studentMapper.selectByPrimaryKeyWithSchool(tId);
    }

6)编写单元测试主键查询多个表中的数据。

——————————第八阶段springmvc使用拦截器———————
1.编写一个类继承HandlerInterceptor接口
在这个方法中实现业务

public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object arg2) throws Exception {
        System.out.println("第一个拦截器中的 preHandle方法被调用");

                        //1).从sesion中获取用户对象
            //2).用当前用户所拥有的菜单url是否包含当前请求
        }

2.配置springmvc的配置文件,添加拦截器

 <mvc:interceptors>

         <!--局部拦截器配置, 配置拦截器不作用的路径 ,要先配置<mvc:mapping path="/**" /> ,否则报错,不能少这个-->
        <mvc:interceptor>
        <mvc:mapping path="/**" />  
        <mvc:exclude-mapping path="/login/**"/>
        <bean class="com.softjx.interceptor.ActionMethodInterceptor"></bean>
        </mvc:interceptor>  

3.登录时要保存当前用户对象到session

——————–第九阶段 mybatis使用三表或者更多表查询——————–
一.不使用数据库中的多表查询(使用用户多,十万,百万,千万,亿)
思想:
1.查询学生表
2.根据学生所有学校的id,查询对应学校名称
3.根据学校的区域id查询区域名
4.用查询的数据组装一个vo(view object)(javabean), 这个javabean只是显示在界面上的。
5.多个vo组装ArrayList中
6.显示ArrayList中的数据

如何做:
1.要把以前写的两个表的关联xml复制到一个地方,使用生成框架,生成后添加方法到dao中和xml中
2.新建一个javabean ,是一个vo
3.在service中编写一个方法,返回一个vo的集合类型。(这个里面要仔细看下)
4.测试一下这个方法。

二.使用数据库中的多表查询(使用用户一般几百,几千,几万)

SELECT  a.*,b.*,c.*  from student a,school b,areatable c where a.t_sid=b.t_id and b.t_area_id=c.t_id

SELECT  a.t_id,a.t_name,a.t_age,a.t_enterdate,b.t_name as t_name1,c.area  from student a,school b,areatable c where a.t_sid=b.t_id and b.t_area_id=c.t_id

思想:
1.使用sql语句
2.在StudentMapper接口中写方法
3.要在StudentMapper.xml中写sql语句实现
1)编写一个
2)编写接口中方法的实现

  <resultMap id="BaseSqlResultMap" type="com.softjx.vo.StudentSchoolAreaVo" >
    <id column="t_id" property="id" jdbcType="BIGINT" />
    <result column="t_name" property="name" jdbcType="VARCHAR" />
    <result column="t_age" property="age" jdbcType="TINYINT" />
    <result column="t_enterdate" property="enterDate" jdbcType="DATE" />
    <result column="t_name1" property="schoolName" jdbcType="VARCHAR" />
    <result column="area" property="areaName" jdbcType="VARCHAR" />
  </resultMap>


   <select id="getStudentSchoolAreaSqlVo" resultMap="BaseSqlResultMap">
       SELECT  a.t_id,a.t_name,a.t_age,a.t_enterdate,b.t_name as t_name1,c.area  from student a,school b,areatable c 
       where a.t_sid=b.t_id and b.t_area_id=c.t_id
  </select>

4.在service中编写接口方法与实现。

——————–第十阶段 使用jquery中的ajax技术——————–
1.需要一个jquery的类库.js 放到static目录下,要注意拦截器放行。
2.jsp中导入js类库。

<script type="text/javascript" src="static/js/jquery-1.8.3.js"></script>

jquery的环境搭建完毕。

3.在springmvc中开发一个业务方法。

 @ResponseBody//返回的数据是json数据
  @RequestMapping("/studentName")
public List<Student> getStudentName(Map<String, Object> map, Student student) 
{
StudentExample studentExample = new StudentExample();
Criteria criteria = studentExample.createCriteria();

if (student.gettName() != null && !student.gettName().trim().equals(""))
criteria.andTNameEqualTo(student.gettName());

List<Student> students = studentService.getStudents(studentExample);
return students;
}

注意:1)返回值是对象类型或者是基本类型,2)@ResponseBody//返回的数据是json数据

4.在jsp页面上控制我们操作的构件,使用jquery的选择器,选中此对象。

5.编写ajax代码

<script type="text/javascript">

$(document).ready(
function(){

 $("#nameid").blur( 

        function()
        {   

        //真实场景下的ajax调用      
        $.ajax(
        {

                  url: "student/studentName1",

                  cache: false,

                  type: "GET",

                  dataType:"json",

                  async: true,

                  data: {tName:$("#nameid").val()},

                  success: function(msg){ 

                     //业务代码,改变页面的数据          
                     //alert(msg);
                     if (msg==true)
                     {

                      $("#namewrongid").text("此用户名存在!");
                      $("#nameid").focus();
                     }

                     else
                     {
                       $("#namewrongid").text("此用户名不存在!");
                       $("#ageid").focus();
                     }


                   },

                  error:function(errordata){
                    alert("wrong!!"+errordata);
                   }

                }

                );


        }

        );          

}

);

</script> 

——————–第十一阶段 使用jquery中的ajax技术加载ztree——————–
1.要构建菜单类

 private Integer id;
    //定义属性要注意pId和zTree要一样   
    private Integer pId;
    private String name;
    private boolean open;
    //定义属性要注意isParent和zTree要一样
    private boolean isParent;

     //定义方法要注意getisParent()
    public boolean getisParent() {
        return isParent;
    }

    //定义方法要注意setisParent()
    public void setisParent(boolean isParent) {
        this.isParent = isParent;
    }
    //要注意
    public Integer getpId() {   
               return pId;   
            } 

    //要注意
        public void setpId(Integer pId) {   
               this.pId = pId;   
      }  

2.编写action方法,返回json
构建菜单时注意父子关系

 @ResponseBody//返回的数据是json数据
            @RequestMapping("/ZtreeMenu")
            public List<MenuItem> ztreePageData() {

                List<MenuItem>  menulist=new ArrayList<MenuItem>();

                MenuItem item1=new MenuItem(1,0,"父节点1 - 展开");
                item1.setisParent(true);
                item1.setOpen(true);            

                MenuItem item2=new MenuItem(11,1,"父节点11 - 折叠");         

                MenuItem item3=new MenuItem(111,11,"叶子节点111");              

                MenuItem item4=new MenuItem(112,11,"叶子节点112");          

                MenuItem item5=new MenuItem(113,11,"叶子节点113");      

                MenuItem item6=new MenuItem(114,11,"叶子节点114");              

                MenuItem item60=new MenuItem(115,11,"叶子节点115");             

                MenuItem item61=new MenuItem(116,11,"叶子节点116");     

                MenuItem item7=new MenuItem(12,1,"父节点12 - 折叠");             

                MenuItem item8=new MenuItem(121,12,"叶子节点121");              

                MenuItem item9=new MenuItem(122,12,"叶子节点122");

                MenuItem item10=new MenuItem(123,12,"叶子节点123");

                MenuItem item11=new MenuItem(124,12,"叶子节点124");             



            MenuItem item12=new MenuItem(13,1,"父节点13 - 没有子节点");
                item12.setisParent(true);               

                MenuItem item13=new MenuItem(2,0,"父节点2 - 折叠");      

                MenuItem item14=new MenuItem(21,2,"父节点21 - 展开");        

                MenuItem item15=new MenuItem(211,21,"叶子节点211");

                MenuItem item16=new MenuItem(212,21,"叶子节点212");

                MenuItem item17=new MenuItem(213,21,"叶子节点213");

                MenuItem item18=new MenuItem(214,21,"叶子节点214"); 

                menulist.add(item1);
                menulist.add(item2);
                menulist.add(item3);
                menulist.add(item4);
                menulist.add(item5);
                menulist.add(item6);
                menulist.add(item7);
                menulist.add(item8);
                menulist.add(item9);
                menulist.add(item10);
                menulist.add(item11);
                menulist.add(item12);
                menulist.add(item13);
                menulist.add(item14);
                menulist.add(item15);               
                menulist.add(item16);
                menulist.add(item17);
                menulist.add(item18);               

                return menulist;
            }

3.编写ztree页面,模拟demo

   <link rel="stylesheet" href="css/demo.css" type="text/css">
    <link rel="stylesheet" href="css/zTreeStyle/zTreeStyle.css" type="text/css">

        <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="js/jquery.ztree.core-3.5.js"></script>


       <SCRIPT type="text/javascript">  

        function bbb()
        {

       var setting = {
                data: {
                    simpleData: {
                        enable: true
                    }
                },
                callback: {
                onClick: onClick
            }
            };


        function onClick(event, treeId, treeNode, clickFlag) {

            alert(treeNode.name);
            alert(treeNode.id);
            alert(treeNode.pId);

        }

        $.getJSON("login/ZtreeMenu",function(data1){

        var zNodes=data1;
        alert(zNodes);


        $.fn.zTree.init($("#treeDemo"), setting, zNodes);

        });


        }


    </SCRIPT>

  </head>

 <body onload="bbb()">

 <div class="content_wrap">
    <div class="zTreeDemoBackground left">
        <ul id="treeDemo" class="ztree"></ul>
    </div>
 </div>

  • 9
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IDEAS是一种用于框架搭建的软件开发方法论,其重点是敏捷、可迭代、可持续的开发过程。以下是IDEAS框架搭建的详细步骤: 1. 确定项目需求:与项目参与者一起明确项目目标,并定义需求。这涉及到与利益相关者讨论并达成一致,以确保对项目的整体理解。 2. 制定项目计划:在项目启动阶段,制定一个详细的项目计划。该计划应包括项目的阶段、交付物、时间表和资源分配。 3. 加强沟通:确保团队成员之间的充分沟通,包括利益相关者。这可以通过定期会议、交流平台和进度更新来实现。 4. 设计和协作:使用适当的设计工具创建项目的架构和原型。这涉及到团队成员之间的协作,以确保设计的完整性和一致性。 5. 实施开发:根据项目计划和设计文档,进行软件开发。这包括编码、测试和调试。 6. 测试和验证:在开发过程中进行测试,包括单元测试、系统测试和用户验收测试。这有助于发现和解决潜在问题,并确保软件符合预期的要求。 7. 部署和交付:经过测试和验证后,将软件部署到生产环境中。这包括安装、配置和推出软件,并对用户进行培训和支持。 8. 持续改进:在软件交付后,根据用户反馈和实际使用情况进行持续改进。这可以通过跟踪问题、收集用户反馈和进行定期维护来实现。 9. 项目收尾:在项目完成后,进行项目的总结和评审。这涉及到评估项目的成功,以及记录和分享项目经验和教训。 通过遵循以上步骤,IDEAS框架可以帮助团队快速启动、高效开发,并持续优化软件产品。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值