KendoUi 实现组织架构树

 

   需求:在前端将组织架构显示为可选择的树形结构,并在选择之后可以回填组织名称,并获取到对应组织id

   实现:系统框架使用kendoui作为前端框架,那么就寻找相关组件,并且在后台java代码中组装数据,设置属性.

  表结构如下

1.建立TreeVo对象

package com.fsl.lcp.demo.vo;

import java.util.List;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

public class TreeVo {
	
	@JsonSerialize(using=ToStringSerializer.class)
	private Long id;
	
	private String text;
	
	private Boolean expanded=false;

	private Boolean checked=false;
	
	private List<TreeVo> items;

	public Boolean getChecked() {
		return checked;
	}

	public void setChecked(Boolean checked) {
		this.checked = checked;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public Boolean getExpanded() {
		return expanded;
	}

	public void setExpanded(Boolean expanded) {
		this.expanded = expanded;
	}

	public List<TreeVo> getItems() {
		return items;
	}

	public void setItems(List<TreeVo> items) {
		this.items = items;
	}

	
	
	
}

2.组装数据

 查找到的组织数据sql就是一个select *,组装数据代码如下

package com.fsl.lcp.demo.service.impl;

import com.fsl.lcp.demo.dto.SalesActivityDemo;
import com.fsl.lcp.demo.service.ISalesActivityDemoService;
import com.fsl.lcp.demo.vo.TreeVo;
import com.hand.hap.hr.dto.HrOrgUnit;
import com.hand.hap.hr.mapper.OrgUnitMapper;
import com.hand.hap.system.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class SalesActivityDemoServiceImpl extends BaseServiceImpl<SalesActivityDemo> implements ISalesActivityDemoService{

	
	
	
	@Autowired
	OrgUnitMapper  orgUnitMapper;
	
	
	@Override
	public List<TreeVo> unitTreeGet() {
		
		List<HrOrgUnit> selectAllUnitAndCharge = orgUnitMapper.selectAllUnitAndCharge(new HrOrgUnit());
		List<TreeVo> treeList=new ArrayList<TreeVo>();
		//根节点
		List<HrOrgUnit> collect = selectAllUnitAndCharge.stream().filter((e)->null==e.getParentId()).collect(Collectors.toList());
		collect.stream().forEach((e)->{
			TreeVo vo=new TreeVo();
			vo.setId(e.getUnitId());
			vo.setText(e.getName());
			vo.setExpanded(true);
			treeList.add(vo);
		});
		//子节点
		getChildNodes(selectAllUnitAndCharge, treeList);
		return treeList;
	}

	
	public void getChildNodes(List<HrOrgUnit> unitsAll,List<TreeVo> treeList) {
		treeList.stream().forEach((a) -> {
			List<TreeVo> childNodes = new ArrayList<>();
			unitsAll.forEach((e) -> {
				if (null != e.getParentId()) {
					if (e.getParentId().equals(a.getId())) {
						//子节点-添加
						TreeVo  child=new TreeVo();
						child.setId(e.getUnitId());
						child.setText(e.getName());
						if(a.getExpanded()){
							child.setExpanded(a.getExpanded());
						}
						if(a.getChecked()){
							child.setChecked(a.getChecked());
						}
						if(e.getName().equals("办公室")){
							child.setChecked(true);
						}
						childNodes.add(child);
					}
				}
			});
			
            if(childNodes.size()>0){
            	a.setItems(childNodes);
            	getChildNodes(unitsAll, childNodes);
            }
		});
	}
	
	
}

3.前端渲染

    


<#include "../include/header.html">
<body>
<script src="${base.contextPath}/lib/kendoui/js/jquery.min.js"></script>

<script src="${base.contextPath}/lib/kendoui/js/jszip.min.js"></script>
<!--<script src="${base.contextPath}/resources/console.js"></script>-->
<script src="${base.contextPath}/resources/kendo.all.min.js"></script>
<link href="${base.contextPath}/resources/kendo.common.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/kendo.rtl.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/kendo.default.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/kendo.default.mobile.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/examples-offline.css" rel="stylesheet" type="text/css"/>





<div id="treeList">
    <div class="demo-section k-content">
        <div id="dialog">
            <div class="dialogContent">
                <input id="filterText" type="text" placeholder="请输入" />
                <div class="selectAll">
                    <input type="checkbox" id="chbAll" class="k-checkbox" onchange="chbAllOnChange()" />
                    <label class="k-checkbox-label" for="chbAll">所有</label>
                    <span id="result">未选择</span>
                </div>
                <div id="treeview"></div>
            </div>
        </div>
        <select id="multiselect"></select>
        <br />
        <button id="openWindow" class="k-primary">请选择</button>
    </div>
    <script>
        var dataTree;
        var myDataSource;
        $.ajax({
            type: "get",
            url: "${base.contextPath}/lcp/sales/activity/demo/audit/line/getTreeUnit",
            /* data: kendo.stringify(data), */
            dataType: "json",
            contentType: 'application/json',
            success: function (datas) {
              
                if(datas){
                    dataTree=datas;
                    myDataSource = new kendo.data.HierarchicalDataSource({
                        data: dataTree
                    });

                    $("#treeview").kendoTreeView({
                        checkboxes: {
                            checkChildren: true
                        },
                        dataSource: myDataSource,
                        check: onCheck
                    });
                }
            }
        });



        $("#multiselect").kendoMultiSelect({
            dataTextField: "text",
            dataValueField: "id"
        });



        $(document).ready(function () {
            var dialog = $("#dialog");
            var multiSelect = $("#multiselect").data("kendoMultiSelect");
            $("#openWindow").kendoButton();

            multiSelect.readonly(true);

            $("#openWindow").click(function () {

                dialog.data("kendoDialog").open();
                $(this).fadeOut();
                var nodes = $("#treeview").data("kendoTreeView").dataSource.view();
                var checkedNodes = [];
                getCheckedNodes(nodes, checkedNodes);
                setMessage(checkedNodes.length);
            });









            dialog.kendoDialog({
                width: "400px",
                title: "组织架构",
                visible: false,
                actions: [
                    {
                        text: '取消',
                        primary: false,
                        action: onCancelClick
                    },
                    {
                        text: '确定',
                        primary: true,
                        action: onOkClick
                    }
                ],
                close: onClose
            }).data("kendoDialog").close();
        });

        function onCancelClick(e) {
            e.sender.close();
        }

        function onOkClick(e) {
            debugger;
            var checkedNodes = [];
            var treeView = $("#treeview").data("kendoTreeView");

            getCheckedNodes(treeView.dataSource.view(), checkedNodes);
            populateMultiSelect(checkedNodes);

            e.sender.close();
        }

        function onClose() {
            $("#openWindow").fadeIn();
        }

        function populateMultiSelect(checkedNodes) {
            var multiSelect = $("#multiselect").data("kendoMultiSelect");
            multiSelect.dataSource.data([]);

            var multiData = multiSelect.dataSource.data();
            if (checkedNodes.length > 0) {
                var array = multiSelect.value().slice();
                for (var i = 0; i < checkedNodes.length; i++) {
                    multiData.push({ text: checkedNodes[i].text, id: checkedNodes[i].id });
                    array.push(checkedNodes[i].id.toString());
                }

                multiSelect.dataSource.data(multiData);
                multiSelect.dataSource.filter({});
                multiSelect.value(array);
            }
        }

        function checkUncheckAllNodes(nodes, checked) {
            debugger;
            for (var i = 0; i < nodes.length; i++) {
                nodes[i].set("checked", checked);

                if (nodes[i].hasChildren) {
                    checkUncheckAllNodes(nodes[i].children.view(), checked);
                }
            }
        }

        function chbAllOnChange() {
            debugger;
            var checkedNodes = [];
            var treeView = $("#treeview").data("kendoTreeView");
            var isAllChecked = $('#chbAll').prop("checked");

            checkUncheckAllNodes(treeView.dataSource.view(), isAllChecked)

            if (isAllChecked) {
                setMessage($('#treeview input[type="checkbox"]').length);
            }
            else {
                setMessage(0);
            }
        }

        function getCheckedNodes(nodes, checkedNodes) {

            var node;

            for (var i = 0; i < nodes.length; i++) {
                node = nodes[i];

                if (node.checked) {
                    checkedNodes.push({ text: node.text, id: node.id });
                }

                if (node.hasChildren) {
                    getCheckedNodes(node.children.view(), checkedNodes);
                }
            }
        }

        function onCheck() {
            var checkedNodes = [];
            var treeView = $("#treeview").data("kendoTreeView");

            getCheckedNodes(treeView.dataSource.view(), checkedNodes);
            setMessage(checkedNodes.length);
        }

        function setMessage(checkedNodes) {
            var message;

            if (checkedNodes > 0) {
                message =  "已选择:"+checkedNodes ;
            }
            else {
                message = "未选择";
            }

            $("#result").html(message);
        }

        $("#filterText").keyup(function (e) {
            var filterText = $(this).val();

            if (filterText !== "") {
                $(".selectAll").css("visibility", "hidden");

                $("#treeview .k-group .k-group .k-in").closest("li").hide();
                $("#treeview .k-group").closest("li").hide();
                $("#treeview .k-group .k-group .k-in:contains(" + filterText + ")").each(function () {
                    $(this).parents("ul, li").each(function () {
                        $(this).show();
                    });
                });
                $("#treeview .k-group .k-in:contains(" + filterText + ")").each(function () {
                    $(this).parents("ul, li").each(function () {
                        $(this).show();
                    });
                });
            }
            else {
                $("#treeview .k-group").find("li").show();
                $(".selectAll").css("visibility", "visible");
            }
        });


        var removeUnit = function(text,id){

            var multiSelect = $("#multiselect").data("kendoMultiSelect");
            var multiData = multiSelect.dataSource.data();
            var array = multiSelect.value().slice();
            multiData.remove({ text: text ,id: id});
            var index = array.indexOf(id.toString());
            if (index > -1) {
                array.splice(index, 1);
            }

            multiSelect.dataSource.data(multiData);
            multiSelect.dataSource.filter({});
            multiSelect.value(array);

                 debugger;
            var nodes = $("#treeview").data("kendoTreeView").dataSource.view();

            checkedToFalse(nodes,text,id);
            debugger;
            var checkedNodes = [];
            getCheckedNodes(nodes, checkedNodes);
            setMessage(checkedNodes.length);
            $('#chbAll').prop("checked",false);

        }



        function dealfalse(nodes, checked) {
               /* nodes.set("checked", checked);
                if (nodes.hasChildren) {
                    dealfalse(nodes.children.view(), checked);
                }*/


            for (var i = 0; i < nodes.length; i++) {
                nodes[i].set("checked", checked);

                if (nodes[i].hasChildren) {
                    checkUncheckAllNodes(nodes[i].children.view(), checked);
                }
            }

        }


        function checkedToFalse(treeView,text,id){
            var node;
            for (var i = 0; i < treeView.length; i++) {
                node = treeView[i];
                if (node.text==text&&node.id==id) {
                    debugger;
                    var nodes=new Array();
                    nodes[0]=node;
                    dealfalse(nodes,false);
                }

                if (node.hasChildren) {
                    checkedToFalse(node.children.view(), text,id);
                }
            }
        }



    </script>
    <style>
        html .k-dialog .k-window-titlebar {
            padding-left: 17px;
        }

        .k-dialog .k-content {
            padding: 17px;
        }

        #filterText {
            width: 100%;
            box-sizing: border-box;
            padding: 6px;
            border-radius: 3px;
            border: 1px solid #d9d9d9;
        }

        .selectAll {
            margin: 17px 0;
        }

        #result {
            color: #9ca3a6;
            float: right;
        }

        #treeview {
            height: 300px;
            overflow-y: auto;
            border: 1px solid #d9d9d9;
        }

        #openWindow {
            min-width: 180px;
        }
    </style>
</div>
</body>
</html>

效果如下图:

注意:

    kendoUi的版本是   v2017.1.223

   此版本的可选择树形组件有点问题,就是在选择了之后回填数据之后没有X掉数据,下图KendoUI的demo

修复:打开kendo.all.min.js,搜索如下代码

<li class="k-button" deselectable="on"><span deselectable="on">'

如下图更改

 var text = '\'' + o(e) +'\'';
 var $kendoOutput,
 $kendoHtmlEncode = kendo.htmlEncode;
 $kendoOutput=''+$kendoHtmlEncode(e.id)+'';
 onclick="removeUnit( ' + text + ',\''+$kendoOutput+'\')"

removeUnit在前端代码中有对应函数

 补充:

 

上面的代码无法实现上图的级联移除,修复如下,更改removeUnit方法,添加如下注释的几个函数


<#include "../include/header.html">
<body>
<script src="${base.contextPath}/lib/kendoui/js/jquery.min.js"></script>

<script src="${base.contextPath}/lib/kendoui/js/jszip.min.js"></script>
<!--<script src="${base.contextPath}/resources/console.js"></script>-->
<script src="${base.contextPath}/resources/kendo.all.min.js"></script>
<link href="${base.contextPath}/resources/kendo.common.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/kendo.rtl.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/kendo.default.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/kendo.default.mobile.min.css" rel="stylesheet" type="text/css"/>
<link href="${base.contextPath}/resources/examples-offline.css" rel="stylesheet" type="text/css"/>





<div id="treeList">
    <div class="demo-section k-content">
        <div id="dialog">
            <div class="dialogContent">
                <input id="filterText" type="text" placeholder="请输入" />
                <div class="selectAll">
                    <input type="checkbox" id="chbAll" class="k-checkbox" onchange="chbAllOnChange()" />
                    <label class="k-checkbox-label" for="chbAll">所有</label>
                    <span id="result">未选择</span>
                </div>
                <div id="treeview"></div>
            </div>
        </div>
        <select id="multiselect"></select>
        <br />
        <button id="openWindow" class="k-primary">请选择</button>
    </div>
    <script>
        var dataTree;
        var myDataSource;
        $.ajax({
            type: "get",
            url: "${base.contextPath}/lcp/sales/activity/demo/audit/line/getTreeUnit",
            /* data: kendo.stringify(data), */
            dataType: "json",
            contentType: 'application/json',
            success: function (datas) {
              
                if(datas){
                    dataTree=datas;
                    myDataSource = new kendo.data.HierarchicalDataSource({
                        data: dataTree
                    });

                    $("#treeview").kendoTreeView({
                        checkboxes: {
                            checkChildren: true
                        },
                        dataSource: myDataSource,
                        check: onCheck
                    });
                }
            }
        });



        $("#multiselect").kendoMultiSelect({
            dataTextField: "text",
            dataValueField: "id"
        });



        $(document).ready(function () {
            var dialog = $("#dialog");
            var multiSelect = $("#multiselect").data("kendoMultiSelect");
            $("#openWindow").kendoButton();

            multiSelect.readonly(true);

            $("#openWindow").click(function () {
                dialog.data("kendoDialog").open();
                $(this).fadeOut();
                var nodes = $("#treeview").data("kendoTreeView").dataSource.view();
                var checkedNodes = [];
                getCheckedNodes(nodes, checkedNodes);
                setMessage(checkedNodes.length);

            });









            dialog.kendoDialog({
                width: "400px",
                title: "组织架构",
                visible: false,
                actions: [
                    {
                        text: '取消',
                        primary: false,
                        action: onCancelClick
                    },
                    {
                        text: '确定',
                        primary: true,
                        action: onOkClick
                    }
                ],
                close: onClose
            }).data("kendoDialog").close();
        });

        function onCancelClick(e) {
            e.sender.close();
        }

        function onOkClick(e) {
            
            var checkedNodes = [];
            var treeView = $("#treeview").data("kendoTreeView");

            getCheckedNodes(treeView.dataSource.view(), checkedNodes);
            populateMultiSelect(checkedNodes);

            e.sender.close();
        }

        function onClose() {
            $("#openWindow").fadeIn();
        }

        function populateMultiSelect(checkedNodes) {
            var multiSelect = $("#multiselect").data("kendoMultiSelect");
            multiSelect.dataSource.data([]);

            var multiData = multiSelect.dataSource.data();
            if (checkedNodes.length > 0) {
                var array = multiSelect.value().slice();
                for (var i = 0; i < checkedNodes.length; i++) {
                    multiData.push({ text: checkedNodes[i].text, id: checkedNodes[i].id });
                    array.push(checkedNodes[i].id.toString());
                }

                multiSelect.dataSource.data(multiData);
                multiSelect.dataSource.filter({});
                multiSelect.value(array);
            }
        }

        function checkUncheckAllNodes(nodes, checked) {
            
            for (var i = 0; i < nodes.length; i++) {
                nodes[i].set("checked", checked);

                if (nodes[i].hasChildren) {
                    checkUncheckAllNodes(nodes[i].children.view(), checked);
                }
            }
        }

        function chbAllOnChange() {
            
            var checkedNodes = [];
            var treeView = $("#treeview").data("kendoTreeView");
            var isAllChecked = $('#chbAll').prop("checked");

            checkUncheckAllNodes(treeView.dataSource.view(), isAllChecked)

            if (isAllChecked) {
                setMessage($('#treeview input[type="checkbox"]').length);
            }
            else {
                setMessage(0);
            }
        }

        function getCheckedNodes(nodes, checkedNodes) {

            var node;

            for (var i = 0; i < nodes.length; i++) {
                node = nodes[i];

                if (node.checked) {
                    checkedNodes.push({ text: node.text, id: node.id });
                }

                if (node.hasChildren) {
                    getCheckedNodes(node.children.view(), checkedNodes);
                }
            }
        }

        function onCheck() {
            var checkedNodes = [];
            var treeView = $("#treeview").data("kendoTreeView");

            getCheckedNodes(treeView.dataSource.view(), checkedNodes);
            setMessage(checkedNodes.length);
        }

        function setMessage(checkedNodes) {
            var message;

            if (checkedNodes > 0) {
                message =  "已选择:"+checkedNodes ;
            }
            else {
                message = "未选择";
            }

            $("#result").html(message);
        }

        $("#filterText").keyup(function (e) {
            var filterText = $(this).val();

            if (filterText !== "") {
                $(".selectAll").css("visibility", "hidden");

                $("#treeview .k-group .k-group .k-in").closest("li").hide();
                $("#treeview .k-group").closest("li").hide();
                $("#treeview .k-group .k-group .k-in:contains(" + filterText + ")").each(function () {
                    $(this).parents("ul, li").each(function () {
                        $(this).show();
                    });
                });
                $("#treeview .k-group .k-in:contains(" + filterText + ")").each(function () {
                    $(this).parents("ul, li").each(function () {
                        $(this).show();
                    });
                });
            }
            else {
                $("#treeview .k-group").find("li").show();
                $(".selectAll").css("visibility", "visible");
            }
        });


        //移除树以及数量得更改
        var removeUnit = function(text,id){
            var nodes = $("#treeview").data("kendoTreeView").dataSource.view();
            removeInput(text,id,nodes); 
            checkedToFalse(nodes,text,id);
            var checkedNodes = [];
            getCheckedNodes(nodes, checkedNodes);
            setMessage(checkedNodes.length);
            $('#chbAll').prop("checked",false);

        }


        

        
        //移除关联节点-1.如果存在子节点,则移除所有子节点在div中得显示2.如果是父节点得唯一一个被选中得节点,那么移除父节点
        function removeInput(text,id,nodes){
        	for (var i = 0; i < nodes.length; i++) {
        		 var node = nodes[i];
	        		 if (node.text==text&&node.id==id) {
	        			 removeOne(node.text,node.id);
	        			 if (node.hasChildren) {
	        				 var childs=node.items;
	            			 removeNodes(childs);
	        			 }
	        		 } else{
	        			 if (node.hasChildren) {
	        				 var childs=node.items;
	        				 removeInput(text,id,childs);
	        			 }
	        		 } 	 
            }
            
        }
        
        
        
        function removeNodes(nodes){
        	for (var i = 0; i < nodes.length; i++) {
        		var node=nodes[i];
        		 if (node.hasChildren) {
        			 var childs=node.items;
        			 removeOne(node.text,node.id);
        			 removeNodes(childs);
        		 }else{
        			 removeOne(node.text,node.id);
        		 }
        	}
        }
        
        
        //移除某个节点
        function  removeOne(text,id){
        	var multiSelect = $("#multiselect").data("kendoMultiSelect");
            var multiData = multiSelect.dataSource.data();
            var array = multiSelect.value().slice();
            multiData.remove({ text: text ,id: id});
            var index = array.indexOf(id.toString());
            if (index > -1) {
                array.splice(index, 1);
            }
            multiSelect.dataSource.data(multiData);
            multiSelect.dataSource.filter({});
            multiSelect.value(array);
            var nodes = $("#treeview").data("kendoTreeView").dataSource.view();
            removePar(text,id,nodes,"");
        }
        
      //获取-父节点等
        function removePar(text,id,nodes,nodePar){
	             	for (var i = 0; i < nodes.length; i++) {
	          		     var node=nodes[i];
	  	        	    if (node.text==text&&node.id==id) {
	  	       			 removeReal(nodePar,text,id);
	  	       		    }else{
			  	       		if (node.hasChildren) {
		 	       				 var childs=node.items;
		 	       			     removePar(text,id,childs,node);
		 	       			 }
	  	       		     } 
	          	      }
        }
        
      //判断-父节点-移除
      function removeReal(nodePar,text,id){
    	  if(""!=nodePar){
    		  var nodes=nodePar.items; 
    		  var boolean=new Boolean(true);
    	      	for (var i = 0; i < nodes.length; i++) {
    	      		var node=nodes[i];
    	      		 if (!(node.text==text&&node.id==id)) {
    	      			if(node.checked){
       	      			   boolean=false;
	       	      		}else{
	       	      		    boolean=true;
	       	      		}	 
    	      		 }
    	      	}
    	      	if(boolean){
    	      		removeOne(nodePar.text,nodePar.id)
    	      	}
    	  }
    	 
      }
      
      
      
        function dealfalse(nodes, checked) {
            for (var i = 0; i < nodes.length; i++) {
                nodes[i].set("checked", checked);
                if (nodes[i].hasChildren) {
                    checkUncheckAllNodes(nodes[i].children.view(), checked);
                }
            }

        }


        function checkedToFalse(treeView,text,id){
            var node;
            for (var i = 0; i < treeView.length; i++) {
                node = treeView[i];
                if (node.text==text&&node.id==id) {
                    var nodes=new Array();
                    nodes[0]=node;
                    dealfalse(nodes,false);
                }

                if (node.hasChildren) {
                    checkedToFalse(node.children.view(), text,id);
                }
            }
        }



    </script>
    <style>
        html .k-dialog .k-window-titlebar {
            padding-left: 17px;
        }

        .k-dialog .k-content {
            padding: 17px;
        }

        #filterText {
            width: 100%;
            box-sizing: border-box;
            padding: 6px;
            border-radius: 3px;
            border: 1px solid #d9d9d9;
        }

        .selectAll {
            margin: 17px 0;
        }

        #result {
            color: #9ca3a6;
            float: right;
        }

        #treeview {
            height: 300px;
            overflow-y: auto;
            border: 1px solid #d9d9d9;
        }

        #openWindow {
            min-width: 180px;
        }
    </style>
</div>
</body>
</html>

 

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值