ztree和datatables组合

1、准备条件

(1)下载ztree,官网:http://www.ztree.me/

(2)下载datatable,官网:http://www.datatables.net/

2、开发

(1)引入js和css代码

<%--树形插件  --%>
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/zTree_v3/css/demo.css" type="text/css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/zTree_v3/css/zTreeStyle/zTreeStyle.css" type="text/css">

<%-- bootstarp tree Table插件 --%>
<link href="${pageContext.request.contextPath}/static/admin/bootstarp/bower_components/datatables-plugins/dataTables.bootstrap.css" rel="stylesheet" />

<script type="text/javascript" src="${pageContext.request.contextPath}/static/admin/bootstarp/bower_components/jquery/dist/jquery.min.js"></script>

<%--树形插件 --%>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/zTree_v3/js/jquery.ztree.core-3.5.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/zTree_v3/js/jquery.ztree.excheck-3.5.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/zTree_v3/js/jquery.ztree.exedit-3.5.js"></script>

<%-- bootstarp tree Table插件 --%>
<script src="${pageContext.request.contextPath}/static/admin/bootstarp/bower_components/datatables-plugins/jquery.dataTables.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/static/admin/bootstarp/bower_components/datatables-plugins/dataTables.bootstrap.js" type="text/javascript"></script>

(2)html代码

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>管理员列表</title>
<style type="text/css">
.ztree li span.button.add {margin-left:2px; margin-right: -1px; background-position:-144px 0; vertical-align:top; *vertical-align:middle}
</style>
</head>
<body style="background-color:#fff;">
<form action="" id="tab" name="tab">
<div >
        <div>
            <h3>商品类型</h3>
            <div class="form-group form-inline well">
             <div style="height:700px;">
             <!-- 显示属性插件 -->
            <div style="height:700px;">
<ul id="treeDemo" style="height:700px;"></ul>
</div>
<div>
<!-- 引入tableData数据 -->
<table id="tableData" class="table table-striped table-bordered table-hover">
                   <thead>
                       <tr>
                        <th>类型名称</th>
                           <th>上级类型</th>
                           <th>排序</th>
                           <th>状态</th>
                           <th width="250px">操作</th>
                       </tr>
                   </thead>
                   <tbody>
                    <!-- <tr>
                        <th>商品类型</th>
                           <th>上级类型</th>
                           <th>排序</th>
                           <th>状态</th>
                           <th>删除 修改</th>
                       </tr> -->
                   </tbody>
               </table>
</div>
             </div>
            </div>
        </div>
    </div>
    
    <!-- 添加商品类型 -->
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div>
     <div>
        <div>
           <button type="button" data-dismiss="modal" 
              aria-hidden="true">×
           </button>
           <h4 id="myModalLabel">添加商品类型</h4>
        </div>
        <div>
<div>
     <label for="name">上级商品类型:</label>
     <input type="text" class="form-control disabled" id="disabledTextInput" readonly="readonly">
     <input type="hidden" name="parentId" class="form-control disabled" id="pid" readonly="readonly">
  </div>
  <div>
     <label for="name">类型名称:</label>
     <input type="text" id="goodsTypeName" name="goodsTypeName" placeholder="请输入商品类型名称">
  </div>
  <div>
     <label for="name">序号:</label>
     <input type="text" id="sort" name="sort" placeholder="请输入排序序号">
  </div>
  <div>
     <label>
  <input type="radio" name="status" id="optionsRadios3" value="1" checked="checked"> 启用
 </label>
 <label>
     <input type="radio" name="status" id="optionsRadios4" value="0"> 禁用
 </label>
  </div>
        </div>
        <div>
          <button id="saveBtn" type="button" class="btn btn-primary">提交更改</button>
           <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
        </div>
     </div>
  </div>
</div>
</form>
</body>
<script type="text/javascript">
var setting = {
edit: {
enable: true
},
data: {
simpleData: {
enable: true
}
},
callback: {
beforeDrag: beforeDrag,
beforeRemove: beforeRemove,
onRemove: onRemove,
/*onRename: onRename,*/
onClick: onClick
}
};

var zNodes =[
{ id:1, pId:0, name:"父节点 1", open:true},
{ id:11, pId:1, name:"叶子节点 1-1"},
{ id:12, pId:1, name:"叶子节点 1-2"},
{ id:13, pId:1, name:"叶子节点 1-3"},
{ id:2, pId:0, name:"父节点 2", open:true},
{ id:21, pId:2, name:"叶子节点 2-1"},
{ id:22, pId:2, name:"叶子节点 2-2"},
{ id:23, pId:2, name:"叶子节点 2-3"},
{ id:3, pId:0, name:"父节点 3", open:true},
{ id:31, pId:3, name:"叶子节点 3-1"},
{ id:32, pId:3, name:"叶子节点 3-2"},
{ id:33, pId:3, name:"叶子节点 3-3"}
];
setting.edit.showRenameBtn = false;

function beforeDrag(treeId, treeNodes) {
return true;
}
function showCode(str) {
var code = $("#code");
code.empty();
for (var i=0, l=str.length; i<l; i++) {
code.append("<li>"+str[i]+"</li>");
}
}
/*回调函数*/
/*添加*/
function onClick(e, treeId, treeNode) {
$("#disabledTextInput").val(treeNode.name);
$("#pid").val(treeNode.id);
$('input[name="goodsTypeName"]').val("");
$('input[name="sort"]').val("");
//弹窗口开发
$('#myModal').modal({
keyboard: true
});
}
/*添加方法*/
$("#saveBtn").click(function(){
var pid = $('input[name="parentId"]').val();
var pName = $('input[name="goodsTypeName"]').val();
var sort = $('input[name="sort"]').val();
var status = $('input[name="status"]:checked').val();
var path = "${path}/admin/goods/saveGoodsType";
$.ajax({
type:"POST",
url:path,
dataType:"json",
contentType: "application/json; charset=utf-8",
beforeSend:function(xhr) {
   xhr.setRequestHeader("If-Modified-Since","0");
   xhr.setRequestHeader("Cache-Control","no-cache");
},
data:JSON.stringify({"parentId":pid,"typeName":pName,"sort":sort,"status":status}), //接送格式
beforeSend:function(xhr) {
   xhr.setRequestHeader("If-Modified-Since","0");
   xhr.setRequestHeader("Cache-Control","no-cache");
},
success:function(result) {
if(result.status == "success"){
genGoodsTypes();
/*div隐藏*/
$('#myModal').modal('hide')
}
}
});
});
/*移除回调函数*/
function beforeRemove(treeId, treeNode) {
return confirm("确认删除 " + treeNode.name + "吗?");
}
function onRemove(e, treeId, treeNode) {
//树状Id  treeNode.id
var path = "${path}/admin/goods/deleteGoodsType/"+treeNode.id;
deleteGoodsType(path);
}
/*拖拽事件*/
function onDrag(e, treeId, treeNodes){
alert(treeNodes);
}
/*生成表格数据*/
function genTableDatas(result){ 
        
        $('#tableData').dataTable().fnClearTable();
        $('#tableData').dataTable().fnDestroy();
        
        var trs = "";
        $.each(result, function(index,n) {  
            trs = trs + "<tr><td class='cs_test edit'>" + n.name + "</td><td>" + n.pname + "</td><td>" + n.sort + "</td><td>";
            if(n.status == 1){
             trs = trs + "<span class='label label-success'>启用</span></td>";
            }else if(n.status == 0){
             trs = trs + "<span class='btn btn-danger btn-xs'>禁用</span>";
            }
            trs = trs + "</td><td>"+
            "<a onclick='javascript:editGoodsType(this.name);'  class='btn btn-info btn-xs' name='${path}/admin/goods/updateGoodsType/"+n.id+"'><i class='fa fa-pencil'></i> 修改</a>&nbsp;"+
         "<a onclick='javascript:deleteGoodsType(this.name);' class='btn btn-danger btn-xs' name='${path}/admin/goods/deleteGoodsType/"+ n.id +"'><i class='fa fa-trash'></i> 删除</a>"+
         "</td></tr>";  
        });
        
        $("#tableData tbody").html(trs);
        
/*生成表格列表*/
$("#tableData").dataTable({
retrieve: true,
paging: true,        //分页
         ordering: true,      //是否启用排序
            searching: true,     //搜索
            pageLength: 15,      //首次加载的数据条数
            bLengthChange: false,//屏蔽tables的一页展示多少条记录的下拉列表 
            language: {
                search: '<button type="button" class="btn btn-success btn-sm"><i class="fa fa-search"></i> 搜索:</button>',//右上角的搜索文本,可以写html标签
                paginate: {//分页的样式内容。
               previous: "<<",
               next: ">>",
               first: "首页",
               last: "尾页"
           },
zeroRecords: "<font color='red'>没有记录...</font>",//table tbody内容为空时,tbody的内容。
           //下面三者构成了总体的左下角的内容。
           info: "总共_PAGES_ 页",//左下角的信息显示,大写的词为关键字。
           infoEmpty: "0条记录",//筛选为空时左下角的显示。
           infoFiltered: ""//筛选之后的左下角筛选提示,
      },
           paging: true,
           pagingType: "full_numbers",//分页样式的类型
});
}
/*生成所有树*/
function genGoodsTypes(){
var url = "${path}/admin/goods/showGoodsTypes"
$.ajax({
type:"POST",
url:url,
dataType:"json",
beforeSend:function(xhr) {
   xhr.setRequestHeader("If-Modified-Since","0");
   xhr.setRequestHeader("Cache-Control","no-cache");
},
success:function(result) {
if(result.data.length != 0){
/*初始化树*/
$.fn.zTree.init($("#treeDemo"), setting, result.data);
/*生成表格数据*/
genTableDatas(result.data);
}
}
});
}
/*修改商品类型*/
function editGoodsType(path){
$("#tab").attr("action",path); 
$("#tab").submit();
}

/*删除商品类型*/
function deleteGoodsType(path){
$.ajax({
type:"POST",
url:path,
dataType:"json",
beforeSend:function(xhr) {
   xhr.setRequestHeader("If-Modified-Since","0");
   xhr.setRequestHeader("Cache-Control","no-cache");
},
success:function(result) {
if(result.status == "success"){
genGoodsTypes();
}
}
});
}
$(document).ready(function(){
genGoodsTypes();
});
</script>
</html>

(3)部分java代码

controller层代码

package com.xtxq.controller.goods;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xtxq.common.SystemConstants;
import com.xtxq.controller.base.BaseController;
import com.xtxq.domain.goods.GoodsProperty;
import com.xtxq.domain.goods.GoodsType;
import com.xtxq.domain.goods.GoodsTypeProperty;
import com.xtxq.service.goods.GoodsInfoService;
import com.xtxq.service.goods.GoodsPropertyService;
import com.xtxq.service.goods.GoodsTypePropertyService;
import com.xtxq.service.goods.GoodsTypeService;
/**
 * 
* @ClassName: GoodsTypeController
* @Description: TODO(商品分类)
* @author zwcheng 1054900400@qq.com
* @date 2016年1月7日 下午8:47:36
*
 */
@Controller
@RequestMapping("/admin/goods/")
public class GoodsTypeController extends BaseController<GoodsType>{
	private Logger logger = Logger.getLogger(GoodsTypeController.class);
	@Autowired
	private GoodsInfoService goodsInfoService ;
	@Autowired
	private GoodsPropertyService goodsPropertyService ;
	@Autowired
	private GoodsTypeService goodsTypeService ;
	@Autowired
	private GoodsTypePropertyService goodsTypePropertyService ;
	
	/**
	 * 重定向路径
	 */
	private static String REDIRECT_PATH = "redirect:/admin/goods/goodsTypeList";
	
	/**
	 * 获取子分类
	 * @param id
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="goodsInfo/getChildGoodsType/{id}",produces = "text/html;charset=UTF-8")
	public String getChildGoodsType(@PathVariable String id,HttpServletResponse response) throws Exception{
		System.out.println(id);
		List<GoodsType> list =  goodsTypeService.getChildrens(id) ;
		String msg = JSON.toJSONString(list) ;
		return msg ;
	}
	/**
	 * 通过商品子类别查看该子类下面的所有公共属性
	 * @param typeId
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="goodsInfo/getPropertyByTypeId/{typeId}",produces = "text/html;charset=UTF-8")
	public String getPropertyByTypeId(@PathVariable String typeId,HttpServletResponse response) throws Exception {
		List<GoodsTypeProperty> list =  goodsTypePropertyService.getPropertyByTypeId(typeId);
		List<GoodsProperty> goodsProperties = new ArrayList<GoodsProperty>();
		for(GoodsTypeProperty goodsTypeProperty:list) {
			GoodsProperty property = new GoodsProperty() ;
			String src= goodsTypeProperty.getPropertySrc() ;
			String[] values = goodsInfoService.splitPath(src) ;
			property = goodsTypeProperty.getGoodsProperty() ;
			goodsProperties.add(property) ;
			for(String value:values) {
				goodsProperties.add(goodsPropertyService.getById(value)) ;
			}
		}
		String msg = JSON.toJSONString(goodsProperties) ;
		System.out.println(msg);
		return msg ;
	}

	@RequestMapping(value="goodsTypeList")
	public String listGoodsType()throws Exception{
		return genGoodsTypePath("goodsTypeList");
	}
	
	/**
	 * 显示所有商品
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="showGoodsTypes",method=RequestMethod.POST)
	@ResponseBody
	public String showGoodsTypes() throws Exception {
		JSONObject json = new JSONObject();
		JSONArray jsons = new JSONArray();
		try {
			this.goodsTypeService.getAllChildsGoodsTypes("0", jsons); //顶级商品类型
			json.put("data", jsons);
		} catch (Exception e) {
			this.logger.error("范问商品类型发生异常。。。");
		}
		return json.toJSONString();
	}
	
	/**
	 * 删除
	 */
	@RequestMapping(value="deleteGoodsType/{id}",method=RequestMethod.POST)
	@ResponseBody
	public String deleteGoodsType(@PathVariable String id) throws Exception{
		Map<String,Object> maps = new HashMap<String, Object>();
		try {
			goodsTypeService.deleteGoodsType(id);
			maps = ajaxJsonMessage("success","删除商品类型成功!");
		} catch (Exception e) {
			logger.error("删除发生错误!");
			e.printStackTrace();
			maps = ajaxJsonMessage("fail","删除商品失败!");
		}
		return JSONObject.toJSONString(maps);
	}
	
	/**
	 * 保存商品类型
	 * @param goodsType
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="saveGoodsType",method=RequestMethod.POST)
	@ResponseBody
	public String saveGoodsType(@RequestBody GoodsType goodsType) throws Exception{
		Map<String,Object> maps = new HashMap<String, Object>();
		try {
			goodsTypeService.add(goodsType);
			maps = ajaxJsonMessage("success","添加商品类型成功!");
		} catch (Exception e) {
			logger.error("添加商品类型发生错误!");
			e.printStackTrace();
			maps = ajaxJsonMessage("fail","添加商品失败!");
		}
		return JSONObject.toJSONString(maps);
	}
	
	/**
	 * 修改商品类型页面
	 */
	@RequestMapping(value="updateGoodsType/{id}",method=RequestMethod.GET)
	public String editGoodsType(@PathVariable String id,Model model) throws Exception{
		GoodsType goodsType = goodsTypeService.getById(id);
		GoodsType pgoodsType = goodsTypeService.getById(goodsType.getParentId());
		goodsType.setPname(pgoodsType.getTypeName());
		model.addAttribute("goodsType", goodsType);
		return genGoodsTypePath("editGoodsType");
	}
	@RequestMapping(value="updateGoodsType",method=RequestMethod.POST)
	public String editGoodsType(GoodsType goodsType) throws Exception{
		GoodsType goodsType_db = goodsTypeService.getById(goodsType.getId());
		goodsType_db.setStatus(goodsType.getStatus());
		goodsType_db.setSort(goodsType.getSort());
		goodsType_db.setTypeName(goodsType.getTypeName());
		goodsTypeService.update(goodsType_db);
		return REDIRECT_PATH;
	}
	
	/**
	 * 生成商品类型路径
	 * @param path
	 * @return
	 */
	private String genGoodsTypePath(String path){
		return SystemConstants.GoodsTypeConstant.GOODS_TYPE_ROOT_PATH + path;
	}
}

service层代码(涉及到递归方法)

package com.xtxq.service.impl.goods;
import java.util.List;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xtxq.basic.SystemException;
import com.xtxq.basic.SystemPager;
import com.xtxq.dao.goods.GoodsTypeMapper;
import com.xtxq.domain.goods.GoodsType;
import com.xtxq.domain.goods.GoodsTypeExample;
import com.xtxq.service.goods.GoodsTypeService;
import com.xtxq.utils.UUIDUtils;
/**
 * @ClassName: GoodsTypeServiceImpl
 * @Description: TODO(商品分类的业务逻辑实现)
 * @author zwcheng 1054900400@qq.com
 * @date 2016年1月7日 下午8:50:03
 */
@Service
public class GoodsTypeServiceImpl implements GoodsTypeService{
	
	@Autowired
	private GoodsTypeMapper goodsTypeDao;
	
	/**
	 * 储存商品大类
	 */
	public void add(GoodsType t) throws Exception {
		GoodsType goodsType2 = getByName(t.getTypeName());
		if(null != goodsType2){
			throw new SystemException("这个商品的类型名称已经存在!");
		}
		t.setId(UUIDUtils.genUUID()); //生成主键
		goodsTypeDao.insert(t);
	}
	/**
	 * 删除商品大类
	 */
	public void deleteById(String id) throws Exception {
		goodsTypeDao.deleteByPrimaryKey(id);
	}
	/**
	 * 更新商品大类
	 */
	public void update(GoodsType t) throws Exception {
		goodsTypeDao.updateByPrimaryKey(t) ;
	}
	/**
	 * 按照商品类别的id查询
	 */
	public GoodsType getById(String id) throws Exception {
		if(id!="" && id != null) {
			return goodsTypeDao.selectByPrimaryKey(id);
		} else {
			return null ;
		}
	}
	/**
	 * 按照商品大类的姓名去查询
	 */
	public GoodsType getByName(String name) throws Exception {
		//按照名称查找
		GoodsTypeExample example = new GoodsTypeExample();
		GoodsTypeExample.Criteria criteria = example.createCriteria();
		criteria.andTypeNameEqualTo(name);
		List<GoodsType> goodsTypeList = goodsTypeDao.selectByExample(example);
		
		if(null != goodsTypeList && !goodsTypeList.isEmpty()){
			return goodsTypeList.get(0);
		}
		return null;
	}
	/**
	 *获取所有的分类
	 */
	public List<GoodsType> list() throws Exception {
		GoodsTypeExample example = new GoodsTypeExample() ;
		return goodsTypeDao.selectByExample(example);
	}
	/**
	 * 分页获取所有的商品类型
	 */
	public List<GoodsType> findNotices(int currentpage)
			throws Exception {
		GoodsTypeExample goodsTypeExample = new GoodsTypeExample() ;
		goodsTypeExample.setLimitStart(currentpage-1);
		goodsTypeExample.setLimitEnd(SystemPager.getPagesize());
		
		List<GoodsType> list = goodsTypeDao.selectByExample(goodsTypeExample) ;
		return list;
	}
	/**
	 * 获取所有类型的计数
	 */
	public int getCount() throws Exception {
		GoodsTypeExample example = new GoodsTypeExample() ;
		return goodsTypeDao.countByExample(example) ;
	}
	/**
	 * 判断是否有子节点
	 */
	public boolean hasChildren(String id) throws Exception {
		int count = goodsTypeDao.hasChildren(id) ;
		if(count>0) {
			return true ;
		}else {
			return false ;
		}
	}
	/**
	 * 获取所有的大类
	 */
	public List<GoodsType> getGoodsTypes() throws Exception{
		return goodsTypeDao.getGoodsTypes() ;
	}
	/**
	 * 获得某一个大类下面的所有子类
	 */
	public List<GoodsType> getChildrens(String id) throws Exception{
		GoodsTypeExample example = new GoodsTypeExample();
		GoodsTypeExample.Criteria criteria = example.createCriteria();
		System.out.println(id);
		criteria.andParentIdEqualTo(id);
		List<GoodsType> goodsTypeList = goodsTypeDao.selectByExample(example);
		if(goodsTypeList!=null) {
			return goodsTypeList;
		} else {
			return null ;
		}
	}
	
	/**
	 * 通过父亲Id获取商品类型
	 * @param pid 父亲Id
	 * @return
	 * @throws Exception
	 */
	public List<GoodsType> getChildsGoodsTypes(String pid) throws Exception{
	    GoodsTypeExample goodsTypeExample = new GoodsTypeExample();
	    GoodsTypeExample.Criteria criteria = goodsTypeExample.createCriteria();
	    criteria.andParentIdEqualTo(pid);
	    return this.goodsTypeDao.selectByExample(goodsTypeExample);
	 }

	public JSONArray getChildsGoodsTypes(String pid, JSONArray jsons) throws Exception {
		List<GoodsType> childs = getChildsGoodsTypes(pid);
		GoodsType pgoodsType = getById(pid);
		for (GoodsType goodsType : childs) {
	      JSONObject jsonObject = new JSONObject();
	      jsonObject.put("id", goodsType.getId());
	      jsonObject.put("pId", pid);
	      jsonObject.put("name", goodsType.getTypeName());
	      jsonObject.put("pname", pgoodsType.getTypeName());
	      jsonObject.put("sort", goodsType.getSort());
	      jsonObject.put("status", goodsType.getStatus());
	      jsonObject.put("open", Boolean.valueOf(true));
	      jsons.add(jsonObject);
	    }
	    return jsons;
	}
	
	/**
	 * 获取所有商品类型
	 * @param pid
	 * @param jsons
	 * @return
	 * @throws Exception
	 */
	public JSONArray getAllChildsGoodsTypes(String pid, JSONArray jsons) throws Exception{
	    List<GoodsType> childs = getChildsGoodsTypes(pid);
	    if ((childs != null) && (!childs.isEmpty()))
	      for (GoodsType goodsType : childs) {
	        jsons = getChildsGoodsTypes(goodsType.getId(), jsons);
	        getAllChildsGoodsTypes(goodsType.getId(), jsons);
	      }
	    else {
	      jsons = getChildsGoodsTypes(pid, jsons);
	    }
	    return jsons;
	}
	
	/**
	 * 通过Id删除所有商品(递归删除)
	 * @param id 主键
	 * @throws Exception
	 */
	public void deleteGoodsType(String id) throws Exception{
		
		//TODO 查询所有与商品类型关联表
		
		//递归删除所有子节点
		List<GoodsType> coodsTypes =  getChildsGoodsTypes(id);
		if(null != coodsTypes && !coodsTypes.isEmpty()){
			for(GoodsType goodsType : coodsTypes){
				deleteGoodsType(goodsType.getId());
				deleteById(goodsType.getId());
			}
		}else{
			deleteById(id);
		}
		deleteById(id); //删除
	}
}

3、运行后效果图

083457_AITt_1754093.png

转载于:https://my.oschina.net/u/1754093/blog/604363

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值