• springboot+easyui+jpa实现动态权限角色的后台管理系统(二)


    上一篇中已经介绍了我初步创建好管理系统和加载菜单的功能,这篇把用户管理(新增用户,修改用户,分配角色)和角色管理(新增角色,修改角色,授权)的功能增设中的心得和问题记录一下:

    放上界面效果图:

    1.首先在数据库的sys_resource表中找到用户管理和角色管理,在这两条数据的url字段中添加ftl的路径

    我在登陆和跳转的controller层中先写了获取路径的代码:

        @RequestMapping(value = "/page/{tail}/{file}", method = RequestMethod.GET)
        public String currency(@PathVariable("file") String file, @PathVariable("tail") String tail) {
            return "/" + tail + "/" + file;
        }

    然后在数据库的url字段中添加

    2.编写前端的界面

    roleInfo.ftl

    <!DOCTYPE html>
    <html>
    <head>
    <#include "../inc/inc.ftl"/>
    </head>
    <body>
    <div class="easyui-layout" data-options="fit:true,border:false">
        <table id="dg"></table>
    </div>
    
    <div id="dlg" class="easyui-dialog" style="450px;height:auto;padding:10px 20px" buttons="#dlg-buttons"
         data-options="closed:true,modal:true">
        <form id="fm" method="post" enctype="multipart/form-data">
            <input type="hidden" id="roleId" name="roleId"/>
            <table class="grid">
                <tr>
                    <td>角色名称:</td>
                    <td>
                        <input type="text" name="roleName" class="easyui-textbox"
                               data-options="required:true,validType:['length[0,50]']"/>
                    </td>
                </tr>
                <tr>
                    <td>备注:</td>
                    <td>
                        <input type="text" name="remark" class="easyui-textbox" data-options="validType:['length[0,50]']"/>
                    </td>
                </tr>
            </table>
        </form>
    </div>
    <div id="dlg-buttons">
        <a href="javascript:void(0)" class="easyui-linkbutton c8" data-options="iconCls:'icon-ok'"
           onclick="javascript:saveRole();" style="90px;">保存</a>
        <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
           onclick="javascript:$('#dlg').dialog('close');" style="90px;">取消</a>
    </div>
    
    <div id="toolbar" style="padding:5px;height:auto">
        <div>
            <a onclick="addRole();" href="javascript:void(0);" class="easyui-linkbutton"
               data-options="plain:true,iconCls:'icon-add'">新增角色</a>
            <a onclick="editRole();" href="javascript:void(0);" class="easyui-linkbutton"
               data-options="plain:true,iconCls:'icon-edit'">修改角色</a>
            <a onclick="openAuth();" href="javascript:void(0);" class="easyui-linkbutton"
               data-options="plain:true,iconCls:'icon-edit'">授权</a>
        </div>
    </div>
    
    <#include "auth.ftl"/>
    </body>
    </html>
    
    
    <script type="text/javascript">
        $(document).ready(function () {
            loadData();
        });
    
        function loadData() {
            $("#dg").datagrid({
                url: '${request.contextPath}/sys/role_list',
                striped: true,
                border: false,
                collapsible: false,        //是否可折叠的
                loadMsg: '正在加载数据...',
                fit: true,                //自动大小
                idField: 'roleId',
                singleSelect: true,//是否单选
                columns: [[{
                    field: 'roleName',
                    title: '角色名',
                     120,
                    halign: 'center'
                }, {
                    field: 'remark',
                    title: '备注',
                     200,
                    halign: 'center'
                }
                ]],
                toolbar: '#toolbar'
            });
        }
    
        function addRole() {
            $('#fm').form('clear');
            $('#dlg').dialog('open').dialog('setTitle', '新增');
        }
    
        function editRole() {
            var row = $('#dg').datagrid('getSelected');
            if (row) {
                $('#dlg').dialog('open').dialog('setTitle', '修改');
                $('#fm').form('load', row);
            } else {
                $.messager.alert("提示", "请选择一条记录");
            }
        }
    
        function saveRole() {
            $('#fm').form('submit', {
                url: "${request.contextPath}/sys/role_save",
                success: function (result) {
                    var result = eval('(' + result + ')');
                    if (result.code == 0) {
                        $('#dg').datagrid('reload');
                        $('#dlg').dialog('close');
                    } else {
                        $.messager.show({
                            title: '提示',
                            msg: result.message
                        });
                    }
                }
            });
        }
    </script>

    userInfo.ftl:

    <!DOCTYPE html>
    <html>
    <head>
    <#include "../inc/inc.ftl"/>
    </head>
    <body>
    <div class="easyui-layout" data-options="fit:true,border:false">
        <table id="dg"></table>
    </div>
    
    <div id="dlg" class="easyui-dialog" style="450px;height:auto;padding:10px 20px" buttons="#dlg-buttons"
         data-options="closed:true,modal:true">
        <form id="fm" method="post" enctype="multipart/form-data">
            <input type="hidden" id="userId" name="userId"/>
            <table class="grid">
                <tr>
                    <td>用户名:</td>
                    <td>
                        <input type="text" name="username" class="easyui-textbox"
                               data-options="required:true,validType:['length[3,20]']"/>
                    </td>
                </tr>
                <tr>
                    <td>密码:</td>
                    <td>
                        <input type="text" name="password" class="easyui-passwordbox" iconWidth="28"
                               data-options="required:true,validType:['length[0,20]']"/>
                    </td>
                </tr>
                <tr>
                    <td>姓名:</td>
                    <td>
                        <input type="text" name="staffName" class="easyui-textbox"
                               data-options="required:true,validType:['length[0,20]']"/>
                    </td>
                </tr>
            </table>
        </form>
    </div>
    <div id="dlg-buttons">
        <a href="javascript:void(0)" class="easyui-linkbutton c8" data-options="iconCls:'icon-ok'"
           onclick="javascript:saveUser();" style="90px;">保存</a>
        <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
           onclick="javascript:$('#dlg').dialog('close');" style="90px;">取消</a>
    </div>
    
    <div id="roleDlg" class="easyui-dialog" style="550px;height:450px;" buttons="#roleDlg-buttons"
         data-options="closed:true,modal:true,resizable:true">
        <div class="easyui-layout" data-options="fit:true,border:false">
            <div data-options="region:'west',collapsible:false" title="可分配角色" style="227px;padding:5px;">
                <table id="selectRoles"></table>
            </div>
            <div data-options="region:'center'" style="padding-top:120px;padding-left:1px;text-align:center">
                <a class="easyui-linkbutton" onclick="addRole();" style="40px;"> &gt;&gt; </a>
                <br/><br/><br/>
                <a class="easyui-linkbutton" onclick="removeRole();" style="40px;"> &lt;&lt; </a>
            </div>
            <div data-options="region:'east',collapsible:false" title="已分配角色" style="227px;padding:5px;">
                <table id="selectedRoles"></table>
            </div>
        </div>
    </div>
    <div id="roleDlg-buttons">
        <a href="javascript:void(0)" class="easyui-linkbutton c2" iconCls="icon-cancel"
           onclick="javascript:$('#roleDlg').dialog('close')" style="90px">关闭</a>
    </div>
    
    <div id="toolbar" style="padding:5px;height:auto">
        <div>
            <a onclick="addUser();" href="javascript:void(0);" class="easyui-linkbutton"
               data-options="plain:true,iconCls:'icon-add'">新增用户</a>
            <a onclick="editUser();" href="javascript:void(0);" class="easyui-linkbutton"
               data-options="plain:true,iconCls:'icon-edit'">修改用户</a>
            <a onclick="grantRole();" href="javascript:void(0);" class="easyui-linkbutton"
               data-options="plain:true,iconCls:'icon-edit'">分配角色</a>
        </div>
    </div>
    </body>
    </html>
    
    
    <script type="text/javascript">
        $(document).ready(function () {
            loadData();
        });
    
        function loadData() {
            $("#dg").datagrid({
                url: '${request.contextPath}/sys/user_list',
                striped: true,
                border: false,
                collapsible: false,        //是否可折叠的
                loadMsg: '正在加载数据...',
                fit: true,                //自动大小
                idField: 'userId',
                singleSelect: true,//是否单选
                columns: [[{
                    field: 'username',
                    title: '用户名',
                     120,
                    halign: 'center'
                }, {
                    field: 'staffName',
                    title: '真实姓名',
                     200,
                    halign: 'center'
                }
                ]],
                toolbar: '#toolbar'
            });
        }
    
        function addUser() {
            $('#fm').form('clear');
            $('#dlg').dialog('open').dialog('setTitle', '新增');
        }
    
        function editUser() {
            var row = $('#dg').datagrid('getSelected');
            if (row) {
                $('#dlg').dialog('open').dialog('setTitle', '修改');
                $('#fm').form('load', row);
            } else {
                $.messager.alert("提示", "请选择一条记录");
            }
        }
    
        function saveUser() {
            $('#fm').form('submit', {
                url: "${request.contextPath}/sys/user_save",
                success: function (result) {
                    var result = eval('(' + result + ')');
                    if (result.code == 0) {
                        $('#dg').datagrid('reload');
                        $('#dlg').dialog('close');
                    } else {
                        $.messager.show({
                            title: '提示',
                            msg: result.message
                        });
                    }
                }
            });
        }
    
        function grantRole() {
            var row = $('#dg').datagrid('getSelected');
            if (row) {
                $('#roleDlg').dialog('open').dialog('setTitle', '分配角色');
                $("#selectRoles").datagrid({
                    url: "${request.contextPath}/sys/user_no_role?userId=" + row.userId,
                     210,
                    height: 'auto',
                    border: false,
                    loadMsg: '正在加载数据...',
                    fit: true,                //自动大小
                    idField: 'roleId',
                    rownumbers: true,//行号
                    remoteSort: false,
                    frozenColumns: [[
                        {field: 'ck', checkbox: true}
                    ]],
                    columns: [[{
                        field: 'roleName',
                        title: '角色名称',
                        sortable: true,
                         150,
                        align: 'center'
                    }]]
                });
                $("#selectedRoles").datagrid({
                    url: "${request.contextPath}/sys/user_role?userId=" + row.userId,
                     210,
                    height: 'auto',
                    border: false,
                    loadMsg: '正在加载数据...',
                    fit: true,                //自动大小
                    idField: 'roleId',
                    rownumbers: true,//行号
                    remoteSort: false,
                    frozenColumns: [[
                        {field: 'ck', checkbox: true}
                    ]],
                    columns: [[{
                        field: 'roleName',
                        title: '角色名称',
                        sortable: true,
                         150,
                        align: 'center'
                    }]]
                });
            } else {
                $.messager.alert('提示', '请选择一条记录', 'info');
            }
        }
    
        //增加角色
        function addRole() {
            var row = $('#dg').datagrid('getSelected');
            var checknodes = $('#selectRoles').datagrid('getChecked');
            var prams = [];
            if (checknodes && checknodes.length > 0) {
                for (var i = 0; i < checknodes.length; i++) {
                    var pram = new Object();
                    pram.userId = row.userId;
                    pram.roleId = checknodes[i].roleId;
                    prams.push(pram);
                }
                //转换成json字符串。
                var jsonText = JSON.stringify(prams);
                $.ajax({
                    url: '${request.contextPath}/sys/add_role',
                    type: 'post',
                    dataType: 'json',
                    data: {data: jsonText},
                    success: function (result) {
                        if (result.code == 0) {
                            $('#selectRoles').datagrid('reload');
                            $('#selectedRoles').datagrid('reload');
                            //清除选中的状态,(虽然看不到选中,但获取选中行的时候还是会有)
                            $('#selectRoles').datagrid('clearSelections');
                            $('#selectedRoles').datagrid('clearSelections');
                            $.messager.show({
                                title: '提示',
                                msg: result.message
                            });
                            $('#dg').datagrid('reload');
                            $('#dlg').dialog('close');
                        } else {
                            $.messager.show({
                                title: '提示',
                                msg: result.message
                            });
                        }
                    }
                });
            } else {
                $.messager.alert('提示', '请选择可分配的角色', 'info');
            }
        }
    
        //移除角色
        function removeRole() {
            var row = $('#dg').datagrid('getSelected');
            var checknodes = $('#selectedRoles').datagrid('getChecked');
            var prams = [];
            if (checknodes && checknodes.length > 0) {
                for (var i = 0; i < checknodes.length; i++) {
                    var pram = new Object();
                    pram.userId = row.userId;
                    pram.roleId = checknodes[i].roleId;
                    prams.push(pram);
                }
                //转换成json字符串。
                var jsonText = JSON.stringify(prams);
                $.ajax({
                    url: '${request.contextPath}/sys/remove_role',
                    type: 'post',
                    dataType: 'json',
                    data: {data: jsonText},
                    success: function (result) {
                        if (result.code == 0) {
                            $('#selectRoles').datagrid('reload');
                            $('#selectedRoles').datagrid('reload');
                            //清除选中的状态,(虽然看不到选中,但获取选中行的时候还是会有)
                            $('#selectRoles').datagrid('clearSelections');
                            $('#selectedRoles').datagrid('clearSelections');
                            $.messager.show({
                                title: '提示',
                                msg: result.message
                            });
                            $('#dg').datagrid('reload');
                            $('#dlg').dialog('close');
                        } else {
                            $.messager.show({
                                title: '提示',
                                msg: result.message
                            });
                        }
                    }
                });
            } else {
                $.messager.alert('提示', '请选择可移除的角色', 'info');
            }
        }
    </script>

    授权功能的资源界面 auth.ftl

    (存在资源树)

    效果图如下:

    代码如下:

    <!-- 授权panel -->
    <div id="authDlg" class="easyui-dialog" style="460px;height:500px;padding:10px;" buttons="#authDlg-buttons"
         data-options="closed:true,modal:true,resizable:true">
        <div class="easyui-layout" data-options="fit:true,border:false">
            <div data-options="region:'west'" style="310px;padding:10px;">
                <ul id="accessTree"></ul>
                <input id="roleId" name="roleId" hidden="hidden"/>
            </div>
            <div data-options="region:'center'" style="text-align:center;padding-top:200px;">
                <div>
                    <a class="easyui-linkbutton" onclick="checkAll();" style="60px;">全选</a>
                    <br/> <br/>
                    <a class="easyui-linkbutton" onclick="checkInverse();" style="60px;">反选</a>
                    <br/> <br/>
                    <a class="easyui-linkbutton" onclick="uncheckAll();" style="60px;">取消</a>
                </div>
            </div>
        </div>
    </div>
    <div id="authDlg-buttons">
        <a href="javascript:void(0)" class="easyui-linkbutton c8" iconCls="icon-ok" onclick="saveAuth();"
           style="90px">保存</a>
        <a href="javascript:void(0)" class="easyui-linkbutton c2" iconCls="icon-cancel"
           onclick="javascript:$('#authDlg').dialog('close')" style="90px">取消</a>
    </div>
    <!-- 授权panel结束 -->
    
    
    <script type="text/javascript">
        //==================================授权=============================
        var accessTree;
    
        function openAuth() {
    
    
            var row = $('#dg').datagrid('getSelected');
            if (row) {
                $('#authDlg').dialog('open').dialog('setTitle', '授权');
                //-----------可分配权限资源树--------------
                accessTree = $('#accessTree').tree({
                    url: '${request.contextPath}/sys/auth_resource',
                    parentField: 'parentId',
                    lines: true,
                    checkbox: true,
                    cascadeCheck: false
                });
    //            $('#authForm').form('clear');
                $('#roleId').val(row.roleId);
                loadAuth(row.roleId);
            } else {
                $.messager.alert('提示', '请选择一条记录');
            }
        }
    
        //加载该角色已有权限
        function loadAuth(id) {
            $.ajax({
                url: '${request.contextPath}/sys/role_auth',
                type: 'post',
                dataType: 'json',
                data: {roleId: id},
                success: function (result) {
                    for (var i = 0; i < result.length; i++) {
                        if (accessTree.tree('find', result[i].resourceId)) {
                            accessTree.tree('check', accessTree.tree('find', result[i].resourceId).target);
                        }
                    }
                }
            });
        }
    
        //全选
        function checkAll() {
            var nodes = accessTree.tree('getChecked', 'unchecked');
            if (nodes && nodes.length > 0) {
                for (var i = 0; i < nodes.length; i++) {
                    accessTree.tree('check', nodes[i].target);
                }
            }
        }
    
        //取消选择
        function uncheckAll() {
            var nodes = accessTree.tree('getChecked');
            if (nodes && nodes.length > 0) {
                for (var i = 0; i < nodes.length; i++) {
                    accessTree.tree('uncheck', nodes[i].target);
                }
            }
        }
    
        //反选
        function checkInverse() {
            var unchecknodes = accessTree.tree('getChecked', 'unchecked');
            var checknodes = accessTree.tree('getChecked');
            if (unchecknodes && unchecknodes.length > 0) {
                for (var i = 0; i < unchecknodes.length; i++) {
                    accessTree.tree('check', unchecknodes[i].target);
                }
            }
            if (checknodes && checknodes.length > 0) {
                for (var i = 0; i < checknodes.length; i++) {
                    accessTree.tree('uncheck', checknodes[i].target);
                }
            }
        }
    
        //保存
        function saveAuth() {
            var checknodes = accessTree.tree('getChecked');
            var roleId = $('#roleId').val();
            var prams = [];
            if (checknodes && checknodes.length > 0) {
                for (var i = 0; i < checknodes.length; i++) {
                    var pram = new Object();
                    pram.roleId = roleId;
                    pram.resourceId = checknodes[i].id;
                    prams.push(pram);
                }
            }
            //转换成json字符串。
            var jsonText = JSON.stringify(prams);
            $.post('${request.contextPath}/sys/auth_save', {data: jsonText, roleId: roleId}, function (result) {
                if (result.code == 0) {
                    $('#authDlg').dialog('close');
                    $.messager.show({
                        title: '提示',
                        msg: result.message
                    });
                } else {
                    $.messager.show({
                        title: '提示',
                        msg: result.message
                    });
                }
            }, 'json');
        }
    </script>

    Service:

    用户管理(依次是获取当前用户角色,获取当前用户没有的角色,添加用户角色,移除用户角色)

    package com.lk.modeleasyui.service;
    
    import com.lk.modeleasyui.dao.SysRoleDAO;
    import com.lk.modeleasyui.dao.SysRoleUserDAO;
    import com.lk.modeleasyui.domain.SysRole;
    import com.lk.modeleasyui.domain.SysRoleUser;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Author: Lukizzz
     * @Date: 2018/9/12 11:48
     * @Description:
     */
    @Service
    public class SysRoleUserService {
    
        @Autowired
        private SysRoleUserDAO sysRoleUserDAO;
        @Autowired
        private SysRoleDAO sysRoleDAO;
    
        public List<SysRole> getUserRole(Long userId) {
            List<SysRoleUser> list = sysRoleUserDAO.findAllByUserId(userId);
            List<Long> roleIds = new ArrayList<>();
            for (SysRoleUser sysRoleUser : list) {
                roleIds.add(sysRoleUser.getRoleId());
            }
            return sysRoleDAO.findAllByRoleIdIn(roleIds);
        }
    
        public List<SysRole> getUserNoRole(Long userId) {
            List<SysRoleUser> list = sysRoleUserDAO.findAllByUserId(userId);
            if (list.isEmpty()) {
                return sysRoleDAO.findAll();
            } else {
                List<Long> roleIds = new ArrayList<>();
                for (SysRoleUser sysRoleUser : list) {
                    roleIds.add(sysRoleUser.getRoleId());
                }
                return sysRoleDAO.findAllByRoleIdNotIn(roleIds);
            }
        }
    
        public void addRole(List<SysRoleUser> roleUserList) {
            for (SysRoleUser roleUser : roleUserList) {
                SysRoleUser sysRoleUser = new SysRoleUser();
                sysRoleUser.setRoleId(roleUser.getRoleId());
                sysRoleUser.setUserId(roleUser.getUserId());
                sysRoleUserDAO.save(sysRoleUser);
            }
        }
    
        public void removeRole(List<SysRoleUser> roleUserList) {
            for (SysRoleUser roleUser : roleUserList) {
                SysRoleUser sysRoleUser = new SysRoleUser();
                sysRoleUser.setUserId(roleUser.getUserId());
                sysRoleUser.setRoleId(roleUser.getRoleId());
                sysRoleUserDAO.deleteAllByRoleIdAndAndUserId(sysRoleUser.getRoleId(),sysRoleUser.getUserId());
            }
        }
    
    }

    角色管理:(获取当前角色列表,修改角色,获取授权列表也就是resource的列表,保存授权的列表)

    package com.lk.modeleasyui.service;
    
    import com.lk.modeleasyui.dao.SysRoleDAO;
    import com.lk.modeleasyui.dao.SysRoleResourceDAO;
    import com.lk.modeleasyui.domain.SysRole;
    import com.lk.modeleasyui.domain.SysRoleResource;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @Author: Lukizzz
     * @Date: 2018/9/11 13:49
     * @Description:
     */
    @Service
    public class SysRoleService {
        @Autowired
        private SysRoleDAO sysRoleDAO;
        @Autowired
        private SysRoleResourceDAO sysRoleResourceDAO;
    
        public List<SysRole> getRoleList() {
            return sysRoleDAO.findAll();
        }
    
        public void editRole(Long roleId, String roleName, String remark) {
            if (roleId != null) {
                sysRoleDAO.editRole(roleId, roleName, remark);
            } else {
                sysRoleDAO.createRole(roleName, remark);
            }
        }
    
        public List<SysRoleResource> getRoleAuth(Long roleId) {
            return sysRoleResourceDAO.findAllByRoleId(roleId);
        }
    
        public void saveRoleAuth(List<SysRoleResource> list, Long roleId) {
            sysRoleResourceDAO.deleteAllByRoleId(roleId);
            for (SysRoleResource sysRoleResource : list) {
                SysRoleResource sysRoleResource1 = new SysRoleResource();
                sysRoleResource1.setRoleId(sysRoleResource.getRoleId());
                sysRoleResource1.setResourceId(sysRoleResource.getResourceId());
                sysRoleResourceDAO.save(sysRoleResource1);
            }
        }
    
    }

    在这期间遇到的问题:

    1.首先一个,因为roleId是个集合(默认一个用户可以有多个角色),又因为roleId是Long类型,所以在获取并计算的过程中,应该用List<Long>,如果不这样的话会报错说明错误的封装类型和long类型不匹配

    2.第二个问题,在前端点击授权功能和分配角色功能的时候出现如下报错:

    看字面意思是说这个表不存在,但是我的数据库里面是没有这个表的,去网上查了一下也没有很好的答案,后来发现是id生成策略的问题,解决方法是在实体类的@GeneratedValue后面加上一句代码

    (strategy = GenerationType.IDENTITY)

    关于id生成策略的问题网上有介绍

    3.我在进行对数据库删除操作的时候出现过这样的问题:

    原因是JPA中特有的在DAO层执行update和delete操作的时候,没有对事务进行处理,我们需要在数据库操作的方法上添加一个注解

    @Transactional(rollbackFor = Exception.class)

    4.增删改查的功能后台功能没有写错,但是在存入数据库的时候出现了乱码,页面上显示的也是数据库的乱码,按照网上的解决办法我进行了一步步的查验:

    首先查看了数据表中相应字段的属性

    没问题,然后看了数据库的属性

    也没问题,然后去看了项目的配置文件

     

    也没什么问题,在网查了解决方法后看到了一个帖子,按照上面的方法查询了数据库的默认编码配置,发现default-character-server的配置不是utf8,按照教程打开MYSQL的安装目录,在安装目录下有个my.ini文件,通过记事本打开这个文件

     

    在[client]下添加default-character-set=utf8

    [mysqld]下添加character-set-server=utf8

    配置修改完成后重启MySQL就可以了

    5.在完成模版项目的编写后打算上传gitlab和github,方便以后大家的使用,在push过程中首先遇到个问题,http认证失败

    因为生成了ssh公钥,但是在gitlab的setting的ssh key中没有添加公钥.我重新生成了一遍公钥并不设置密码,在gitlab的setting的ssh key中添加key,通过ssh的地址上传

    而这样又跳出来提示是push被拦截,在网上搜了一个教程,自己使用后push成功.

    解决方案如下:

    1.切换到自己项目所在的目录,右键选择GIT BASH Here,Idea中可使用Alt+F12

    2.在terminl窗口中依次输入命令:

    git pull

    git pull origin master

    git pull origin master --allow-unrelated-histories

    3.在idea中重新push自己的项目,成功!!!

  • 相关阅读:
    [LUOGU] 1364 医院设置
    [POJ] 3278 Catch That Cow
    [OpenJudge] 2727 仙岛寻药
    [POJ] 2386 Lake Counting
    [POJ]1118 Lining up
    [LUOGU]1141 01迷宫
    [POJ]1111 Image Perimeters
    python之路——初识函数
    python----------文件操作
    Python中的split()函数的用法
  • 原文地址:https://www.cnblogs.com/Lukizzz/p/9644728.html
Copyright © 2020-2023  润新知