Commit d27fd389 authored by Junling Bu's avatar Junling Bu
Browse files

feat[litemall-admin, litemall-admin-api]: 支持操作日志管理

parent f3d21d8b
......@@ -463,25 +463,73 @@ litemall_coupon_user表的status字段,包含以后三种状态:
当用户或者管理员上传图像时,图像文件会保存到本地或者第三方云存储服务器中,
同时在存储对象表中记录一下。
### 2.1.10 通用设计
### 2.1.10 操作日志设计
业务日志表litemall_log记录管理员的关键性操作。
需要讨论的是,很多项目的业务日志模块采用注解方式,即加上方法注解,因此可以自动捕获
用户的操作行为。虽然这样做很方便且不会影响业务代码,但是实际上最终是粗颗粒地记录,反而记录意义不大。
因此本项目采用在方法内手写业务日志代码方式记录业务操作行为及结果。
虽然比较繁琐,但是可以保证记录是细颗粒的。而且,如果管理员最终关心的操作较少,那么
实际上需要写的代码不是很多。
考虑到语义,操作业务应该是“谁做了什么操作,结果成功还是失败,失败原因是什么,补充信息是什么”,
因此这里设计的业务日志表关键字段如下:
* 管理员
* IP地址
* 操作分类
* 操作动作
* 操作状态
* 操作结果
* 补充信息
#### 2.1.10.1 操作类别
这里的日志类型设计成四种(当然开发者需要可以扩展)
* 一般日志:用户觉得需要查看的一般操作日志,建议是默认的日志级别
* 安全日志:用户安全相关的操作日志,例如登录、删除管理员
* 订单日志:用户交易相关的操作日志,例如订单发货、退款
* 其他日志:如果以上三种不合适,可以选择其他日志,建议是优先级最低的日志级别
当然建议开发者应该和最终用户讨论交流,记录真正关键性的业务操作,例如登录相关或订单相关等。
#### 2.1.10.2 操作结果
如果操作成功,可以使用操作结果字段记录被操作的对象。
当然,有些操作没有具体对象,那么可以省略。
如果操作失败,也可以使用操作结果字段记录失败的原因。
#### 2.1.10.3 操作失败
虽然这里有操作状态字段和操作结果字段,可以记录操作失败的状态。
但是通常失败操作不会对系统或者数据库带来影响,因此实际上开发者其实不需要
记录太多操作失败的日志,而是记录操作成功的日志,告诉系统管理员当前状态的变化。
当然,是否记录操作失败取决于开发者或者最终用户是否需要。
例如,登录这里应该记录用户登录失败的日志,因为保存的IP地址可以帮助管理员了解
系统被访问的情况。
### 2.1.11 通用设计
除了以上表,数据库还存在其他一些业务表,例如专题表litemall_topic,
但是都很直观,不需要多讨论。
以下是一些表设计中无具体业务意义可通用的字段。
#### 2.1.10.1 deleted
#### 2.1.11.1 deleted
除极少数表,其他所有表都存在`deleted`字段,支持逻辑删除。
因此目前删除数据时,不会直接删除数据,而是修改`deleted`字段。
当然,数据库管理员可以连接到数据库直接删除数据,或者开发者
可以修改这里的逻辑采用物理删除。
#### 2.1.10.2 add_time
#### 2.1.11.2 add_time
除极少数表,其他所有表都存在`add_time`字段,记录数据创建时间。
#### 2.1.10.3 update_time
#### 2.1.11.3 update_time
除极少数表,其他所有表都存在`update_time`字段,记录数据修改时间。
......
......@@ -49,6 +49,8 @@ public class AdminOrderService {
private WxPayService wxPayService;
@Autowired
private NotifyService notifyService;
@Autowired
private LogHelper logHelper;
public Object list(Integer userId, String orderSn, List<Short> orderStatusArray,
Integer page, Integer limit, String sort, String order) {
......@@ -161,6 +163,7 @@ public class AdminOrderService {
// 注意订单号只发后6位
notifyService.notifySmsTemplate(order.getMobile(), NotifyType.REFUND, new String[]{order.getOrderSn().substring(8, 14)});
logHelper.logOrderSucceed("退款", "订单编号 " + orderId);
return ResponseUtil.ok();
}
......@@ -205,6 +208,7 @@ public class AdminOrderService {
// "您的订单已经发货,快递公司 {1},快递单 {2} ,请注意查收"
notifyService.notifySmsTemplate(order.getMobile(), NotifyType.SHIP, new String[]{shipChannel, shipSn});
logHelper.logOrderSucceed("发货", "订单编号 " + orderId);
return ResponseUtil.ok();
}
......
package org.linlinjava.litemall.admin.service;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.linlinjava.litemall.core.util.IpUtil;
import org.linlinjava.litemall.db.domain.LitemallAdmin;
import org.linlinjava.litemall.db.domain.LitemallLog;
import org.linlinjava.litemall.db.service.LitemallLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* 这里的日志类型设计成四种(当然开发者需要可以自己扩展)
* 一般日志:用户觉得需要查看的一般操作日志,建议是默认的日志级别
* 安全日志:用户安全相关的操作日志,例如登录、删除管理员
* 订单日志:用户交易相关的操作日志,例如订单发货、退款
* 其他日志:如果以上三种不合适,可以选择其他日志,建议是优先级最低的日志级别
*
* 当然可能很多操作是不需要记录到数据库的,例如编辑商品、编辑广告品之类。
*/
@Component
public class LogHelper {
public final static Integer LOG_TYPE_GENERAL = 0;
public final static Integer LOG_TYPE_AUTH = 1;
public final static Integer LOG_TYPE_ORDER = 2;
public final static Integer LOG_TYPE_OTHER = 3;
@Autowired
private LitemallLogService logService;
public void logGeneralSucceed(String action){
logAdmin(LOG_TYPE_GENERAL, action, true, "", "");
}
public void logGeneralSucceed(String action, String result){
logAdmin(LOG_TYPE_GENERAL, action, true, result, "");
}
public void logGeneralFail(String action, String error){
logAdmin(LOG_TYPE_GENERAL, action, false, error, "");
}
public void logAuthSucceed(String action){
logAdmin(LOG_TYPE_AUTH, action, true, "", "");
}
public void logAuthSucceed(String action, String result){
logAdmin(LOG_TYPE_AUTH, action, true, result, "");
}
public void logAuthFail(String action, String error){
logAdmin(LOG_TYPE_AUTH, action, false, error, "");
}
public void logOrderSucceed(String action){
logAdmin(LOG_TYPE_ORDER, action, true, "", "");
}
public void logOrderSucceed(String action, String result){
logAdmin(LOG_TYPE_ORDER, action, true, result, "");
}
public void logOrderFail(String action, String error){
logAdmin(LOG_TYPE_ORDER, action, false, error, "");
}
public void logOtherSucceed(String action){
logAdmin(LOG_TYPE_OTHER, action, true, "", "");
}
public void logOtherSucceed(String action, String result){
logAdmin(LOG_TYPE_OTHER, action, true, result, "");
}
public void logOtherFail(String action, String error){
logAdmin(LOG_TYPE_OTHER, action, false, error, "");
}
public void logAdmin (Integer type, String action, Boolean succeed, String result, String comment){
LitemallLog log = new LitemallLog();
Subject currentUser = SecurityUtils.getSubject();
if(currentUser != null) {
LitemallAdmin admin = (LitemallAdmin) currentUser.getPrincipal();
if(admin != null) {
log.setAdmin(admin.getUsername());
}
else{
log.setAdmin("匿名用户");
}
}
else{
log.setAdmin("匿名用户");
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
if(request != null) {
log.setIp(IpUtil.getIpAddr(request));
}
log.setType(type);
log.setAction(action);
log.setStatus(succeed);
log.setResult(result);
log.setComment(comment);
logService.add(log);
}
}
......@@ -5,6 +5,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc;
import org.linlinjava.litemall.admin.service.LogHelper;
import org.linlinjava.litemall.core.util.RegexUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder;
......@@ -32,6 +33,8 @@ public class AdminAdminController {
@Autowired
private LitemallAdminService adminService;
@Autowired
private LogHelper logHelper;
@RequiresPermissions("admin:admin:list")
@RequiresPermissionsDesc(menu={"系统管理" , "管理员管理"}, button="查询")
......@@ -85,6 +88,7 @@ public class AdminAdminController {
String encodedPassword = encoder.encode(rawPassword);
admin.setPassword(encodedPassword);
adminService.add(admin);
logHelper.logAuthSucceed("添加管理员", username);
return ResponseUtil.ok(admin);
}
......@@ -119,6 +123,7 @@ public class AdminAdminController {
return ResponseUtil.updatedDataFailed();
}
logHelper.logAuthSucceed("编辑管理员", admin.getUsername());
return ResponseUtil.ok(admin);
}
......@@ -132,6 +137,7 @@ public class AdminAdminController {
}
adminService.deleteById(anotherAdminId);
logHelper.logAuthSucceed("删除管理员", admin.getUsername());
return ResponseUtil.ok();
}
}
......@@ -9,12 +9,15 @@ import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.linlinjava.litemall.admin.service.LogHelper;
import org.linlinjava.litemall.admin.util.Permission;
import org.linlinjava.litemall.admin.util.PermissionUtil;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallAdmin;
import org.linlinjava.litemall.db.domain.LitemallLog;
import org.linlinjava.litemall.db.service.LitemallAdminService;
import org.linlinjava.litemall.db.service.LitemallLogService;
import org.linlinjava.litemall.db.service.LitemallPermissionService;
import org.linlinjava.litemall.db.service.LitemallRoleService;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -39,6 +42,8 @@ public class AdminAuthController {
private LitemallRoleService roleService;
@Autowired
private LitemallPermissionService permissionService;
@Autowired
private LogHelper logHelper;
/*
* { username : value, password : value }
......@@ -56,13 +61,18 @@ public class AdminAuthController {
try {
currentUser.login(new UsernamePasswordToken(username, password));
} catch (UnknownAccountException uae) {
logHelper.logAuthFail("登录", "用户帐号或密码不正确");
return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "用户帐号或密码不正确");
} catch (LockedAccountException lae) {
logHelper.logAuthFail("登录", "用户帐号已锁定不可用");
return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "用户帐号已锁定不可用");
} catch (AuthenticationException ae) {
logHelper.logAuthFail("登录", "认证失败");
return ResponseUtil.fail(ADMIN_INVALID_ACCOUNT, "认证失败");
}
logHelper.logAuthSucceed("登录");
return ResponseUtil.ok(currentUser.getSession().getId());
}
......@@ -73,6 +83,8 @@ public class AdminAuthController {
@PostMapping("/logout")
public Object login() {
Subject currentUser = SecurityUtils.getSubject();
logHelper.logAuthSucceed("退出");
currentUser.logout();
return ResponseUtil.ok();
}
......
package org.linlinjava.litemall.admin.web;
import com.github.pagehelper.PageInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.validator.Order;
import org.linlinjava.litemall.core.validator.Sort;
import org.linlinjava.litemall.db.domain.LitemallLog;
import org.linlinjava.litemall.db.service.LitemallLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/log")
@Validated
public class AdminLogController {
private final Log logger = LogFactory.getLog(AdminLogController.class);
@Autowired
private LitemallLogService logService;
@RequiresPermissions("admin:log:list")
@RequiresPermissionsDesc(menu={"系统管理" , "操作日志"}, button="查询")
@GetMapping("/list")
public Object list(String name,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<LitemallLog> logList = logService.querySelective(name, page, limit, sort, order);
long total = PageInfo.of(logList).getTotal();
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", logList);
return ResponseUtil.ok(data);
}
}
import request from '@/utils/request'
export function listLog(query) {
return request({
url: '/log/list',
method: 'get',
params: query
})
}
......@@ -375,6 +375,16 @@ export const asyncRouterMap = [
noCache: true
}
},
{
path: 'log',
component: () => import('@/views/sys/log'),
name: 'log',
meta: {
perms: ['GET /admin/admin/log'],
title: '操作日志',
noCache: true
}
},
{
path: 'role',
component: () => import('@/views/sys/role'),
......
<template>
<div class="app-container">
<!-- 查询和其他操作 -->
<div class="filter-container">
<el-input v-model="listQuery.name" clearable class="filter-item" style="width: 200px;" placeholder="请输入操作管理员"/>
<el-button v-permission="['GET /admin/log/list']" class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
</div>
<!-- 查询结果 -->
<el-table v-loading="listLoading" :data="list" element-loading-text="正在查询中。。。" border fit highlight-current-row>
<el-table-column align="center" label="操作管理员" prop="admin"/>
<el-table-column align="center" label="IP地址" prop="ip"/>
<el-table-column align="center" label="操作时间" prop="addTime"/>
<el-table-column align="center" label="操作类别" prop="type">
<template slot-scope="scope">
<el-tag>{{ scope.row.type | typeFilter }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作动作" prop="action"/>
<el-table-column align="center" label="操作状态" prop="status">
<template slot-scope="scope">
<el-tag :type="scope.row.status ? 'success' : 'error' ">{{ scope.row.status ? '成功' : '失败' }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作结果" prop="result"/>
<el-table-column align="center" label="备注信息" prop="comment"/>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
</div>
</template>
<script>
import { listLog } from '@/api/log'
import Pagination from '@/components/Pagination'
const typeMap = {
0: '一般操作',
1: '安全操作',
2: '订单操作',
3: '其他操作'
}
export default {
name: 'Log',
components: { Pagination },
filters: {
typeFilter(type) {
return typeMap[type]
}
},
data() {
return {
list: null,
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
name: undefined,
sort: 'add_time',
order: 'desc'
},
rules: {
name: [
{ required: true, message: '角色名称不能为空', trigger: 'blur' }
]
}
}
},
created() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listLog(this.listQuery)
.then(response => {
this.list = response.data.data.items
this.total = response.data.data.total
this.listLoading = false
})
.catch(() => {
this.list = []
this.total = 0
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
}
}
}
</script>
package org.linlinjava.litemall.wx.util;
package org.linlinjava.litemall.core.util;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
......@@ -8,13 +8,6 @@ import java.net.UnknownHostException;
* IP地址相关工具类
*/
public class IpUtil {
public static String client(HttpServletRequest request) {
String xff = request.getHeader("x-forwarded-for");
if (xff == null) {
xff = request.getRemoteAddr();
}
return xff;
}
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = null;
......
......@@ -174,5 +174,8 @@
<table tableName="litemall_permission">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
<table tableName="litemall_log">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
</context>
</generatorConfiguration>
\ No newline at end of file
package org.linlinjava.litemall.db.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.linlinjava.litemall.db.domain.LitemallLog;
import org.linlinjava.litemall.db.domain.LitemallLogExample;
public interface LitemallLogMapper {
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
long countByExample(LitemallLogExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int deleteByExample(LitemallLogExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int deleteByPrimaryKey(Integer id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int insert(LitemallLog record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int insertSelective(LitemallLog record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallLog selectOneByExample(LitemallLogExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallLog selectOneByExampleSelective(@Param("example") LitemallLogExample example, @Param("selective") LitemallLog.Column ... selective);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
List<LitemallLog> selectByExampleSelective(@Param("example") LitemallLogExample example, @Param("selective") LitemallLog.Column ... selective);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
List<LitemallLog> selectByExample(LitemallLogExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallLog selectByPrimaryKeySelective(@Param("id") Integer id, @Param("selective") LitemallLog.Column ... selective);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
LitemallLog selectByPrimaryKey(Integer id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallLog selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer id, @Param("andLogicalDeleted") boolean andLogicalDeleted);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int updateByExampleSelective(@Param("record") LitemallLog record, @Param("example") LitemallLogExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int updateByExample(@Param("record") LitemallLog record, @Param("example") LitemallLogExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int updateByPrimaryKeySelective(LitemallLog record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
*/
int updateByPrimaryKey(LitemallLog record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int logicalDeleteByExample(@Param("example") LitemallLogExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_log
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int logicalDeleteByPrimaryKey(Integer id);
}
\ No newline at end of file
package org.linlinjava.litemall.db.service;
import com.github.pagehelper.PageHelper;
import org.linlinjava.litemall.db.dao.LitemallLogMapper;
import org.linlinjava.litemall.db.domain.LitemallAd;
import org.linlinjava.litemall.db.domain.LitemallLog;
import org.linlinjava.litemall.db.domain.LitemallLogExample;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class LitemallLogService {
@Resource
private LitemallLogMapper logMapper;
public void deleteById(Integer id) {
logMapper.logicalDeleteByPrimaryKey(id);
}
public void add(LitemallLog log) {
log.setAddTime(LocalDateTime.now());
log.setUpdateTime(LocalDateTime.now());
logMapper.insertSelective(log);
}
public List<LitemallLog> querySelective(String name, Integer page, Integer size, String sort, String order) {
LitemallLogExample example = new LitemallLogExample();
LitemallLogExample.Criteria criteria = example.createCriteria();
if (!StringUtils.isEmpty(name)) {
criteria.andAdminLike("%" + name + "%");
}
criteria.andDeletedEqualTo(false);
if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
example.setOrderByClause(sort + " " + order);
}
PageHelper.startPage(page, size);
return logMapper.selectByExample(example);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.linlinjava.litemall.db.dao.LitemallLogMapper">
<resultMap id="BaseResultMap" type="org.linlinjava.litemall.db.domain.LitemallLog">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="admin" jdbcType="VARCHAR" property="admin" />
<result column="ip" jdbcType="VARCHAR" property="ip" />
<result column="type" jdbcType="INTEGER" property="type" />
<result column="action" jdbcType="VARCHAR" property="action" />
<result column="status" jdbcType="BIT" property="status" />
<result column="result" jdbcType="VARCHAR" property="result" />
<result column="comment" jdbcType="VARCHAR" property="comment" />
<result column="add_time" jdbcType="TIMESTAMP" property="addTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
<result column="deleted" jdbcType="BIT" property="deleted" />
</resultMap>
<sql id="Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
id, `admin`, ip, `type`, `action`, `status`, `result`, `comment`, add_time, update_time,
deleted
</sql>
<select id="selectByExample" parameterType="org.linlinjava.litemall.db.domain.LitemallLogExample" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from litemall_log
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByExampleSelective" parameterType="map" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
@project https://github.com/itfsw/mybatis-generator-plugin
-->
select
<if test="example.distinct">
distinct
</if>
<choose>
<when test="selective != null and selective.length &gt; 0">
<foreach collection="selective" item="column" separator=",">
${column.escapedColumnName}
</foreach>
</when>
<otherwise>
id, `admin`, ip, `type`, `action`, `status`, `result`, `comment`, add_time, update_time,
deleted
</otherwise>
</choose>
from litemall_log
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
<if test="example.orderByClause != null">
order by ${example.orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<include refid="Base_Column_List" />
from litemall_log
where id = #{id,jdbcType=INTEGER}
</select>
<select id="selectByPrimaryKeyWithLogicalDelete" parameterType="map" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
@project https://github.com/itfsw/mybatis-generator-plugin
-->
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select
<include refid="Base_Column_List" />
from litemall_log
where id = #{id,jdbcType=INTEGER}
and deleted =
<choose>
<when test="andLogicalDeleted">
1
</when>
<otherwise>
0
</otherwise>
</choose>
</select>
<select id="selectByPrimaryKeySelective" parameterType="map" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
@project https://github.com/itfsw/mybatis-generator-plugin
-->
select
<choose>
<when test="selective != null and selective.length &gt; 0">
<foreach collection="selective" item="column" separator=",">
${column.escapedColumnName}
</foreach>
</when>
<otherwise>
id, `admin`, ip, `type`, `action`, `status`, `result`, `comment`, add_time, update_time,
deleted
</otherwise>
</choose>
from litemall_log
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from litemall_log
where id = #{id,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="org.linlinjava.litemall.db.domain.LitemallLogExample">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
delete from litemall_log
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="org.linlinjava.litemall.db.domain.LitemallLog">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into litemall_log (`admin`, ip, `type`,
`action`, `status`, `result`,
`comment`, add_time, update_time,
deleted)
values (#{admin,jdbcType=VARCHAR}, #{ip,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER},
#{action,jdbcType=VARCHAR}, #{status,jdbcType=BIT}, #{result,jdbcType=VARCHAR},
#{comment,jdbcType=VARCHAR}, #{addTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP},
#{deleted,jdbcType=BIT})
</insert>
<insert id="insertSelective" parameterType="org.linlinjava.litemall.db.domain.LitemallLog">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into litemall_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="admin != null">
`admin`,
</if>
<if test="ip != null">
ip,
</if>
<if test="type != null">
`type`,
</if>
<if test="action != null">
`action`,
</if>
<if test="status != null">
`status`,
</if>
<if test="result != null">
`result`,
</if>
<if test="comment != null">
`comment`,
</if>
<if test="addTime != null">
add_time,
</if>
<if test="updateTime != null">
update_time,
</if>
<if test="deleted != null">
deleted,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="admin != null">
#{admin,jdbcType=VARCHAR},
</if>
<if test="ip != null">
#{ip,jdbcType=VARCHAR},
</if>
<if test="type != null">
#{type,jdbcType=INTEGER},
</if>
<if test="action != null">
#{action,jdbcType=VARCHAR},
</if>
<if test="status != null">
#{status,jdbcType=BIT},
</if>
<if test="result != null">
#{result,jdbcType=VARCHAR},
</if>
<if test="comment != null">
#{comment,jdbcType=VARCHAR},
</if>
<if test="addTime != null">
#{addTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
#{updateTime,jdbcType=TIMESTAMP},
</if>
<if test="deleted != null">
#{deleted,jdbcType=BIT},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="org.linlinjava.litemall.db.domain.LitemallLogExample" resultType="java.lang.Long">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
select count(*) from litemall_log
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update litemall_log
<set>
<if test="record.id != null">
id = #{record.id,jdbcType=INTEGER},
</if>
<if test="record.admin != null">
`admin` = #{record.admin,jdbcType=VARCHAR},
</if>
<if test="record.ip != null">
ip = #{record.ip,jdbcType=VARCHAR},
</if>
<if test="record.type != null">
`type` = #{record.type,jdbcType=INTEGER},
</if>
<if test="record.action != null">
`action` = #{record.action,jdbcType=VARCHAR},
</if>
<if test="record.status != null">
`status` = #{record.status,jdbcType=BIT},
</if>
<if test="record.result != null">
`result` = #{record.result,jdbcType=VARCHAR},
</if>
<if test="record.comment != null">
`comment` = #{record.comment,jdbcType=VARCHAR},
</if>
<if test="record.addTime != null">
add_time = #{record.addTime,jdbcType=TIMESTAMP},
</if>
<if test="record.updateTime != null">
update_time = #{record.updateTime,jdbcType=TIMESTAMP},
</if>
<if test="record.deleted != null">
deleted = #{record.deleted,jdbcType=BIT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update litemall_log
set id = #{record.id,jdbcType=INTEGER},
`admin` = #{record.admin,jdbcType=VARCHAR},
ip = #{record.ip,jdbcType=VARCHAR},
`type` = #{record.type,jdbcType=INTEGER},
`action` = #{record.action,jdbcType=VARCHAR},
`status` = #{record.status,jdbcType=BIT},
`result` = #{record.result,jdbcType=VARCHAR},
`comment` = #{record.comment,jdbcType=VARCHAR},
add_time = #{record.addTime,jdbcType=TIMESTAMP},
update_time = #{record.updateTime,jdbcType=TIMESTAMP},
deleted = #{record.deleted,jdbcType=BIT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="org.linlinjava.litemall.db.domain.LitemallLog">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update litemall_log
<set>
<if test="admin != null">
`admin` = #{admin,jdbcType=VARCHAR},
</if>
<if test="ip != null">
ip = #{ip,jdbcType=VARCHAR},
</if>
<if test="type != null">
`type` = #{type,jdbcType=INTEGER},
</if>
<if test="action != null">
`action` = #{action,jdbcType=VARCHAR},
</if>
<if test="status != null">
`status` = #{status,jdbcType=BIT},
</if>
<if test="result != null">
`result` = #{result,jdbcType=VARCHAR},
</if>
<if test="comment != null">
`comment` = #{comment,jdbcType=VARCHAR},
</if>
<if test="addTime != null">
add_time = #{addTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
update_time = #{updateTime,jdbcType=TIMESTAMP},
</if>
<if test="deleted != null">
deleted = #{deleted,jdbcType=BIT},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="org.linlinjava.litemall.db.domain.LitemallLog">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
-->
update litemall_log
set `admin` = #{admin,jdbcType=VARCHAR},
ip = #{ip,jdbcType=VARCHAR},
`type` = #{type,jdbcType=INTEGER},
`action` = #{action,jdbcType=VARCHAR},
`status` = #{status,jdbcType=BIT},
`result` = #{result,jdbcType=VARCHAR},
`comment` = #{comment,jdbcType=VARCHAR},
add_time = #{addTime,jdbcType=TIMESTAMP},
update_time = #{updateTime,jdbcType=TIMESTAMP},
deleted = #{deleted,jdbcType=BIT}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectOneByExample" parameterType="org.linlinjava.litemall.db.domain.LitemallLogExample" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
@project https://github.com/itfsw/mybatis-generator-plugin
-->
select
<include refid="Base_Column_List" />
from litemall_log
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
limit 1
</select>
<select id="selectOneByExampleSelective" parameterType="map" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
@project https://github.com/itfsw/mybatis-generator-plugin
-->
select
<choose>
<when test="selective != null and selective.length &gt; 0">
<foreach collection="selective" item="column" separator=",">
${column.escapedColumnName}
</foreach>
</when>
<otherwise>
id, `admin`, ip, `type`, `action`, `status`, `result`, `comment`, add_time, update_time,
deleted
</otherwise>
</choose>
from litemall_log
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
<if test="example.orderByClause != null">
order by ${example.orderByClause}
</if>
limit 1
</select>
<update id="logicalDeleteByExample" parameterType="map">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
@project https://github.com/itfsw/mybatis-generator-plugin
-->
update litemall_log set deleted = 1
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="logicalDeleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
@project https://github.com/itfsw/mybatis-generator-plugin
-->
update litemall_log set deleted = 1
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
\ No newline at end of file
......@@ -25,7 +25,7 @@ import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.CouponUserConstant;
import org.linlinjava.litemall.db.util.OrderHandleOption;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.linlinjava.litemall.wx.util.IpUtil;
import org.linlinjava.litemall.core.util.IpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......
......@@ -21,7 +21,7 @@ import org.linlinjava.litemall.wx.dao.UserToken;
import org.linlinjava.litemall.wx.dao.WxLoginInfo;
import org.linlinjava.litemall.wx.service.CaptchaCodeManager;
import org.linlinjava.litemall.wx.service.UserTokenManager;
import org.linlinjava.litemall.wx.util.IpUtil;
import org.linlinjava.litemall.core.util.IpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
......@@ -145,7 +145,7 @@ public class WxAuthController {
user.setUserLevel((byte) 0);
user.setStatus((byte) 0);
user.setLastLoginTime(LocalDateTime.now());
user.setLastLoginIp(IpUtil.client(request));
user.setLastLoginIp(IpUtil.getIpAddr(request));
userService.add(user);
......@@ -153,7 +153,7 @@ public class WxAuthController {
couponAssignService.assignForRegister(user.getId());
} else {
user.setLastLoginTime(LocalDateTime.now());
user.setLastLoginIp(IpUtil.client(request));
user.setLastLoginIp(IpUtil.getIpAddr(request));
if (userService.updateById(user) == 0) {
return ResponseUtil.updatedDataFailed();
}
......@@ -293,7 +293,7 @@ public class WxAuthController {
user.setUserLevel((byte) 0);
user.setStatus((byte) 0);
user.setLastLoginTime(LocalDateTime.now());
user.setLastLoginIp(IpUtil.client(request));
user.setLastLoginIp(IpUtil.getIpAddr(request));
userService.add(user);
// 给新用户发送注册优惠券
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment