01.基于自定义MVC架构的用户登录与首页展示实现 — OA项目实践

目录

本章节目标:完成OA项目用户登录及首页展示

一.用户登录

User.java

UserDao.java

IUserDao.java

UserAction.java

login.jsp(登录界面)

userManage.jsp (数据绑定,修改,删除)

userEdit.jsp(用户新增)

效果展示

登录界面

 绑定数据

 新增界面 ​编辑

 删除界面

 修改界面


本章节目标:
完成OA项目用户登录及首页展示

一.用户登录

        用户查询

        用户角色case when后台处理

        用户新增

        用户修改

        用户删除

        重置密码

        安全退出

1.用户查询SQL语句

2.后台增删改查方法及测试

3.web层的编写

4.增删改查需要用到的所有组件-来自于官网

如搜索框,数据表格,工具栏,弹出层,form数据回显,父子页面传参

5.完全依葫芦画瓢,copy完成相对应功能

6.将使用一个MVC自定义框架

User.java

package com.zking.oa.model;import java.io.Serializable;import org.lisen.mvc.util.AutoIncrement;
import org.lisen.mvc.util.Ignore;
import org.lisen.mvc.util.Key;
import org.lisen.mvc.util.Table;@Table("t_oa_user")
public class User implements Serializable{@AutoIncrement@Keyprivate Integer id;private String name;private String loginName;private String pwd;private long rid;//忽略字段@Ignore private String roleName;public String getRoleName() {if(this.rid == 1) return "管理员";if(this.rid == 2) return "发起者";if(this.rid == 3) return "审批者";if(this.rid == 4) return "参与者";if(this.rid == 5) return "会议管理员";return "";}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}public long getRid() {return rid;}public void setRid(long rid) {this.rid = rid;}public User() {// TODO Auto-generated constructor stub}public User(int id, String name, String loginName, String pwd, long rid) {this.id = id;this.name = name;this.loginName = loginName;this.pwd = pwd;this.rid = rid;}public User(String name, String loginName, String pwd, long rid) {this.name = name;this.loginName = loginName;this.pwd = pwd;this.rid = rid;}@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + ", loginName=" + loginName + ", pwd=" + pwd + ", rid=" + rid + "]";}}

UserDao.java

package com.zking.oa.dao;import java.util.ArrayList;
import java.util.List;import org.junit.Test;
import org.lisen.mvc.util.DbTemplate;
import org.lisen.mvc.util.PageBean;import com.zking.oa.model.User;
import com.zking.oa.util.MD5;public class UserDao implements IUserDao {@Overridepublic User loadUser(String loginName) {String sql  = "select * from t_oa_user where loginName = ?";if(loginName == null || "".equals(loginName)) return null;List<User> users = DbTemplate.query(sql, new Object[] {loginName}, User.class);return users == null || users.size() == 0 ? null : users.get(0);}@Overridepublic List<User> listUser(User user,PageBean pageBean){String sql="select * from t_oa_user ";//用来保存参数List<Object> param = new ArrayList<>();if(user !=null && !"".equals(user.getName())) {sql+="where name like ?";param.add(user.getName()+"%");}return DbTemplate.query(sql, param.toArray(), pageBean,User.class);}@Testpublic void testListUser() {User u = new User();u.setName("瑶");List<User> listuser = listUser(u, PageBean());//System.out.println(listuser);}@Overridepublic void addUser(User user) {DbTemplate.save(user);}@Overridepublic void updateUser(User user) {String sql="update t_oa_user set loginName=?,rid=? where id=?";DbTemplate.update(sql, new Object[] {user.getLoginName(),user.getRid(),user.getId()});}@Overridepublic void deleteUser(User user) {String sql="delete from t_oa_user where id=?";DbTemplate.update(sql, new Object[] {user.getId()});}@Overridepublic void resetPwd(User user) {String sql="update t_oa_user set pwd=? where id=?";DbTemplate.update(sql, new Object[] {new MD5().getMD5ofStr("1234"),user.getId()});}private PageBean PageBean() {// TODO Auto-generated method stubreturn null;}public static void main(String[] args) {UserDao userDao = new UserDao();User loadUser = userDao.loadUser("dg");System.out.println(loadUser);}
}

IUserDao.java

package com.zking.oa.dao;import java.util.List;import org.lisen.mvc.util.PageBean;import com.zking.oa.model.User;public interface IUserDao {/*** 通过登录名获取用户信息* @param loginName 登录名* @return User*/User loadUser(String loginName);/*** 通过用户查询* @param user* @param pageBean* @return*/List<User> listUser(User user, PageBean pageBean);/*** 增加用户* @param user*/void addUser(User user);/*** 修改用户* @param user*/void updateUser(User user);/*** 删除用户* @param user*/void deleteUser(User user);/*** 重置密码* @param user*/void resetPwd(User user);}

UserAction.java

package com.zking.oa.action;import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.lisen.mvc.framework.AbstractDispatchAction;
import org.lisen.mvc.framework.ModelDrive;
import org.lisen.mvc.util.PageBean;import com.fasterxml.jackson.databind.ObjectMapper;
import com.zking.oa.model.User;
import com.zking.oa.service.IUserService;
import com.zking.oa.service.UserService;
import com.zking.oa.util.CommonUtil;
import com.zking.oa.util.MD5;public class UserAction extends AbstractDispatchAction implements ModelDrive {private User user  = new User();@Overridepublic Object getModel() {return user;}private IUserService service = new UserService();public void login(HttpServletRequest req, HttpServletResponse resp) {User db_user = service.loadUser(user.getLoginName());if(db_user != null && user.getLoginName().equals(db_user.getLoginName())) {if(user.getPwd() != null)  {//得到前台传过来的密码,然后进行MD5计算,在和数据库中的配置进行比较String tmp = user.getPwd();MD5 md5 = new MD5();String _pwd = md5.getMD5ofStr(tmp);if(_pwd.equals(db_user.getPwd())) {CommonUtil.sendResponse(1, "用户名密码正确", resp);//登录成功,则将用户放入session中req.getSession().setAttribute("user", db_user);}else {CommonUtil.sendResponse(-1,  "密码不正确", resp);}}} else {CommonUtil.sendResponse(-1,  "用户名不存在", resp);}}public void logout(HttpServletRequest req,HttpServletResponse resp) {req.getSession().invalidate();CommonUtil.sendResponse(1, "安全退出", resp);}public void listUser(HttpServletRequest req,HttpServletResponse resp) {try {PageBean pageBean = new PageBean();pageBean.setRequest(req);List<User> list = service.listUser(user, pageBean);CommonUtil.sendResponse(0, "成功",pageBean.getTotal() , list, resp);} catch (Exception e) {e.printStackTrace();}}public void addUser(HttpServletRequest req,HttpServletResponse resp) {try {MD5 md5 = new MD5();user.setPwd(md5.getMD5ofStr(user.getPwd()));service.addUser(user);CommonUtil.sendResponse(0, "增加用户成功", resp);} catch (Exception e) {e.printStackTrace();CommonUtil.sendResponse(-1, "增加用户失败", resp);}}public void updateUser(HttpServletRequest req,HttpServletResponse resp) {try {service.updateUser(user);CommonUtil.sendResponse(0, "修改用户成功", resp);} catch (Exception e) {e.printStackTrace();CommonUtil.sendResponse(-1, "修改用户失败", resp);}}public void deleteUser(HttpServletRequest req,HttpServletResponse resp) {try {service.deleteUser(user);CommonUtil.sendResponse(0, "删除用户成功", resp);} catch (Exception e) {e.printStackTrace();CommonUtil.sendResponse(-1, "删除用户失败", resp);}}public void resetPwd(HttpServletRequest req,HttpServletResponse resp) {try {service.resetPwd(user);CommonUtil.sendResponse(0, "密码修改成功", resp);} catch (Exception e) {e.printStackTrace();CommonUtil.sendResponse(-1, "密码修改失败", resp);}}}
login.jsp(登录界面)
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<html><head><%@include file="/common/head.jsp" %><style>body {color: #;}a {color: #;}  a:hover {color: #;}.bg-black {background-color: #;}#bg-video {position: fixed;top: 0;left: 0;width: 100%;height: 100%;object-fit: cover;z-index: -1;}</style><script type="text/javascript">layui.use(['layer', 'jquery'], function() {let layer=layui.layer;let $=layui.jquery;$("#login").click(function() {$.ajax({url: ctx+"/userAction.action?methodName=login",data: {loginName: $("#username").val(),pwd: $("#password").val()},dataType: 'json',type: 'post',success: function(data) {if(data.code == 1) {layer.msg(data.msg,{icon:1},function(){location.href="index.jsp";});}else{layer.msg(data.msg,{icon:5},function(){});}} })});});</script>
</head><body class="tx-login-bg">
<video id="bg-video" autoplay muted loop><source src="${ctx}/images/4.mp4" type="video/mp4">
</video><div class="tx-login-box"><div class="login-avatar bg-black"><img alt="" src="images/壁纸3.png" style="width:100px;height:65px;border-radius:50%"> </div><ul class="tx-form-li row"><li class="col-24 col-m-24"><p><input type="text" id="username" value="yaoyao" placeholder="登录账号" class="tx-input"></p></li><li class="col-24 col-m-24"><p><input type="password" id="password" value="1234" placeholder="登录密码" class="tx-input"></p></li><li class="col-24 col-m-24"><p class="tx-input-full"><button id="login" class="tx-btn tx-btn-big bg-black">登录</button></p></li><li class="col-12 col-m-12"><p><a href="#" class="f-12 f-gray">新用户注册</a></p></li><li class="col-12 col-m-12"><p class="ta-r"><a href="#" class="f-12 f-gray">忘记密码</a></p></li></ul></div></body>
</html>
userManage.jsp (数据绑定,修改,删除)
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<%@ include file="/common/head.jsp" %>
<title>数据绑定</title>
<style>
.layui-inline {margin-top: 20px;
}
</style>
<script>
let table=null;
let $ = null;
var row = null;layui.use(['table','jquery'], function(){table = layui.table;$ = layui.jquery;loadUsers();$("#queryUser").click(function() {loadUsers();});table.on('tool(userTable)', function(e) {// console.log(e);row = e.data;//console.log(row);if('edit' == e.event) {layer.open({type: 2,  //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)title: '增加用户',area: ['660px', '350px'],   //宽高skin: 'layui-layer-rim',    //样式类名content: ctx+'/jsp/system/userEdit.jsp'});}if('del' == e.event) {// alert("del = " + row.id);row = e.data;//console.log(row);layer.confirm("亲,真的删除吗?",function(index){e.del();layer.close(index);//发送请求到后台调用删除方法$.ajax({url: ctx+"/userAction.action?methodName=deleteUser",data: row,type: 'post',dataType: 'json',success: function(resp){if(resp.code == 0){var index = parent.layer.getFrameIndex(window.name);parent.layer.close(index);loadUsers();}else{alert("no");}}})})}if('reset'==e.event){row = e.data;//console.log(row);layer.confirm("亲,真的重置吗?",function(index){layer.close(index);//发送请求到后台调用删除方法$.ajax({url: ctx+"/userAction.action?methodName=resetPwd",data: row,type: 'post',dataType: 'json',success: function(resp){if(resp.code == 0){var index = parent.layer.getFrameIndex(window.name);parent.layer.close(index);loadUsers();}else{alert("no");}}})})}});$("#addUser").click(function() {row = null;layer.open({type: 2,  //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)title: '增加用户',area: ['660px', '350px'],   //宽高skin: 'layui-layer-rim',    //样式类名content: ctx+'/jsp/system/userEdit.jsp'});}); });function loadUsers() {table.render({elem: '#userTable',url: ctx + '/userAction.action?methodName=listUser',cols: [[{field:'id', width:80, title: 'ID'},{field:'name', width:180, title: '姓名', sort: true},{field:'loginName', width:180, title: '登录名', sort: true},{field:'roleName', width:180, title: '角色'},{field: '', title: '操作', width: 250, toolbar:'#toolbar'}]],page: true,request: {pageName: 'page',limitName: 'rows'},method: 'post',where: {name: $("#name").val()},loading: true,});
}
</script></head>
<body><!-- 查询条件 --><div class="layui-inline"><label class="layui-form-label">姓名:</label><div class="layui-input-block"><input type="text" name="name" id="name" placeholder="名称" class="layui-input"></div></div><div class="layui-inline"><button class="layui-btn" id="queryUser"><i class="layui-icon layui-icon-search"></i>查询</button><button class="layui-btn layui-btn-normal" id="addUser"><i class="layui-icon layui-icon-add-1"></i>增加</button></div><!-- 用户信息表格 --><table class="layui-hide" id="userTable" lay-filter="userTable"></table><!-- 工具条 --><script type="text/html" id="toolbar"><button class="layui-btn layui-btn-sm" lay-event="edit">编辑</button><button class="layui-btn layui-btn-sm" lay-event="del">删除</button><button class="layui-btn layui-btn-sm" lay-event="reset">重置密码</button></script>
</body>
</html>
userEdit.jsp(用户新增)
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>新增用户</title>
<%@include file="/common/head.jsp" %><script type="text/javascript">
let layer,form,$;
layui.use(['jquery', 'layer','form'],function() {layer=layui.layer,form=layui.form,$=layui.jquery;debugger;//获取用户信息,并回填在表单中,同时将name属性设置为只读,将密码隐藏(不允许在此处改密码)if(null!=parent.row){form.val('user',$.extend({}, parent.row||{}));$('#name').attr("readonly","readonly");$('#password').hide();}form.on('submit(user)', function(data){let id = $("#id").val();//如果有id则说明是修改,否则为新增if(!id) {//增加$.ajax({url: ctx + "/userAction.action?methodName=addUser",data: data.field,type: 'post',dataType: 'json',success: function(resp) {if(resp.code == 0) {layer.msg(resp.msg);var index = parent.layer.getFrameIndex(window.name);//再执行关闭parent.layer.close(index); parent.loadUsers();}}});} else {//修改$.ajax({url: ctx + "/userAction.action?methodName=updateUser",data: data.field,type: 'post',dataType: 'json',success: function(resp) {if(resp.code == 0) {layer.msg(resp.msg);var index = parent.layer.getFrameIndex(window.name);//再执行关闭parent.layer.close(index); parent.loadUsers();}}});}});});
</script></head><body>
<div style="padding:10px;"><form id="user" class="layui-form layui-form-pane" lay-filter="user"><input type="hidden" name="id" id="id"/><div class="layui-form-item"><label class="layui-form-label">用户名称</label><div class="layui-input-block"><input type="text" id="name" name="name" autocomplete="off" placeholder="请输入用户名" class="layui-input"></div></div><div class="layui-form-item"><label class="layui-form-label">用户角色</label><div class="layui-input-block"><select name="rid"><option value="">---请选择---</option><option value="1">管理员</option><option value="2">发起者</option><option value="3">审批者</option><option value="4">参与者</option><option value="5">会议管理员</option></select></div></div><div class="layui-form-item"><label class="layui-form-label">登录账号</label><div class="layui-input-block"><input type="text" name="loginName" lay-verify="required" placeholder="请输入账号" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item" id="password"><label class="layui-form-label">登录密码</label><div class="layui-input-block"><input type="password" name="pwd" placeholder="请输入密码" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item" style="text-align:center;"><button type="button" lay-submit="" lay-filter="user" class="layui-btn layui-btn-normal">保存</button><button type="reset" class="layui-btn">重置</button></div></form>
</div></body></html>

效果展示

登录界面

 绑定数据

 新增界面 

 删除界面

 修改界面

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1619224.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Python WEB框架之FastAPI

Python WEB框架之FastAPI 今天想记录一下最近项目上一直在用的Python框架——FastAPI。 个人认为&#xff0c;FastAPI是我目前接触到的Python最好用的WEB框架&#xff0c;没有之一。 之前也使用过像Django、Flask等框架&#xff0c;但是Django就用起来太重了&#xff0c;各种…

苹果手机怎么查看历史足迹

1.解锁手机&#xff0c;点击设置&#xff0c;如下图。 2.进入到设置界面&#xff0c;点击【隐私】选项&#xff0c;如下图。 3.进入到隐私界面&#xff0c;点击【定位服务】&#xff0c;如下图。 4.进入定位服务界面&#xff0c;点击【系统服务】&#xff0c;如下图。 5.在打开…

苹果uwb定位技术

昨天的文章简单说明了手机定位的技术&#xff0c;文章写的比较简单&#xff0c;但是阅读量却还可以&#xff0c;这篇文章转一个uwb定位技术的文章&#xff0c;让更多的人了解这项技术。 相关阅读&#xff1a; 手机是怎么确定位置信息的&#xff1f; 载波和LoRa #前言 关于昨天的…

常见手机定位方式浅谈

引言 前段时间在知乎上回答了一个关于手机定位相关的问题&#xff0c;被一个知友问到“加一个人微信聊天之后&#xff0c;收到了人家的一个视频&#xff0c;随后也把这个人及他发的视频都删除了&#xff0c;几天后在网吧上网&#xff0c;被别人定位到了&#xff0c;勒索了一笔钱…

苹果手机如何显示定位服务器地址,iOS8定位服务在哪?苹果iPhone6/Plus开启或关闭定位方法图文介绍...

以下是具体的iPhone6/Plus开启或关闭定位方法&#xff0c;适合所有iOS8系统的iPhone设备。 iOS8定位服务在哪&#xff1f; 定位服务关系用户隐私方面的东西&#xff0c;因此iOS8定位服务在iOS8设置中的“隐私”设置中&#xff0c;大家可以在下面的iOS8开启或者关闭定位服务教程…

小程序定位苹果手机可以,但是安装手机获取不到定位

1.确认是否开通定位权限 如果还没有权限&#xff0c;就去申请&#xff1a;申请时 注明场景&#xff0c;多上传几张 那个位置需要上传的照片 更容易通过本人申请场景(参考)&#xff1a;需要获取工人拍照验收位置照片注明定位位置时间&#xff0c;验证工人师傅在现场 审核是否通…

vscode 对模型train、detect脚本进行Debug时配置参数

我们训练yolov5代码时&#xff0c;一般会配置一些参数&#xff0c;比如模型权重文件--weights, 模型的配置文件--cfg, 以及训练的数据--data, 对应的训练脚本为: 训练train python train.py -- weights ./yolov5s.pt --cfg models\yolov5s.yaml --data ./data/coco128.yaml…

uniapp iOS打包证书申请流程——window

uniapp 如何在 window 创建 iOS打包证书&#xff1f; 文章目录 uniapp 如何在 window 创建 iOS打包证书&#xff1f;下载 Appuploader安装创建证书相关入口创建证书创建描述文件运行调试账号过期提示 前提&#xff1a; 下载 Appuploader工具 Appuploader辅助工具&#xff0c;解…

微服务学习资料

文章目录 参考资料一. 微服务概述1. CAP理论2. BASE理论3. SpringBoot 与 SpringCloud对比 二. 服务注册&#xff1a;Zookeeper,Eureka,Nacos,Consul1. Nacos两种健康检查方式&#xff1f;2. nacos中负责负载均衡底层是如何实现的3. Nacos原理4. 临时实例和持久化(非临时)实例 …

监控摄像头镜头焦距计算方法

一、公式计算法&#xff1a; 视场和焦距的计算 视场系指被摄取物体的大小&#xff0c;视场的大小是以镜头至被摄取物体距离&#xff0c;镜头焦头及所要求的成像大小确定的。 1、镜头的焦距&#xff0c;视场大小及镜头到被摄取物体的距离的计算如下&#xff1b; …

手把手教你如何调配监控镜头

监控镜头指监控摄像机的镜头&#xff0c;由于监控摄像机只是一个单一的视频扑捉设备&#xff0c;镜头的像素和分辨率比电脑的视频头要高但是赶不上专业的数码相机或dv。在闭路监控体系中&#xff0c;摄像机又称摄像头或CCD&#xff08;Charge Coupled Device&#xff09;即电荷…

中国式安全感:2亿视频监控镜头守护社会生活

随着科技发展&#xff0c;视频监控设备早已成为保障城市公共安全的必需品&#xff0c;车站、公园、公路、街角随处可见&#xff0c;数量庞大的视频监控设备从各方面为社会安全与智慧化发展提供了有力保障。 打造中国式安全感 监控覆盖面不断扩大 古往今来&#xff0c;更高的社…

监控相机镜头 焦距

1、相机上面的数字6mm 8mm 12mm,这些是摄像头的焦距 2、镜头毫米数越小&#xff0c;看到的画面视角越宽&#xff0c;视线也就越近&#xff0c;远处的地方就会看不清楚&#xff0c;越大的镜头&#xff0c;照出来画面视视角越窄&#xff0c;视线越远 3、安装的距离与高度&#xf…

监控摄像机如何选择镜头视场角

监控摄像机如何选择镜头视场角 对于监控摄像机如何选取合适的镜头&#xff0c;是一门学问。对于监控摄像机厂商&#xff0c;无论是用在家里&#xff0c;办公室&#xff0c;用在电梯&#xff0c;用在公共场所等等&#xff0c;在选择使用多大视场角的镜头及配合什么样的CCD&#…

2.8/4/6/8mm/12mm焦距的镜头分别能监控多大范围?

2.8/4/6/8mm/12mm焦距的镜头分别能监控多大范围&#xff1f; 相关介绍 一、焦距和监控距离的关系 我司IPC镜头焦距有2.8/4mm/6mm/8mm等多种选择&#xff0c;可以满足室内外各种环境的拍摄需求。IPC每个产品系列都可以选择镜头焦距&#xff0c;产品型号末位即表示镜头焦距&am…

docker,nvidia-docker安装

卸载先前的docker Docker 的旧版本被称为 docker&#xff0c;docker.io 或 docker-engine 。如果已安装&#xff0c;请卸载它们&#xff1a; sudo apt-get remove docker docker-engine docker.io containerd runc使用 Docker 仓库进行安装 设置仓库 更新 apt 包索引 sudo…

Unix及类Unix系统文本编辑器的介绍

概述 Vim是一个类似于Vi的著名的功能强大、高度可定制的文本编辑器&#xff0c;在Vi的基础上改进和增加了很多特性。VIM是纯粹的自由软件。 Vim普遍被推崇为类Vi编辑器中最好的一个&#xff0c;事实上真正的劲敌来自Emacs的不同变体。1999 年Emacs被选为Linuxworld文本编辑分类…

有趣免费的开源机器人课程实践指北-2019-

如果对机器人方向学习有些迷茫&#xff0c;推荐先阅读如下文章&#xff1a; 机器人工程师学习计划&#xff08;4.3k赞&#xff09;&#xff1a;https://zhuanlan.zhihu.com/p/22266788开源机器人学学习指南&#xff08;376赞&#xff09;&#xff1a;https://github.com/qqfly…

2022.管理类软件工具

管理类的工具软件 1 filezilla工具1.1 filezilla 绑定本地wps&#xff0c;可远程查看编辑 2 gitLab 本地代码类托管2.1 ubuntu 安装gitlab 3 tftp下载应用程序至开发板3.1 windows端安装服务器软件tftpd643.2 开发板内核需要配置tftp客户端 4 开发板操作常用指令5 vscode工具5.…