随笔9

easyui+springboot+jpa实现一个简单的后台管理系统

1.首先,添加依赖,配置yml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.32</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>

    </dependencies>

yml:

server:
  port: 8081
  servlet:
    context-path: /
spring:
  http:
    encoding:
      force: true
      charset: UTF-8
  freemarker:
    suffix: .ftl
    cache: false
    request-context-attribute: request
    charset: UTF-8
    template-loader-path: classpath:/view/
    check-template-location: false
  profiles:
    active: config
  mvc:
    static-path-pattern: /static/**
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://xx.xxx.xxx:3306/game?useUnicode=true&amp;characterEncoding=UTF-8mb4&useSSL=false
    username: xxx
    password: xxx
  jpa:
    database: mysql
    show-sql: true

整体的截图:

static里面放的是静态资源,yml里static-path-pattern是配置了静态资源的路径

inc文件夹中放置了inc.ftl 调用了一些样式,方便其他页面的调用静态资源

inc.ftl:

<script src="${request.contextPath}/static/jquery/jquery.min.js"></script>
<script src="${request.contextPath}/static/jquery/jquery.form.js"></script>
<!--easyui  -->
<!-- easyui.css放前面 -->
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/default/easyui.css" rel="stylesheet" title="default">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/black/easyui.css" rel="stylesheet" title="black">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/bootstrap/easyui.css" rel="stylesheet" title="bootstrap">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/gray/easyui.css" rel="stylesheet" title="gray">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/metro/easyui.css" rel="stylesheet" title="metro">


<link rel="stylesheet" href="${request.contextPath}/static/easyui/themes/icon.css" />
<link rel="stylesheet" href="${request.contextPath}/static/easyui/themes/color.css" />

<script src="${request.contextPath}/static/easyui/jquery.easyui.min.js"></script>
<script src="${request.contextPath}/static/easyui/datagrid-detailview.js"></script>
<script src="${request.contextPath}/static/easyui/easyui-lang-zh_CN.js"></script>
<script src="${request.contextPath}/static/easyui/extEasyUI.js" charset="utf-8"></script>
<script src="${request.contextPath}/static/jquery/jquery.serializejson.js"></script>

<#--<!--自定义样式  &ndash;&gt;-->
<link rel="stylesheet" href="${request.contextPath}/static/manager/css/global.css" />
<script src="${request.contextPath}/static/manager/js/global.js"></script>
<link rel="stylesheet" href="${request.contextPath}/static/manager/css/img.css" />
<script src="${request.contextPath}/static/manager/js/img.js"></script>

其他页面只需要在<head>中加入

<#include "inc/inc.ftl"/>,就能调用和inc一样的静态资源

2.完成登陆/修改密码/退出系统的功能和工具类/页面的编写

login.ftl就不放了
index.ftl:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <title>ace Admin</title>
    <meta name="description" content=""/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <#include "inc/inc.ftl"/>
</head>
<body>
<div id="test"></div>
<div class="easyui-layout" data-options="fit:true">
    <div data-options="region:'north'" class="head_body" style="overflow:hidden;">
        <div>
            <div class="head_left"></div>
            <div class="head_right">
                <div class="huanying">
                    欢迎 <span>${Session.userInfo.username}</span> 登陆 | 现在是<span id="show_date"></span>
                </div>
                <div class="anniu">
                    <div class="bb">
                        <a href="javascript:logout();" class="logout"></a>
                        <a id="open_change_password" class="changePwd" href="javascript:editPassword();"></a>
                    </div>
                    <div class="bs">
                        <a class="styleswitch a1" style="CURSOR: pointer" title="黑灰色" rel="black"></a>
                        <a class="styleswitch a2" style="CURSOR: pointer" title="天蓝色" rel="default"></a>
                        <a class="styleswitch a3" style="CURSOR: pointer" title="灰色" rel="bootstrap"></a>
                        <a class="styleswitch a4" style="CURSOR: pointer" title="浅灰色" rel="gray"></a>
                        <a class="styleswitch a5" style="CURSOR: pointer" title="白色" rel="metro"></a>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div data-options="region:'west',split:true,title:'导航菜单'" style="width:188px;">
        <div class="easyui-accordion" id="main-accordion" data-options="fit:true,border:false">
            <ul>
                <li><a href="javascript:void(0)" class="easyui-linkbutton"
                       onclick="addTab('设置一级权重','resources/to_setting')">设置一级权重</a></li>
                <li><a href="javascript:void(0)" class="easyui-linkbutton"
                       onclick="addTab('设置二级权重','resources/to_detailSetting')">设置二级权重</a></li>
                <li><a href="javascript:void(0)" class="easyui-linkbutton"
                       onclick="addTab('设置游戏道具','resources/to_gameProp')">设置游戏道具</a></li>
            </ul>
        </div>
    </div>

    <div id="mainPanel" data-options="region:'center'">
        <div id="index_tabs" class="easyui-tabs" data-options="fit:true,border:false,tabHeight:30"
             style="height:600px;">
            <div title="Home">
                <div style="padding:10px 0 10px 10px">
                    <h2>系统介绍</h2>
                    <div class="light-info">

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div id="dlg" class="easyui-dialog" style="width: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="password" class="easyui-passwordbox" iconWidth="28"
                           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="width:90px;">保存</a>
    <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
       onclick="javascript:$('#dlg').dialog('close');" style="width:90px;">取消</a>
</div>
</body>
</html>
<script type="text/javascript">
    $(document).ready(function () {
        var myDate = new Date();
        var week = ['日', '一', '二', '三', '四', '五', '六'];
        var month = myDate.getMonth() + 1;
        var weekDay = " 星期" + week[myDate.getDay()];
        var showDate = myDate.getFullYear() + "年" + month + "月" + myDate.getDate() + "日" + weekDay;
        $("#show_date").text(showDate);

    });


    //初始化TABS组件
    $('#index_tabs').tabs({
        fit: true,
        border: false,
        tabHeight: 30,
        tools: [{
            iconCls: 'icon-reload',
            handler: function () {
                var currTab = $('#index_tabs').tabs('getSelected');
                var index = $('#index_tabs').tabs('getTabIndex', currTab);
                if (index != 0) {
                    var updateUrl = $(currTab.panel('options').content).attr('src');
                    $('#index_tabs').tabs('update', {
                        tab: currTab,
                        options: {
                            content: refreshTab(updateUrl)
                        }
                    });
                }
            }
        }, {
            iconCls: 'icon-clear',
            handler: function () {
                $.messager.confirm('提示', '确定要全部关闭选项卡?', function (r) {
                    if (r) {
                        var tabTitle = new Array();
                        var tabs = $('#index_tabs').tabs("tabs");
                        var tCount = tabs.length;
                        if (tCount > 0) {
                            for (var i = 0; i < tCount; i++) {
                                tabTitle.push(tabs[i].panel('options').title);
                            }
                            for (var i = 0; i < tabTitle.length; i++) {
                                if (tabTitle[i] != '首页') {
                                    $('#index_tabs').tabs("close", tabTitle[i]);
                                }
                            }
                        }
                    }
                });
            }
        }]
    });

    function editPassword() {
        $('#dlg').dialog('open').dialog('setTitle', '修改');
        $("#userId").val(${Session.userInfo.id});
    }

    function saveUser() {

        $('#fm').form('submit', {
            url: "${request.contextPath}/user_save",
            success: function (result) {
                var result = eval('(' + result + ')');
                if (result.code == 0) {
                    $.messager.show({
                        title: '提示',
                        msg: result.message
                    });
                    $('#dlg').dialog('close');
                }
            }
        });
    }
</script>

页面截图:


登陆/修改密码/退出系统功能的控制层:
package com.yz.slotsgameht.controller;

import com.yz.slotsgameht.domain.SysUser;
import com.yz.slotsgameht.service.SysUserService;
import com.yz.slotsgameht.utils.GetIpAddress;
import com.yz.slotsgameht.utils.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


/**
 * @Author: Lukizzz
 * @Date: 2018/8/28 14:19
 * @Description:
 */
@Controller
public class SysUserController {

    private final Logger log = LoggerFactory.getLogger(SysUser.class);

    @Autowired
    private SysUserService sysUserService;


    @RequestMapping("/login")
    public String login2() {
        return "login";
    }

    @RequestMapping(value = "/do_login")
    public String login(String username, String password, HttpServletRequest request) {
        SysUser user = sysUserService.getUserByLogin(username);
        HttpSession session = request.getSession();
        String xIp = GetIpAddress.getIpAddress(request);
        log.info("账号: {},密码: {},本地ip:{}", username, password, xIp);
        if (user == null) {
            request.setAttribute("errorInfo", "用户名不存在");
            return "login";
        } else if (user.getPassword().equals(password)) {
//将获取的user数据存入session中,名字为"userInfo" session.setAttribute(
"userInfo", user); return "redirect:/index"; } else { request.setAttribute("errorInfo", "用户名密码错误"); return "login"; } } @RequestMapping(value = "/logout") public String logout(HttpServletRequest request) { HttpSession session = request.getSession(); session.removeAttribute("userInfo"); return "login"; } @RequestMapping(value = "/index") public String index() { return "index"; } @RequestMapping(value = "/user_save") @ResponseBody public Result saveUser(Long userId,String password,HttpServletRequest request){
//获取ip地址 String ip
= GetIpAddress.getIpAddress(request);
//日志 log.info(
"新密码: {},本地ip地址:{}", password, ip); sysUserService.saveUser(userId, password); return Result.builder(); } }

Result工具类:

package com.yz.slotsgameht.utils;

import lombok.Data;

/**
 * @Author: Lukizzz
 * @Date: 2018/8/29 16:02
 * @Description:
 */
@Data
public class Result<T> {
    private int code = 0;
    private String message;
    private T data;
    private CodeMsg codeMsg = CodeMsg.SUCCESS;

    public static Result builder(CodeMsg codeMsg) {
        Result result = new Result();
        result.setCode(codeMsg.getCode());
        result.setMessage(codeMsg.getMsg());
        return result;
    }

    public static Result builder() {
        return builder(CodeMsg.SUCCESS);
    }

    public Result withCode(CodeMsg codeMsg) {
        message = codeMsg.getMsg();
        code = codeMsg.getCode();
        return this;
    }

    public Result withData(T data) {
        this.data = data;
        return this;
    }


    public Result() {
        this.code = codeMsg.getCode();
        this.message = codeMsg.getMsg();
    }

    public Result(CodeMsg codeMsg) {
        this.code = codeMsg.getCode();
        this.message = codeMsg.getMsg();
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public void setCodeMsg(CodeMsg codeMsg) {
        this.codeMsg = codeMsg;
    }
}

CodeMsg工具类:

package com.yz.slotsgameht.utils;

/**
 * @author admin
 * @date 2017/8/24
 */
public enum CodeMsg {

    SUCCESS(0, "成功"),
    FAIL(1, "未知错误"),
    USER_PWD_ERROR(1000, "用户名密码错误"),
    CHANNEL_EXIST(1001, "已存在此代理渠道"),
    SUBCHANNEL_EXIST(1002, "已存此在渠道"),
    USERNAME_EXIST(1003, "此用户名已存在"),
    UID_NOT_EXIST(1004, "UID不存在"),
    FID_NOT_EXIST(1005, "FID不存在"),
    ANCHOR_NOT_EXIST(1006, "主播不存在"),
    BOTTOM(10000000, "垫底");

    private int code;
    private String msg;

    CodeMsg(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

从Http中解析request获取ip地址

package com.yz.slotsgameht.utils;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @Author: Lukizzz
 * @Date: 2018/8/30 10:13
 * @Description:
 */
public class GetIpAddress {

    public static String getIpAddress(HttpServletRequest request) {
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                // 根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress = inet.getHostAddress();
            }
        }
        if (ipAddress != null && ipAddress.length() > 15) {
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }

}

            

3.修改游戏设置功能(以修改道具名称和兑换金币为例)

控制层:
package com.yz.slotsgameht.controller;

import com.yz.slotsgameht.domain.AppGameProp;
import com.yz.slotsgameht.domain.AppProbabilitySetting;
import com.yz.slotsgameht.service.AppGamePropService;
import com.yz.slotsgameht.utils.GetIpAddress;
import com.yz.slotsgameht.utils.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @Author: Lukizzz
 * @Date: 2018/8/31 11:45
 * @Description:
 */
@RestController
@RequestMapping(value = "/prop")
public class AppGamePropController {

    private final Logger log = LoggerFactory.getLogger(AppProbabilitySetting.class);

    @Autowired
    private AppGamePropService appGamePropService;

    @RequestMapping(value ="/findPropList" )
    public List<AppGameProp> findPropList(){
        return appGamePropService.findPropList();
    }

    @RequestMapping(value = "editNameSave")
    public Result editNameSave(Long id, String name, HttpServletRequest request){
        String ip = GetIpAddress.getIpAddress(request);
        log.info("修改名称的id: {},新名称: {},本地ip地址:{}", id, name, ip);
        appGamePropService.editNameSave(id, name);
        return new Result();
    }

    @RequestMapping(value = "editGoldNumSave")
    public Result editGoldNumSave(Long id, Integer goldNum,HttpServletRequest request){
        String ip = GetIpAddress.getIpAddress(request);
        log.info("修改兑换金币的id: {},新兑换金币数量: {},本地ip地址:{}", id, goldNum, ip);
        appGamePropService.editGoldNumSave(id, goldNum);
        return new Result();
    }
}

上面的代码中有一点需要注意:datagrid传输的数据是json,因为这边还有一个查找的功能,所以在控制层需要加上@responsebody注解或是将@controller注解变成@restcontroller,里面也包含了@responsebody的注解

业务逻辑层:

package com.yz.slotsgameht.service;

import com.yz.slotsgameht.dao.AppGamePropDAO;
import com.yz.slotsgameht.domain.AppGameProp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author: Lukizzz
 * @Date: 2018/8/31 11:48
 * @Description:
 */
@Service
public class AppGamePropService {

    @Autowired
    private AppGamePropDAO appGamePropDAO;

    public List<AppGameProp> findPropList(){
        return appGamePropDAO.findAll();
    }

    public void editNameSave(Long id,String name){
        appGamePropDAO.updateNameById(id,name);
    }

    public void editGoldNumSave(Long id,Integer goldNum){
        appGamePropDAO.updateGoldNumById(id,goldNum);
    }
}

数据访问层:

package com.yz.slotsgameht.dao;

import com.yz.slotsgameht.domain.AppGameProp;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: Lukizzz
 * @Date: 2018/8/31 11:48
 * @Description:
 */
public interface AppGamePropDAO extends JpaRepository<AppGameProp,Long> {

    /**
     * 修改道具名称
     * @param id
     * @param name
     */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value = "update app_game_prop u set u.name = :name where u.id = :id", nativeQuery = true)
    void updateNameById(@Param(value = "id") Long id, @Param(value = "name") String name);

    /**
     * 修改兑换金币
     * @param id
     * @param goldNum
     */
    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query(value = "update app_game_prop  set gold_num = :goldNum where id = :id", nativeQuery = true)
    void updateGoldNumById(@Param(value = "id") Long id, @Param(value = "goldNum") Integer goldNum);
}

这边也需要注意一点是:因为功能是修改update,所以不需要返回数据,在service层和DAO都使用void

附上这个功能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="toolbar" style="padding:5px;height:auto">
    <div>
        <a onclick="editName();" href="javascript:void(0);" class="easyui-linkbutton"
           data-options="plain:true,iconCls:'icon-edit'">修改道具名称</a>
        <a onclick="editGoldNum();" href="javascript:void(0);" class="easyui-linkbutton"
           data-options="plain:true,iconCls:'icon-edit'">修改兑换金币数</a>
    </div>
</div>

<div id="dlg_edit" class="easyui-dialog" style="width:400px;height:auto;padding:10px 20px" buttons="#dlg-buttons_edit1"
           data-options="closed:true,modal:true">
    <form id="fm_edit" method="post" enctype="multipart/form-data">
        <input type="hidden" id="id1" name="id"/>
        请输入新名称:
        <input class="easyui-textbox" data-options="prompt:'请输入新的道具名称'" style="width:50%;height:32px" name="name">
    </form>
</div>
<div id="dlg-buttons_edit1">
    <a href="javascript:void(0)" class="easyui-linkbutton c8" data-options="iconCls:'icon-ok'"
       onclick="javascript:editNameSave();" style="width:90px;">保存</a>
    <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
       onclick="javascript:$('#dlg_edit').dialog('close');" style="width:90px;">取消</a>
</div>

<div id="dlg_editNum" class="easyui-dialog" style="width:400px;height:auto;padding:10px 20px" buttons="#dlg-buttons_edit2"
     data-options="closed:true,modal:true">
    <form id="fm_editNum" method="post" enctype="multipart/form-data">
        <input type="hidden" id="id2" name="id"/>
        请输入兑换金币数:
        <input class="easyui-textbox" data-options="prompt:'请输入兑换金币数'" style="width:50%;height:32px" name="goldNum">
    </form>
</div>
<div id="dlg-buttons_edit2">
    <a href="javascript:void(0)" class="easyui-linkbutton c8" data-options="iconCls:'icon-ok'"
       onclick="javascript:editGoldNumSave();" style="width:90px;">保存</a>
    <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
       onclick="javascript:$('#dlg_editNum').dialog('close');" style="width:90px;">取消</a>
</div>
</body>
</html>


<script type="text/javascript">
    $(document).ready(function () {
        loadData();
    });

    function loadData() {
        $("#dg").datagrid({
            url: '${request.contextPath}/prop/findPropList',
            striped: true,
            border: false,
            collapsible: false,        //是否可折叠的
            loadMsg: '正在加载数据...',
            idField: 'id',
            fit: true,                //自动大小
            singleSelect: true,//是否单选
            pagination: true,//分页控件
            pageSize: 20,
            columns: [[{
                field: 'name',
                title: '道具名称',
                width: 150,
                align: 'center'
            }, {
                field: 'goldNum',
                title: '兑换金币数',
                width: 150,
                align: 'center'
            }, {
                field: 'propType',
                title: '所属元素',
                width: 150,
                align: 'center'
            }]],
            toolbar: '#toolbar'
        });
    }

    function editName() {
        var row = $('#dg').datagrid('getSelected');
        if (row) {
            $('#fm_edit').form('load', row);
            $('#dlg_edit').dialog('open').dialog('setTitle', '修改');
        } else {
            $.messager.alert("提示", "请选择一条记录");
        }
    }

    function editNameSave() {
        $('#fm_edit').form('submit', {
            url: "${request.contextPath}/prop/editNameSave",
            success: function (result) {
                var result = eval('(' + result + ')');
                if (result.code == 0) {
                    $('#dg').datagrid('reload');
                    $('#dlg_edit').dialog('close');
                } else {
                    $.messager.show({
                        title: '提示',
                        msg: result.message
                    });
                }
            }
        });
    }

    function editGoldNum() {
        var row = $('#dg').datagrid('getSelected');
        if (row) {
            $('#fm_editNum').form('load', row);
            $('#dlg_editNum').dialog('open').dialog('setTitle', '修改');
        } else {
            $.messager.alert("提示", "请选择一条记录");
        }
    }

    function editGoldNumSave() {
        $('#fm_editNum').form('submit', {
            url: "${request.contextPath}/prop/editGoldNumSave",
            success: function (result) {
                var result = eval('(' + result + ')');
                if (result.code == 0) {
                    $('#dg').datagrid('reload');
                    $('#dlg_editNum').dialog('close');
                } else {
                    $.messager.show({
                        title: '提示',
                        msg: result.message
                    });
                }
            }
        });
    }


</script>

在日志配置的时候,要添加一个配置文件

网上应该有很多:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>

<configuration scan="true">
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

<!-- The FILE and ASYNC appenders are here as examples for a production configuration -->
    <property name="PROJECT" value="hnuser" />
    <property name="ROOT" value="logs/" />
    <property name="FILESIZE" value="10MB" />
    <property name="MAXHISTORY" value="3" />
    <timestamp key="DATETIME" datePattern="yyyy-MM-dd HH:mm:ss" />

    <!-- ERROR 输入到文件,按日期和文件大小 -->
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/error.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <!-- WARN 输入到文件,按日期和文件大小 -->
    <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/warn.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <!-- INFO 输入到文件,按日期和文件大小 -->
    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/info.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <!-- DEBUG 输入到文件,按日期和文件大小 -->
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder charset="utf-8">
            <Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}%d/debug.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!-- Logger 根目录 -->
    <root level="INFO">
        <appender-ref ref="DEBUG" />
        <appender-ref ref="ERROR" />
        <appender-ref ref="WARN" />
        <appender-ref ref="INFO" />
    </root>

    <logger name="javax.activation" level="WARN"/>
    <logger name="javax.mail" level="WARN"/>
    <logger name="javax.management.remote" level="WARN"/>
    <logger name="javax.xml.bind" level="WARN"/>
    <logger name="ch.qos.logback" level="WARN"/>
    <logger name="com.codahale.metrics" level="WARN"/>
    <logger name="com.netflix" level="WARN"/>
    <logger name="com.netflix.discovery" level="INFO"/>
    <logger name="com.ryantenney" level="WARN"/>
    <logger name="com.sun" level="WARN"/>
    <logger name="com.zaxxer" level="WARN"/>
    <logger name="io.undertow" level="WARN"/>
    <logger name="io.undertow.websockets.jsr" level="ERROR"/>
    <logger name="org.ehcache" level="WARN"/>
    <logger name="org.apache" level="WARN"/>
    <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/>
    <logger name="org.bson" level="WARN"/>
    <logger name="org.hibernate.validator" level="WARN"/>
    <logger name="org.hibernate" level="WARN"/>
    <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
    <logger name="org.springframework" level="WARN"/>
    <logger name="org.springframework.web" level="WARN"/>
    <logger name="org.springframework.security" level="WARN"/>
    <logger name="org.springframework.cache" level="WARN"/>
    <logger name="org.thymeleaf" level="WARN"/>
    <logger name="org.xnio" level="WARN"/>
    <logger name="springfox" level="WARN"/>
    <logger name="sun.rmi" level="WARN"/>
    <logger name="liquibase" level="WARN"/>
    <logger name="LiquibaseSchemaResolver" level="INFO"/>
    <logger name="sun.net.www" level="INFO"/>
    <logger name="sun.rmi.transport" level="WARN"/>

    <!-- https://logback.qos.ch/manual/configuration.html#shutdownHook and https://jira.qos.ch/browse/LOGBACK-1090 -->
    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>

    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
        <resetJUL>true</resetJUL>
    </contextListener>

</configuration>

也别忘了在控制层引入

 private final Logger log = LoggerFactory.getLogger(SysUser.class);

猜你喜欢

转载自www.cnblogs.com/Lukizzz/p/9582473.html