From 6652d8ca46a9708d67443043fb9caef4fc80262d Mon Sep 17 00:00:00 2001 From: lijiantao Date: Mon, 17 Jun 2019 18:03:16 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/annotation/OperationLog.java | 29 ++++ .../common/aspect/OperationLogAspect.java | 63 +++++++++ .../java/com/antdsp/data/entity/User.java | 14 +- .../antdsp/data/entity/system/SystemLog.java | 132 ++++++++++++++++++ .../data/entityeenum/OperationType.java | 24 ++++ 5 files changed, 255 insertions(+), 7 deletions(-) create mode 100644 antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java create mode 100644 antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java create mode 100644 antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java create mode 100644 antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java diff --git a/antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java b/antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java new file mode 100644 index 0000000..01b4df7 --- /dev/null +++ b/antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java @@ -0,0 +1,29 @@ +package com.antdsp.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.antdsp.data.entityeenum.OperationType; + + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OperationLog { + + /** + * 操作名称 + * @return + */ + String name() default ""; + + /** + * 操作类型 + * @return + */ + OperationType type() default OperationType.UNKNOWN; + +} diff --git a/antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java b/antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java new file mode 100644 index 0000000..102797c --- /dev/null +++ b/antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java @@ -0,0 +1,63 @@ +package com.antdsp.common.aspect; + +import java.lang.reflect.Method; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.support.RequestContextUtils; + +import com.antdsp.common.annotation.OperationLog; +import com.antdsp.data.entity.User; +import com.antdsp.data.entity.system.SystemLog; + +@Aspect +public class OperationLogAspect { + + @Pointcut(value="@annotation(com.antdsp.common.annotation.OperationLog)") + public void pointCut() {} + + @Around(value="pointCut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + long time = System.currentTimeMillis(); + + try { + Object result = joinPoint.proceed(); + time = System.currentTimeMillis() - time; + this.saveLog(joinPoint, time); + return result; + }catch(Exception e) { + + } + return new Object(); + } + + private void saveLog(ProceedingJoinPoint joinPoint , long executeTime) { + MethodSignature ms = (MethodSignature) joinPoint.getSignature(); + Method excuteMthod = ms.getMethod(); + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + + User current = (User) SecurityUtils.getSubject().getPrincipal(); + Object[] args = joinPoint.getArgs(); + OperationLog optLog = excuteMthod.getAnnotation(OperationLog.class); + + SystemLog systemLog = new SystemLog(); + systemLog.setCreator(""); + systemLog.setModifier(""); + systemLog.setId(null); + systemLog.setOptName(optLog.name()); + systemLog.setOptorId(current.getId()); + systemLog.setOptorIp(request.getRemoteHost()); + systemLog.setOptorName(current.getLoginname()); + + + } +} diff --git a/antdsp-core/src/main/java/com/antdsp/data/entity/User.java b/antdsp-core/src/main/java/com/antdsp/data/entity/User.java index 572724f..356fe8c 100644 --- a/antdsp-core/src/main/java/com/antdsp/data/entity/User.java +++ b/antdsp-core/src/main/java/com/antdsp/data/entity/User.java @@ -12,25 +12,25 @@ import com.antdsp.data.entityeenum.UserStatus; @Entity public class User extends AbstractEntity{ - @Column(name="login_name" , nullable=false) + @Column(name="login_name" , nullable=false, length=64) private String loginname; - @Column(name="real_name" , nullable=false) + @Column(name="real_name" , nullable=false, length=64) private String realname; - @Column(name="password" , nullable=false) + @Column(name="password" , nullable=false, length=32) private String password; - @Column(name="avatar") + @Column(name="avatar", length=64) private String avatar; - @Column(name="email" ) + @Column(name="email", length=64 ) private String email; - @Column(name="qq") + @Column(name="qq", length=64) private String qq; - @Column(name="status" , nullable=false) + @Column(name="status" , nullable=false, length=16) @Enumerated(EnumType.STRING) private UserStatus status; diff --git a/antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java b/antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java new file mode 100644 index 0000000..71a967f --- /dev/null +++ b/antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java @@ -0,0 +1,132 @@ +package com.antdsp.data.entity.system; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Table; + +import com.antdsp.data.entity.AbstractEntity; +import com.antdsp.data.entityeenum.OperationType; + +/** + * + *

title:SystemLog

+ *

Description: 系统操作日志表

+ *

Copyright: Copyright (c) 2019

+ * + * @author lijiantao + * @date 2019年6月17日 + * @email a496401006@qq.com + * + */ +@Table(name="tb_system_log") +@Entity +public class SystemLog extends AbstractEntity{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * 操作者Id + */ + @Column(name="optor_id", nullable=false) + private Long optorId; + + /** + * 操作者名称 + */ + @Column(name="optor_name", nullable=false, length=64) + private String optorName; + + /** + * 操作者IP + */ + @Column(name="optor_ip", nullable=false, length=64) + private String optorIp; + + /** + * 操作名称 + */ + @Column(name="opt_name", nullable=false, length=64) + private String optName; + + /** + * 操作详情 + */ + @Column(name="opt_detail", nullable=false, length=1024) + private String optDetail; + + /** + * 操作类型 + */ + @Column(name="opt_type", nullable=false, length=16) + @Enumerated(EnumType.STRING) + private OperationType optType; + + /** + * 操作时间 + */ + @Column(name="run_time", nullable=false) + private long runTime; + + public Long getOptorId() { + return optorId; + } + + public void setOptorId(Long optorId) { + this.optorId = optorId; + } + + public String getOptorName() { + return optorName; + } + + public void setOptorName(String optorName) { + this.optorName = optorName; + } + + public String getOptorIp() { + return optorIp; + } + + public void setOptorIp(String optorIp) { + this.optorIp = optorIp; + } + + public String getOptName() { + return optName; + } + + public void setOptName(String optName) { + this.optName = optName; + } + + public String getOptDetail() { + return optDetail; + } + + public void setOptDetail(String optDetail) { + this.optDetail = optDetail; + } + + public OperationType getOptType() { + return optType; + } + + public void setOptType(OperationType optType) { + this.optType = optType; + } + + public long getRunTime() { + return runTime; + } + + public void setRunTime(long runTime) { + this.runTime = runTime; + } + + +} diff --git a/antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java b/antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java new file mode 100644 index 0000000..8b85bb6 --- /dev/null +++ b/antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java @@ -0,0 +1,24 @@ +package com.antdsp.data.entityeenum; + +public enum OperationType { + + UNKNOWN("unknown"), + INSERT("insert"), + DELETE("delete"), + SELECT("select"), + UPDATE("update"); + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + OperationType(String value){ + this.value = value; + } +} -- Gitee From 6ea5adb5ad32c331e213f2393373a2151cafc6c7 Mon Sep 17 00:00:00 2001 From: lijiantao Date: Thu, 20 Jun 2019 15:23:57 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/annotation/OperationLog.java | 8 -- .../common/aspect/OperationLogAspect.java | 53 ++++++++- .../com/antdsp/web/rest/sys/SystemLogApi.java | 39 +++++++ .../antdsp/web/rest/sys/SystemMenuApi.java | 10 ++ .../antdsp/web/rest/sys/SystemRoleApi.java | 12 ++ .../antdsp/web/rest/sys/SystemUserApi.java | 16 ++- .../src/main/resources/application.yml | 2 + .../src/main/web/config/router.config.js | 16 ++- .../src/main/web/src/defaultSettings.js | 2 +- .../src/main/web/src/locales/zh-CN/menu.js | 2 + antdsp-admin/src/main/web/src/manifest.json | 4 +- antdsp-admin/src/main/web/src/models/login.js | 2 +- .../main/web/src/pages/Operation/Log/Index.js | 109 ++++++++++++++++++ .../src/pages/Operation/Log/models/operlog.js | 32 +++++ .../src/main/web/src/services/system.js | 4 + antdsp-core/pom.xml | 6 + .../com/antdsp/common/enums/SortType.java | 8 ++ .../antdsp/common/pagination/Pagination.java | 0 .../common/pagination/PaginationData.java | 2 +- .../antdsp/dao/jpa/AntdspBaseRepository.java | 31 +++-- .../dao/jpa/AntdspBaseRepositoryImpl.java | 48 ++++---- .../antdsp/dao/jpa/system/SystemLogJpa.java | 11 ++ .../antdsp/data/entity/system/SystemLog.java | 46 +++++--- .../data/entityeenum/OperationType.java | 24 ---- 24 files changed, 372 insertions(+), 115 deletions(-) create mode 100644 antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemLogApi.java create mode 100644 antdsp-admin/src/main/web/src/pages/Operation/Log/Index.js create mode 100644 antdsp-admin/src/main/web/src/pages/Operation/Log/models/operlog.js create mode 100644 antdsp-core/src/main/java/com/antdsp/common/enums/SortType.java rename {antdsp-admin => antdsp-core}/src/main/java/com/antdsp/common/pagination/Pagination.java (100%) rename {antdsp-admin => antdsp-core}/src/main/java/com/antdsp/common/pagination/PaginationData.java (94%) create mode 100644 antdsp-core/src/main/java/com/antdsp/dao/jpa/system/SystemLogJpa.java delete mode 100644 antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java diff --git a/antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java b/antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java index 01b4df7..529482c 100644 --- a/antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java +++ b/antdsp-admin/src/main/java/com/antdsp/common/annotation/OperationLog.java @@ -6,8 +6,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.antdsp.data.entityeenum.OperationType; - @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @@ -20,10 +18,4 @@ public @interface OperationLog { */ String name() default ""; - /** - * 操作类型 - * @return - */ - OperationType type() default OperationType.UNKNOWN; - } diff --git a/antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java b/antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java index 102797c..f6586f3 100644 --- a/antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java +++ b/antdsp-admin/src/main/java/com/antdsp/common/aspect/OperationLogAspect.java @@ -1,26 +1,36 @@ package com.antdsp.common.aspect; import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.shiro.SecurityUtils; -import org.apache.shiro.subject.Subject; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; +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 org.springframework.web.servlet.support.RequestContextUtils; +import com.alibaba.fastjson.JSON; import com.antdsp.common.annotation.OperationLog; +import com.antdsp.dao.jpa.system.SystemLogJpa; import com.antdsp.data.entity.User; import com.antdsp.data.entity.system.SystemLog; @Aspect +@Component public class OperationLogAspect { + + private static final String X_REAL_IP ="x-real-ip"; + + @Autowired + private SystemLogJpa systemLogJpa; @Pointcut(value="@annotation(com.antdsp.common.annotation.OperationLog)") public void pointCut() {} @@ -46,7 +56,6 @@ public class OperationLogAspect { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); User current = (User) SecurityUtils.getSubject().getPrincipal(); - Object[] args = joinPoint.getArgs(); OperationLog optLog = excuteMthod.getAnnotation(OperationLog.class); SystemLog systemLog = new SystemLog(); @@ -55,9 +64,41 @@ public class OperationLogAspect { systemLog.setId(null); systemLog.setOptName(optLog.name()); systemLog.setOptorId(current.getId()); - systemLog.setOptorIp(request.getRemoteHost()); + /** + * 由于前后端分离,ant design使用代理的方式访问后台,因此getRemoteHost() 获取的总是ant design 项目的代理地址,也即本机服务器的地址 + * 因此使用nginx 做反向代理,并配置上以下信息, + * proxy_set_header Host $http_host; + * proxy_set_header X-Real-IP $remote_addr; + * + * x-real-ip 即客户端ip地址 + */ + systemLog.setOptorIp(getIp(request)); systemLog.setOptorName(current.getLoginname()); - - + systemLog.setRunTime(executeTime); + systemLog.setOptType(request.getMethod()); + systemLog.setOptURI(request.getRequestURI()); + systemLog.setOptDetail(dealDetail(ms.getParameterNames(), joinPoint.getArgs())); + systemLog.onPreInsert(); + ms.getParameterNames(); + systemLogJpa.save(systemLog); + } + + private String dealDetail(String[] paramNames, Object[] args) { + if(args != null && args.length > 0) { + Map map = new HashMap<>(); + for(int i=0; i< args.length; i++) { + map.put(paramNames[i], args[i]); + } + return JSON.toJSONString(map); + } + return ""; + } + + private String getIp(HttpServletRequest request) { + String ip = request.getHeader(X_REAL_IP); + if(ip == null || ip.length() == 0 || "unknown".equals(ip)) { + ip = request.getRemoteHost(); + } + return ip; } } diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemLogApi.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemLogApi.java new file mode 100644 index 0000000..cf446c8 --- /dev/null +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemLogApi.java @@ -0,0 +1,39 @@ +package com.antdsp.web.rest.sys; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.antdsp.common.pagination.PaginationData; +import com.antdsp.dao.jpa.system.SystemLogJpa; +import com.antdsp.data.entity.system.SystemLog; + +@RestController("/operation/log") +public class SystemLogApi { + + @Autowired + private SystemLogJpa systemLogJpa; + + @GetMapping + public PaginationData list(int page, int count){ + + Specification specification = new Specification() { + + @Override + public Predicate toPredicate(Root root, CriteriaQuery query, + CriteriaBuilder criteriaBuilder) { + return null; + } + + }; + + return this.systemLogJpa.list(specification, page, count); + } + +} diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemMenuApi.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemMenuApi.java index 444ca2c..d01931d 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemMenuApi.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemMenuApi.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.stream.Collectors; import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.antdsp.common.AntdspResponse; +import com.antdsp.common.annotation.OperationLog; import com.antdsp.dao.jpa.system.MenuJpa; import com.antdsp.data.entity.User; import com.antdsp.data.entity.system.SystemMenu; @@ -31,6 +33,8 @@ public class SystemMenuApi { private MenuJpa menuJpa; @GetMapping("") + @OperationLog(name="查询菜单列表") + @RequiresPermissions(value= {"menu:list"}) public MenuTree list() { MenuTree rootMenu = new MenuTree(); @@ -45,6 +49,8 @@ public class SystemMenuApi { @PostMapping("") @Transactional + @OperationLog(name="添加菜单") + @RequiresPermissions(value= {"menu:add"}) public AntdspResponse add(@RequestBody MenuTree menu) { SystemMenu data = new SystemMenu(); @@ -59,6 +65,8 @@ public class SystemMenuApi { @PutMapping("") @Transactional + @OperationLog(name="修改菜单") + @RequiresPermissions(value= {"menu:update"}) public AntdspResponse update(@RequestBody MenuTree menu) { SystemMenu oldMenu = this.menuJpa.findById(menu.getId()).orElse(null); @@ -74,6 +82,8 @@ public class SystemMenuApi { } @DeleteMapping("/{id:\\d+}") + @OperationLog(name="删除菜单") + @RequiresPermissions(value= {"menu:delete"}) public AntdspResponse delete(@PathVariable("id") Long id) { SystemMenu oldMenu = this.menuJpa.findById(id).orElse(null); diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemRoleApi.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemRoleApi.java index 56a80c8..989a0e9 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemRoleApi.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemRoleApi.java @@ -8,6 +8,7 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -27,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.antdsp.common.AntdspResponse; +import com.antdsp.common.annotation.OperationLog; import com.antdsp.common.pagination.PaginationData; import com.antdsp.dao.jpa.system.RoleJpa; import com.antdsp.data.entity.system.SystemRole; @@ -51,6 +53,8 @@ public class SystemRoleApi { private RoleJpa roleJpa; @GetMapping("") + @OperationLog(name="查询角色列表") + @RequiresPermissions(value= {"role:list"}) public PaginationData list(int page , int count , String roleName){ int start = (page - 1) * count; @@ -73,6 +77,8 @@ public class SystemRoleApi { } @GetMapping("/{id:\\d+}") + @OperationLog(name="查询角色信息") + @RequiresPermissions(value= {"role:list"}) public RoleDto detail(@PathVariable("id") Long id) { RoleDto dto = new RoleDto(); @@ -92,6 +98,8 @@ public class SystemRoleApi { @PostMapping("") @Transactional + @OperationLog(name="添加角色") + @RequiresPermissions(value= {"role:add"}) public AntdspResponse add(@RequestBody RoleDto role) { SystemRole data = new SystemRole(); @@ -113,6 +121,8 @@ public class SystemRoleApi { @PutMapping("") @Transactional + @OperationLog(name="修改角色") + @RequiresPermissions(value= {"role:update"}) public AntdspResponse update(@RequestBody RoleDto role) { Long roleId = role.getId(); @@ -133,6 +143,8 @@ public class SystemRoleApi { @DeleteMapping("/{id:\\d+}") @Transactional() + @OperationLog(name="删除角色") + @RequiresPermissions(value= {"role:delete"}) public AntdspResponse delete(@PathVariable("id") Long id) { SystemRole role = this.roleJpa.findById(id).orElse(null); diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java index 94ecfa7..2688ff2 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java @@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.antdsp.common.AntdspResponse; +import com.antdsp.common.annotation.OperationLog; import com.antdsp.common.pagination.PaginationData; import com.antdsp.dao.jpa.UserJpa; import com.antdsp.dao.jpa.system.RoleJpa; @@ -50,11 +51,10 @@ public class SystemUserApi { private RoleJpa roleJpa; @GetMapping("") + @OperationLog(name="查询用户列表") + @RequiresPermissions(value= {"user:list"}) public PaginationData list(int page , int count , String loginname , UserStatus status){ - int start = (page - 1) * count; - Pageable pageable = PageRequest.of(start, count , Sort.by(Order.desc("creator"))); //Sort.and(Order.desc("creator")) - Specification specification = new Specification() { @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { @@ -70,12 +70,13 @@ public class SystemUserApi { } }; - Page userList = userJpa.findAll(specification , pageable); - PaginationData pagination = new PaginationData<>(userList.getContent() , page , userList.getTotalElements()); + PaginationData pagination = this.userJpa.list(specification, page, count); return pagination; } @GetMapping("/{id:\\d+}") + @OperationLog(name="查询用户信息") + @RequiresPermissions(value= {"user:list"}) public SystemUserDto detail(@PathVariable("id") Long userId) { List roles = this.roleJpa.findRoleNameAndIds(); @@ -102,6 +103,8 @@ public class SystemUserApi { @PostMapping("") @Transactional + @OperationLog(name="添加用户") + @RequiresPermissions(value= {"user:add"}) public AntdspResponse add(@RequestBody SystemUserDto dto) { User user = dto.getUser(); @@ -127,6 +130,8 @@ public class SystemUserApi { @PutMapping("/{id:\\d+}") @Transactional + @OperationLog(name="修改用户信息") + @RequiresPermissions(value= {"user:update"}) public AntdspResponse update(@RequestBody SystemUserDto dto) { User user = dto.getUser(); @@ -151,6 +156,7 @@ public class SystemUserApi { @DeleteMapping("/{id:\\d+}") @RequiresPermissions(value= {"user:delete"}) @Transactional + @OperationLog(name="删除用户") public AntdspResponse delete(@PathVariable("id") Long id) { User oldUser = userJpa.findById(id).orElse(null); diff --git a/antdsp-admin/src/main/resources/application.yml b/antdsp-admin/src/main/resources/application.yml index 572f4e8..fcfadf9 100644 --- a/antdsp-admin/src/main/resources/application.yml +++ b/antdsp-admin/src/main/resources/application.yml @@ -13,3 +13,5 @@ spring: active: dev application: name: antdsp + aop: + auto: true #启动Spring AOP 配置 diff --git a/antdsp-admin/src/main/web/config/router.config.js b/antdsp-admin/src/main/web/config/router.config.js index 2246bc7..0a51433 100644 --- a/antdsp-admin/src/main/web/config/router.config.js +++ b/antdsp-admin/src/main/web/config/router.config.js @@ -16,32 +16,38 @@ export default [ path: '/', redirect: '/system/user', }, - // dashboard { path: '/system', name: 'system', - icon: 'setting', routes: [ { path: '/system/user', name: 'user', - icon: 'user', component: './System/User/Index', }, { path: '/system/menu', name: 'menu', - icon: 'menu', component: './System/Menu/Index', }, { path: '/system/role', name: 'role', - icon: 'team', component: './System/Role/Index', }, ], }, + { + path: '/operation', + name: 'operation', + routes:[ + { + path: '/operation/log', + name: 'log', + component: './Operation/Log/Index' + } + ] + }, { component: '404', }, diff --git a/antdsp-admin/src/main/web/src/defaultSettings.js b/antdsp-admin/src/main/web/src/defaultSettings.js index 4e7e801..c952cb8 100644 --- a/antdsp-admin/src/main/web/src/defaultSettings.js +++ b/antdsp-admin/src/main/web/src/defaultSettings.js @@ -9,7 +9,7 @@ module.exports = { menu: { disableLocal: false, }, - title: 'Ant Design Pro', + title: 'Antdsp', pwa: true, // Your custom iconfont Symbol script Url // eg://at.alicdn.com/t/font_1039637_btcrd5co4w.js diff --git a/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js b/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js index ef57461..f8ffdb9 100644 --- a/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js +++ b/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js @@ -6,4 +6,6 @@ export default { 'menu.system.role': '角色管理', 'menu.account.center': '个人中心', 'menu.account.logout': '退出登录', + 'menu.operation': '运维管理', + 'menu.operation.log': '操作日志' }; diff --git a/antdsp-admin/src/main/web/src/manifest.json b/antdsp-admin/src/main/web/src/manifest.json index 839bc5b..1a4e488 100644 --- a/antdsp-admin/src/main/web/src/manifest.json +++ b/antdsp-admin/src/main/web/src/manifest.json @@ -1,6 +1,6 @@ { - "name": "Ant Design Pro", - "short_name": "Ant Design Pro", + "name": "Antdsp", + "short_name": "Antdsp", "display": "standalone", "start_url": "./?utm_source=homescreen", "theme_color": "#002140", diff --git a/antdsp-admin/src/main/web/src/models/login.js b/antdsp-admin/src/main/web/src/models/login.js index 122a452..88f772a 100644 --- a/antdsp-admin/src/main/web/src/models/login.js +++ b/antdsp-admin/src/main/web/src/models/login.js @@ -61,7 +61,7 @@ export default { }); reloadAuthorized(); // redirect - if (window.location.pathname !== '/login') { + if (window.location.pathname !== '/antdsp/login') { yield put( routerRedux.replace({ pathname: '/login', diff --git a/antdsp-admin/src/main/web/src/pages/Operation/Log/Index.js b/antdsp-admin/src/main/web/src/pages/Operation/Log/Index.js new file mode 100644 index 0000000..d3b4676 --- /dev/null +++ b/antdsp-admin/src/main/web/src/pages/Operation/Log/Index.js @@ -0,0 +1,109 @@ +import { PureComponent } from "react"; +import { connect } from 'dva'; +import PageHeaderWrapper from "@/components/PageHeaderWrapper"; +import Block from "@/custom/Block"; +import { Form, Table, Card } from "antd"; +import moment from "moment"; + +const FormItem = Form.Item; + +@connect(({ operlog , loading })=>({ + operlog, + loading: loading.models.operlog +})) +@Form.create() +export default class SystemLog extends PureComponent{ + + state={ + formValues:{ + page: 1, + count: 10, + } + } + + componentDidMount(){ + const{ dispatch} = this.props; + + dispatch({ + type: 'operlog/fetchAll', + payload: { + ...this.state.formValues + } + }); + } + + handlerTableOnChange = (pagination, filters, sorter) => { + const { dispatch } = this.props; + let { formValues } = this.state; + + formValues = { + ...formValues, + page: pagination.current, + count: pagination.pageSize, + }; + + this.setState({ + formValues: { + ...formValues, + }, + }); + + dispatch({ + type: 'operlog/fetchAll', + payload: { + ...formValues + } + }); + } + + render(){ + + const { operlog:{ LogList} , loading } = this.props; + + const columns = [{ + title: '用户名', + dataIndex: 'optorName' + },{ + title: '用户操作', + dataIndex: 'optName', + },{ + title: '请求URI', + dataIndex: 'optURI', + },{ + title: '请求方式', + dataIndex: 'optType', + },{ + title: '请求参数', + dataIndex: 'optDetail', + width: '100px', + },{ + title: '耗时', + dataIndex: 'runTime', + },{ + title: '操作IP', + dataIndex: 'optorIp', + },{ + title: '创建时间', + dataIndex: 'created', + render: (val)=> {moment(val).format('YYYY-MM-DD HH:mm:ss')} + }]; + + return ( + + + + + + + + + + ) + } +} \ No newline at end of file diff --git a/antdsp-admin/src/main/web/src/pages/Operation/Log/models/operlog.js b/antdsp-admin/src/main/web/src/pages/Operation/Log/models/operlog.js new file mode 100644 index 0000000..e746c1f --- /dev/null +++ b/antdsp-admin/src/main/web/src/pages/Operation/Log/models/operlog.js @@ -0,0 +1,32 @@ +import { fetchAllLog } from "@/services/system"; + +export default { + namespace: 'operlog', + + state: { + LogList:{ + data:[], + pagination:{} + } + }, + + effects: { + *fetchAll({payload},{call, put}){ + const response = yield call(fetchAllLog, payload); + + yield put({ + type: 'reducersLogList', + payload: response, + }) + } + }, + + reducers: { + reducersLogList(state,{payload}){ + return { + ...state, + LogList: payload + } + } + } +} \ No newline at end of file diff --git a/antdsp-admin/src/main/web/src/services/system.js b/antdsp-admin/src/main/web/src/services/system.js index 7d58feb..9296f75 100644 --- a/antdsp-admin/src/main/web/src/services/system.js +++ b/antdsp-admin/src/main/web/src/services/system.js @@ -108,4 +108,8 @@ export async function queryRoles(){ export async function queryRoleMenus(){ return request(`${MENU_API}/route`); +} + +export async function fetchAllLog(param){ + return request(`${API_BASE}/operation/log?${qs.stringify(param, { indices: false })}`); } \ No newline at end of file diff --git a/antdsp-core/pom.xml b/antdsp-core/pom.xml index 6a0138c..d0e566b 100644 --- a/antdsp-core/pom.xml +++ b/antdsp-core/pom.xml @@ -28,6 +28,12 @@ druid1.1.14 + + com.alibaba + fastjson + 1.2.58 + + org.mybatis.spring.boot diff --git a/antdsp-core/src/main/java/com/antdsp/common/enums/SortType.java b/antdsp-core/src/main/java/com/antdsp/common/enums/SortType.java new file mode 100644 index 0000000..25d02ba --- /dev/null +++ b/antdsp-core/src/main/java/com/antdsp/common/enums/SortType.java @@ -0,0 +1,8 @@ +package com.antdsp.common.enums; + +public enum SortType { + + DESC, + ASC; + +} diff --git a/antdsp-admin/src/main/java/com/antdsp/common/pagination/Pagination.java b/antdsp-core/src/main/java/com/antdsp/common/pagination/Pagination.java similarity index 100% rename from antdsp-admin/src/main/java/com/antdsp/common/pagination/Pagination.java rename to antdsp-core/src/main/java/com/antdsp/common/pagination/Pagination.java diff --git a/antdsp-admin/src/main/java/com/antdsp/common/pagination/PaginationData.java b/antdsp-core/src/main/java/com/antdsp/common/pagination/PaginationData.java similarity index 94% rename from antdsp-admin/src/main/java/com/antdsp/common/pagination/PaginationData.java rename to antdsp-core/src/main/java/com/antdsp/common/pagination/PaginationData.java index 74c14e5..f885d93 100644 --- a/antdsp-admin/src/main/java/com/antdsp/common/pagination/PaginationData.java +++ b/antdsp-core/src/main/java/com/antdsp/common/pagination/PaginationData.java @@ -38,7 +38,7 @@ public class PaginationData { */ public PaginationData(List data , int current , Long total) { this.data = data; - this.pagination = new Pagination(current , total); + this.pagination = new Pagination(current + 1 , total); } public List getData() { diff --git a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java index fa99ea3..b05b174 100644 --- a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java +++ b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java @@ -4,10 +4,14 @@ import java.io.Serializable; import java.util.List; import java.util.Map; +import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.NoRepositoryBean; +import com.antdsp.common.enums.SortType; +import com.antdsp.common.pagination.PaginationData; + /** * *

title:AntdspBaseRepository.java

@@ -33,30 +37,21 @@ public interface AntdspBaseRepository extends JpaR int executeSQL(String sqlString , Map params); /** - * 一般的SQL语句(select),表名、字段名和数据库对应 - * @param sqlString - * @param params - * @return - */ - List queryBySQL(String sqlStr , Map params, Class clazz); - - /** - * (select) 多表联合查询,表名、字段名和实体类对应 - * @param sqlStr - * @param params + * 通用分页, 默认排序方式(创建时间倒序查询) + * @param specification * @return */ - List selectUnion(String queryStr , Map params , Class clazz); + PaginationData list(Specification specification, int page , int count); /** - * 分页(select) 多表联合查询,表名、字段名和实体类对应 - * @param sqlStr - * @param params - * @param clazz - * @param start + * 通用分页 + * @param specification + * @param page * @param count + * @param sort + * @param orderField * @return */ - List selectUnion(String queryStr , Map params , Class clazz, int start, int count); + PaginationData list(Specification specification, int page , int count, SortType sort, String orderField); } diff --git a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java index 2ca6fcf..6b66408 100644 --- a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java +++ b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java @@ -2,15 +2,23 @@ package com.antdsp.dao.jpa; import java.io.Serializable; import java.util.Iterator; -import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.Query; import javax.persistence.TypedQuery; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Order; +import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; +import com.antdsp.common.enums.SortType; +import com.antdsp.common.pagination.PaginationData; + /** * *

title:AntdspBaseRepositoryImpl.java

@@ -28,12 +36,9 @@ public class AntdspBaseRepositoryImpl extends Simple private final EntityManager em; - private Class clazz; - public AntdspBaseRepositoryImpl(Class domainClass, EntityManager em) { super(domainClass, em); this.em = em; - this.clazz = domainClass; } @Override @@ -55,32 +60,23 @@ public class AntdspBaseRepositoryImpl extends Simple } @Override - public List selectUnion(String queryStr, Map params, Class clazz) { - - TypedQuery query = em.createQuery(queryStr, clazz); - this.querySetParameter(query, params); - return query.getResultList(); + public PaginationData list(Specification specification, int page , int count) { + return this.list(specification, page, count, SortType.DESC, "created"); } @Override - public List selectUnion(String queryStr, Map params, Class clazz, int start, int count) { - - TypedQuery query = em.createQuery(queryStr, clazz); - this.querySetParameter(query, params); - query.setFirstResult(start).setMaxResults(count); - return query.getResultList(); - } - - @Override - public List queryBySQL(String sqlStr, Map params, Class clazz) { - - Query query; - if(clazz == null) { - query = em.createNativeQuery(sqlStr); + public PaginationData list(Specification specification, int page, int count, SortType sort, String orderField) { + + page = (page - 1) ; + Pageable pageable ; + if(SortType.DESC.equals(sort)) { + pageable = PageRequest.of(page, count , Sort.by(Order.desc(orderField))); }else { - query = em.createNativeQuery(sqlStr, clazz); + pageable = PageRequest.of(page, count , Sort.by(Order.asc(orderField))); } - this.querySetParameter(query, params); - return query.getResultList(); + Page userList = this.findAll(specification, pageable); + return new PaginationData<>(userList.getContent() , page , userList.getTotalElements()); } + + } diff --git a/antdsp-core/src/main/java/com/antdsp/dao/jpa/system/SystemLogJpa.java b/antdsp-core/src/main/java/com/antdsp/dao/jpa/system/SystemLogJpa.java new file mode 100644 index 0000000..289a1ed --- /dev/null +++ b/antdsp-core/src/main/java/com/antdsp/dao/jpa/system/SystemLogJpa.java @@ -0,0 +1,11 @@ +package com.antdsp.dao.jpa.system; + +import org.springframework.stereotype.Repository; + +import com.antdsp.dao.jpa.AntdspBaseRepository; +import com.antdsp.data.entity.system.SystemLog; + +@Repository("systemLogJpa") +public interface SystemLogJpa extends AntdspBaseRepository{ + +} diff --git a/antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java b/antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java index 71a967f..4db4c7e 100644 --- a/antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java +++ b/antdsp-core/src/main/java/com/antdsp/data/entity/system/SystemLog.java @@ -2,12 +2,9 @@ package com.antdsp.data.entity.system; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; import javax.persistence.Table; import com.antdsp.data.entity.AbstractEntity; -import com.antdsp.data.entityeenum.OperationType; /** * @@ -52,19 +49,24 @@ public class SystemLog extends AbstractEntity{ */ @Column(name="opt_name", nullable=false, length=64) private String optName; - + /** - * 操作详情 + * 请求uri */ - @Column(name="opt_detail", nullable=false, length=1024) - private String optDetail; + @Column(name="opt_uri", nullable=false, length=128) + private String optURI; /** - * 操作类型 + * 操作请求方式 */ @Column(name="opt_type", nullable=false, length=16) - @Enumerated(EnumType.STRING) - private OperationType optType; + private String optType; + + /** + * 操作详情 + */ + @Column(name="opt_detail", nullable=false, length=1024) + private String optDetail; /** * 操作时间 @@ -112,14 +114,6 @@ public class SystemLog extends AbstractEntity{ this.optDetail = optDetail; } - public OperationType getOptType() { - return optType; - } - - public void setOptType(OperationType optType) { - this.optType = optType; - } - public long getRunTime() { return runTime; } @@ -127,6 +121,22 @@ public class SystemLog extends AbstractEntity{ public void setRunTime(long runTime) { this.runTime = runTime; } + + public String getOptURI() { + return optURI; + } + + public void setOptURI(String optURI) { + this.optURI = optURI; + } + + public String getOptType() { + return optType; + } + + public void setOptType(String optType) { + this.optType = optType; + } } diff --git a/antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java b/antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java deleted file mode 100644 index 8b85bb6..0000000 --- a/antdsp-core/src/main/java/com/antdsp/data/entityeenum/OperationType.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.antdsp.data.entityeenum; - -public enum OperationType { - - UNKNOWN("unknown"), - INSERT("insert"), - DELETE("delete"), - SELECT("select"), - UPDATE("update"); - - private String value; - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - OperationType(String value){ - this.value = value; - } -} -- Gitee From 8af77e98db1fff1d48ddc3f149b234d2af403a1d Mon Sep 17 00:00:00 2001 From: lijiantao Date: Fri, 21 Jun 2019 17:06:12 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/antdsp/ApplicationStarter.java | 6 +- .../configuration/ShiroConfiguration.java | 1 + .../common/exception/AntdspException.java | 6 + .../common/exception/CaptchaException.java | 12 ++ .../shiro/AntdspShiroSessionManager.java | 5 +- .../java/com/antdsp/utils/ShiroUtils.java | 36 +++++ .../com/antdsp/web/dto/LoginUserInfo.java | 7 + .../main/java/com/antdsp/web/rest/Login.java | 33 ++++- .../src/main/web/src/pages/Login/Index.js | 36 ++++- .../src/main/web/src/pages/Login/style.less | 4 + .../src/main/web/src/pages/document.ejs | 4 +- .../antdsp/utils/ApplicationContextUtil.java | 19 +++ .../java/com/antdsp/utils/CaptchaUtils.java | 123 ++++++++++++++++++ .../main/java/com/antdsp/utils/Constants.java | 7 + 14 files changed, 282 insertions(+), 17 deletions(-) create mode 100644 antdsp-admin/src/main/java/com/antdsp/common/exception/CaptchaException.java create mode 100644 antdsp-admin/src/main/java/com/antdsp/utils/ShiroUtils.java create mode 100644 antdsp-core/src/main/java/com/antdsp/utils/ApplicationContextUtil.java create mode 100644 antdsp-core/src/main/java/com/antdsp/utils/CaptchaUtils.java create mode 100644 antdsp-core/src/main/java/com/antdsp/utils/Constants.java diff --git a/antdsp-admin/src/main/java/com/antdsp/ApplicationStarter.java b/antdsp-admin/src/main/java/com/antdsp/ApplicationStarter.java index ad9cb78..fa7aaca 100644 --- a/antdsp-admin/src/main/java/com/antdsp/ApplicationStarter.java +++ b/antdsp-admin/src/main/java/com/antdsp/ApplicationStarter.java @@ -4,11 +4,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.core.env.Environment; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.antdsp.common.AntdspRepositoryFactoryBean; +import com.antdsp.utils.ApplicationContextUtil; @SpringBootApplication @EnableTransactionManagement @@ -21,7 +22,8 @@ public class ApplicationStarter { SpringApplication app = new SpringApplication(ApplicationStarter.class); - Environment environment = app.run(args).getEnvironment(); + ConfigurableApplicationContext context = app.run(args); + ApplicationContextUtil.setApplicationContext(context); logger.info("antdsp is started"); diff --git a/antdsp-admin/src/main/java/com/antdsp/common/configuration/ShiroConfiguration.java b/antdsp-admin/src/main/java/com/antdsp/common/configuration/ShiroConfiguration.java index 09fa7ef..47a9131 100644 --- a/antdsp-admin/src/main/java/com/antdsp/common/configuration/ShiroConfiguration.java +++ b/antdsp-admin/src/main/java/com/antdsp/common/configuration/ShiroConfiguration.java @@ -58,6 +58,7 @@ public class ShiroConfiguration { filterMap.put("/login","anon"); filterMap.put("/logout","anon"); filterMap.put("/unauth","anon"); + filterMap.put("/captcha.jpg","anon"); filterMap.put("/**","authc"); shiroFilterFactory.setFilterChainDefinitionMap(filterMap); diff --git a/antdsp-admin/src/main/java/com/antdsp/common/exception/AntdspException.java b/antdsp-admin/src/main/java/com/antdsp/common/exception/AntdspException.java index 722dd94..5feefc9 100644 --- a/antdsp-admin/src/main/java/com/antdsp/common/exception/AntdspException.java +++ b/antdsp-admin/src/main/java/com/antdsp/common/exception/AntdspException.java @@ -27,4 +27,10 @@ public class AntdspException extends RuntimeException{ public AntdspResponse unauthorizedException() { return new AntdspResponse( ResponseCode.FORBIDDEN , false , "权限不足,请联系管理员."); } + + @ExceptionHandler(value= {CaptchaException.class}) + @ResponseBody + public AntdspResponse captchaException(CaptchaException e) { + return new AntdspResponse( ResponseCode.ERROR , false , e.getMessage()); + } } diff --git a/antdsp-admin/src/main/java/com/antdsp/common/exception/CaptchaException.java b/antdsp-admin/src/main/java/com/antdsp/common/exception/CaptchaException.java new file mode 100644 index 0000000..af21901 --- /dev/null +++ b/antdsp-admin/src/main/java/com/antdsp/common/exception/CaptchaException.java @@ -0,0 +1,12 @@ +package com.antdsp.common.exception; + +public class CaptchaException extends RuntimeException { + + public CaptchaException() { + super(); + } + + public CaptchaException(String message) { + super(message); + } +} diff --git a/antdsp-admin/src/main/java/com/antdsp/common/shiro/AntdspShiroSessionManager.java b/antdsp-admin/src/main/java/com/antdsp/common/shiro/AntdspShiroSessionManager.java index 201e5ea..aeb09dc 100644 --- a/antdsp-admin/src/main/java/com/antdsp/common/shiro/AntdspShiroSessionManager.java +++ b/antdsp-admin/src/main/java/com/antdsp/common/shiro/AntdspShiroSessionManager.java @@ -11,9 +11,10 @@ import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.apache.shiro.web.util.WebUtils; import org.springframework.util.StringUtils; +import com.antdsp.utils.Constants; + public class AntdspShiroSessionManager extends DefaultWebSessionManager{ - private static final String AUTHORIZATION = "Authorization"; private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request"; public AntdspShiroSessionManager() { @@ -25,7 +26,7 @@ public class AntdspShiroSessionManager extends DefaultWebSessionManager{ // TODO Auto-generated method stub HttpServletRequest httpRequest = WebUtils.toHttp(request); - String sessionId = httpRequest.getHeader(AUTHORIZATION); + String sessionId = httpRequest.getHeader(Constants.AUTHORIZATION); if(!StringUtils.isEmpty(sessionId)) { request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId); diff --git a/antdsp-admin/src/main/java/com/antdsp/utils/ShiroUtils.java b/antdsp-admin/src/main/java/com/antdsp/utils/ShiroUtils.java new file mode 100644 index 0000000..ecf636d --- /dev/null +++ b/antdsp-admin/src/main/java/com/antdsp/utils/ShiroUtils.java @@ -0,0 +1,36 @@ +package com.antdsp.utils; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.session.Session; +import org.apache.shiro.subject.Subject; + +import com.antdsp.common.exception.CaptchaException; + +public class ShiroUtils { + + public static Subject getSubject() { + return SecurityUtils.getSubject(); + } + + public static Session getSession() { + return SecurityUtils.getSubject().getSession(); + } + + public static void setSessionAttribute(Object key, Object value) { + getSession().setAttribute(key, value); + } + + public static Object getSeesionAttribute(Object key) { + return getSession().getAttribute(key); + } + + public static String getCaptcha() { + String key = Constants.CAPTCHA_SESSION_KEY; + Object captcha = getSeesionAttribute(key); + if(captcha == null) { + throw new CaptchaException("验证码已失效"); + } + getSession().removeAttribute(key); + return captcha.toString(); + } +} diff --git a/antdsp-admin/src/main/java/com/antdsp/web/dto/LoginUserInfo.java b/antdsp-admin/src/main/java/com/antdsp/web/dto/LoginUserInfo.java index 838cda9..4ab8b3c 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/dto/LoginUserInfo.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/dto/LoginUserInfo.java @@ -4,6 +4,7 @@ public class LoginUserInfo { private String loginname; private String password; + private String code; public String getLoginname() { return loginname; @@ -17,5 +18,11 @@ public class LoginUserInfo { public void setPassword(String password) { this.password = password; } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } } diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java index 5aeaafb..c1839e7 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java @@ -1,24 +1,42 @@ package com.antdsp.web.rest; +import java.io.IOException; +import java.io.OutputStream; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; + import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; -import org.springframework.http.HttpStatus; +import org.springframework.http.HttpHeaders; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.server.ResponseStatusException; import com.antdsp.common.AntdspResponse; import com.antdsp.common.ResponseCode; +import com.antdsp.utils.CaptchaUtils; +import com.antdsp.utils.Constants; +import com.antdsp.utils.ShiroUtils; import com.antdsp.web.dto.LoginUserInfo; @RestController public class Login { + @GetMapping("/captcha.jpg") + public void captcha(HttpServletResponse response)throws IOException{ + response.setHeader(HttpHeaders.CACHE_CONTROL, "no-store, no-cache"); + response.setContentType("image/jpeg"); + + String text = CaptchaUtils.createText(); + ShiroUtils.setSessionAttribute(Constants.CAPTCHA_SESSION_KEY , text); + ImageIO.write(CaptchaUtils.createImage(text), "jpg", response.getOutputStream()); + } + @GetMapping("/login") public AntdspResponse login() { return AntdspResponse.error(ResponseCode.UNAUTHORIZED , "请先登录"); @@ -26,12 +44,18 @@ public class Login { @PostMapping("/login") public AntdspResponse login(@RequestBody LoginUserInfo userInfo) { + + String code = userInfo.getCode(); + System.out.println(code); + if(!ShiroUtils.getCaptcha().equalsIgnoreCase(code)) { + return AntdspResponse.error(ResponseCode.ERROR , "验证码错误"); + } + Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(userInfo.getLoginname() , userInfo.getPassword()); try { subject.login(token); Session session = subject.getSession(); -// session.setTimeout(180000); return AntdspResponse.success(session.getId().toString()); }catch(AuthenticationException e) { return AntdspResponse.error(e.getMessage()); @@ -41,8 +65,7 @@ public class Login { @GetMapping("/login_success") public AntdspResponse loginsuccess() { - Subject subject = SecurityUtils.getSubject(); - Session session = subject.getSession(); + Session session = ShiroUtils.getSession(); return AntdspResponse.success(session.getId().toString()); } diff --git a/antdsp-admin/src/main/web/src/pages/Login/Index.js b/antdsp-admin/src/main/web/src/pages/Login/Index.js index af69fe2..0b81d17 100644 --- a/antdsp-admin/src/main/web/src/pages/Login/Index.js +++ b/antdsp-admin/src/main/web/src/pages/Login/Index.js @@ -4,6 +4,7 @@ import { Card, Form, Input, Icon, Button, message } from 'antd'; import Block from '@/custom/Block'; import styles from './style.less'; import md5 from 'js-md5' +import moment from 'moment'; const FormItem = Form.Item; @@ -14,7 +15,8 @@ const FormItem = Form.Item; export default class Login extends PureComponent{ state={ - btnLoading: false + btnLoading: false, + captcha: moment().milliseconds() } handlerLogin=()=>{ @@ -25,23 +27,31 @@ export default class Login extends PureComponent{ form.validateFields((err , fieldsValue)=>{ if(err) return this.setState({btnLoading: false}); - const loginname = fieldsValue.loginname; let password = fieldsValue.password; + dispatch({ type: 'login/login', payload:{ - loginname: loginname, + ...fieldsValue, password: md5(password) }, - callback:(result)=>{ - message.error(result.message); - this.setState({btnLoading: false}); + callback: ()=>{ + this.setState({ + btnLoading: false, + captcha: moment().milliseconds() + }); } }) }); } + changeCaptcha=()=>{ + this.setState({ + captcha: moment().milliseconds() + }); + } + render(){ const { @@ -77,6 +87,20 @@ export default class Login extends PureComponent{ } type="password" placeholder="密 码" /> )} + + {getFieldDecorator('code',{ + rules: [{ + required: true, + message: '请输入验证码', + }] + })( + + )} + + + + 点击刷新 + diff --git a/antdsp-admin/src/main/web/src/pages/Login/style.less b/antdsp-admin/src/main/web/src/pages/Login/style.less index fa972d7..cfc8b68 100644 --- a/antdsp-admin/src/main/web/src/pages/Login/style.less +++ b/antdsp-admin/src/main/web/src/pages/Login/style.less @@ -18,4 +18,8 @@ font-weight: bold; margin-bottom: 20px; } + .fresh { + margin-left: 40px; + color: white; + } } \ No newline at end of file diff --git a/antdsp-admin/src/main/web/src/pages/document.ejs b/antdsp-admin/src/main/web/src/pages/document.ejs index cf09eff..9a88919 100644 --- a/antdsp-admin/src/main/web/src/pages/document.ejs +++ b/antdsp-admin/src/main/web/src/pages/document.ejs @@ -7,8 +7,8 @@ name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" /> - Ant Design Pro - + Antdsp + diff --git a/antdsp-core/src/main/java/com/antdsp/utils/ApplicationContextUtil.java b/antdsp-core/src/main/java/com/antdsp/utils/ApplicationContextUtil.java new file mode 100644 index 0000000..6fa93a2 --- /dev/null +++ b/antdsp-core/src/main/java/com/antdsp/utils/ApplicationContextUtil.java @@ -0,0 +1,19 @@ +package com.antdsp.utils; + +import org.springframework.context.ApplicationContext; + +public class ApplicationContextUtil{ + + private static ApplicationContext applicationContext ; + + public static void setApplicationContext(ApplicationContext context) { + if(ApplicationContextUtil.applicationContext == null) { + ApplicationContextUtil.applicationContext = context; + } + } + + public static String getActiveProfile() { + return applicationContext.getEnvironment().getActiveProfiles()[0]; + } + +} diff --git a/antdsp-core/src/main/java/com/antdsp/utils/CaptchaUtils.java b/antdsp-core/src/main/java/com/antdsp/utils/CaptchaUtils.java new file mode 100644 index 0000000..17402e3 --- /dev/null +++ b/antdsp-core/src/main/java/com/antdsp/utils/CaptchaUtils.java @@ -0,0 +1,123 @@ +package com.antdsp.utils; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.util.Random; + +public class CaptchaUtils { + + private static final int WIDTH = 200; + private static final int HEIGHT = 50; + private static final int CODE_LENGTH = 4; + + private static final String chars = "23456789abcdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ"; + + private static final Random RANDOM = new Random(); + + public static String createText() { + return createText(CODE_LENGTH); + } + + public static String createText(int length) { + char[] code = new char[length]; + for(int i=0; i< length; i++) { + code[i] = chars.charAt(RANDOM.nextInt(chars.length())); + } + return new String(code); + } + + public static BufferedImage createImage(String text) { + + BufferedImage image = new BufferedImage(WIDTH , HEIGHT , BufferedImage.TYPE_INT_RGB); + + //创建画笔 + Graphics2D pen = image.createGraphics(); + //开始画图 + drawImage(pen, text); + return image; + } + + /** + * 画图片 + */ + private static void drawImage(Graphics pen, String text) { + drawBackground(pen); + drawLine(pen , 2); + drawOval(pen, 10); + drawCode(pen, text); + } + + private static void drawBackground(Graphics pen) { + pen.setColor(new Color(240,240,240)); + pen.fillRect(0, 0, WIDTH , HEIGHT); + } + + /** + * 画干扰线 + */ + private static void drawLine(Graphics pen, int count) { + Color color ; + for(int i=1; i<= count; i++) { + color = randomColor(); + pen.setColor(color); + pen.drawLine(0, randomNum(HEIGHT), WIDTH, randomNum(HEIGHT)); + color = null; + } + } + + /** + * 画干扰圈 + * @param pen 画笔 + * @param count 画多少个 + */ + private static void drawOval(Graphics pen , int count) { + Color color ; + for(int i=1; i<= count; i++) { + color = randomColor(); + pen.setColor(color); + pen.drawOval(randomNum(WIDTH), randomNum(HEIGHT), 2+randomNum(10) , 2+randomNum(10)); + color = null; + } + } + + /** + * 画验证码 + * @param pen + * @param code + */ + private static void drawCode(Graphics pen , String code) { + + int width = WIDTH / code.length(); //单个字符的宽度 + Color color ; + for(int i = 0; i< code.length(); i++) { + color = randomColor(); + + pen.setColor(color); + pen.setFont(randomForn()); + pen.drawString(code.substring(i, i+1), width * i + 5 , 30); + color = null; + } + } + + private static Color randomColor() { + //240 避免出现白色 + int red = randomNum(240); + int green = randomNum(240); + int blue = randomNum(240); + return new Color(red, green, blue); + } + + private static Font randomForn() { + int style = randomNum(4); //生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体) + int size = randomNum(5) + 28; //生成随机字号, 24 ~ 28 + return new Font("Verdana", style, size); + } + + private static int randomNum(int num) { + return RANDOM.nextInt(num); + } + +} diff --git a/antdsp-core/src/main/java/com/antdsp/utils/Constants.java b/antdsp-core/src/main/java/com/antdsp/utils/Constants.java new file mode 100644 index 0000000..f00ecac --- /dev/null +++ b/antdsp-core/src/main/java/com/antdsp/utils/Constants.java @@ -0,0 +1,7 @@ +package com.antdsp.utils; + +public class Constants { + public static final String AUTHORIZATION = "Authorization"; + + public static final String CAPTCHA_SESSION_KEY = "CAPTCHA_SESSION_KEY"; +} -- Gitee From 5fdc41f1f3af8822995894c979c23746b5735371 Mon Sep 17 00:00:00 2001 From: lijiantao Date: Mon, 24 Jun 2019 18:04:32 +0800 Subject: [PATCH 4/5] tijiao --- antdsp-admin/pom.xml | 34 +++--- .../com/antdsp/utils/FileUploadUtils.java | 33 ++++++ .../com/antdsp/web/rest/FileUploadApi.java | 103 ++++++++++++++++++ .../main/java/com/antdsp/web/rest/Login.java | 1 - .../antdsp/web/rest/sys/SystemUserApi.java | 4 +- .../src/main/resources/application-dev.yml | 8 +- .../src/main/web/config/router.config.js | 5 + .../src/main/web/src/custom/UnipicUpload.js | 78 +++++++++++++ .../src/main/web/src/locales/zh-CN/menu.js | 3 +- .../web/src/pages/Operation/Article/Index.js | 0 .../pages/Operation/Article/models/article.js | 0 .../main/web/src/pages/System/User/Index.js | 27 ++++- .../antdsp/dao/jpa/AntdspBaseRepository.java | 7 ++ .../dao/jpa/AntdspBaseRepositoryImpl.java | 6 + 14 files changed, 287 insertions(+), 22 deletions(-) create mode 100644 antdsp-admin/src/main/java/com/antdsp/utils/FileUploadUtils.java create mode 100644 antdsp-admin/src/main/java/com/antdsp/web/rest/FileUploadApi.java create mode 100644 antdsp-admin/src/main/web/src/custom/UnipicUpload.js create mode 100644 antdsp-admin/src/main/web/src/pages/Operation/Article/Index.js create mode 100644 antdsp-admin/src/main/web/src/pages/Operation/Article/models/article.js diff --git a/antdsp-admin/pom.xml b/antdsp-admin/pom.xml index ccf175b..a037d9b 100644 --- a/antdsp-admin/pom.xml +++ b/antdsp-admin/pom.xml @@ -1,23 +1,23 @@ - + 4.0.0 - + com.antdsp antdsp 0.0.1 ../pom.xml - + antdsp-admin antdsp-admin - + UTF-8 - + org.springframework.boot @@ -29,18 +29,24 @@ 1.3.2 - - org.springframework.boot - spring-boot-devtools - true - + + org.springframework.boot + spring-boot-devtools + true + + + + com.qiniu + qiniu-java-sdk + 7.2.22 + com.antdsp antdsp-core 0.0.1 - + @@ -52,9 +58,9 @@ UTF-8 true true - - com.antdsp.admin.ApplicationStarter - ZIP + + com.antdsp.admin.ApplicationStarter + ZIP diff --git a/antdsp-admin/src/main/java/com/antdsp/utils/FileUploadUtils.java b/antdsp-admin/src/main/java/com/antdsp/utils/FileUploadUtils.java new file mode 100644 index 0000000..b5bd355 --- /dev/null +++ b/antdsp-admin/src/main/java/com/antdsp/utils/FileUploadUtils.java @@ -0,0 +1,33 @@ +package com.antdsp.utils; + +import org.springframework.beans.factory.annotation.Value; + +import com.qiniu.common.Zone; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; + +public class FileUploadUtils { + + @Value("${qiniu.accessKey}") + private static String accessKey ; + @Value("${qiniu.secretKey}") + private static String secretKey; + @Value("${qiniu.bucket}") + private static String bucket; + + private static String key; + + + + private final static Configuration cfg = new Configuration(Zone.zone0()); + + public static String uploadImage() { + + UploadManager uploadManager = new UploadManager(cfg); + + System.out.println(FileUploadUtils.accessKey); + + return null; + } + +} diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/FileUploadApi.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/FileUploadApi.java new file mode 100644 index 0000000..672e69b --- /dev/null +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/FileUploadApi.java @@ -0,0 +1,103 @@ +package com.antdsp.web.rest; + +import java.io.IOException; +import java.util.UUID; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.antdsp.common.AntdspResponse; +import com.qiniu.common.Zone; +import com.qiniu.http.Response; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; +import com.qiniu.util.Auth; + +/** + * 文件上传 + *

title:FileUploadApi

+ *

Description:

+ *

Copyright: Copyright (c) 2019

+ * + * @author lijiantao + * @date 2019年6月24日 + * @email a496401006@qq.com + * + */ +@RestController +@RequestMapping("/fileupload") +public class FileUploadApi { + + private final String GROUP = "public"; + + @Value("${qiniu.accessKey}") + private String accessKey; + + @Value("${qiniu.secretKey}") + private String secretKey; + + @Value("${qiniu.bucket}") + private String bucket; + + private Auth auth ; + + private String upToken; + + private UploadManager uploadManager; + + @PostConstruct + private void init() { + + uploadManager = new UploadManager(new Configuration(Zone.zone0())); + auth = Auth.create(accessKey, secretKey); + upToken = auth.uploadToken(bucket); + } + + /** + * 上传文件 + * @param group + * @param filename + * @return + */ + @PostMapping("/{group}") + public AntdspResponse upload(@PathVariable("group") String group, @RequestParam("file") MultipartFile file) { + + if(StringUtils.isEmpty(group)) { + group = GROUP; + } + if(file == null || file.getSize() <= 0) { + return AntdspResponse.error("未找到上传文件,请重试!"); + } + + try { + + String key = fileName(group , file.getOriginalFilename()); + Response response = uploadManager.put(file.getBytes(), key, upToken); + if(response.isOK()) { + return AntdspResponse.success(key); + }else { + return AntdspResponse.error("上传文件失败,请重试或联系管理员!"); + } + + }catch(IOException e) { + return AntdspResponse.error("上传文件异常,请联系管理员!"); + } + + } + + private String fileName(String group , String originalFilename) { + + String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length()); + String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + fileSuffix; + return group +"/"+ newFileName; + } + +} diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java index c1839e7..79fcf22 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/Login.java @@ -46,7 +46,6 @@ public class Login { public AntdspResponse login(@RequestBody LoginUserInfo userInfo) { String code = userInfo.getCode(); - System.out.println(code); if(!ShiroUtils.getCaptcha().equalsIgnoreCase(code)) { return AntdspResponse.error(ResponseCode.ERROR , "验证码错误"); } diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java index 2688ff2..15d972d 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java @@ -88,6 +88,8 @@ public class SystemUserApi { } User user = this.userJpa.findById(userId).orElse(null); + this.userJpa.detach(user); + if(user == null) { return result; } @@ -181,7 +183,7 @@ public class SystemUserApi { if(roleIds != null && roleIds.size() > 0) { StringBuffer sqlStr = new StringBuffer("INSERT INTO `tb_role_user` (`role_id`, `user_id`) VALUES "); sqlStr.append("("+roleIds.get(0)+ ", " + userId+")"); - if(roleIds.size()>2) { + if(roleIds.size()>=2) { for(int i= 1 ; i< roleIds.size(); i++) { sqlStr.append(",("+roleIds.get(i)+ ", " + userId+")"); } diff --git a/antdsp-admin/src/main/resources/application-dev.yml b/antdsp-admin/src/main/resources/application-dev.yml index 673bd66..e09238e 100644 --- a/antdsp-admin/src/main/resources/application-dev.yml +++ b/antdsp-admin/src/main/resources/application-dev.yml @@ -10,4 +10,10 @@ spring: hibernate: ddl-auto: update show-sql: true - database-platform: org.hibernate.dialect.MySQL5InnoDBDialect \ No newline at end of file + database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + +qiniu: + accessKey: TnmENtV4x4oG0qfnXY3gSAmLplBw9bvRJ3IKS0X1 + secretKey: nMKAApnVrmBDifwuT5Pq5V33XhNOgcT4njErx5fV + bucket: antdsp + \ No newline at end of file diff --git a/antdsp-admin/src/main/web/config/router.config.js b/antdsp-admin/src/main/web/config/router.config.js index 0a51433..f8bfc0c 100644 --- a/antdsp-admin/src/main/web/config/router.config.js +++ b/antdsp-admin/src/main/web/config/router.config.js @@ -45,6 +45,11 @@ export default [ path: '/operation/log', name: 'log', component: './Operation/Log/Index' + }, + { + path: '/operation/article', + name: 'article', + component: './Operation/Article/Index' } ] }, diff --git a/antdsp-admin/src/main/web/src/custom/UnipicUpload.js b/antdsp-admin/src/main/web/src/custom/UnipicUpload.js new file mode 100644 index 0000000..c77f891 --- /dev/null +++ b/antdsp-admin/src/main/web/src/custom/UnipicUpload.js @@ -0,0 +1,78 @@ +import { PureComponent } from "react"; +import { Upload, Icon, message } from "antd"; + +export default class UnipicUpload extends PureComponent{ + + state = { + imgUrl: "", + loading: false, + } + + componentDidMount(){ + const { image } = this.props; + this.setState({ + imgUrl: image + }) + } + + uploadUrl(group){ + return "/antdsp-api/fileupload/"+group; + } + + handlerBeforeUpload=(file)=>{ + const isJPG = file.type === 'image/jpeg'; + if (!isJPG) { + message.error('只能上传图片文件'); + } + const isLt2M = file.size / 1024 / 1024 < 2; + if (!isLt2M) { + message.error('图片大小必须小于2M!'); + } + return isJPG && isLt2M; + } + + handlerUploadOnChange=(info)=>{ + const { onChange } = this.props; + if (info.file.status === 'uploading') { + this.setState({ loading: true }); + return; + } + + if (info.file.status === 'done') { + const response = info.file.response; + if(response.success){ + this.setState({ + imgUrl: response.message + }); + onChange(response.message); + } + } + } + + render(){ + + const{ group } = this.props; + + const {imgUrl} = this.state; + + return( + + { + imgUrl ? + + : +
+ +
Upload
+
+ } +
+ ) + } +} \ No newline at end of file diff --git a/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js b/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js index f8ffdb9..688550e 100644 --- a/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js +++ b/antdsp-admin/src/main/web/src/locales/zh-CN/menu.js @@ -7,5 +7,6 @@ export default { 'menu.account.center': '个人中心', 'menu.account.logout': '退出登录', 'menu.operation': '运维管理', - 'menu.operation.log': '操作日志' + 'menu.operation.log': '操作日志', + 'menu.operation.article': '文章管理' }; diff --git a/antdsp-admin/src/main/web/src/pages/Operation/Article/Index.js b/antdsp-admin/src/main/web/src/pages/Operation/Article/Index.js new file mode 100644 index 0000000..e69de29 diff --git a/antdsp-admin/src/main/web/src/pages/Operation/Article/models/article.js b/antdsp-admin/src/main/web/src/pages/Operation/Article/models/article.js new file mode 100644 index 0000000..e69de29 diff --git a/antdsp-admin/src/main/web/src/pages/System/User/Index.js b/antdsp-admin/src/main/web/src/pages/System/User/Index.js index 5bfafcf..50c69e3 100644 --- a/antdsp-admin/src/main/web/src/pages/System/User/Index.js +++ b/antdsp-admin/src/main/web/src/pages/System/User/Index.js @@ -14,8 +14,11 @@ import { message, Popconfirm, Checkbox, + Upload, + Icon } from 'antd'; import md5 from 'js-md5' +import UnipicUpload from '@/custom/UnipicUpload'; const FormItem = Form.Item; @@ -122,8 +125,8 @@ export default class extends PureComponent { }); }; - showModal = currentObj => { - + showModal = (e , currentObj) => { + e.preventDefault(); const { dispatch } = this.props; dispatch({ @@ -250,8 +253,8 @@ export default class extends PureComponent { { - this.showModal(record); + onClick={(e) => { + this.showModal(e, record); }} > 编辑 @@ -322,6 +325,7 @@ export default class extends PureComponent { @Form.create() export class EditUser extends PureComponent { + compareToPassword = (rule, value, callback) => { const form = this.props.form; if (value && value !== form.getFieldValue('password')) { @@ -331,6 +335,10 @@ export class EditUser extends PureComponent { } }; + handlerUploadOnChange=(info)=>{ + console.log(info); + } + roleToNameId(roleNameId){ let newRoleNameId=[]; @@ -365,6 +373,17 @@ export class EditUser extends PureComponent { return (
+ + {getFieldDecorator('avatar',{ + initialValue: user.avatar + })( + {this.handlerUploadOnChange}} + image={user.avatar} + /> + )} + {getFieldDecorator('loginname', { initialValue: user.loginname, diff --git a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java index b05b174..0a75d4d 100644 --- a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java +++ b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepository.java @@ -54,4 +54,11 @@ public interface AntdspBaseRepository extends JpaR */ PaginationData list(Specification specification, int page , int count, SortType sort, String orderField); + /** + * 将一个托管状态的对象变为游离态 + * 如果查询出一个对象后,要对对象字段set新值但不想保存到数据库,可以使用此方法 + * @param obj + */ + void detach(T obj); + } diff --git a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java index 6b66408..a749424 100644 --- a/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java +++ b/antdsp-core/src/main/java/com/antdsp/dao/jpa/AntdspBaseRepositoryImpl.java @@ -8,6 +8,7 @@ import javax.persistence.EntityManager; import javax.persistence.Query; import javax.persistence.TypedQuery; +import org.hibernate.jpa.HibernateEntityManager; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -77,6 +78,11 @@ public class AntdspBaseRepositoryImpl extends Simple Page userList = this.findAll(specification, pageable); return new PaginationData<>(userList.getContent() , page , userList.getTotalElements()); } + + @Override + public void detach(T obj) { + em.detach(obj); + } } -- Gitee From b945668e76cefaf6e1985345c5f2c1604f6bf5b6 Mon Sep 17 00:00:00 2001 From: lijiantao Date: Tue, 25 Jun 2019 13:46:11 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/antdsp/web/rest/sys/SystemUserApi.java | 2 +- .../src/main/resources/application-dev.yml | 4 ++-- .../src/main/web/src/pages/System/User/Index.js | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java index 15d972d..721c0cf 100644 --- a/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java +++ b/antdsp-admin/src/main/java/com/antdsp/web/rest/sys/SystemUserApi.java @@ -118,7 +118,6 @@ public class SystemUserApi { return AntdspResponse.error("登录名重复"); } - user.setAvatar(""); user.setCreator(current.getLoginname()); user.setModifier(current.getLoginname()); user.setStatus(UserStatus.NORMAL); @@ -146,6 +145,7 @@ public class SystemUserApi { oldUser.setQq(user.getQq()); oldUser.setRealname(user.getRealname()); oldUser.setModifier(current.getLoginname()); + oldUser.setAvatar(user.getAvatar()); oldUser.onPreUpdate(); this.userJpa.save(oldUser); this.userJpa.deleteUserRoleId(user.getId()); diff --git a/antdsp-admin/src/main/resources/application-dev.yml b/antdsp-admin/src/main/resources/application-dev.yml index e09238e..cb6fc7f 100644 --- a/antdsp-admin/src/main/resources/application-dev.yml +++ b/antdsp-admin/src/main/resources/application-dev.yml @@ -13,7 +13,7 @@ spring: database-platform: org.hibernate.dialect.MySQL5InnoDBDialect qiniu: - accessKey: TnmENtV4x4oG0qfnXY3gSAmLplBw9bvRJ3IKS0X1 - secretKey: nMKAApnVrmBDifwuT5Pq5V33XhNOgcT4njErx5fV + accessKey: xxx + secretKey: xxx bucket: antdsp \ No newline at end of file diff --git a/antdsp-admin/src/main/web/src/pages/System/User/Index.js b/antdsp-admin/src/main/web/src/pages/System/User/Index.js index 50c69e3..b54e5f5 100644 --- a/antdsp-admin/src/main/web/src/pages/System/User/Index.js +++ b/antdsp-admin/src/main/web/src/pages/System/User/Index.js @@ -224,6 +224,11 @@ export default class extends PureComponent { { title: '头像', dataIndex: 'avatar', + render:(val)=>{ + if(val){ + return
+ } + } }, { title: '登录名', @@ -285,8 +290,8 @@ export default class extends PureComponent {