editors;//记录可编辑者
+
+
+ //----------------------norm标准属性-----------------------
+ @Column(length = 126)
+ protected String name;//名称
+
+ protected Boolean avtag=true;//可用标记 1启用,0禁用
+
+ @ManyToOne
+ @JoinColumn(name = "crman", updatable = false)
+ protected SysOrg crman;//创建人
+
+ @Column(updatable = false)
+ protected Date crtim = new Date();//创建时间
+
+ @ManyToOne
+ @JoinColumn(name = "upman")
+ protected SysOrg upman;//更新人
+
+ protected Date uptim;//更新时间
+
+
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/BadConfigurationException.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/BadConfigurationException.java
new file mode 100644
index 0000000..fd96a60
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/BadConfigurationException.java
@@ -0,0 +1,77 @@
+package com.zsvg.vboot.common.mvc.exception;
+
+public class BadConfigurationException extends RuntimeException {
+ /**
+ * Constructs a new runtime exception with {@code null} as its
+ * detail message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause}.
+ */
+ public BadConfigurationException() {
+ super();
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public BadConfigurationException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message and
+ * cause. Note that the detail message associated with
+ * {@code cause} is not automatically incorporated in
+ * this runtime exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public BadConfigurationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified cause and a
+ * detail message of {@code (cause==null ? null : cause.toString())}
+ * (which typically contains the class and detail message of
+ * {@code cause}). This constructor is useful for runtime exceptions
+ * that are little more than wrappers for other throwables.
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public BadConfigurationException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail
+ * message, cause, suppression enabled or disabled, and writable
+ * stack trace enabled or disabled.
+ *
+ * @param message the detail message.
+ * @param cause the cause. (A {@code null} value is permitted,
+ * and indicates that the cause is nonexistent or unknown.)
+ * @param enableSuppression whether or not suppression is enabled
+ * or disabled
+ * @param writableStackTrace whether or not the stack trace should
+ * be writable
+ * @since 1.7
+ */
+ protected BadConfigurationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/BadRequestException.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/BadRequestException.java
new file mode 100644
index 0000000..f607426
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/BadRequestException.java
@@ -0,0 +1,21 @@
+package com.zsvg.vboot.common.mvc.exception;
+
+import lombok.Getter;
+import org.springframework.http.HttpStatus;
+
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+
+@Getter
+public class BadRequestException extends RuntimeException{
+
+ private Integer status = BAD_REQUEST.value();
+
+ public BadRequestException(String msg){
+ super(msg);
+ }
+
+ public BadRequestException(HttpStatus status, String msg){
+ super(msg);
+ this.status = status.value();
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/EntityExistException.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/EntityExistException.java
new file mode 100644
index 0000000..8fe28b9
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/EntityExistException.java
@@ -0,0 +1,15 @@
+package com.zsvg.vboot.common.mvc.exception;
+
+import org.springframework.util.StringUtils;
+
+public class EntityExistException extends RuntimeException {
+
+ public EntityExistException(Class clazz, String field, String val) {
+ super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val));
+ }
+
+ private static String generateMessage(String entity, String field, String val) {
+ return StringUtils.capitalize(entity)
+ + " with " + field + " "+ val + " existed";
+ }
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/EntityNotFoundException.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/EntityNotFoundException.java
new file mode 100644
index 0000000..362eb59
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/EntityNotFoundException.java
@@ -0,0 +1,15 @@
+package com.zsvg.vboot.common.mvc.exception;
+
+import org.springframework.util.StringUtils;
+
+public class EntityNotFoundException extends RuntimeException {
+
+ public EntityNotFoundException(Class clazz, String field, String val) {
+ super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val));
+ }
+
+ private static String generateMessage(String entity, String field, String val) {
+ return StringUtils.capitalize(entity)
+ + " with " + field + " "+ val + " does not exist";
+ }
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/ApiError.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/ApiError.java
new file mode 100644
index 0000000..2623c68
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/ApiError.java
@@ -0,0 +1,34 @@
+package com.zsvg.vboot.common.mvc.exception.handler;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+class ApiError {
+
+ private Integer status = 500;
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private LocalDateTime timestamp;
+ private String message;
+
+ private ApiError() {
+ timestamp = LocalDateTime.now();
+ }
+
+ public static ApiError error(String message){
+ ApiError apiError = new ApiError();
+ apiError.setMessage(message);
+ return apiError;
+ }
+
+ public static ApiError error(Integer status, String message){
+ ApiError apiError = new ApiError();
+ apiError.setStatus(status);
+ apiError.setMessage(message);
+ return apiError;
+ }
+}
+
+
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/GlobalExceptionHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/GlobalExceptionHandler.java
new file mode 100644
index 0000000..fd3f7bc
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/GlobalExceptionHandler.java
@@ -0,0 +1,95 @@
+package com.zsvg.vboot.common.mvc.exception.handler;
+
+import com.zsvg.vboot.common.mvc.exception.BadRequestException;
+import com.zsvg.vboot.common.mvc.exception.EntityExistException;
+import com.zsvg.vboot.common.mvc.exception.EntityNotFoundException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.Objects;
+
+import static org.springframework.http.HttpStatus.NOT_FOUND;
+
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+ /**
+ * 处理所有不可知的异常
+ */
+ @ExceptionHandler(Throwable.class)
+ public ResponseEntity handleException(Throwable e){
+ // 打印堆栈信息
+ log.error(ThrowableUtil.getStackTrace(e));
+ return buildResponseEntity(ApiError.error(e.getMessage()));
+ }
+
+ /**
+ * BadCredentialsException
+ */
+ @ExceptionHandler(BadCredentialsException.class)
+ public ResponseEntity badCredentialsException(BadCredentialsException e){
+ // 打印堆栈信息
+ String message = "坏的凭证".equals(e.getMessage()) ? "用户名或密码不正确" : e.getMessage();
+ log.error(message);
+ return buildResponseEntity(ApiError.error(message));
+ }
+
+ /**
+ * 处理自定义异常
+ */
+ @ExceptionHandler(value = BadRequestException.class)
+ public ResponseEntity badRequestException(BadRequestException e) {
+ // 打印堆栈信息
+ log.error(ThrowableUtil.getStackTrace(e));
+ return buildResponseEntity(ApiError.error(e.getStatus(),e.getMessage()));
+ }
+
+ /**
+ * 处理 EntityExist
+ */
+ @ExceptionHandler(value = EntityExistException.class)
+ public ResponseEntity entityExistException(EntityExistException e) {
+ // 打印堆栈信息
+ log.error(ThrowableUtil.getStackTrace(e));
+ return buildResponseEntity(ApiError.error(e.getMessage()));
+ }
+
+ /**
+ * 处理 EntityNotFound
+ */
+ @ExceptionHandler(value = EntityNotFoundException.class)
+ public ResponseEntity entityNotFoundException(EntityNotFoundException e) {
+ // 打印堆栈信息
+ log.error(ThrowableUtil.getStackTrace(e));
+ return buildResponseEntity(ApiError.error(NOT_FOUND.value(),e.getMessage()));
+ }
+
+ /**
+ * 处理所有接口数据验证异常
+ */
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
+ // 打印堆栈信息
+ log.error(ThrowableUtil.getStackTrace(e));
+ String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\.");
+ String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
+ String msg = "不能为空";
+ if(msg.equals(message)){
+ message = str[1] + ":" + message;
+ }
+ return buildResponseEntity(ApiError.error(message));
+ }
+
+ /**
+ * 统一返回
+ */
+ private ResponseEntity buildResponseEntity(ApiError apiError) {
+ return new ResponseEntity<>(apiError, HttpStatus.valueOf(apiError.getStatus()));
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/ThrowableUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/ThrowableUtil.java
new file mode 100644
index 0000000..252de81
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/exception/handler/ThrowableUtil.java
@@ -0,0 +1,18 @@
+package com.zsvg.vboot.common.mvc.exception.handler;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public class ThrowableUtil {
+
+ /**
+ * 获取堆栈信息
+ */
+ public static String getStackTrace(Throwable throwable){
+ StringWriter sw = new StringWriter();
+ try (PrintWriter pw = new PrintWriter(sw)) {
+ throwable.printStackTrace(pw);
+ return sw.toString();
+ }
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/others/MapHelper.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/others/MapHelper.java
new file mode 100644
index 0000000..5dfc661
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/others/MapHelper.java
@@ -0,0 +1,34 @@
+package com.zsvg.vboot.common.mvc.others;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MapHelper {
+ private Map map;
+
+ public MapHelper(){
+ map = new LinkedHashMap<>();
+ }
+
+ public MapHelper(String field,String title){
+ map = new LinkedHashMap<>();
+ map.put("field", field);
+ map.put("title", title);
+ }
+
+ public MapHelper put(String key,String value){
+ map.put(key, value);
+ return this;
+ }
+
+ public Map get(){
+ return map;
+ }
+
+ public MapHelper addTo(List list){
+ list.add(map);
+ return this;
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Zconn.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Zconn.java
new file mode 100644
index 0000000..7203c50
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Zconn.java
@@ -0,0 +1,72 @@
+package com.zsvg.vboot.common.mvc.pojo;
+
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Zconn {
+ private String type;
+
+ private String url;
+
+ private String username;
+
+ private String passcode;
+
+
+
+ public String getSid()
+ {
+ if(isMysql())
+ {
+ return url.substring(url.lastIndexOf("/")+1).replaceAll("/","");
+ }
+ else if (isOracle())
+ {
+ return url.substring(url.lastIndexOf(":")+1);
+ }
+ else if (isDB2())
+ {
+ return url.substring(url.lastIndexOf("/")+1);
+ }
+ else{
+ return null;
+ }
+ }
+
+ public String getDriver(){
+ if(isOracle()){
+ return "oracle.jdbc.driver.OracleDriver";
+ }else if(isMysql()){
+ return "com.mysql.jdbc.Driver";
+ }else if(isMysql8()){
+ return "com.mysql.cj.jdbc.Driver";
+ }else if(isDB2()){
+ return "com.ibm.db2.jcc.DB2Driver";
+ }else{
+ return "暂不支持";
+ }
+ }
+
+ public boolean isOracle()
+ {
+ return "ORACLE".equals(type);
+ }
+ public boolean isMysql()
+ {
+ return "MYSQL".equals(type);
+ }
+ public boolean isMysql8()
+ {
+ return "MYSQL8".equals(type);
+ }
+ public boolean isDB2()
+ {
+ return "DB2".equals(type);
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/ZidName.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/ZidName.java
new file mode 100644
index 0000000..155c42a
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/ZidName.java
@@ -0,0 +1,47 @@
+package com.zsvg.vboot.common.mvc.pojo;
+
+
+public class ZidName
+{
+ private String id;
+ private String name;
+
+ @Override
+ public String toString() {
+ return "ZidName{" +
+ "id='" + id + '\'' +
+ ", name='" + name + '\'' +
+ '}';
+ }
+
+ public ZidName(String id, String name)
+ {
+ this.id = id;
+ this.name = name;
+ }
+
+ public ZidName()
+ {
+ }
+
+ //get and set-------
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Zinp.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Zinp.java
new file mode 100644
index 0000000..ab52953
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Zinp.java
@@ -0,0 +1,49 @@
+package com.zsvg.vboot.common.mvc.pojo;
+
+public class Zinp {
+ private String id;
+ private String name;
+ private String pid;
+
+ public Zinp() {
+ }
+
+ public Zinp(String id) {
+ this.id = id;
+ }
+
+ public Zinp(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public Zinp(String id, String name, String pid) {
+ this.id = id;
+ this.name = name;
+ this.pid = pid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPid() {
+ return pid;
+ }
+
+ public void setPid(String pid) {
+ this.pid = pid;
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Ztree.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Ztree.java
new file mode 100644
index 0000000..ab8f2af
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/pojo/Ztree.java
@@ -0,0 +1,23 @@
+package com.zsvg.vboot.common.mvc.pojo;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class Ztree {
+ private String id;
+
+ private String name;
+
+ @JsonIgnore
+ private String pid;
+
+ private List children;
+
+ private Map data;
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseCateService.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseCateService.java
new file mode 100644
index 0000000..bcb69d2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseCateService.java
@@ -0,0 +1,229 @@
+package com.zsvg.vboot.common.mvc.service;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.mvc.pojo.ZidName;
+import com.zsvg.vboot.common.mvc.pojo.Ztree;
+import com.zsvg.vboot.common.mvc.entity.BaseCateEntity;
+import com.zsvg.vboot.common.mvc.api.PageData;
+import com.zsvg.vboot.common.mvc.pojo.Zinp;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import com.zsvg.vboot.common.util.web.XuserUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Transactional(rollbackFor = Exception.class)
+public abstract class BaseCateService {
+
+ @Transactional(readOnly = true)
+ public PageData findPageData(Sqler sqler) {
+ sqler.selectCUinfo().addSelect("t.label");
+ sqler.addOrder("t.ornum");
+ return jdbcDao.findPageData(sqler);
+ }
+
+ @Transactional(readOnly = true)
+ public List findIdNameRes(Sqler sqler) {
+ return jdbcDao.findIdNameList(sqler);
+ }
+
+
+
+ //用户编辑时选择父类别,不能选择自己及孩子节点,否则会造成无线循环
+ @Transactional(readOnly = true)
+ public List inpChoose(String table, String id, String name){
+ Sqler sqler = new Sqler(table);
+ sqler.addSelect("pid");
+ sqler.addWhere("t.avtag = 1");
+ if (XstringUtil.isNotBlank(id)) {
+ sqler.addWhere("t.tier not like ?", "%;" + id + ";%");
+ sqler.addWhere("t.id <> ?", id);
+ }
+ if(XstringUtil.isNotBlank(name)){
+ sqler.addLike("t.name", name);
+ }
+ sqler.addOrder("t.ornum");
+ return jdbcDao.findInpList(sqler);
+ }
+
+ @Transactional(readOnly = true)
+ public List tier2Choose(String table, String id, String name){
+ Sqler sqler = new Sqler(table);
+ sqler.addSelect("pid");
+ sqler.addWhere("t.avtag = 1");
+ if (XstringUtil.isNotBlank(id)) {
+ sqler.addWhere("t.tier not like ?", "%;" + id + ";%");
+ sqler.addWhere("t.id <> ?", id);
+ }
+ if(XstringUtil.isNotBlank(name)){
+ sqler.addLike("t.name", name);
+ }
+ sqler.addOrder("t.ornum");
+ return jdbcDao.findTreeList(sqler);
+ }
+
+
+ @Transactional(readOnly = true)
+ public RestResult inpFind(String table){
+ Sqler sqlHelper = new Sqler(table);
+ sqlHelper.addSelect("pid");
+ sqlHelper.addWhere("t.avtag = 1");
+ sqlHelper.addOrder("t.ornum");
+ return RestResult.ok(jdbcDao.findInpList(sqlHelper));
+ }
+
+ public RestResult inpDele(String table, String id){
+ String sql = "select id from " + table + " where tier like ? order by tier";
+ List stringList = jdbcDao.findStringList(sql, "%;" + id + ";%");
+ for (String sid : stringList) {
+ repo.deleteById(sid);
+ }
+ repo.deleteById(id);
+ return RestResult.ok();
+ }
+
+ public String insert(T cate) {
+ if(cate.getId()==null||"".equals(cate.getId())){
+ cate.setId(XstringUtil.getUUID());
+ }
+ if(cate.getCrman()==null){
+ cate.setCrman(XuserUtil.getUser());
+ }
+ if (cate.getParent() != null) {
+ T parent = repo.findById(cate.getParent().getId()).get();
+ cate.setTier(parent.getTier()+parent.getId()+ ";");
+ } else {
+ cate.setTier("null;");
+ }
+ repo.save(cate);
+ return cate.getId();
+ }
+
+ public String update(T cate){
+ cate.setUptim(new Date());
+ if(cate.getUpman()==null){
+ cate.setUpman(XuserUtil.getUser());
+ }
+ repo.save(cate);
+ return cate.getId();
+ }
+
+
+ public String update(T cate,String table){
+ cate.setUptim(new Date());
+ if(cate.getUpman()==null){
+ cate.setUpman(XuserUtil.getUser());
+ }
+ String newPid = "";
+ if(cate.getParent()!=null){
+ newPid=cate.getParent().getId();
+ }
+ T oldCate=repo.findById(cate.getId()).get();
+ String oldPid="";
+ if(oldCate.getParent()!=null){
+ oldPid =oldCate.getParent().getId();
+ }
+ String oldTier=oldCate.getTier();
+ if(oldPid.equals(newPid)){//如果父节点没有变,则只更新自己
+// System.out.println("父节点没有变");
+ cate.setTier(oldTier);
+ repo.save(cate);
+ }else{//如果父节点变了,则另外需要更新自己孩子节点的tier层级
+ String newTier = "null;";
+ if(cate.getParent()!=null){
+// System.out.println("父节点变成其他点了");
+ T newParentCate=repo.findById(cate.getParent().getId()).get();
+ newTier =newParentCate.getTier()+newParentCate.getId()+";";
+ }else{
+// System.out.println("父节点变成更节点了");
+ }
+ cate.setTier(newTier);
+ repo.save(cate);
+ //更新子节点
+ String sql = "select id,tier as name from " + table + " where tier like ? and id<>?";
+// System.out.println(sql);
+ List list = jdbcDao.findIdNameList(sql, oldTier+oldCate.getId()+";%",cate.getId());
+
+ String updateSql = "update " + table + " set tier=? where id=?";
+ List updateList = new ArrayList();
+ for (ZidName ztwo : list) {
+ Object[] arr = new Object[2];
+ arr[0] = ztwo.getName().replace(oldTier,newTier);
+ arr[1] = ztwo.getId();
+ updateList.add(arr);
+ }
+ jdbcDao.batch(updateSql, updateList);
+ }
+ return cate.getId();
+
+ }
+
+ @Autowired
+ protected JdbcDao jdbcDao;
+
+ protected JpaRepository repo;
+
+ public void setRepo(JpaRepository repo) {
+ this.repo = repo;
+ }
+
+// public T save(T t) {
+// return repo.save(t);
+// }
+//
+// public T update(T t) {
+// return repo.saveAndFlush(t);
+// }
+//
+ @Transactional(readOnly = true)
+ public T findOne(String id) {
+ return repo.findById(id).get();
+ }
+
+ public int delete(String[] ids) {
+ for (String id : ids) {
+ repo.deleteById(id);
+ }
+ return ids.length;
+ }
+//
+// public void deleteOne(T t) {
+// repo.delete(t);
+// }
+//
+//// public boolean exists(String id) {
+//// return baseDao.exists(id);
+//// }
+//
+// public long count() {
+// return baseDao.count();
+// }
+//
+// public List findAll() {
+// return baseDao.findAll();
+// }
+//
+// public List findAll(Sort sort) {
+// return baseDao.findAll(sort);
+// }
+//
+// public List findAll(Specification specification) {
+// // TODO Auto-generated method stub
+// return null;
+// }
+//
+// public Page findAll(Pageable pageable) {
+// return baseDao.findAll(pageable);
+// }
+//
+// public Page findAll(Specification specification, Pageable pageable) {
+// // TODO Auto-generated method stub
+// return null;
+// }
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseMainService.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseMainService.java
new file mode 100644
index 0000000..8ca761e
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseMainService.java
@@ -0,0 +1,98 @@
+package com.zsvg.vboot.common.mvc.service;
+
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.mvc.entity.BaseMainEntity;
+import com.zsvg.vboot.common.mvc.api.PageData;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import com.zsvg.vboot.common.util.web.XuserUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@Transactional(rollbackFor = Exception.class)
+public abstract class BaseMainService {
+
+ //---------------------------------------查询-------------------------------------
+ @Transactional(readOnly = true)
+ public PageData findPageData(Sqler sqler) {
+ if (sqler.getAutoType() == 1) {
+ sqler.selectCUinfo();
+ sqler.addOrder("t.crtim desc");
+ }
+ return jdbcDao.findPageData(sqler);
+ }
+
+ @Transactional(readOnly = true)
+ public List> findMapList(Sqler sqler) {
+ return jdbcDao.findMapList(sqler);
+ }
+
+ @Transactional(readOnly = true)
+ public List> findMapList(String sql, Object... args) {
+ return jdbcDao.findMapList(sql, args);
+ }
+
+ @Transactional(readOnly = true)
+ public boolean existsById(String id) {
+ return repo.existsById(id);
+ }
+
+ @Transactional(readOnly = true)
+ public T findOne(String id) {
+ return repo.findById(id).get();
+ }
+
+ @Transactional(readOnly = true)
+ public List findAll() {
+ return repo.findAll();
+ }
+
+ //---------------------------------------增删改-------------------------------------
+ public T insert(T main) {
+ if (main.getId() == null || "".equals(main.getId())) {
+ main.setId(XstringUtil.getUUID());
+ }
+ main.setCrtim(new Date());
+ if (main.getCrman() == null) {
+ main.setCrman(XuserUtil.getUser());
+ }
+ return repo.save(main);
+ }
+
+ public int delete(String[] ids) {
+ for (String id : ids) {
+ repo.deleteById(id);
+ }
+ return ids.length;
+ }
+
+ public T update(T main) {
+ main.setUptim(new Date());
+ if (main.getUpman() == null) {
+ main.setUpman(XuserUtil.getUser());
+ }
+ return repo.save(main);
+ }
+
+ public T save(T t) {
+ return repo.save(t);
+ }
+
+
+ //---------------------------------------bean注入-------------------------------------
+ @Autowired
+ protected JdbcDao jdbcDao;
+
+ protected JpaRepository repo;
+
+ public void setRepo(JpaRepository repo) {
+ this.repo = repo;
+ }
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseService.java b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseService.java
new file mode 100644
index 0000000..7a32a7d
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/mvc/service/BaseService.java
@@ -0,0 +1,85 @@
+package com.zsvg.vboot.common.mvc.service;
+
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.mvc.api.PageData;
+import com.zsvg.vboot.common.mvc.entity.BaseEntity;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+@Transactional(rollbackFor = Exception.class)
+public abstract class BaseService {
+
+ //---------------------------------------查询-------------------------------------
+ @Transactional(readOnly = true)
+ public PageData findPageData(Sqler sqler) {
+ return jdbcDao.findPageData(sqler);
+ }
+
+ @Transactional(readOnly = true)
+ public List> findMapList(Sqler sqler) {
+ return jdbcDao.findMapList(sqler);
+ }
+
+ @Transactional(readOnly = true)
+ public List> findMapList(String sql,Object... args) {
+ return jdbcDao.findMapList(sql,args);
+ }
+
+ @Transactional(readOnly = true)
+ public boolean existsById(String id) {
+ return repo.existsById(id);
+ }
+
+ @Transactional(readOnly = true)
+ public T findOne(String id) {
+ return repo.findById(id).get();
+ }
+
+ @Transactional(readOnly = true)
+ public List findAll() {
+ return repo.findAll();
+ }
+
+
+ //---------------------------------------增删改-------------------------------------
+ public T insert(T main) {
+ if (main.getId() == null||"".equals(main.getId())) {
+ main.setId(XstringUtil.getUUID());
+ }
+ return repo.save(main);
+ }
+
+ public int delete(String[] ids) {
+ for (String id : ids) {
+ repo.deleteById(id);
+ }
+ return ids.length;
+ }
+
+ public T update(T main) {
+ return repo.save(main);
+ }
+
+ public T save(T t) {
+ return repo.save(t);
+ }
+
+
+ //---------------------------------------bean注入-------------------------------------
+ @Autowired
+ protected JdbcDao jdbcDao;
+
+ protected JpaRepository repo;
+
+ public void setRepo(JpaRepository repo) {
+ this.repo = repo;
+ }
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XexcelUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XexcelUtil.java
new file mode 100644
index 0000000..e6f595a
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XexcelUtil.java
@@ -0,0 +1,159 @@
+package com.zsvg.vboot.common.util.file;
+
+import com.zsvg.vboot.common.util.lang.XdateUtil;
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.util.Iterator;
+
+@SuppressWarnings("unchecked")
+public class XexcelUtil
+{
+ //转换列数字序号列字母序号
+ public static String excelColIndexToStr(int columnIndex)
+ {
+ if (columnIndex <= 0)
+ {
+ return null;
+ }
+ String columnStr = "";
+ columnIndex--;
+ do
+ {
+ if (columnStr.length() > 0)
+ {
+ columnIndex--;
+ }
+ columnStr = ((char) (columnIndex % 26 + (int) 'A')) + columnStr;
+ columnIndex = ((columnIndex - columnIndex % 26) / 26);
+ } while (columnIndex > 0);
+ return columnStr;
+ }
+
+
+ //---------------------以下为EXCEL复制功能-----------------
+
+
+ //行复制功能
+ public static void copyRow(Row fromRow, Row toRow, boolean copyValueFlag) {
+ toRow.setHeight(fromRow.getHeight());
+ for(Iterator cellIt = fromRow.cellIterator(); cellIt.hasNext(); ) {
+ Cell tmpCell = (Cell) cellIt.next();
+ Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
+ copyCell(tmpCell, newCell, copyValueFlag);
+ }
+ Sheet worksheet = fromRow.getSheet();
+ for(int i = 0; i < worksheet.getNumMergedRegions(); i++) {
+ CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i);
+ if(cellRangeAddress.getFirstRow() == fromRow.getRowNum()) {
+ CellRangeAddress newCellRangeAddress = new CellRangeAddress(toRow.getRowNum(), (toRow.getRowNum() +
+ (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())), cellRangeAddress
+ .getFirstColumn(), cellRangeAddress.getLastColumn());
+ worksheet.addMergedRegionUnsafe(newCellRangeAddress);
+ }
+ }
+ }
+
+ //复制单元格 true则连同cell的内容一起复制
+ public static void copyCell(Cell srcCell, Cell distCell, boolean copyValueFlag) {
+ //样式
+ distCell.setCellStyle(srcCell.getCellStyle());
+ //评论
+ if(srcCell.getCellComment() != null) {
+ distCell.setCellComment(srcCell.getCellComment());
+ }
+ // 不同数据类型处理
+ CellType srcCellType = srcCell.getCellTypeEnum();
+ distCell.setCellType(srcCellType);
+ if(copyValueFlag) {
+ if(srcCellType == CellType.NUMERIC) {
+ if(DateUtil.isCellDateFormatted(srcCell)) {
+ distCell.setCellValue(srcCell.getDateCellValue());
+ } else {
+ distCell.setCellValue(srcCell.getNumericCellValue());
+ }
+ } else if(srcCellType == CellType.STRING) {
+ distCell.setCellValue(srcCell.getRichStringCellValue());
+ } else if(srcCellType == CellType.BLANK) {
+
+ } else if(srcCellType == CellType.BOOLEAN) {
+ distCell.setCellValue(srcCell.getBooleanCellValue());
+ } else if(srcCellType == CellType.ERROR) {
+ distCell.setCellErrorValue(srcCell.getErrorCellValue());
+ } else if(srcCellType == CellType.FORMULA) {
+ distCell.setCellFormula(srcCell.getCellFormula());
+ } else {
+ }
+ }
+ }
+
+ //复制单元格 true则连同cell的内容一起复制
+ public static HSSFCellStyle createCellStyle(HSSFWorkbook workbook,short index)
+ {
+ HSSFCellStyle style = workbook.createCellStyle();
+ style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+ style.setFillForegroundColor(index);
+ style.setBorderBottom(BorderStyle.HAIR);
+ style.setBorderTop(BorderStyle.HAIR);
+ style.setBorderLeft(BorderStyle.HAIR);
+ style.setBorderRight(BorderStyle.HAIR);
+ return style;
+ }
+
+ public static Object getCellValue(Cell cell)
+ {
+ Object back = null;
+ if (null != cell)
+ {
+ switch (cell.getCellType())
+ {
+ case Cell.CELL_TYPE_BLANK:
+ back = null;
+ break;
+ case Cell.CELL_TYPE_BOOLEAN:
+ back = Boolean.toString(cell.getBooleanCellValue());
+ break;
+ //数值
+ case Cell.CELL_TYPE_NUMERIC:
+ if (DateUtil.isCellDateFormatted(cell))
+ {
+ back = XdateUtil.getDate(cell.getDateCellValue());
+ } else
+ {
+ cell.setCellType(Cell.CELL_TYPE_STRING);
+ String temp = cell.getStringCellValue();
+ //判断是否包含小数点,如果不含小数点,则以字符串读取,如果含小数点,则转换为Double类型的字符串
+ if (temp.indexOf(".") > -1)
+ {
+ back = String.valueOf(new Double(temp)).trim();
+ } else
+ {
+ back = temp.trim();
+ }
+ }
+ break;
+ case Cell.CELL_TYPE_STRING:
+ back = cell.getStringCellValue().trim();
+ if ("".equals(back))
+ {
+ back = null;
+ }
+ break;
+ case Cell.CELL_TYPE_ERROR:
+ back = null;
+ break;
+ case Cell.CELL_TYPE_FORMULA:
+ cell.setCellType(Cell.CELL_TYPE_STRING);
+ back = cell.getStringCellValue();
+ break;
+ default:
+ back = null;
+ break;
+ }
+ }
+ return back;
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XfileUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XfileUtil.java
new file mode 100644
index 0000000..d633fc2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XfileUtil.java
@@ -0,0 +1,76 @@
+package com.zsvg.vboot.common.util.file;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.text.DecimalFormat;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class XfileUtil
+{
+ public static String getFileSize(long fileS)
+ {
+ String size = "";
+ DecimalFormat df = new DecimalFormat("#.00");
+ if (fileS < 1024)
+ {
+ size = df.format((double) fileS) + "B";
+ } else if (fileS < 1048576)
+ {
+ size = df.format((double) fileS / 1024) + "KB";
+ } else if (fileS < 1073741824)
+ {
+ size = df.format((double) fileS / 1048576) + "MB";
+ } else
+ {
+ size = df.format((double) fileS / 1073741824) + "GB";
+ }
+ return size;
+ }
+
+ public static void unZipFiles(File zipFile,String descDir)throws IOException
+ {
+ File pathFile = new File(descDir);
+ if(!pathFile.exists())
+ {
+ pathFile.mkdirs();
+ }
+ //解决zip文件中有中文目录或者中文文件
+ ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
+ for(Enumeration entries = zip.entries(); entries.hasMoreElements();)
+ {
+ ZipEntry entry = (ZipEntry)entries.nextElement();
+ String zipEntryName = entry.getName();
+ int len2=zipEntryName.split("/")[0].length();
+ zipEntryName = zipEntryName.substring(len2, zipEntryName.length());
+ System.out.println(zipEntryName);
+ InputStream in = zip.getInputStream(entry);
+ String outPath = (descDir+zipEntryName).replaceAll("\\*", "/");;
+ //判断路径是否存在,不存在则创建文件路径
+ File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
+ if(!file.exists())
+ {
+ file.mkdirs();
+ }
+ //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
+ if(new File(outPath).isDirectory())
+ {
+ continue;
+ }
+ //输出文件路径信息
+// System.out.println(outPath);
+ OutputStream out = new FileOutputStream(outPath);
+ byte[] buf1 = new byte[1024];
+ int len;
+ while((len=in.read(buf1))>0)
+ {
+ out.write(buf1,0,len);
+ }
+ in.close();
+ out.close();
+ }
+// System.out.println("******************解压完毕********************");
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XpdfUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XpdfUtil.java
new file mode 100644
index 0000000..556cbcf
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XpdfUtil.java
@@ -0,0 +1,104 @@
+package com.zsvg.vboot.common.util.file;
+
+import com.itextpdf.text.BaseColor;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.pdf.BaseFont;
+import com.itextpdf.text.pdf.PdfContentByte;
+import com.itextpdf.text.pdf.PdfGState;
+import com.itextpdf.text.pdf.PdfReader;
+import com.itextpdf.text.pdf.PdfStamper;
+
+import java.io.*;
+
+public class XpdfUtil {
+// public static void main(String[] args) throws IOException {
+// setWatermark(new BufferedOutputStream(new FileOutputStream(new File("D:\\bb.pdf"))),
+// new FileInputStream("D:\\aa.pdf"), "借阅借阅水印借阅水印借阅水印水印", 1);
+// }
+
+
+ /**
+ * 中间或者两边水印
+ * @param bos 添加完水印的输出
+ * @param input 原PDF文件输入
+ * @param word 水印内容
+ * @param model 水印添加位置1中间,2两边
+ */
+ public static void setWatermark(BufferedOutputStream bos, InputStream input, String word, int model) {
+ PdfReader reader = null;
+ try {
+ reader = new PdfReader(input);
+ PdfStamper stamper = new PdfStamper(reader, bos);
+ PdfContentByte content;
+ // 创建字体,第一个参数是字体路径,itext有一些默认的字体比如说:
+// BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
+ //2 BaseFont base = BaseFont.createFont("/msyh.ttf", BaseFont.IDENTITY_H,
+ // BaseFont.EMBEDDED);
+ //这个是为了解决linux服务器,水印乱码问题,如果是windows服务器,用第一个就可以。
+ // 需要指定的字体,用第2,3个写法,在resources文件夹下放置对应字体就行。
+
+// BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
+ BaseFont base = BaseFont.createFont("C:/WINDOWS/Fonts/simhei.ttf", BaseFont.IDENTITY_H,BaseFont.EMBEDDED);
+// BaseFont base = BaseFont.createFont();
+
+ PdfGState gs = new PdfGState();
+ // 获取PDF页数
+ int total = reader.getNumberOfPages();
+ // 遍历每一页
+ for (int i = 0; i < total; i++) {
+ // 页宽度
+ float width = reader.getPageSize(i + 1).getWidth();
+ // 页高度
+ float height = reader.getPageSize(i + 1).getHeight();
+ // 内容
+ content = stamper.getOverContent(i + 1);
+ //开始写入文本
+ content.beginText();
+ //水印透明度
+ gs.setFillOpacity(0.2f);
+ content.setGState(gs);
+ content.setColorFill(BaseColor.LIGHT_GRAY);
+ //设置字体的输出位置
+ content.setTextMatrix(70, 200);
+
+ if (model == 1) {
+ //平行居中的3条水印
+ //字体大小
+ content.setFontAndSize(base, 50);
+ //showTextAligned 方法的参数分别是(文字对齐方式,位置内容,输出水印X轴位置,Y轴位置,旋转角度)
+ content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 650, 30);
+ content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 400, 30);
+ content.showTextAligned(Element.ALIGN_CENTER, word, width / 2, 150, 30);
+ } else {
+ // 左右两边个从上到下4条水印
+ // 水印旋转度数
+ float rotation = 30;
+ content.setFontAndSize(base, 20);
+ content.showTextAligned(Element.ALIGN_LEFT, word, 20, height - 50, rotation);
+ content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 4 * 3 - 50, rotation);
+ content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 2 - 50, rotation);
+ content.showTextAligned(Element.ALIGN_LEFT, word, 20, height / 4 - 50, rotation);
+
+ content.setFontAndSize(base, 22);
+ content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height - 50, rotation);
+ content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 4 * 3 - 50, rotation);
+ content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 2 - 50, rotation);
+ content.showTextAligned(Element.ALIGN_RIGHT, word, width - 20, height / 4 - 50, rotation);
+ }
+ //结束写入文本
+ content.endText();
+ //要打图片水印的话
+ //Image image = Image.getInstance("c:/1.jpg");
+ //content.addImage(image);
+ }
+ stamper.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (DocumentException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XqcodeUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XqcodeUtil.java
new file mode 100644
index 0000000..611c79f
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/file/XqcodeUtil.java
@@ -0,0 +1,111 @@
+package com.zsvg.vboot.common.util.file;
+
+import com.google.zxing.*;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.HybridBinarizer;
+import com.google.zxing.qrcode.QRCodeReader;
+import com.google.zxing.qrcode.QRCodeWriter;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.Hashtable;
+
+public class XqcodeUtil {
+ /**
+ * 生成包含字符串信息的二维码图片
+ * @param outputStream 文件输出流路径
+ * @param content 二维码携带信息
+ * @param qrCodeSize 二维码图片大小
+ * @param imageFormat 二维码的格式
+ * @throws WriterException
+ * @throws IOException
+ */
+ public static boolean createQrCode(OutputStream outputStream, String content, int qrCodeSize, String imageFormat) throws WriterException, IOException{
+ //设置二维码纠错级别MAP
+ Hashtable hintMap = new Hashtable();
+ hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 矫错级别
+ QRCodeWriter qrCodeWriter = new QRCodeWriter();
+ //创建比特矩阵(位矩阵)的QR码编码的字符串
+ BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
+ // 使BufferedImage勾画QRCode (matrixWidth 是行二维码像素点)
+ int matrixWidth = byteMatrix.getWidth();
+ BufferedImage image = new BufferedImage(matrixWidth-200, matrixWidth-200, BufferedImage.TYPE_INT_RGB);
+ image.createGraphics();
+ Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setColor(Color.WHITE);
+ graphics.fillRect(0, 0, matrixWidth, matrixWidth);
+ // 使用比特矩阵画并保存图像
+ graphics.setColor(Color.BLACK);
+ for (int i = 0; i < matrixWidth; i++){
+ for (int j = 0; j < matrixWidth; j++){
+ if (byteMatrix.get(i, j)){
+ graphics.fillRect(i-100, j-100, 1, 1);
+ }
+ }
+ }
+ return ImageIO.write(image, imageFormat, outputStream);
+ }
+
+
+ public static InputStream createQrCode(String content, int qrCodeSize, String imageFormat) throws WriterException, IOException{
+ //设置二维码纠错级别MAP
+ Hashtable hintMap = new Hashtable();
+ hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 矫错级别
+ QRCodeWriter qrCodeWriter = new QRCodeWriter();
+ //创建比特矩阵(位矩阵)的QR码编码的字符串
+ BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
+ // 使BufferedImage勾画QRCode (matrixWidth 是行二维码像素点)
+ int matrixWidth = byteMatrix.getWidth();
+ BufferedImage image = new BufferedImage(matrixWidth-200, matrixWidth-200, BufferedImage.TYPE_INT_RGB);
+ image.createGraphics();
+ Graphics2D graphics = (Graphics2D) image.getGraphics();
+ graphics.setColor(Color.WHITE);
+ graphics.fillRect(0, 0, matrixWidth, matrixWidth);
+ // 使用比特矩阵画并保存图像
+ graphics.setColor(Color.BLACK);
+ for (int i = 0; i < matrixWidth; i++){
+ for (int j = 0; j < matrixWidth; j++){
+ if (byteMatrix.get(i, j)){
+ graphics.fillRect(i-100, j-100, 1, 1);
+ }
+ }
+ }
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ ImageIO.write(image, imageFormat, os);
+ return new ByteArrayInputStream(os.toByteArray());
+ }
+
+
+ /**
+ * 读二维码并输出携带的信息
+ */
+ public static void readQrCode(InputStream inputStream) throws IOException{
+ //从输入流中获取字符串信息
+ BufferedImage image = ImageIO.read(inputStream);
+ //将图像转换为二进制位图源
+ LuminanceSource source = new BufferedImageLuminanceSource(image);
+ BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ QRCodeReader reader = new QRCodeReader();
+ Result result = null ;
+ try {
+ result = reader.decode(bitmap);
+ } catch (ReaderException e) {
+ e.printStackTrace();
+ }
+// System.out.println(result.getText());
+ }
+
+ /**
+ * 测试代码
+ * @throws WriterException
+ */
+ public static void main(String[] args) throws IOException, WriterException {
+ createQrCode(new FileOutputStream(new File("d:\\qrcode.jpg")),"WE1231238239128sASDASDSADSDWEWWREWRERWSDFDFSDSDF123123123123213123",900,"JPEG");
+ readQrCode(new FileInputStream(new File("d:\\qrcode.jpg")));
+ }
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XdateUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XdateUtil.java
new file mode 100644
index 0000000..380a6fb
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XdateUtil.java
@@ -0,0 +1,162 @@
+package com.zsvg.vboot.common.util.lang;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public class XdateUtil {
+
+ public static XMLGregorianCalendar dateToXmlDate(Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ DatatypeFactory dtf = null;
+ try {
+ dtf = DatatypeFactory.newInstance();
+ } catch (DatatypeConfigurationException e) {
+ }
+ XMLGregorianCalendar dateType = dtf.newXMLGregorianCalendar();
+ dateType.setYear(cal.get(Calendar.YEAR));
+ //由于Calendar.MONTH取值范围为0~11,需要加1
+ dateType.setMonth(cal.get(Calendar.MONTH) + 1);
+ dateType.setDay(cal.get(Calendar.DAY_OF_MONTH));
+ dateType.setHour(cal.get(Calendar.HOUR_OF_DAY));
+ dateType.setMinute(cal.get(Calendar.MINUTE));
+ dateType.setSecond(cal.get(Calendar.SECOND));
+ return dateType;
+ }
+
+ public static Date xmlDate2Date(XMLGregorianCalendar cal) {
+ return cal.toGregorianCalendar().getTime();
+ }
+
+ public static String getYYYY() {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
+ return dateFormat.format(new Date());
+ }
+
+ public static String getYYYYMM() {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");
+ return dateFormat.format(new Date());
+ }
+
+ public static String getMM() {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("MM");
+ return dateFormat.format(new Date());
+ }
+
+ public static String getDD() {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("dd");
+ return dateFormat.format(new Date());
+ }
+
+ public static Date strToDate(String strDate) {
+ if (XstringUtil.isBlank(strDate)) {
+ return null;
+ }
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ ParsePosition pos = new ParsePosition(0);
+ Date strtodate = formatter.parse(strDate, pos);
+ return strtodate;
+ }
+
+ public static Date strToDateBySap(String strDate) {
+ if (XstringUtil.isBlank(strDate)) {
+ return null;
+ }
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
+ ParsePosition pos = new ParsePosition(0);
+ Date strtodate = formatter.parse(strDate, pos);
+ return strtodate;
+ }
+
+ public static String getDate() {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ return dateFormat.format(new Date());
+ }
+
+ public static String getDate(int i) {
+ Calendar c = Calendar.getInstance();
+ int day = c.get(Calendar.DATE);
+ c.set(Calendar.DATE, day + i);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ return dateFormat.format(c.getTime());
+ }
+
+ public static String getSapDate(int i) {
+ Calendar c = Calendar.getInstance();
+ int day = c.get(Calendar.DATE);
+ c.set(Calendar.DATE, day + i);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ return dateFormat.format(c.getTime());
+ }
+
+ public static String getDate(String geshi) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(geshi);
+ return dateFormat.format(new Date());
+ }
+
+ public static String getDate(Date date) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ return dateFormat.format(date);
+ }
+
+
+ public static int getDifferDays(Date data1, Date date2) {
+ if (null == data1 || null == date2) {
+ return -1;
+
+ }
+ long intervalMilli = data1.getTime() - date2.getTime();
+ return (int) (intervalMilli / (24 * 60 * 60 * 1000));
+ }
+
+ public static int getDifferDays(String strDate1, String strDate2) {
+ Date date1 = strToDate(strDate1);
+ Date date2 = strToDate(strDate2);
+ if (null == date1 || null == date2) {
+ return -1;
+ }
+ long intervalMilli = date1.getTime() - date2.getTime();
+ return (int) (intervalMilli / (24 * 60 * 60 * 1000));
+ }
+
+ public static int getDifferDaysBySap(String strDate1, String strDate2) {
+ Date date1 = strToDateBySap(strDate1);
+ Date date2 = strToDateBySap(strDate2);
+ if (null == date1 || null == date2) {
+ return -1;
+ }
+ long intervalMilli = date1.getTime() - date2.getTime();
+ return (int) (intervalMilli / (24 * 60 * 60 * 1000));
+ }
+
+ public static String getStringDateAfterTian(String strDate, int i) {
+ Calendar c = Calendar.getInstance();
+ c.setTime(strToDateBySap(strDate));
+ int day = c.get(Calendar.DATE);
+ c.set(Calendar.DATE, day + i);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
+ return dateFormat.format(c.getTime());
+ }
+
+ public static String getMonthFirstDay() {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
+ Calendar c = Calendar.getInstance();
+ c.add(Calendar.MONTH, 0);
+ c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
+ return format.format(c.getTime());
+ }
+
+ public static String getMonthLastDay() {
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
+ Calendar ca = Calendar.getInstance();
+ ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
+ return format.format(ca.getTime());
+ }
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XjsonUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XjsonUtil.java
new file mode 100644
index 0000000..3b08cb9
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XjsonUtil.java
@@ -0,0 +1,70 @@
+package com.zsvg.vboot.common.util.lang;
+
+import com.zsvg.vboot.common.mvc.pojo.Zinp;
+import com.zsvg.vboot.common.mvc.pojo.Ztree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class XjsonUtil {
+
+
+ //使用递归方法建树
+ public static List buildByRecursive(List treeNodes) {
+ List trees = new ArrayList<>();
+ for (Ztree treeNode : treeNodes) {
+ if (treeNode.getPid()==null) {
+ trees.add(findChildrenByTier(treeNode,treeNodes));
+ }
+ }
+ return trees;
+ }
+
+
+
+
+ //递归查找子节点
+ public static Ztree findChildrenByTier(Ztree treeNode, List treeNodes) {
+// treeNode.setChildren(new ArrayList<>());
+ for (Ztree it : treeNodes) {
+ if(treeNode.getId().equals(it.getPid())) {
+ if (treeNode.getChildren() == null) {
+ treeNode.setChildren(new ArrayList<>());
+ }
+ treeNode.getChildren().add(findChildrenByTier(it,treeNodes));
+ }
+ }
+ return treeNode;
+ }
+
+
+ //
+ public static List inpToTree(List inpList) {
+ List trees = new ArrayList<>();
+ for (Zinp zinp : inpList) {
+ if (zinp.getPid()==null) {
+ trees.add(findChildrenByTree(zinp,inpList));
+ }
+ }
+ return trees;
+ }
+
+
+ public static Ztree findChildrenByTree(Zinp zinp, List zinpList) {
+// treeNode.setChildren(new ArrayList<>());
+ Ztree ztree =new Ztree();
+ ztree.setId(zinp.getId());
+ ztree.setName(zinp.getName());
+ for (Zinp it : zinpList) {
+ if(zinp.getId().equals(it.getPid())) {
+ if (ztree.getChildren() == null) {
+ ztree.setChildren(new ArrayList<>());
+ }
+ ztree.getChildren().add(findChildrenByTree(it,zinpList));
+ }
+ }
+ return ztree;
+ }
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XmapUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XmapUtil.java
new file mode 100644
index 0000000..0a40562
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XmapUtil.java
@@ -0,0 +1,135 @@
+package com.zsvg.vboot.common.util.lang;
+
+import java.util.HashMap;
+import java.util.Map;
+public class XmapUtil
+{
+ public static String getName(String id)
+ {
+ String[] arr = id.split("/");
+ String back = "";
+ for (int i = 0; i < arr.length; i++)
+ {
+ if (!"".equals(arr[i]))
+ {
+ String mapValue = map.get(arr[i]);
+ if (mapValue != null)
+ {
+ back += map.get(arr[i]) + "-";
+ }
+ else
+ {
+ back += arr[i] + "-";
+ }
+ }
+ }
+ return back.substring(0, back.length() - 1);
+ }
+
+ public static Map map = new HashMap();
+
+ static
+ {
+ //a
+ map.put("admin", "管理员");
+ map.put("address", "地址");
+ map.put("att", "附件");
+ map.put("auth", "认证");
+ map.put("actual", "实际");
+ //b
+ map.put("bar", "块");
+ //c
+ map.put("choose", "选择");
+ map.put("customer", "客户");
+ map.put("config", "配置");
+ map.put("choose_data", "选择数据");
+ //d
+ map.put("demo", "样例");
+ //e
+ map.put("edit", "编辑");
+ map.put("edit_save", "编辑保存");
+
+ //f
+ map.put("file", "文件");
+ map.put("flow", "流程");
+
+ //g
+ map.put("group", "组");
+
+ //l
+ map.put("log", "日志");
+ map.put("login", "登入");
+
+ //i
+ map.put("index", "主页");
+ map.put("info", "信息");
+ //t
+ map.put("task", "任务");
+ map.put("type", "分类");
+
+ //m
+ map.put("mail", "邮箱");
+ map.put("main", "主信息");
+ map.put("move", "移动");
+ map.put("mobile", "移动端");
+ //n
+ map.put("node", "节点");
+
+ //o
+ map.put("org", "组织架构");
+ //p
+ map.put("password", "密码");
+ map.put("product", "产品");
+ map.put("project", "项目");
+ map.put("pp", "生产");
+ //q
+ map.put("quote", "报价");
+
+ //k
+
+ //l
+ map.put("line", "线");
+ map.put("list", "列表");
+ map.put("list_data", "列表数据");
+ map.put("list_dele", "列表删除");
+ map.put("layout", "扶梯排布");
+
+ //r
+ map.put("register", "注册");
+ map.put("report", "报表");
+ map.put("perm", "权限");
+ map.put("role", "角色");
+ map.put("scheme", "方案");
+
+ //s
+ map.put("save", "保存");
+ map.put("sd", "销售");
+ map.put("send", "发送");
+ map.put("set", "设置");
+ map.put("show", "展示");
+ map.put("stock", "股票");
+
+ //t
+ map.put("task", "任务");
+ map.put("template", "模块");
+ map.put("test", "测试");
+ map.put("tool", "工具");
+ map.put("tree", "树");
+ map.put("turn", "转换");
+ map.put("tree_data", "树数据");
+ map.put("tree_move", "树移动");
+ map.put("tree_remove", "树删除");
+
+ //v
+ map.put("view", "查看");
+
+ //w
+ map.put("warn", "警告");
+ map.put("weather", "天气");
+ map.put("write", "撰写");
+
+ }
+
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XnumberUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XnumberUtil.java
new file mode 100644
index 0000000..200b76b
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XnumberUtil.java
@@ -0,0 +1,32 @@
+package com.zsvg.vboot.common.util.lang;
+
+import java.util.Random;
+
+public class XnumberUtil {
+ public static double tsize = 1024L * 1024;
+
+ public static double gsize = 1024L;
+
+
+ public static String tranWellSize(Long space) {
+
+ if (space > tsize) {
+ return String.format("%.2f", space / tsize) + "T";
+ } else if (space > gsize) {
+ return String.format("%.2f", space / gsize) + "G";
+ } else if(space>0){
+ return space + "M";
+ }else{
+ return "0";
+ }
+ }
+
+ public static int getRandom6(){
+ int radom = new Random().nextInt(999999);
+ if (radom < 100000) {
+ radom += 100000;
+ }
+ return radom;
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XreflectUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XreflectUtil.java
new file mode 100644
index 0000000..a13fc75
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XreflectUtil.java
@@ -0,0 +1,138 @@
+package com.zsvg.vboot.common.util.lang;
+
+import com.zsvg.vboot.common.util.obj.AlterPropertyInfo;
+import com.zsvg.vboot.common.util.obj.PropertyModelInfo;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.BeanUtils;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.util.*;
+
+public class XreflectUtil {
+
+ public static void print(Object obj){
+ Field[] fields = obj.getClass().getDeclaredFields();
+ System.out.println("---------------------------------");
+ for (Field field:fields) {
+ field.setAccessible(true);
+ try {
+ System.out.println(field.getName()+":"+field.get(obj));
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * 比较两个对象属性值是否相同
+ * 如果不同返回修改过的属性信息
+ * @param oldObj
+ * @param newObj
+ * @param ignoreProperties
+ * @param
+ * @return 修改过的属性字段
+ */
+ public static List getDifferentProperty(T oldObj , T newObj , String... ignoreProperties){
+ if (oldObj != null && newObj != null) {
+ // 比较全部字段
+ if (ignoreProperties == null || ignoreProperties.length > 0) {
+ if (oldObj.equals(newObj)) {
+ return Collections.emptyList();
+ }
+ }
+ List oldObjectPropertyValue = getObjectPropertyValue(oldObj, ignoreProperties);
+ if (!CollectionUtils.isEmpty(oldObjectPropertyValue)) {
+ List modifiedPropertyInfos = new ArrayList<>(oldObjectPropertyValue.size());
+
+ List newObjectPropertyValue = getObjectPropertyValue(newObj, ignoreProperties);
+ Map objectMap = new HashMap<>(newObjectPropertyValue.size());
+ // 获取新对象所有属性值
+ for (PropertyModelInfo propertyModelInfo : newObjectPropertyValue) {
+ String prnam = propertyModelInfo.getPrnam();
+ Object value = propertyModelInfo.getValue();
+ objectMap.put(prnam , value);
+ }
+
+ for (PropertyModelInfo propertyModelInfo : oldObjectPropertyValue) {
+ String prnam = propertyModelInfo.getPrnam();
+ Object value = propertyModelInfo.getValue();
+ if (objectMap.containsKey(prnam)) {
+ Object newValue = objectMap.get(prnam);
+ AlterPropertyInfo modifiedPropertyInfo = new AlterPropertyInfo();
+// System.out.println("----------------------");
+// System.out.println(propertyName);
+// System.out.println(value);
+// System.out.println(newValue);
+ if (value != null && newValue != null) {
+ if(value instanceof BigDecimal){
+ if ((new BigDecimal(value.toString())).compareTo(new BigDecimal(newValue.toString()))!=0) {
+ modifiedPropertyInfo.setPrnam(prnam);
+ modifiedPropertyInfo.setOlval(value);
+ modifiedPropertyInfo.setNeval(newValue);
+ modifiedPropertyInfos.add(modifiedPropertyInfo);
+ }
+ }else{
+ if (!(value.toString()).equals(newValue.toString())) {
+ modifiedPropertyInfo.setPrnam(prnam);
+ modifiedPropertyInfo.setOlval(value);
+ modifiedPropertyInfo.setNeval(newValue);
+ modifiedPropertyInfos.add(modifiedPropertyInfo);
+ }
+ }
+ }else if ((XstringUtil.isNotBlank(""+value)&& newValue == null) ||(value== null && XstringUtil.isNotBlank(""+newValue))){
+ modifiedPropertyInfo.setPrnam(prnam);
+ modifiedPropertyInfo.setOlval(value);
+ modifiedPropertyInfo.setNeval(newValue);
+ modifiedPropertyInfos.add(modifiedPropertyInfo);
+ }
+ }
+ }
+ return modifiedPropertyInfos;
+ }
+ }
+ return Collections.emptyList();
+ }
+
+
+ /**
+ * 通过反射获取对象的属性名称、getter返回值类型、属性值等信息
+ * @param obj
+ * @param ignoreProperties
+ * @param
+ * @return
+ */
+ public static List getObjectPropertyValue(T obj , String... ignoreProperties){
+ if (obj != null) {
+
+ Class> objClass = obj.getClass();
+ PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(objClass);
+ List modelInfos = new ArrayList<>(propertyDescriptors.length);
+
+ List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
+ for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+ Method readMethod = propertyDescriptor.getReadMethod();
+ String name = propertyDescriptor.getName();
+ if (readMethod != null && (ignoreList == null || !ignoreList.contains(name))) {
+ Object invoke = null;
+ Class> returnType = readMethod.getReturnType();
+ try {
+ invoke = readMethod.invoke(obj);
+ PropertyModelInfo propertyModelInfo = new PropertyModelInfo();
+ propertyModelInfo.setPrnam(name);
+ propertyModelInfo.setValue(invoke);
+ propertyModelInfo.setRetyp(returnType);
+ modelInfos.add(propertyModelInfo);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ System.out.println("反射获取类【"+objClass.getName()+"】方法异常,");
+ }
+ }
+ }
+ return modelInfos;
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XregUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XregUtil.java
new file mode 100644
index 0000000..890d82c
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XregUtil.java
@@ -0,0 +1,37 @@
+package com.zsvg.vboot.common.util.lang;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class XregUtil {
+ public static boolean match(String reg, String str) {
+ return Pattern.matches(reg, str);
+ }
+
+ public static List find(String reg, String str) {
+ Matcher matcher = Pattern.compile(reg).matcher(str);
+ List list = new ArrayList();
+ while (matcher.find()) {
+ list.add(matcher.group());
+ }
+ return list;
+ }
+
+ public static String find(String reg, String str, int index) {
+ Matcher matcher = Pattern.compile(reg).matcher(str);
+ if (matcher.find()) {
+ return matcher.group(index);
+ }
+ return null;
+ }
+
+ public static String findString(String reg, String str) {
+ String returnStr = null;
+ List list = find(reg, str);
+ if (list.size() != 0)
+ returnStr = list.get(0);
+ return returnStr;
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XscanUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XscanUtil.java
new file mode 100644
index 0000000..93467af
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XscanUtil.java
@@ -0,0 +1,149 @@
+package com.zsvg.vboot.common.util.lang;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class XscanUtil
+{
+ //从包package中获取所有的Class
+ public static Set> getClasses(String pack) {
+
+ // 第一个class类的集合
+ Set> classes = new LinkedHashSet>();
+ // 是否循环迭代
+ boolean recursive = true;
+ // 获取包的名字 并进行替换
+ String packageName = pack;
+ String packageDirName = packageName.replace('.', '/');
+ // 定义一个枚举的集合 并进行循环来处理这个目录下的things
+ Enumeration dirs;
+ try {
+ dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
+ // 循环迭代下去
+ while (dirs.hasMoreElements()) {
+ // 获取下一个元素
+ URL url = dirs.nextElement();
+ // 得到协议的名称
+ String protocol = url.getProtocol();
+ // 如果是以文件的形式保存在服务器上
+ if ("file".equals(protocol)) {
+// System.err.println("file类型的扫描");
+ // 获取包的物理路径
+ String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
+ // 以文件的方式扫描整个包下的文件 并添加到集合中
+ findAndAddClassesInPackageByFile(packageName, filePath,recursive, classes);
+ } else if ("jar".equals(protocol)) {
+ // 如果是jar包文件
+ // 定义一个JarFile
+// System.err.println("jar类型的扫描");
+ JarFile jar;
+ try {
+ // 获取jar
+ jar = ((JarURLConnection) url.openConnection())
+ .getJarFile();
+ // 从此jar包 得到一个枚举类
+ Enumeration entries = jar.entries();
+ // 同样的进行循环迭代
+ while (entries.hasMoreElements()) {
+ // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
+ JarEntry entry = entries.nextElement();
+ String name = entry.getName();
+ // 如果是以/开头的
+ if (name.charAt(0) == '/') {
+ // 获取后面的字符串
+ name = name.substring(1);
+ }
+ // 如果前半部分和定义的包名相同
+ if (name.startsWith(packageDirName)) {
+ int idx = name.lastIndexOf('/');
+ // 如果以"/"结尾 是一个包
+ if (idx != -1) {
+ // 获取包名 把"/"替换成"."
+ packageName = name.substring(0, idx)
+ .replace('/', '.');
+ }
+ // 如果可以迭代下去 并且是一个包
+ if ((idx != -1) || recursive) {
+ // 如果是一个.class文件 而且不是目录
+ if (name.endsWith(".class")
+ && !entry.isDirectory()) {
+ // 去掉后面的".class" 获取真正的类名
+ String className = name.substring(
+ packageName.length() + 1, name
+ .length() - 6);
+ try {
+ // 添加到classes
+ classes.add(Class
+ .forName(packageName + '.'
+ + className));
+ } catch (ClassNotFoundException e) {
+ // log
+ // .error("添加用户自定义视图类错误 找不到此类的.class文件");
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ // log.error("在扫描用户定义视图时从jar包获取文件出错");
+ e.printStackTrace();
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return classes;
+ }
+
+ //以文件的形式来获取包下的所有Class
+ public static void findAndAddClassesInPackageByFile(String packageName,
+ String packagePath, final boolean recursive, Set> classes) {
+ // 获取此包的目录 建立一个File
+ File dir = new File(packagePath);
+ // 如果不存在或者 也不是目录就直接返回
+ if (!dir.exists() || !dir.isDirectory()) {
+ // log.warn("用户定义包名 " + packageName + " 下没有任何文件");
+ return;
+ }
+ // 如果存在 就获取包下的所有文件 包括目录
+ File[] dirfiles = dir.listFiles(new FileFilter() {
+ // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
+ public boolean accept(File file) {
+ return (recursive && file.isDirectory())
+ || (file.getName().endsWith(".class"));
+ }
+ });
+ // 循环所有文件
+ for (File file : dirfiles) {
+ // 如果是目录 则继续扫描
+ if (file.isDirectory()) {
+ findAndAddClassesInPackageByFile(packageName + "."
+ + file.getName(), file.getAbsolutePath(), recursive,
+ classes);
+ } else {
+ // 如果是java类文件 去掉后面的.class 只留下类名
+ String className = file.getName().substring(0,
+ file.getName().length() - 6);
+ try {
+ // 添加到集合中去
+ //classes.add(Class.forName(packageName + '.' + className));
+ //经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净
+ classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
+ } catch (ClassNotFoundException e) {
+ // log.error("添加用户自定义视图类错误 找不到此类的.class文件");
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XstringUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XstringUtil.java
new file mode 100644
index 0000000..2b22516
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XstringUtil.java
@@ -0,0 +1,143 @@
+package com.zsvg.vboot.common.util.lang;
+
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class XstringUtil {
+
+ public static boolean containChinese(String str) {
+ Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
+ Matcher m = p.matcher(str);
+ if (m.find()) {
+ return true;
+ }
+ return false;
+ }
+
+// public static boolean isEmpty(String str) {
+// return str == null || str.length() == 0|| "null".equals(str);
+// }
+//
+// public static boolean isNotEmpty(String str) {
+// return !XstringUtil.isEmpty(str);
+// }
+
+ public static boolean isBlank(String str) {
+ int strLen;
+ if (str == null || (strLen = str.length()) == 0|| "null".equals(str)) {
+ return true;
+ }
+ for (int i = 0; i < strLen; i++) {
+ if ((!Character.isWhitespace(str.charAt(i)))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isAllBlank(String str1,String str2) {
+ return XstringUtil.isBlank(str1)&&XstringUtil.isBlank(str2);
+ }
+
+ public static boolean isAllBlank(String str1,String str2,String str3) {
+ return XstringUtil.isBlank(str1)&&XstringUtil.isBlank(str2)&&XstringUtil.isBlank(str3);
+ }
+
+ public static boolean isNotBlank(String str) {
+ return !XstringUtil.isBlank(str);
+ }
+
+ public static String addWhereInCondition(String field,List list){
+ if(list==null||list.size()==0){
+ return " 1=0 ";
+ }
+ StringBuilder sb=new StringBuilder(field).append(" in (");
+ for (String str : list) {
+ sb.append("'").append(str).append("',");
+ }
+ sb.setCharAt(sb.length()-1,')');
+ return sb.toString();
+ }
+
+ public static String getUUID()
+ {
+ return UUID.randomUUID().toString().replace("-", "");
+ }
+
+ //生成随机字母和数字,
+ public static String getRSID(int length) {
+ String val = "";
+ Random random = new Random();
+ //参数length,表示生成几位随机数
+ for(int i = 0; i < length; i++) {
+ String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
+ //输出字母还是数字
+ if( "char".equalsIgnoreCase(charOrNum) ) {
+ //输出是大写字母还是小写字母
+// int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
+ val += (char)(random.nextInt(26) + 97);
+ } else if( "num".equalsIgnoreCase(charOrNum) ) {
+ val += String.valueOf(random.nextInt(10));
+ }
+ }
+ return val;
+ }
+
+ public static String getRSID4() {
+ return getRSID(4);
+ }
+
+ public static String getRSID8() {
+ return getRSID(8);
+ }
+
+ //首字母转小写
+ public static String toLowerfirst(String s)
+ {
+ if (Character.isLowerCase(s.charAt(0)))
+ {
+ return s;
+ } else
+ {
+ return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
+ }
+ }
+
+ //首字母转大写
+ public static String toUpperfirst(String s)
+ {
+ if (Character.isUpperCase(s.charAt(0)))
+ {
+ return s;
+ } else
+ {
+ return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
+ }
+ }
+
+
+ public static String DelZeroBefore(String str){
+ return str.replaceAll("^(0+)", "");
+ }
+
+ public static String addZeroBefore(String str, int strLength) {
+ int strLen = str.length();
+ if (strLen < strLength) {
+ while (strLen < strLength) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("0").append(str);// 左补0
+ // sb.append(str).append("0");//右补0
+ str = sb.toString();
+ strLen = str.length();
+ }
+ }
+
+ return str;
+ }
+
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XtimeUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XtimeUtil.java
new file mode 100644
index 0000000..900c022
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/XtimeUtil.java
@@ -0,0 +1,71 @@
+package com.zsvg.vboot.common.util.lang;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class XtimeUtil
+{
+ private static long lastTime;
+ private static long startTime;
+
+ public static String getTime()
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return sdf.format(new Date());
+ }
+
+ public static void calStart()
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
+ startTime=System.currentTimeMillis();
+ lastTime=startTime;
+ System.err.println("----"+sdf.format(new Date())+" 计时开始▼ ");
+ }
+
+ public static void calMid()
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
+ long curTime=System.currentTimeMillis();
+ long time = curTime - lastTime;
+ System.err.println("----"+sdf.format(new Date())+" 中间用时■ "+time + "毫秒");
+ lastTime=curTime;
+ }
+
+ public static void calEnd()
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
+ long curTime=System.currentTimeMillis();
+ long time = curTime - lastTime;
+ long time2 = curTime - startTime;
+ System.err.println("----"+sdf.format(new Date())+" 计时结束▲ "+time + "毫秒,合计:" + time2+ "毫秒");
+
+ }
+
+ public static String getTimeByDate(Date date)
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return sdf.format(date);
+ }
+
+ public static Boolean compare(String s1, String s2)
+ {
+ if(s1==null){
+ return false;
+ }else if(s2==null){
+ return true;
+ }
+ int i = s1.compareTo(s2);
+ if (i >= 0)
+ {
+ return true;
+ } else
+ {
+ return false;
+ }
+ }
+
+ public static long getTimeGap(long beforeTimeMillis)
+ {
+ return (System.currentTimeMillis() - beforeTimeMillis) / 1000;
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/AlterPropertyInfo.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/AlterPropertyInfo.java
new file mode 100644
index 0000000..1b3528e
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/AlterPropertyInfo.java
@@ -0,0 +1,18 @@
+package com.zsvg.vboot.common.util.obj;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class AlterPropertyInfo implements Serializable {
+
+ // 对应的属性名
+ private String prnam;
+
+ // 未修改之前的值
+ private Object olval;
+
+ // 修改后的值
+ private Object neval;
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/JsonDateValueProcessor.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/JsonDateValueProcessor.java
new file mode 100644
index 0000000..ace2a57
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/JsonDateValueProcessor.java
@@ -0,0 +1,34 @@
+package com.zsvg.vboot.common.util.obj;
+
+import net.sf.json.JsonConfig;
+import net.sf.json.processors.JsonValueProcessor;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class JsonDateValueProcessor implements JsonValueProcessor {
+ @Override
+ public Object processArrayValue(Object obj, JsonConfig jsonconfig) {
+ return process(obj);
+ }
+ @Override
+ public Object processObjectValue(String s, Object obj, JsonConfig jsonconfig) {
+ return process(obj);
+ }
+ private Object process(Object obj) {
+ if (obj == null) {// 如果时间为null,则返回空字串
+ return "";
+ }
+ if (obj instanceof Date) {
+ obj = new java.util.Date(((Date) obj).getTime());
+ }
+ if (obj instanceof java.util.Date) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
+ Locale.CHINA);// 格式化时间为yyyy-MM-dd类型
+ return sdf.format(obj);
+ } else {
+ return new Object();
+ }
+ }
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/PropertyModelInfo.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/PropertyModelInfo.java
new file mode 100644
index 0000000..78b0b53
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/obj/PropertyModelInfo.java
@@ -0,0 +1,13 @@
+package com.zsvg.vboot.common.util.obj;
+
+import lombok.Data;
+
+@Data
+public class PropertyModelInfo {
+ //属性名
+ private String prnam;
+ // 属性值
+ private Object value;
+ // 返回值类型
+ private Class> retyp;
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XhttpUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XhttpUtil.java
new file mode 100644
index 0000000..d443c69
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XhttpUtil.java
@@ -0,0 +1,145 @@
+package com.zsvg.vboot.common.util.web;
+
+import org.apache.commons.lang.StringUtils;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+
+public class XhttpUtil {
+
+ public static String httpGetConnect(String httpUrl, String key) {
+ String back = "error";
+ if (StringUtils.isBlank(httpUrl)) {
+ return back;
+ }
+ HttpURLConnection connection = null;
+ InputStream is = null;
+ BufferedReader br = null;
+ String result = "";
+ try {
+ URL url = new URL(httpUrl);
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.setRequestProperty("Content-Type", "text/html");
+ connection.setRequestProperty("Cache-Control", "no-cache");
+ connection.setRequestProperty("Charsert", "UTF-8");
+ connection.setConnectTimeout(15000);
+ connection.setReadTimeout(60000);
+ connection.connect();
+ if (connection.getResponseCode() == 200) {
+ is = connection.getInputStream();
+ // 封装输入流is,并指定字符集
+ br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ // 存放数据
+ StringBuffer sbf = new StringBuffer();
+ String temp = null;
+ while ((temp = br.readLine()) != null) {
+ sbf.append(temp);
+ //sbf.append("\r\n");
+ }
+ result = sbf.toString();
+ back = result;
+ } else {
+ System.out.println("http链接错误!" + key);
+ back = "error";
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ back = "error";
+ } finally {
+ // 关闭资源
+ if (null != br) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (null != is) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ connection.disconnect();// 关闭远程连接
+ }
+ return back;
+ }
+
+ public static String httpPostConnect(String httpUrl, String param, String key) {
+ String back = "";
+ if (StringUtils.isBlank(httpUrl)) {
+ return back;
+ }
+ HttpURLConnection connection = null;
+ InputStream is = null;
+ OutputStream os = null;
+ BufferedReader br = null;
+ try {
+ URL url = new URL(httpUrl);
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setConnectTimeout(15000);
+ connection.setReadTimeout(60000);
+ /** 设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个 */
+ // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
+ connection.setDoOutput(true);
+ // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
+ connection.setDoInput(true);
+ // 设置是否使用缓存
+ connection.setUseCaches(false);
+ /** 设置通用的请求属性 */
+ connection.setRequestProperty("accept", "*/*");
+ connection.setRequestProperty("connection", "Keep-Alive");
+ connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+ // 设置传入参数的格式
+ connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //name1=value1&name2=value2 的形式
+ //connection.setRequestProperty("Content-Type", "application/json;charset=utf-8"); //json格式
+ //connection.connect();
+
+ os = connection.getOutputStream();
+ if (StringUtils.isNotBlank(param)) {
+ os.write(param.getBytes());
+ }
+
+ if (connection.getResponseCode() == 200) {
+ is = connection.getInputStream();
+ br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ StringBuffer sbf = new StringBuffer();
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ sbf.append(line);
+ //sbf.append("\r\n");
+ }
+ back = sbf.toString();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ back = "error";
+ } finally {
+ // 关闭资源
+ try {
+ if (null != br) {
+ br.close();
+ }
+ if (null != is) {
+ is.close();
+ }
+ if (null != os) {
+ os.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ connection.disconnect();// 关闭远程连接
+ }
+ return back;
+ }
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XpageUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XpageUtil.java
new file mode 100644
index 0000000..5155f08
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XpageUtil.java
@@ -0,0 +1,7 @@
+package com.zsvg.vboot.common.util.web;
+
+public class XpageUtil {
+
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XreqUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XreqUtil.java
new file mode 100644
index 0000000..c150b06
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XreqUtil.java
@@ -0,0 +1,206 @@
+package com.zsvg.vboot.common.util.web;
+
+import cn.hutool.core.convert.Convert;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.util.Enumeration;
+
+public class XreqUtil {
+ /**
+ * 当前记录起始索引
+ */
+ public static final String PAGE_NUM = "page";
+
+ /**
+ * 每页显示记录数
+ */
+ public static final String PAGE_SIZE = "pageSize";
+
+
+ public static void testParams(HttpServletRequest request) {
+ Enumeration pNames = request.getParameterNames();
+ while (pNames.hasMoreElements()) {
+ String pName = (String) pNames.nextElement();
+ Object pValue = request.getParameter(pName);
+ System.out.println(pName + ":" + pValue);
+ }
+ }
+
+
+
+ public static String getIpAddress(HttpServletRequest request) {
+ String ip = request.getHeader("x-forwarded-for");
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_CLIENT_IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ }
+ return ip;
+ }
+
+
+ public static void setPageParam(Sqler sqler) {
+ HttpServletRequest request = getRequest();
+ Integer pageNum = Convert.toInt(request.getParameter(PAGE_NUM));
+ Integer pageSize = Convert.toInt(request.getParameter(PAGE_SIZE));
+ if(pageNum!=null){
+ sqler.setPanum(pageNum);
+ }
+ if(pageSize!=null){
+ sqler.setPasiz(pageSize);
+ }
+ }
+
+
+ /**
+ * 获取String参数
+ */
+ public static String getParameter(String name)
+ {
+ return getRequest().getParameter(name);
+ }
+
+ /**
+ * 获取String参数
+ */
+ public static String getParameter(String name, String defaultValue)
+ {
+ return Convert.toStr(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 获取Integer参数
+ */
+ public static Integer getParameterToInt(String name)
+ {
+ return Convert.toInt(getRequest().getParameter(name));
+ }
+
+ /**
+ * 获取Integer参数
+ */
+ public static Integer getParameterToInt(String name, Integer defaultValue)
+ {
+ return Convert.toInt(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 获取Boolean参数
+ */
+ public static Boolean getParameterToBool(String name)
+ {
+ return Convert.toBool(getRequest().getParameter(name));
+ }
+
+ /**
+ * 获取Boolean参数
+ */
+ public static Boolean getParameterToBool(String name, Boolean defaultValue)
+ {
+ return Convert.toBool(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 获取request
+ */
+ public static HttpServletRequest getRequest()
+ {
+ return getRequestAttributes().getRequest();
+ }
+
+ /**
+ * 获取response
+ */
+ public static HttpServletResponse getResponse()
+ {
+ return getRequestAttributes().getResponse();
+ }
+
+ /**
+ * 获取session
+ */
+ public static HttpSession getSession()
+ {
+ return getRequest().getSession();
+ }
+
+ public static ServletRequestAttributes getRequestAttributes()
+ {
+ RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+ return (ServletRequestAttributes) attributes;
+ }
+
+ /**
+ * 将字符串渲染到客户端
+ *
+ * @param response 渲染对象
+ * @param string 待渲染的字符串
+ * @return null
+ */
+ public static String renderString(HttpServletResponse response, String string)
+ {
+ try
+ {
+ response.setStatus(200);
+ response.setContentType("application/json");
+ response.setCharacterEncoding("utf-8");
+ response.getWriter().print(string);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 是否是Ajax异步请求
+ *
+ * @param request
+ */
+// public static boolean isAjaxRequest(HttpServletRequest request)
+// {
+// String accept = request.getHeader("accept");
+// if (accept != null && accept.indexOf("application/json") != -1)
+// {
+// return true;
+// }
+//
+// String xRequestedWith = request.getHeader("X-Requested-With");
+// if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
+// {
+// return true;
+// }
+//
+// String uri = request.getRequestURI();
+// if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
+// {
+// return true;
+// }
+//
+// String ajax = request.getParameter("__ajax");
+// if (StringUtils.inStringIgnoreCase(ajax, "json", "xml"))
+// {
+// return true;
+// }
+// return false;
+// }
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XresUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XresUtil.java
new file mode 100644
index 0000000..d529bb4
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XresUtil.java
@@ -0,0 +1,35 @@
+package com.zsvg.vboot.common.util.web;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+
+public class XresUtil {
+
+
+ public static void downloadExcelXls(HttpServletResponse response, HSSFWorkbook workbook, String name) throws IOException
+ {
+ String fileName = URLEncoder.encode(name, "UTF-8");
+ response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xls");
+ response.setContentType("application/vnd.ms-excel");
+ OutputStream out = response.getOutputStream();
+ workbook.write(out);
+ out.flush();
+ out.close();
+ }
+
+ public static void downloadExcelXlsx(HttpServletResponse response, XSSFWorkbook workbook, String name) throws IOException
+ {
+ String fileName = URLEncoder.encode(name, "UTF-8");
+ response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
+ response.setContentType("application/vnd.ms-excel");
+ OutputStream out = response.getOutputStream();
+ workbook.write(out);
+ out.flush();
+ out.close();
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XspringUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XspringUtil.java
new file mode 100644
index 0000000..52f6fc6
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XspringUtil.java
@@ -0,0 +1,32 @@
+package com.zsvg.vboot.common.util.web;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+
+public class XspringUtil {
+
+ private static ApplicationContext applicationContext = null;
+
+ public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ if(XspringUtil.applicationContext == null){
+ XspringUtil.applicationContext = applicationContext;
+ }
+ }
+
+ public static ApplicationContext getApp() {
+ return applicationContext;
+ }
+
+ public static Object getBean(String name){
+ return getApp().getBean(name);
+ }
+
+ public static T getBean(Class clazz){
+ return getApp().getBean(clazz);
+ }
+
+ public static T getBean(String name,Class clazz){
+ return getApp().getBean(name, clazz);
+ }
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XuserUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XuserUtil.java
new file mode 100644
index 0000000..d2c2ab8
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XuserUtil.java
@@ -0,0 +1,48 @@
+package com.zsvg.vboot.common.util.web;
+
+import com.zsvg.vboot.module.sys.org.root.SysOrg;
+import com.zsvg.vboot.config.security.pojo.Zuser;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+public class XuserUtil {
+
+ public static String[] admins;
+
+ public static boolean isAdmin(String usnam) {
+ if ("sa".equals(usnam)) {
+ return true;
+ }
+ for (int i = 0; i < XuserUtil.admins.length; i++) {
+ if (XuserUtil.admins[i].equals(usnam)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static SysOrg getUser() {
+ String userId = null;
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ userId = calcUserId(userId, authentication);
+ return new SysOrg(userId, "");
+ }
+
+ public static String getUserId() {
+ String userId = null;
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ userId = calcUserId(userId, authentication);
+ return userId;
+ }
+
+ private static String calcUserId(String userId, Authentication authentication) {
+ if (authentication.getPrincipal() instanceof String) {
+ userId = (String) authentication.getPrincipal();
+ } else if (authentication.getPrincipal() instanceof Zuser) {
+ Zuser zuser = (Zuser) authentication.getPrincipal();
+ userId = zuser.getId();
+ }
+ return userId;
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/AppConfig.java b/vboot-core/src/main/java/com/zsvg/vboot/config/AppConfig.java
new file mode 100644
index 0000000..88e330d
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/AppConfig.java
@@ -0,0 +1,51 @@
+package com.zsvg.vboot.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+
+@Validated
+@Configuration
+@ConfigurationProperties(prefix = "zsvg")
+public class AppConfig {
+
+ @Getter
+ @Setter
+ @Valid
+ private Jwt jwt = new Jwt();
+
+ @Getter
+ @Setter
+ public static class Jwt {
+ private String header = "Authorization"; //HTTP 报头的认证字段的 key
+ private String prefix = "Bearer "; //HTTP 报头的认证字段的值的前缀
+
+ private long atime = 28800L; //accessToken过期时间 此处单位秒 ,默认8小时 28800
+
+ private long rtime = 3456000L; //accessToken过期时间 此处单位秒 ,默认30天 3456000
+
+ private String akey;//生成accessToken用的key
+
+ private String rkey;//生成refreshToken用的key
+
+
+ //以下赞未用到
+// //在线用户 key,根据 key 查询 redis 中在线用户的数据
+// private String onlineKey;
+//
+// //验证码 key
+// private String codeKey;
+//
+// //token 续期检查
+// private Long detect;
+//
+// //续期时间
+// private Long renew;
+
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/DbInitListener.java b/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/DbInitListener.java
new file mode 100644
index 0000000..d9d3461
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/DbInitListener.java
@@ -0,0 +1,57 @@
+package com.zsvg.vboot.config.db.init;
+
+import com.zsvg.vboot.module.sys.org.user.SysOrgUserRepo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.event.ContextRefreshedEvent;
+
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+
+@Configuration
+@Slf4j
+public class DbInitListener implements ApplicationListener {
+
+
+ /**
+ * 首次数据库生成后,初始化组织架构,菜单,权限角色等信息
+ * 增加sa,admin管理员账号及相关测试账号
+ * 判断依据是sys_org_user是否含有id为sa的账号
+ */
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ try {
+ if (!userDao.existsById("sa")) {
+ System.out.println("首次启动系统,正在进行数据库初始化,请耐心等待。");
+ sysOrgInit.initCorp();
+ System.out.println("1.1 初始化部门完毕");
+ sysOrgInit.initUser();
+ sysOrgInit.initZsf();
+ sysOrgInit.initSa();
+ System.out.println("1.2 初始化用户完毕");
+// sysOrgInit.initPost();
+// sysOrgInit.initGroup();
+
+ sysAuthInit.initMenu();
+ System.out.println("2.1 初始化菜单完毕");
+ }
+ } catch (Exception e) {
+ System.err.println("初始化出错");
+ e.printStackTrace();
+ }
+ }
+
+ @Autowired
+ private SysOrgUserRepo userDao;
+
+
+ @Autowired
+ private SysOrgInit sysOrgInit;
+
+ @Autowired
+ private SysAuthInit sysAuthInit;
+
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/SysAuthInit.java b/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/SysAuthInit.java
new file mode 100644
index 0000000..baa0794
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/SysAuthInit.java
@@ -0,0 +1,146 @@
+package com.zsvg.vboot.config.db.init;
+
+import com.zsvg.vboot.module.sys.auth.menu.SysAuthMenu;
+import com.zsvg.vboot.module.sys.auth.menu.SysAuthMenuService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SysAuthInit {
+
+ protected void initMenu() {
+ SysAuthMenu menu1 = new SysAuthMenu();
+ menu1.setId("Sys");
+ menu1.setName("系统管理");
+ menu1.setCode("Sys");
+ menu1.setComp("LAYOUT");
+ menu1.setPath("/sys");
+ menu1.setRedirect("/sys/org/user");
+ menu1.setOrnum(1);
+ menu1.setIcon("ant-design:setting-outlined");
+ menu1.setAvtag(true);
+ menu1.setShtag(true);
+ menu1.setType("D");
+ menuService.insert(menu1);
+
+ SysAuthMenu menu11 = new SysAuthMenu();
+ menu11.setId("SysOrg");
+ menu11.setName("组织架构");
+ menu11.setCode("SysOrg");
+ menu11.setComp("LAYOUT");
+ menu11.setPath("/sys/org");
+ menu11.setRedirect("/sys/org/user");
+ menu11.setOrnum(1);
+ menu11.setIcon("ant-design:partition-outlined");
+ menu11.setPid("Sys");
+ menu11.setAvtag(true);
+ menu11.setShtag(true);
+ menu11.setType("D");
+ menuService.insert(menu11);
+
+ SysAuthMenu menu111 = new SysAuthMenu();
+ menu111.setId("SysOrgDept");
+ menu111.setName("部门管理");
+ menu111.setCode("SysOrgDept");
+ menu111.setPath("/sys/org/dept");
+ menu111.setComp("/sys/org/dept/index.vue");
+ menu111.setOrnum(1);
+ menu111.setPid("SysOrg");
+ menu111.setCatag(false);
+ menu111.setAvtag(true);
+ menu111.setShtag(true);
+ menu111.setType("M");
+ menuService.insert(menu111);
+
+ SysAuthMenu menu112 = new SysAuthMenu();
+ menu112.setId("SysOrgUser");
+ menu112.setName("用户管理");
+ menu112.setCode("SysOrgUser");
+ menu112.setPath("/sys/org/user");
+ menu112.setComp("/sys/org/user/index.vue");
+ menu112.setOrnum(2);
+ menu112.setPid("SysOrg");
+ menu112.setCatag(false);
+ menu112.setAvtag(true);
+ menu112.setShtag(true);
+ menu112.setType("M");
+ menuService.insert(menu112);
+
+ SysAuthMenu menu113 = new SysAuthMenu();
+ menu113.setId("SysOrgPost");
+ menu113.setName("岗位管理");
+ menu113.setCode("SysOrgPost");
+ menu113.setPath("/sys/org/post");
+ menu113.setComp("/sys/org/post/index.vue");
+ menu113.setOrnum(3);
+ menu113.setPid("SysOrg");
+ menu113.setCatag(false);
+ menu113.setAvtag(true);
+ menu113.setShtag(true);
+ menu113.setType("M");
+ menuService.insert(menu113);
+
+ SysAuthMenu menu114 = new SysAuthMenu();
+ menu114.setId("SysOrgGroup");
+ menu114.setName("群组管理");
+ menu114.setCode("SysOrgGroup");
+ menu114.setPath("/sys/org/group");
+ menu114.setComp("/sys/org/group/index.vue");
+ menu114.setOrnum(4);
+ menu114.setPid("SysOrg");
+ menu114.setCatag(false);
+ menu114.setAvtag(true);
+ menu114.setShtag(true);
+ menu114.setType("M");
+ menuService.insert(menu114);
+
+ SysAuthMenu menu12 = new SysAuthMenu();
+ menu12.setId("SysAuth");
+ menu12.setName("权限管理");
+ menu12.setCode("SysAuth");
+ menu12.setComp("LAYOUT");
+ menu12.setPath("/sys/auth");
+ menu12.setRedirect("/sys/auth/menu");
+ menu12.setOrnum(2);
+ menu12.setIcon("ant-design:safety-certificate-outlined");
+ menu12.setPid("Sys");
+ menu12.setAvtag(true);
+ menu12.setShtag(true);
+ menu12.setType("D");
+ menuService.insert(menu12);
+
+ SysAuthMenu menu121 = new SysAuthMenu();
+ menu121.setId("SysAuthMenu");
+ menu121.setName("菜单管理");
+ menu121.setCode("SysAuthMenu");
+ menu121.setPath("/sys/auth/menu");
+ menu121.setComp("/sys/auth/menu/index.vue");
+ menu121.setOrnum(1);
+ menu121.setPid("SysAuth");
+ menu121.setCatag(false);
+ menu121.setAvtag(true);
+ menu121.setShtag(true);
+ menu121.setType("M");
+ menuService.insert(menu121);
+
+ SysAuthMenu menu122 = new SysAuthMenu();
+ menu122.setId("SysAuthRole");
+ menu122.setName("角色管理");
+ menu122.setCode("SysAuthRole");
+ menu122.setPath("/sys/auth/role");
+ menu122.setComp("/sys/auth/role/index.vue");
+ menu122.setOrnum(1);
+ menu122.setPid("SysAuth");
+ menu122.setCatag(false);
+ menu122.setAvtag(true);
+ menu122.setShtag(true);
+ menu122.setType("M");
+ menuService.insert(menu122);
+
+ }
+
+ @Autowired
+ private SysAuthMenuService menuService;
+
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/SysOrgInit.java b/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/SysOrgInit.java
new file mode 100644
index 0000000..db987b5
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/db/init/SysOrgInit.java
@@ -0,0 +1,317 @@
+package com.zsvg.vboot.config.db.init;
+
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import com.zsvg.vboot.module.sys.org.dept.SysOrgDeptService;
+import com.zsvg.vboot.module.sys.org.root.SysOrg;
+import com.zsvg.vboot.module.sys.org.user.SysOrgUser;
+import com.zsvg.vboot.module.sys.org.user.SysOrgUserService;
+import com.zsvg.vboot.module.sys.org.dept.SysOrgDept;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class SysOrgInit {
+
+
+ //公司及子公司初始化
+ protected void initCorp() throws Exception {
+ List deptList = new ArrayList<>();
+ initDept(deptList,"刘", "LIU",1);
+ initDept(deptList,"陈", "CHEN",2);
+ initDept(deptList,"张", "ZHANG",3);
+ initDept(deptList,"李", "LI",4);
+ initDept(deptList,"王", "WANG",5);
+ initDept(deptList,"赵", "ZHAO",6);
+ initDept(deptList,"孙", "SUN",7);
+ initDept(deptList,"周", "ZHOU",8);
+ initDept(deptList,"吴", "WU",9);
+ initDept(deptList,"郑", "ZHENG",10);
+ deptService.insertAll(deptList);
+ }
+
+ //部门初始化
+ private void initDept(List deptList,String name, String id,Integer ornum) throws Exception {
+ SysOrgDept corp = new SysOrgDept();
+ corp.setType(1);
+ corp.setId(id);
+ corp.setName(name + "家科技");
+ corp.setLabel(id);
+ corp.setOrnum(ornum);
+ corp.setAvtag(true);
+ corp.setTier("x"+id+"x");
+ deptList.add(corp);
+
+ SysOrgDept dept1 = new SysOrgDept();
+ dept1.setType(2);
+ dept1.setId(id + "-1");
+ dept1.setName(name + "一总金办");
+ dept1.setLabel(id);
+ dept1.setParent(new SysOrg(id));
+ dept1.setOrnum(1);
+ dept1.setAvtag(true);
+ dept1.setTier("x"+id+"x"+id + "-1"+"x");
+ deptList.add(dept1);
+
+ SysOrgDept dept2 = new SysOrgDept();
+ dept2.setType(2);
+ dept2.setId(id + "-2");
+ dept2.setName(name + "二人事部");
+ dept2.setLabel(id);
+ dept2.setParent(new SysOrg(id));
+ dept2.setOrnum(2);
+ dept2.setAvtag(true);
+ dept2.setTier("x"+id+"x"+id + "-2"+"x");
+ deptList.add(dept2);
+
+ SysOrgDept dept3 = new SysOrgDept();
+ dept3.setType(2);
+ dept3.setId(id + "-3");
+ dept3.setName(name + "三销售部");
+ dept3.setLabel(id);
+ dept3.setParent(new SysOrg(id));
+ dept3.setOrnum(3);
+ dept3.setAvtag(true);
+ dept3.setTier("x"+id+"x"+id + "-3"+"x");
+ deptList.add(dept3);
+
+ SysOrgDept dept4 = new SysOrgDept();
+ dept4.setType(2);
+ dept4.setId(id + "-4");
+ dept4.setName(name + "四财务部");
+ dept4.setLabel(id);
+ dept4.setParent(new SysOrg(id));
+ dept4.setOrnum(4);
+ dept4.setAvtag(true);
+ dept4.setTier("x"+id+"x"+id + "-4"+"x");
+ deptList.add(dept4);
+
+ SysOrgDept dept5 = new SysOrgDept();
+ dept5.setType(2);
+ dept5.setId(id + "-5");
+ dept5.setName(name + "五采购部");
+ dept5.setLabel(id);
+ dept5.setParent(new SysOrg(id));
+ dept5.setOrnum(5);
+ dept5.setAvtag(true);
+ dept5.setTier("x"+id+"x"+id + "-5"+"x");
+ deptList.add(dept5);
+
+ SysOrgDept dept6 = new SysOrgDept();
+ dept6.setType(2);
+ dept6.setId(id + "-6");
+ dept6.setName(name + "六技术部");
+ dept6.setLabel(id);
+ dept6.setParent(new SysOrg(id));
+ dept6.setOrnum(6);
+ dept6.setAvtag(true);
+ dept6.setTier("x"+id+"x"+id + "-6"+"x");
+ deptList.add(dept6);
+
+ SysOrgDept dept7 = new SysOrgDept();
+ dept7.setType(2);
+ dept7.setId(id + "-7");
+ dept7.setName(name + "七制造部");
+ dept7.setLabel(id);
+ dept7.setParent(new SysOrg(id));
+ dept7.setOrnum(7);
+ dept7.setAvtag(true);
+ dept7.setTier("x"+id+"x"+id + "-7"+"x");
+ deptList.add(dept7);
+
+ SysOrgDept dept8 = new SysOrgDept();
+ dept8.setType(2);
+ dept8.setId(id + "-8");
+ dept8.setName(name + "八法务部");
+ dept8.setLabel(id);
+ dept8.setParent(new SysOrg(id));
+ dept8.setOrnum(8);
+ dept8.setAvtag(true);
+ dept8.setTier("x"+id+"x"+id + "-8"+"x");
+ deptList.add(dept8);
+
+ SysOrgDept dept9 = new SysOrgDept();
+ dept9.setType(2);
+ dept9.setId(id + "-9");
+ dept9.setName(name + "九信息部");
+ dept9.setLabel(id);
+ dept9.setParent(new SysOrg(id));
+ dept9.setOrnum(9);
+ dept9.setAvtag(true);
+ dept9.setTier("x"+id+"x"+id + "-9"+"x");
+ deptList.add(dept9);
+
+ for (int i = 1; i <= 50; i++) {
+ String RSID8= XstringUtil.getRSID8();
+ SysOrgDept xdept = new SysOrgDept();
+ xdept.setType(2);
+ xdept.setId(id + "--"+i);
+ xdept.setName(RSID8);
+ xdept.setLabel(id);
+ xdept.setParent(new SysOrg(id+"-"+(i%10==0?1:i%10)));
+ xdept.setAvtag(true);
+ xdept.setTier("x"+id+"x"+id+"-"+(i%10==0?1:i%10)+"x"+id + "--"+i+"x");
+ deptList.add(xdept);
+ }
+
+ }
+
+ protected void initUser() {
+ List userList = new ArrayList<>();
+ initUser(userList,"刘", "liu", "LIU");
+ initUser(userList,"陈", "c", "CHEN");
+ initUser(userList,"张", "z", "ZHANG");
+ initUser(userList,"李", "l", "LI");
+ initUser(userList,"王", "w", "WANG");
+ initUser(userList,"赵", "zhao", "ZHAO");
+ initUser(userList,"孙", "s", "SUN");
+ initUser(userList,"周", "zhou", "ZHOU");
+ initUser(userList,"吴", "wu", "WU");
+ initUser(userList,"郑", "zheng", "ZHENG");
+ userService.insertAll(userList);
+ }
+
+ private void initUser(List userList,String name, String id, String pid) {
+ SysOrgUser user0 = new SysOrgUser();
+ user0.setId(id+"lao");
+ user0.setUsnam(id);
+ user0.setName(name + "老");
+ user0.setDept(new SysOrg(pid));
+ user0.setPacod("1");//1
+ user0.setAvtag(true);
+ user0.setTier("x"+pid+"x"+id+"lao");
+ userList.add(user0);
+
+ for (int i = 1; i <= 9; i++) {
+ SysOrgUser userx = new SysOrgUser();
+ userx.setId(id + i);
+ userx.setUsnam(id + i);
+ userx.setName(name + numChange("" + i));
+ userx.setDept(new SysOrg(pid + "-" + i));
+ userx.setOrnum(i);
+ userx.setPacod("1");//1
+ userx.setAvtag(true);
+ userx.setTier("x"+pid+"x"+pid + "-" + i+"x"+id + i+"x");
+ userList.add(userx);
+
+ for (int j = 1; j <= 9; j++) {
+ SysOrgUser usery = new SysOrgUser();
+ usery.setId(id + i + j);
+ usery.setUsnam(id + i + j);
+ usery.setName(name + numChange("" + i) + numChange("" + j));
+ usery.setDept(new SysOrg(pid + "-" + i));
+ usery.setOrnum(j);
+ usery.setPacod("1");//1
+ usery.setAvtag(true);
+ usery.setTier("x"+pid+"x"+pid + "-" + i+"x"+id + i + j+"x");
+ userList.add(usery);
+ }
+ }
+ }
+
+
+ protected void initZsf() {
+
+ SysOrgDept dept1 = new SysOrgDept();
+ dept1.setType(2);
+ dept1.setId("ZHANG-3-1");
+ dept1.setName("张三销售一室");
+ dept1.setLabel("ZHANG");
+ dept1.setParent(new SysOrg("ZHANG-3"));
+ dept1.setOrnum(1);
+ dept1.setAvtag(true);
+ dept1.setTier("xZHANGxZHANG-3xZHANG-3-1x");
+ deptService.insert(dept1);
+
+ SysOrgDept dept2 = new SysOrgDept();
+ dept2.setType(2);
+ dept2.setId("ZHANG-3-2");
+ dept2.setName("张三销售二室");
+ dept2.setLabel("ZHANG");
+ dept2.setParent(new SysOrg("ZHANG-3"));
+ dept2.setOrnum(1);
+ dept2.setAvtag(true);
+ dept2.setTier("xZHANGxZHANG-3xZHANG-3-2x");
+ deptService.insert(dept2);
+
+ SysOrgUser user4 = new SysOrgUser();
+ user4.setId("zsf");
+ user4.setUsnam("zsf");
+ user4.setName("张三丰");
+ user4.setDept(new SysOrg("ZHANG-3-2"));
+ user4.setOrnum(1);
+ user4.setPacod("1");
+ user4.setAvtag(true);
+ user4.setTier("xZHANGxZHANG-3xZHANG-3-2xzsfx");
+ userService.insert(user4);
+ }
+
+ protected void initSa() {
+ SysOrgUser user = new SysOrgUser();
+ user.setId("sa");
+ user.setUsnam("sa");
+ user.setName("管理员");
+ user.setPacod("1");
+ user.setAvtag(true);
+ user.setTier("xsax");
+ userService.insert(user);
+
+ SysOrgUser user2 = new SysOrgUser();
+ user2.setId("vben");
+ user2.setUsnam("vben");
+ user2.setName("小维");
+ user2.setPacod("123456");
+ user2.setAvtag(true);
+ user2.setTier("xvbenx");
+ userService.insert(user2);
+ }
+
+ private String numChange(String num) {
+ switch (num) {
+ case "1":
+ return "一";
+ case "2":
+ return "二";
+ case "3":
+ return "三";
+ case "4":
+ return "四";
+ case "5":
+ return "五";
+ case "6":
+ return "六";
+ case "7":
+ return "七";
+ case "8":
+ return "八";
+ case "9":
+ return "九";
+ case "10":
+ return "十";
+ }
+ return "零";
+ }
+
+//
+// //岗位初始化
+// private void initPost() {
+//
+// }
+//
+// //组织架构组初始化
+// private void initGroup() {
+//
+// }
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+ @Autowired
+ private SysOrgDeptService deptService;
+
+ @Autowired
+ private SysOrgUserService userService;
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/ldap/LdapConfig.java b/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/ldap/LdapConfig.java
new file mode 100644
index 0000000..b180516
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/ldap/LdapConfig.java
@@ -0,0 +1,50 @@
+package com.zsvg.vboot.config.dbx.ldap;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.LdapContextSource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class LdapConfig {
+
+ @Value("${ldap.url}")
+ private String ldapUrl;
+
+ @Value("${ldap.base}")
+ private String ldapBase;
+
+ @Value("${ldap.userDn}")
+ private String ldapUserDn;
+
+ @Value("${ldap.userPwd}")
+ private String ldapUserPwd;
+
+ @Value("${ldap.referral}")
+ private String ldapReferral;
+
+ @Bean
+ public LdapTemplate ldapTemplate() {
+ return new LdapTemplate(contextSourceTarget());
+ }
+
+ @Bean
+ public LdapContextSource contextSourceTarget() {
+ LdapContextSource ldapContextSource = new LdapContextSource();
+ ldapContextSource.setUrl(ldapUrl);
+ ldapContextSource.setBase(ldapBase);
+ ldapContextSource.setUserDn(ldapUserDn);
+ ldapContextSource.setPassword(ldapUserPwd);
+ ldapContextSource.setReferral(ldapReferral);
+ Map config = new HashMap();
+ config.put("java.naming.ldap.attributes.binary", "objectGUID");
+// config.put("com.sun.jndi.ldap.read.timeout","3000");
+ ldapContextSource.setPooled(false);
+ ldapContextSource.setBaseEnvironmentProperties(config);
+ return ldapContextSource;
+ }
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/redis/RedisConfig.java b/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/redis/RedisConfig.java
new file mode 100644
index 0000000..bdf20d2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/redis/RedisConfig.java
@@ -0,0 +1,197 @@
+package com.zsvg.vboot.config.dbx.redis;
+
+import cn.hutool.core.lang.Assert;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.parser.ParserConfig;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import lombok.extern.slf4j.Slf4j;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cache.Cache;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.CacheErrorHandler;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.RedisSerializer;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+@Configuration
+@EnableCaching
+@ConditionalOnClass(RedisOperations.class)
+@EnableConfigurationProperties(RedisProperties.class)
+public class RedisConfig extends CachingConfigurerSupport {
+
+ /**
+ * 设置 redis 数据默认过期时间,默认2小时
+ * 设置@cacheable 序列化方式
+ */
+ @Bean
+ public RedisCacheConfiguration redisCacheConfiguration() {
+ FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
+ RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
+ configuration = configuration.serializeValuesWith(RedisSerializationContext.
+ SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(6));
+ return configuration;
+ }
+
+ @SuppressWarnings("all")
+ @Bean(name = "redisTemplate")
+ @ConditionalOnMissingBean(name = "redisTemplate")
+ public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
+ RedisTemplate template = new RedisTemplate<>();
+ //序列化
+ FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
+ // value值的序列化采用fastJsonRedisSerializer
+ template.setValueSerializer(fastJsonRedisSerializer);
+ template.setHashValueSerializer(fastJsonRedisSerializer);
+ // 全局开启AutoType,这里方便开发,使用全局的方式
+ ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
+ // 建议使用这种方式,小范围指定白名单
+ // ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain");
+ // key的序列化采用StringRedisSerializer
+ template.setKeySerializer(new StringRedisSerializer());
+ template.setHashKeySerializer(new StringRedisSerializer());
+ template.setConnectionFactory(redisConnectionFactory);
+ return template;
+ }
+
+ /**
+ * 自定义缓存key生成策略,默认将使用该策略
+ */
+ @Bean
+ @Override
+ public KeyGenerator keyGenerator() {
+ return (target, method, params) -> {
+ Map container = new HashMap<>(3);
+ Class> targetClassClass = target.getClass();
+ // 类地址
+ container.put("class", targetClassClass.toGenericString());
+ // 方法名称
+ container.put("methodName", method.getName());
+ // 包名称
+ container.put("package", targetClassClass.getPackage());
+ // 参数列表
+ for (int i = 0; i < params.length; i++) {
+ container.put(String.valueOf(i), params[i]);
+ }
+ // 转为JSON字符串
+ String jsonString = JSON.toJSONString(container);
+ // 做SHA256 Hash计算,得到一个SHA256摘要作为Key
+ return DigestUtils.sha256Hex(jsonString);
+ };
+ }
+
+ @Bean
+ @Override
+ public CacheErrorHandler errorHandler() {
+ // 异常处理,当Redis发生异常时,打印日志,但是程序正常走
+ log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
+ return new CacheErrorHandler() {
+ @Override
+ public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
+ log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
+ }
+
+ @Override
+ public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
+ log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
+ }
+
+ @Override
+ public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
+ log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
+ }
+
+ @Override
+ public void handleCacheClearError(RuntimeException e, Cache cache) {
+ log.error("Redis occur handleCacheClearError:", e);
+ }
+ };
+ }
+
+}
+
+/**
+ * Value 序列化
+ *
+ * @param
+ * @author /
+ */
+class FastJsonRedisSerializer implements RedisSerializer {
+
+ private final Class clazz;
+
+ FastJsonRedisSerializer(Class clazz) {
+ super();
+ this.clazz = clazz;
+ }
+
+ @Override
+ public byte[] serialize(T t) {
+ if (t == null) {
+ return new byte[0];
+ }
+ return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public T deserialize(byte[] bytes) {
+ if (bytes == null || bytes.length <= 0) {
+ return null;
+ }
+ String str = new String(bytes, StandardCharsets.UTF_8);
+ return JSON.parseObject(str, clazz);
+ }
+
+}
+
+/**
+ * 重写序列化器
+ *
+ * @author /
+ */
+class StringRedisSerializer implements RedisSerializer {
+
+ private final Charset charset;
+
+ StringRedisSerializer() {
+ this(StandardCharsets.UTF_8);
+ }
+
+ private StringRedisSerializer(Charset charset) {
+ Assert.notNull(charset, "Charset must not be null!");
+ this.charset = charset;
+ }
+
+ @Override
+ public String deserialize(byte[] bytes) {
+ return (bytes == null ? null : new String(bytes, charset));
+ }
+
+ @Override
+ public byte[] serialize(Object object) {
+ String string = JSON.toJSONString(object);
+ if (XstringUtil.isBlank(string)) {
+ return null;
+ }
+ string = string.replace("\"", "");
+ return string.getBytes(charset);
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/redis/RedisHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/redis/RedisHandler.java
new file mode 100644
index 0000000..2d12376
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/dbx/redis/RedisHandler.java
@@ -0,0 +1,693 @@
+package com.zsvg.vboot.config.dbx.redis;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.Cursor;
+import org.springframework.data.redis.core.RedisConnectionUtils;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+@Component
+@SuppressWarnings({"unchecked", "all"})
+public class RedisHandler {
+ private static final Logger log = LoggerFactory.getLogger(RedisHandler.class);
+ private RedisTemplate redisTemplate;
+
+// @Value("${jwt.online-key}")
+ private String onlineKey="online-key";
+
+ public RedisHandler(RedisTemplate redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }
+
+ /**
+ * 指定缓存失效时间
+ *
+ * @param key 键
+ * @param time 时间(秒)
+ */
+ public boolean expire(String key, long time) {
+ try {
+ if (time > 0) {
+ redisTemplate.expire(key, time, TimeUnit.SECONDS);
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 指定缓存失效时间
+ *
+ * @param key 键
+ * @param time 时间(秒)
+ * @param timeUnit 单位
+ */
+ public boolean expire(String key, long time, TimeUnit timeUnit) {
+ try {
+ if (time > 0) {
+ redisTemplate.expire(key, time, timeUnit);
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 根据 key 获取过期时间
+ *
+ * @param key 键 不能为null
+ * @return 时间(秒) 返回0代表为永久有效
+ */
+ public long getExpire(Object key) {
+ return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+ }
+
+ /**
+ * 查找匹配key
+ *
+ * @param pattern key
+ * @return /
+ */
+ public List scan(String pattern) {
+ ScanOptions options = ScanOptions.scanOptions().match(pattern).build();
+ RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
+ RedisConnection rc = Objects.requireNonNull(factory).getConnection();
+ Cursor cursor = rc.scan(options);
+ List result = new ArrayList<>();
+ while (cursor.hasNext()) {
+ result.add(new String(cursor.next()));
+ }
+ try {
+ RedisConnectionUtils.releaseConnection(rc, factory);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return result;
+ }
+
+ /**
+ * 分页查询 key
+ *
+ * @param patternKey key
+ * @param page 页码
+ * @param size 每页数目
+ * @return /
+ */
+ public List findKeysForPage(String patternKey, int page, int size) {
+ ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
+ RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
+ RedisConnection rc = Objects.requireNonNull(factory).getConnection();
+ Cursor cursor = rc.scan(options);
+ List result = new ArrayList<>(size);
+ int tmpIndex = 0;
+ int fromIndex = page * size;
+ int toIndex = page * size + size;
+ while (cursor.hasNext()) {
+ if (tmpIndex >= fromIndex && tmpIndex < toIndex) {
+ result.add(new String(cursor.next()));
+ tmpIndex++;
+ continue;
+ }
+ // 获取到满足条件的数据后,就可以退出了
+ if (tmpIndex >= toIndex) {
+ break;
+ }
+ tmpIndex++;
+ cursor.next();
+ }
+ try {
+ RedisConnectionUtils.releaseConnection(rc, factory);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return result;
+ }
+
+ /**
+ * 判断key是否存在
+ *
+ * @param key 键
+ * @return true 存在 false不存在
+ */
+ public boolean hasKey(String key) {
+ try {
+ return redisTemplate.hasKey(key);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 删除缓存
+ *
+ * @param key 可以传一个值 或多个
+ */
+ public void del(String... keys) {
+ if (keys != null && keys.length > 0) {
+ if (keys.length == 1) {
+ boolean result = redisTemplate.delete(keys[0]);
+ log.debug("--------------------------------------------");
+ log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString());
+ log.debug("--------------------------------------------");
+ } else {
+ Set keySet = new HashSet<>();
+ for (String key : keys) {
+ keySet.addAll(redisTemplate.keys(key));
+ }
+ long count = redisTemplate.delete(keySet);
+ log.debug("--------------------------------------------");
+ log.debug("成功删除缓存:" + keySet.toString());
+ log.debug("缓存删除数量:" + count + "个");
+ log.debug("--------------------------------------------");
+ }
+ }
+ }
+
+ // ============================String=============================
+
+ /**
+ * 普通缓存获取
+ *
+ * @param key 键
+ * @return 值
+ */
+ public Object get(String key) {
+ return key == null ? null : redisTemplate.opsForValue().get(key);
+ }
+
+ /**
+ * 批量获取
+ *
+ * @param keys
+ * @return
+ */
+ public List multiGet(List keys) {
+ List list = redisTemplate.opsForValue().multiGet(Sets.newHashSet(keys));
+ List resultList = Lists.newArrayList();
+ Optional.ofNullable(list).ifPresent(e -> list.forEach(ele -> Optional.ofNullable(ele).ifPresent(resultList::add)));
+ return resultList;
+ }
+
+ /**
+ * 普通缓存放入
+ *
+ * @param key 键
+ * @param value 值
+ * @return true成功 false失败
+ */
+ public boolean set(String key, Object value) {
+ try {
+ redisTemplate.opsForValue().set(key, value);
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 普通缓存放入并设置时间
+ *
+ * @param key 键
+ * @param value 值
+ * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
+ * @return true成功 false 失败
+ */
+ public boolean set(String key, Object value, long time) {
+ try {
+ if (time > 0) {
+ redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+ } else {
+ set(key, value);
+ }
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 普通缓存放入并设置时间
+ *
+ * @param key 键
+ * @param value 值
+ * @param time 时间
+ * @param timeUnit 类型
+ * @return true成功 false 失败
+ */
+ public boolean set(String key, Object value, long time, TimeUnit timeUnit) {
+ try {
+ if (time > 0) {
+ redisTemplate.opsForValue().set(key, value, time, timeUnit);
+ } else {
+ set(key, value);
+ }
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ // ================================Map=================================
+
+ /**
+ * HashGet
+ *
+ * @param key 键 不能为null
+ * @param item 项 不能为null
+ * @return 值
+ */
+ public Object hget(String key, String item) {
+ return redisTemplate.opsForHash().get(key, item);
+ }
+
+ /**
+ * 获取hashKey对应的所有键值
+ *
+ * @param key 键
+ * @return 对应的多个键值
+ */
+ public Map hmget(String key) {
+ return redisTemplate.opsForHash().entries(key);
+
+ }
+
+ /**
+ * HashSet
+ *
+ * @param key 键
+ * @param map 对应多个键值
+ * @return true 成功 false 失败
+ */
+ public boolean hmset(String key, Map map) {
+ try {
+ redisTemplate.opsForHash().putAll(key, map);
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * HashSet 并设置时间
+ *
+ * @param key 键
+ * @param map 对应多个键值
+ * @param time 时间(秒)
+ * @return true成功 false失败
+ */
+ public boolean hmset(String key, Map map, long time) {
+ try {
+ redisTemplate.opsForHash().putAll(key, map);
+ if (time > 0) {
+ expire(key, time);
+ }
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 向一张hash表中放入数据,如果不存在将创建
+ *
+ * @param key 键
+ * @param item 项
+ * @param value 值
+ * @return true 成功 false失败
+ */
+ public boolean hset(String key, String item, Object value) {
+ try {
+ redisTemplate.opsForHash().put(key, item, value);
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 向一张hash表中放入数据,如果不存在将创建
+ *
+ * @param key 键
+ * @param item 项
+ * @param value 值
+ * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
+ * @return true 成功 false失败
+ */
+ public boolean hset(String key, String item, Object value, long time) {
+ try {
+ redisTemplate.opsForHash().put(key, item, value);
+ if (time > 0) {
+ expire(key, time);
+ }
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 删除hash表中的值
+ *
+ * @param key 键 不能为null
+ * @param item 项 可以使多个 不能为null
+ */
+ public void hdel(String key, Object... item) {
+ redisTemplate.opsForHash().delete(key, item);
+ }
+
+ /**
+ * 判断hash表中是否有该项的值
+ *
+ * @param key 键 不能为null
+ * @param item 项 不能为null
+ * @return true 存在 false不存在
+ */
+ public boolean hHasKey(String key, String item) {
+ return redisTemplate.opsForHash().hasKey(key, item);
+ }
+
+ /**
+ * hash递增 如果不存在,就会创建一个 并把新增后的值返回
+ *
+ * @param key 键
+ * @param item 项
+ * @param by 要增加几(大于0)
+ * @return
+ */
+ public double hincr(String key, String item, double by) {
+ return redisTemplate.opsForHash().increment(key, item, by);
+ }
+
+ /**
+ * hash递减
+ *
+ * @param key 键
+ * @param item 项
+ * @param by 要减少记(小于0)
+ * @return
+ */
+ public double hdecr(String key, String item, double by) {
+ return redisTemplate.opsForHash().increment(key, item, -by);
+ }
+
+ // ============================set=============================
+
+ /**
+ * 根据key获取Set中的所有值
+ *
+ * @param key 键
+ * @return
+ */
+ public Set sGet(String key) {
+ try {
+ return redisTemplate.opsForSet().members(key);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * 根据value从一个set中查询,是否存在
+ *
+ * @param key 键
+ * @param value 值
+ * @return true 存在 false不存在
+ */
+ public boolean sHasKey(String key, Object value) {
+ try {
+ return redisTemplate.opsForSet().isMember(key, value);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 将数据放入set缓存
+ *
+ * @param key 键
+ * @param values 值 可以是多个
+ * @return 成功个数
+ */
+ public long sSet(String key, Object... values) {
+ try {
+ return redisTemplate.opsForSet().add(key, values);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return 0;
+ }
+ }
+
+ /**
+ * 将set数据放入缓存
+ *
+ * @param key 键
+ * @param time 时间(秒)
+ * @param values 值 可以是多个
+ * @return 成功个数
+ */
+ public long sSetAndTime(String key, long time, Object... values) {
+ try {
+ Long count = redisTemplate.opsForSet().add(key, values);
+ if (time > 0) {
+ expire(key, time);
+ }
+ return count;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return 0;
+ }
+ }
+
+ /**
+ * 获取set缓存的长度
+ *
+ * @param key 键
+ * @return
+ */
+ public long sGetSetSize(String key) {
+ try {
+ return redisTemplate.opsForSet().size(key);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return 0;
+ }
+ }
+
+ /**
+ * 移除值为value的
+ *
+ * @param key 键
+ * @param values 值 可以是多个
+ * @return 移除的个数
+ */
+ public long setRemove(String key, Object... values) {
+ try {
+ Long count = redisTemplate.opsForSet().remove(key, values);
+ return count;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return 0;
+ }
+ }
+
+ // ===============================list=================================
+
+ /**
+ * 获取list缓存的内容
+ *
+ * @param key 键
+ * @param start 开始
+ * @param end 结束 0 到 -1代表所有值
+ * @return
+ */
+ public List lGet(String key, long start, long end) {
+ try {
+ return redisTemplate.opsForList().range(key, start, end);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * 获取list缓存的长度
+ *
+ * @param key 键
+ * @return
+ */
+ public long lGetListSize(String key) {
+ try {
+ return redisTemplate.opsForList().size(key);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return 0;
+ }
+ }
+
+ /**
+ * 通过索引 获取list中的值
+ *
+ * @param key 键
+ * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
+ * @return
+ */
+ public Object lGetIndex(String key, long index) {
+ try {
+ return redisTemplate.opsForList().index(key, index);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * 将list放入缓存
+ *
+ * @param key 键
+ * @param value 值
+ * @return
+ */
+ public boolean lSet(String key, Object value) {
+ try {
+ redisTemplate.opsForList().rightPush(key, value);
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 将list放入缓存
+ *
+ * @param key 键
+ * @param value 值
+ * @param time 时间(秒)
+ * @return
+ */
+ public boolean lSet(String key, Object value, long time) {
+ try {
+ redisTemplate.opsForList().rightPush(key, value);
+ if (time > 0) {
+ expire(key, time);
+ }
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 将list放入缓存
+ *
+ * @param key 键
+ * @param value 值
+ * @return
+ */
+ public boolean lSet(String key, List value) {
+ try {
+ redisTemplate.opsForList().rightPushAll(key, value);
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 将list放入缓存
+ *
+ * @param key 键
+ * @param value 值
+ * @param time 时间(秒)
+ * @return
+ */
+ public boolean lSet(String key, List value, long time) {
+ try {
+ redisTemplate.opsForList().rightPushAll(key, value);
+ if (time > 0) {
+ expire(key, time);
+ }
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 根据索引修改list中的某条数据
+ *
+ * @param key 键
+ * @param index 索引
+ * @param value 值
+ * @return /
+ */
+ public boolean lUpdateIndex(String key, long index, Object value) {
+ try {
+ redisTemplate.opsForList().set(key, index, value);
+ return true;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 移除N个值为value
+ *
+ * @param key 键
+ * @param count 移除多少个
+ * @param value 值
+ * @return 移除的个数
+ */
+ public long lRemove(String key, long count, Object value) {
+ try {
+ return redisTemplate.opsForList().remove(key, count, value);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return 0;
+ }
+ }
+
+ /**
+ * @param prefix 前缀
+ * @param ids id
+ */
+ public void delByKeys(String prefix, Set ids) {
+ Set keys = new HashSet<>();
+ for (Long id : ids) {
+ keys.addAll(redisTemplate.keys(new StringBuffer(prefix).append(id).toString()));
+ }
+ long count = redisTemplate.delete(keys);
+ // 此处提示可自行删除
+ log.debug("--------------------------------------------");
+ log.debug("成功删除缓存:" + keys.toString());
+ log.debug("缓存删除数量:" + count + "个");
+ log.debug("--------------------------------------------");
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/SecurityConfig.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/SecurityConfig.java
new file mode 100644
index 0000000..64a7b14
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/SecurityConfig.java
@@ -0,0 +1,116 @@
+package com.zsvg.vboot.config.security;
+
+import com.zsvg.vboot.config.dbx.redis.RedisHandler;
+import com.zsvg.vboot.config.security.authn.AuthnFailedHandler;
+import com.zsvg.vboot.config.security.authz.AuthzDeniedHandler;
+import com.zsvg.vboot.config.security.jwt.JwtFilterAdapter;
+import com.zsvg.vboot.config.security.jwt.JwtHandler;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+@Configuration
+@RequiredArgsConstructor
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ //1.禁用JWT登录无关的相关功能
+ http.headers().frameOptions().disable().and()
+ .formLogin(AbstractHttpConfigurer::disable)
+ .httpBasic(AbstractHttpConfigurer::disable)
+ .csrf(AbstractHttpConfigurer::disable)
+ .logout(AbstractHttpConfigurer::disable)
+ .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
+
+ //2.跨域处理
+ http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
+
+ //3.启用JWT过滤器
+ http.apply(securityConfigurerAdapter());
+
+ //4.过滤器异常与授权失败处理
+ http.exceptionHandling()
+ .authenticationEntryPoint(authnFailedHandler)
+ .accessDeniedHandler(authzDeniedHandler);
+
+ //5.授权配置
+ http.authorizeRequests(authorizeRequests -> authorizeRequests
+ .antMatchers("/gen/**").permitAll()//gen通用的请求直接放行
+// .antMatchers("/sys/**").hasRole("ADMIN")//sys开头的需要管理员权限
+// .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()//放行OPTIONS请求
+ .antMatchers("/**").access("@authzHandler.hasPermission(request, authentication)")//其他请求统一认证
+// .antMatchers("/getUserInfo").hasRole("xxx")
+ .anyRequest().authenticated());
+
+ }
+
+ //<<-------------------------------2.跨域处理-------------------------------
+ @Bean
+ CorsConfigurationSource corsConfigurationSource() {
+ CorsConfiguration configuration = new CorsConfiguration();
+// if (environment.acceptsProfiles(Profiles.of("dev"))) {
+// configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3100"));
+// } else {
+// configuration.setAllowedOrigins(Collections.singletonList("https://uaa.imooc.com"));
+// }
+// configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3100"));
+ configuration.setAllowedOrigins(Collections.singletonList("*"));
+ configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
+ configuration.setAllowedHeaders(Collections.singletonList("*"));
+ configuration.addExposedHeader("X-Authenticate");
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ source.registerCorsConfiguration("/**", configuration);
+ return source;
+ }
+ //>>
+
+ //<<-------------------------------3.启用JWT过滤器-------------------------------
+ private final JwtHandler jwtHandler;
+
+ private final RedisHandler redisHandler;
+
+ //JwtFilter 如果通过@Component 注解注入,则web.ignoring().antMatchers 不起作用,还是会被拦截过滤
+ private JwtFilterAdapter securityConfigurerAdapter() {
+ return new JwtFilterAdapter(jwtHandler, redisHandler);
+ }
+ //>>
+
+ //<<-------------------------------4.过滤器异常与授权失败处理-------------------------------
+ private final AuthzDeniedHandler authzDeniedHandler;//解决认证过的用户访问无权限资源时的异常
+
+ private final AuthnFailedHandler authnFailedHandler;//解决匿名用户访问无权限资源时的异常
+ //>>
+
+ //<<-------------------------------X.其他配置-------------------------------
+ //配置security忽略的请求与资源
+ @Override
+ public void configure(WebSecurity web) {
+ web.ignoring().antMatchers("/**","/assets/**","/druid/**","/login", "/pub/**","/index.html","/vben.html","/favicon.ico","/resource/**","/_app.config.js");
+ }
+
+// @Override
+// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+// auth.authenticationProvider(ssLoginProvider);
+//// auth.userDetailsService(ssUserDetailsService).passwordEncoder( passwordEncoder());
+// }
+
+// @Bean
+// public PasswordEncoder passwordEncoder() {
+// return new BCryptPasswordEncoder();
+// }
+ //authn是认证相关的类,authz是授权相关的类
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnController.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnController.java
new file mode 100644
index 0000000..5210c8e
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnController.java
@@ -0,0 +1,152 @@
+package com.zsvg.vboot.config.security.authn;
+
+import cn.hutool.core.util.IdUtil;
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.config.AppConfig;
+import com.zsvg.vboot.module.sys.org.user.SysOrgUserService;
+import com.zsvg.vboot.config.dbx.redis.RedisHandler;
+import com.zsvg.vboot.config.security.jwt.JwtHandler;
+import com.zsvg.vboot.config.security.pojo.Duser;
+import com.zsvg.vboot.config.security.pojo.Zmenu;
+import com.zsvg.vboot.config.security.pojo.Zmeta;
+import com.zsvg.vboot.config.security.pojo.Zuser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.security.core.Authentication;
+import org.springframework.util.DigestUtils;
+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 javax.validation.Valid;
+import javax.websocket.server.PathParam;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+@RestController
+public class AuthnController {
+
+ @PostMapping("/login")
+ public RestResult login(@Valid @RequestBody LoginDto loginDTO) throws IOException, ClassNotFoundException {
+ System.out.println("开始登录");
+
+ //1.登录验证
+ Duser duser = null;
+ try {
+ duser = jdbcDao.getTp().queryForObject("select id,name,pacod,retag from sys_org_user where usnam=? and avtag=1",
+ new Object[]{loginDTO.getUsername()}, new BeanPropertyRowMapper<>(Duser.class));
+ } catch (DataAccessException ignored) {
+
+ }
+
+ boolean passFlag = false;
+ if (duser != null) {
+ String encodePassword = DigestUtils.md5DigestAsHex(("abc" + loginDTO.getPassword() + "xyz").getBytes());//数据库密码验证
+ if (encodePassword.equals(duser.getPacod())) {
+ passFlag = true;
+ } else {
+ passFlag = ldapService.authenticate(loginDTO.getUsername(), loginDTO.getPassword());//AD域密码验证
+ }
+ }
+ if (!passFlag) {
+ return RestResult.build(402, "账号不存在或密码错误");
+ }
+
+ //2.初始化用户信息,获取菜单与权限
+ String atokenUUID = IdUtil.simpleUUID();
+ String atoken = jwtHandler.createTokenByUuid(atokenUUID);
+ String rtoken = jwtHandler.createTokenByUuid(loginDTO.getUsername());//需要加密下
+
+ Map backMap = new HashMap<>();
+ backMap.put("token", atoken);
+ backMap.put("rtoken", rtoken);
+
+ Zuser zuser = new Zuser(duser.getId(), duser.getName(), loginDTO.getUsername());
+ authnService.initZuser(zuser, duser, backMap);//初始化用户
+
+ redisHandler.set(atokenUUID, zuser, appConfig.getJwt().getAtime());//默认8小时过期
+
+ //3.登录日志记录
+ return RestResult.ok(backMap);
+
+ }
+
+ @GetMapping("/rtoken")
+ public RestResult rtoken(@PathParam("token2") String token2) {
+ System.out.println("token2=" + token2);
+ String username = jwtHandler.getClaims(token2).getId();
+ System.out.println("username=" + username);
+ String uuid = IdUtil.simpleUUID();
+ String token = jwtHandler.createTokenByUuid(uuid);
+ Zuser zuser = authnService.getUser(username);
+ redisHandler.set(uuid, zuser, 10000 / 1000);
+ Map backMap = new HashMap<>();
+ backMap.put("token", token);
+ return RestResult.ok(backMap);
+ }
+
+ @GetMapping("/getMenuList")
+ public RestResult getMenuList(Authentication auth) {
+ List zmenuList = new ArrayList<>();
+ Zmenu zmenu = new Zmenu();
+ zmenu.setPath("/sys/org");
+ zmenu.setName("SysOrg");
+ zmenu.setComponent("LAYOUT");
+ zmenu.setRedirect("/sys/org/user");
+ Zmeta zmeta = new Zmeta();
+ zmeta.setOrderNo(1);
+ zmeta.setIcon("ant-design:apartment-outlined");
+ zmeta.setTitle("组织架构");
+ zmenu.setMeta(zmeta);
+ zmenuList.add(zmenu);
+
+ Zmenu zmenu2 = new Zmenu();
+ zmenu2.setPath("dept");
+ zmenu2.setName("SysOrgDept");
+ zmenu2.setComponent("/sys/org/dept/index.vue");
+ Zmeta zmeta2 = new Zmeta();
+ zmeta2.setOrderNo(1);
+ zmeta2.setIcon("ant-design:apartment-outlined");
+ zmeta2.setTitle("部门管理");
+ zmeta2.setIgnoreKeepAlive(false);
+ zmenu2.setMeta(zmeta2);
+
+ zmenu.setChildren(new ArrayList<>());
+ zmenu.getChildren().add(zmenu2);
+
+
+// return RestResult.ok(authnService.findMenuList(auth));
+ return RestResult.ok(zmenuList);
+ }
+
+
+ @Autowired
+ private AuthnService authnService;
+
+ @Autowired
+ private AppConfig appConfig;
+
+ @Autowired
+ private RedisHandler redisHandler;
+
+ @Autowired
+ private JwtHandler jwtHandler;
+
+ @Autowired
+ private LdapService ldapService;
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+ @Autowired
+ private SysOrgUserService userService;
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnFailedHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnFailedHandler.java
new file mode 100644
index 0000000..1969352
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnFailedHandler.java
@@ -0,0 +1,40 @@
+package com.zsvg.vboot.config.security.authn;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.http.HttpStatus;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+@Component
+public class AuthnFailedHandler implements AuthenticationEntryPoint {
+
+ @Override
+ public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
+ if (!response.isCommitted()) {
+ response.setCharacterEncoding(StandardCharsets.UTF_8.name());
+ response.setStatus(200);
+ response.setHeader("Content-Type", "application/json;charset=UTF-8");
+ try (ServletOutputStream ous = response.getOutputStream()) {
+ Map map = new HashMap<>(16);
+ map.put("code", HttpStatus.SC_UNAUTHORIZED);
+// map.put("code", HttpStatus.SC_OK);
+ map.put("success", false);
+ System.out.println(e.getMessage());
+// response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage());
+
+ map.put("message", Optional.ofNullable(request.getAttribute("errorMessage")).orElse("认证失败").toString());
+ ous.write(JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8));
+ }
+ }
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnService.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnService.java
new file mode 100644
index 0000000..a2554fa
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnService.java
@@ -0,0 +1,262 @@
+package com.zsvg.vboot.config.security.authn;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.config.security.pojo.Duser;
+import com.zsvg.vboot.config.security.pojo.Zmenu;
+import com.zsvg.vboot.config.security.pojo.Zmeta;
+import com.zsvg.vboot.config.security.pojo.Zuser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class AuthnService {
+
+ public void initZuser(Zuser zuser, Duser duser, Map backMap) {
+ if (!duser.getRetag()) {
+ //1.获取用户所有的组织架构集:conds
+ String conds = findConds(duser);
+ zuser.setConds(conds);
+
+ //2.根据组织架构集conds查询前台菜单集:menus
+ List menuList = findMenuList(zuser.getConds());
+
+ //3.根据组织架构集conds查询前台按钮集:btns
+ List btnList = findBtnList(zuser.getConds());
+
+ //4.计算后台缓存的url权限集
+ List permList = new ArrayList<>();
+ for (Zmenu menu : menuList) {
+ if (StrUtil.isNotBlank(menu.getPerm())) {
+ permList.add(menu.getPerm());
+ }
+ }
+ permList.addAll(btnList);
+ zuser.setPermList(permList);
+
+ //5.设置前台返回数据
+ menuList = buildTree(menuList);
+ backMap.put("menus", menuList);
+ backMap.put("btns", btnList);
+ backMap.put("zuser", zuser);
+
+ //6.更新用户,序列化保存数据,使下次这些数据可直接从数据库取
+ updateUser(zuser, menuList, btnList);
+ System.out.println("通过数据库");
+
+ } else {
+ String sql = "select conds,menus,btns,perms from sys_org_user where id=?";
+ Map map = jdbcDao.findMap(sql, zuser.getId());
+
+ zuser.setConds((String) map.get("conds"));
+
+ List menuList = JSON.parseArray((String) map.get("menus"), Zmenu.class);
+
+ String[] btnArr = null;
+ String btns = (String) map.get("btns");
+ if (btns != null) {
+ btnArr = btns.split(";");
+ }
+
+ String[] permArr = null;
+ String perms = (String) map.get("perms");
+ if (perms != null) {
+ permArr = perms.split(";");
+ }
+ List permList = new ArrayList<>();
+ if (permArr != null) {
+ permList = Arrays.asList(permArr);
+ }
+
+ zuser.setPermList(permList);
+ backMap.put("menus", menuList);
+ backMap.put("btns", btnArr);
+ backMap.put("zuser", zuser);
+ System.out.println("通过缓存");
+ }
+
+// //初始化数据库user
+// String perms = "";
+// for (int i = 0; i < permSum.length; i++) {
+// perms += permSum[i] + ";";
+// }
+// if (!perms.equals("")) {
+// perms = perms.substring(0, perms.length() - 1);
+// } else {
+// perms = "0";
+// }
+// updatePerson(perms, conds, id);
+// zuser = new Zuser(id, "" + orgInfo.get("name"), sysOrgUser.getUsnam(), permSum, conds);
+// zuser.setAdmin(XuserUtil.isAdmin(sysOrgUser.getUsnam()));
+// zuser.setWatag(sysOrgUser.getWatag());
+// } else {
+// String[] permArr = sysOrgUser.getPerms().split(";");
+// long[] permSum = new long[permArr.length];
+// for (int i = 0; i < permArr.length; i++) {
+// permSum[i] = Long.parseLong(permArr[i]);
+// }
+// zuser = new Zuser(id, "" + orgInfo.get("name"), "" + sysOrgUser.getUsnam(), permSum, sysOrgUser.getConds());
+// zuser.setAdmin(XuserUtil.isAdmin(sysOrgUser.getUsnam()));
+// zuser.setWatag(sysOrgUser.getWatag());
+// }
+// return zuser;
+
+
+ }
+
+// private void calcPerms(Zuser zuser,){
+// //查询权限集合
+// Integer posSum = SysAuthPermService.AUTHPOS + 1;//取出最大权限位
+// long[] permSum = new long[posSum];
+////
+// List zpermList = getPermList(conds);
+// for (Zperm zperm : zpermList) {
+// for (int i = 0; i < posSum; i++) {
+// if (i == zperm.getPos()) {
+// permSum[i] = permSum[i] + zperm.getCode();
+// }
+// }
+// }
+// }
+
+
+ private String findConds(Duser duser) {
+ StringBuilder conds = new StringBuilder();
+ //1. conds拼接父级id
+ if (StrUtil.isNotBlank(duser.getTier())) {
+ String[] pidArr = duser.getTier().split("x");
+ for (int i = pidArr.length - 1; i >= 0; i--) {
+ if (!"".equals(pidArr[i])) {
+ conds.append("'").append(pidArr[i]).append("',");
+ }
+ }
+ } else {
+ conds = new StringBuilder("'" + duser.getId() + "',");
+ }
+ //2. conds拼接岗位id
+ List postList = findPostList(duser.getId());
+ for (String str : postList) {
+ conds.append("'").append(str).append("',");
+ }
+ conds = new StringBuilder(conds.substring(0, conds.length() - 1));//优化
+ //3. conds拼接群组id
+ List groupList = findGroupList(conds.toString());
+ for (String str : groupList) {
+ conds.append(",'").append(str).append("'");
+ }
+ return conds.toString();
+ }
+
+
+ private List findPostList(String uid) {
+ String sql = "select pid as id from sys_org_post_user where uid=?";
+ return jdbcDao.findStringList(sql, uid);
+ }
+
+ private List findGroupList(String conds) {
+ String sql = "select DISTINCT gid as id from sys_org_group_org where oid in (" + conds + ")";
+ return jdbcDao.findStringList(sql);
+ }
+
+
+ private List findMenuList(String conds) {
+ String sql = "select distinct m.name,m.code,m.path,m.icon,m.comp,m.ornum,m.id,m.pid,m.perm from sys_auth_menu m inner join sys_auth_role_menu rm on rm.mid=m.id inner join sys_auth_role_org ru on ru.rid=rm.rid where m.type in ('D','M') and m.avtag=1 and ru.oid in (" + conds + ") order by m.ornum";
+ if(conds.contains("'sa'")||conds.contains("'vben'")){
+ sql = "select m.name,m.code,m.path,m.icon,m.comp,m.ornum,m.id,m.pid,m.perm from sys_auth_menu m where m.type in ('D','M') and m.avtag=1 order by m.ornum";
+ }
+
+ List list = jdbcDao.getTp().query(sql, (rs, rowNum) -> {
+ Zmenu zmenu = new Zmenu();
+ zmenu.setId(rs.getString("id"));
+ zmenu.setPid(rs.getString("pid"));
+ zmenu.setPerm(rs.getString("perm"));
+ zmenu.setName(rs.getString("code"));
+ zmenu.setPath(rs.getString("path"));
+ zmenu.setComponent(rs.getString("comp"));
+ Zmeta zmeta = new Zmeta();
+ zmeta.setTitle(rs.getString("name"));
+ zmeta.setOrderNo(rs.getInt("ornum"));
+ zmeta.setIcon(rs.getString("icon"));
+ zmenu.setMeta(zmeta);
+ return zmenu;
+ });
+ return list;
+ }
+
+
+ //使用递归方法建树
+ private List buildTree(List treeNodes) {
+ List trees = new ArrayList<>();
+ for (Zmenu treeNode : treeNodes) {
+ if (treeNode.getPid() == null) {
+ trees.add(recTree(treeNode, treeNodes));
+ }
+ }
+ return trees;
+ }
+
+
+ //递归查找子节点
+ private Zmenu recTree(Zmenu treeNode, List treeNodes) {
+ for (Zmenu it : treeNodes) {
+ if (treeNode.getId().equals(it.getPid())) {
+ if (treeNode.getChildren() == null) {
+ treeNode.setChildren(new ArrayList<>());
+ }
+ treeNode.getChildren().add(recTree(it, treeNodes));
+ }
+ }
+ return treeNode;
+ }
+
+
+ private List findBtnList(String conds) {
+ String sql = "select distinct m.perm id from sys_auth_menu m inner join sys_auth_role_menu rm on rm.mid=m.id inner join sys_auth_role_org ru on ru.rid=rm.rid where m.type = 'B' and m.avtag=1 and ru.oid in (" + conds + ") order by m.ornum";
+ if(conds.contains("'sa'")||conds.contains("'vben'")){
+ sql = "select m.perm id from sys_auth_menu m where m.type = 'B' and m.avtag=1 order by m.ornum";
+ }
+ return jdbcDao.findStringList(sql);
+ }
+
+
+ private void updateUser(Zuser zuser, List menuList, List btnList) {
+
+ String menus = JSON.toJSONString(menuList);
+ StringBuilder btns = new StringBuilder();
+ for (String str : btnList) {
+ btns.append(str).append(";");
+ }
+
+ StringBuilder perms = new StringBuilder();
+ for (String str : zuser.getPermList()) {
+ perms.append(str).append(";");
+ }
+
+ String sql = "update sys_org_user set conds=?,menus=?,btns=?,perms=?,retag=1 where id=?";
+ jdbcDao.update(sql, zuser.getConds(), menus, btns.toString(), perms.toString(), zuser.getId());
+ }
+
+
+ @Transactional(readOnly = true)
+ public Zuser getUser(String username) {
+ Map map = jdbcDao.getTp().queryForMap("select u.id,u.name from sys_org_user u where u.usnam=? and u.avtag=1", username);
+ Zuser user = new Zuser();
+ user.setId((String) map.get("id"));
+ user.setName((String) map.get("name"));
+ return user;
+ }
+
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/LdapService.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/LdapService.java
new file mode 100644
index 0000000..6d17f94
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/LdapService.java
@@ -0,0 +1,38 @@
+package com.zsvg.vboot.config.security.authn;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.support.LdapUtils;
+import org.springframework.stereotype.Service;
+
+import javax.naming.directory.DirContext;
+
+@Service
+public class LdapService {
+
+ @Autowired
+ private LdapTemplate ldapTemplate;
+
+ @Value("${ldap.domainName}")
+ private String ldapDomainName;
+
+ @Value("${ldap.base}")
+ private String ldapBaseDn;
+
+ public boolean authenticate(String userName, String password) {
+ //String userDomainName = getDnForUser(userName);
+ String userDomainName = String.format(ldapDomainName, userName);
+ DirContext ctx = null;
+ try {
+ ctx = ldapTemplate.getContextSource().getContext(userDomainName, password);
+ return true;
+ } catch (Exception e) {
+// e.printStackTrace();
+ } finally {
+ LdapUtils.closeContext(ctx);
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/LoginDto.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/LoginDto.java
new file mode 100644
index 0000000..d6d01f8
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/LoginDto.java
@@ -0,0 +1,22 @@
+package com.zsvg.vboot.config.security.authn;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LoginDto implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ private String username;
+
+ @NotNull
+ private String password;
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzController.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzController.java
new file mode 100644
index 0000000..6e87e30
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzController.java
@@ -0,0 +1,40 @@
+package com.zsvg.vboot.config.security.authz;
+
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class AuthzController {
+
+
+ @GetMapping("/getUserInfo")
+ public RestResult getUserInfo(Authentication auth) {
+
+ return RestResult.ok("test");
+ }
+
+ @GetMapping("/getPermCode")
+ public RestResult getPermCode(Authentication auth) {
+
+ return RestResult.ok("test");
+ }
+
+
+
+
+
+ @GetMapping("/com/getZuser")
+ public RestResult getZuser(Authentication auth) {
+ return RestResult.ok("test");
+ }
+
+
+
+ @Autowired
+ private AuthzService authzService;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzDeniedHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzDeniedHandler.java
new file mode 100644
index 0000000..ca58980
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzDeniedHandler.java
@@ -0,0 +1,36 @@
+package com.zsvg.vboot.config.security.authz;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.http.HttpStatus;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.access.AccessDeniedHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+@Component
+public class AuthzDeniedHandler implements AccessDeniedHandler {
+
+ @Override
+ public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
+ response.setStatus(403);
+ response.setCharacterEncoding(StandardCharsets.UTF_8.name());
+ response.setHeader("Content-Type", "application/json;charset=UTF-8");
+
+ try (ServletOutputStream ous = response.getOutputStream()) {
+ Map map = new HashMap<>(16);
+ map.put("code", HttpStatus.SC_FORBIDDEN);
+ map.put("success", false);
+ map.put("message", Optional.ofNullable(request.getAttribute("errorMessage")).orElse("授权失败").toString());
+ ous.write(JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8));
+ }
+
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzHandler.java
new file mode 100644
index 0000000..a631b32
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzHandler.java
@@ -0,0 +1,21 @@
+package com.zsvg.vboot.config.security.authz;
+
+import com.zsvg.vboot.config.security.pojo.Zuser;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+
+@Component
+public class AuthzHandler {
+
+ public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
+ String uri=request.getRequestURI();
+ Zuser zuser = (Zuser) authentication.getPrincipal();
+
+
+
+ return true;
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzService.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzService.java
new file mode 100644
index 0000000..e45ef38
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzService.java
@@ -0,0 +1,66 @@
+package com.zsvg.vboot.config.security.authz;
+
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class AuthzService {
+
+
+// public List findMenuList(Authentication auth) {
+// String sql = "select name,code,path,icon,comp,ornum,id,pid from sys_auth_menu where type in ('D','M') and avtag=1 order by ornum";
+// List list=jdbcDao.getTp().query(sql, (rs, rowNum) -> {
+// Zmenu zmenu = new Zmenu();
+// zmenu.setId(rs.getString("id"));
+// zmenu.setPid(rs.getString("pid"));
+// zmenu.setName(rs.getString("code"));
+// zmenu.setPath(rs.getString("path"));
+// zmenu.setComponent(rs.getString("comp"));
+// Zmeta zmeta = new Zmeta();
+// zmeta.setTitle(rs.getString("name"));
+// zmeta.setOrderNo(rs.getInt("ornum"));
+// zmeta.setIcon(rs.getString("icon"));
+// zmenu.setMeta(zmeta);
+// return zmenu;
+// });
+// return buildByRecursive(list);
+// }
+//
+//
+// //使用递归方法建树
+// public List buildByRecursive(List treeNodes) {
+// List trees = new ArrayList<>();
+// for (Zmenu treeNode : treeNodes) {
+// if (treeNode.getPid()==null) {
+// trees.add(findChildrenByTier(treeNode,treeNodes));
+// }
+// }
+// return trees;
+// }
+//
+//
+// //递归查找子节点
+// public Zmenu findChildrenByTier(Zmenu treeNode, List treeNodes) {
+//// treeNode.setChildren(new ArrayList<>());
+// for (Zmenu it : treeNodes) {
+// if(treeNode.getId().equals(it.getPid())) {
+// if (treeNode.getChildren() == null) {
+// treeNode.setChildren(new ArrayList<>());
+// }
+// treeNode.getChildren().add(findChildrenByTier(it,treeNodes));
+// }
+// }
+// return treeNode;
+// }
+
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtFilter.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtFilter.java
new file mode 100644
index 0000000..2b12da8
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtFilter.java
@@ -0,0 +1,64 @@
+package com.zsvg.vboot.config.security.jwt;
+
+import com.zsvg.vboot.config.dbx.redis.RedisHandler;
+import com.zsvg.vboot.config.security.pojo.Zuser;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Slf4j
+public class JwtFilter extends OncePerRequestFilter {
+
+ private final JwtHandler jwtHandler;
+
+ private final RedisHandler redisHandler;
+
+
+ public JwtFilter(JwtHandler jwtHandler, RedisHandler redisHandler) {
+ this.jwtHandler = jwtHandler;
+ this.redisHandler = redisHandler;
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
+// System.out.println("拦截的URL:" + request.getRequestURI());
+ String token = jwtHandler.getToken(request);
+ if (token != null) {
+ String uuid = jwtHandler.getClaims(token).getId();
+// System.out.println("过滤器:uuid:" + uuid);
+ Zuser zuser = (Zuser) redisHandler.get(uuid);
+ if (zuser != null) {
+ UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(zuser, null, zuser.getAuthorities());
+ authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+ } else {
+// response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "当前登录状态过期");
+ throw new BadCredentialsException("当前登录状态过期");
+ }
+ }
+
+ //测试用时
+ String uri = request.getRequestURI();
+ String ip = request.getRemoteAddr();
+ long start = System.currentTimeMillis();
+ log.debug(ip + "--" + uri + "--开始▼...");
+ chain.doFilter(request, response);
+ long time = (System.currentTimeMillis() - start);
+ if (time > 3000) {
+ log.warn(ip + "--" +uri + "--结束▲...用时:" + time / 1000 + "秒");
+ } else {
+ log.debug(ip + "--"+uri + "--结束▲...用时:" + time + "毫秒");
+ }
+ }
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtFilterAdapter.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtFilterAdapter.java
new file mode 100644
index 0000000..7d8293e
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtFilterAdapter.java
@@ -0,0 +1,22 @@
+package com.zsvg.vboot.config.security.jwt;
+
+import lombok.RequiredArgsConstructor;
+import com.zsvg.vboot.config.dbx.redis.RedisHandler;
+import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.web.DefaultSecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+@RequiredArgsConstructor
+public class JwtFilterAdapter extends SecurityConfigurerAdapter {
+
+ private final JwtHandler jwtHandler;
+ private final RedisHandler redisHandler;
+
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ JwtFilter jwtFilter = new JwtFilter(jwtHandler, redisHandler);
+ http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtHandler.java
new file mode 100644
index 0000000..f2eaee9
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/jwt/JwtHandler.java
@@ -0,0 +1,97 @@
+package com.zsvg.vboot.config.security.jwt;
+
+import cn.hutool.core.util.IdUtil;
+import com.zsvg.vboot.config.AppConfig;
+import com.zsvg.vboot.config.dbx.redis.RedisHandler;
+import io.jsonwebtoken.*;
+import io.jsonwebtoken.io.Decoders;
+import io.jsonwebtoken.security.Keys;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.security.Key;
+import java.util.ArrayList;
+
+@Component
+public class JwtHandler implements InitializingBean {
+
+ private final Key key; // 用于签名 Access Token
+ private final Key refreshKey; // 用于签名 Refresh Token
+ private final AppConfig appConfig;
+ private JwtParser jwtParser;
+ private JwtBuilder jwtBuilder;
+ private final RedisHandler redisHandler;
+
+ public JwtHandler(AppConfig appConfig, RedisHandler redisHandler) {
+ this.appConfig = appConfig;
+ this.redisHandler = redisHandler;
+ key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(appConfig.getJwt().getAkey()));
+ refreshKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(appConfig.getJwt().getRkey()));
+ }
+
+ @Override
+ public void afterPropertiesSet() {
+ jwtParser = Jwts.parserBuilder().setSigningKey(key).build();
+ jwtBuilder = Jwts.builder().signWith(key, SignatureAlgorithm.HS512);
+ }
+
+ //创建Token 设置永不过期,Token 的时间有效性转到Redis 维护
+ public String createToken(Authentication authentication) {
+ return jwtBuilder
+ // 加入ID确保生成的 Token 都不一致
+ .setId(IdUtil.simpleUUID())
+ .claim("user", authentication.getName())
+ .setSubject(authentication.getName())
+ .compact();
+ }
+
+ public String createTokenByUuid(String uuid) {
+// System.out.println("uuidz:" + uuid);
+ return jwtBuilder
+ .setId(uuid)
+ .claim("username", uuid)
+ .setSubject(uuid)
+ .compact();
+ }
+
+
+ //依据Token 获取鉴权信息
+ Authentication getAuthentication(String token) {
+ Claims claims = getClaims(token);
+ User principal = new User(claims.getSubject(), "******", new ArrayList<>());
+ return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
+ }
+
+ public Claims getClaims(String token) {
+ return jwtParser
+ .parseClaimsJws(token)
+ .getBody();
+ }
+
+ //需要检查的token
+// public void checkRenewal(String token) {
+// // 判断是否续期token,计算token的过期时间
+// long time = redisHandler.getExpire("online" + token) * 1000;
+// Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
+// // 判断当前时间与过期时间的时间差
+// long differ = expireDate.getTime() - System.currentTimeMillis();
+// // 如果在续期检查的范围内,则续期
+// if (differ <= appConfig.getJwt().getDetect()) {
+// long renew = time + appConfig.getJwt().getRenew();
+// redisHandler.expire(appConfig.getJwt().getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
+// }
+// }
+
+ public String getToken(HttpServletRequest request) {
+ final String requestHeader = request.getHeader(appConfig.getJwt().getHeader());
+ if (requestHeader != null && requestHeader.startsWith(appConfig.getJwt().getPrefix())) {
+ return requestHeader.substring(7);
+ }
+ return null;
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Duser.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Duser.java
new file mode 100644
index 0000000..3f880ab
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Duser.java
@@ -0,0 +1,18 @@
+package com.zsvg.vboot.config.security.pojo;
+
+import lombok.Data;
+
+@Data
+public class Duser {
+
+ private String id;
+
+ private String name;
+
+ private String pacod;
+
+ private Boolean retag;
+
+ private String tier;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zmenu.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zmenu.java
new file mode 100644
index 0000000..1b158c7
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zmenu.java
@@ -0,0 +1,38 @@
+package com.zsvg.vboot.config.security.pojo;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class Zmenu implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @JsonIgnore
+ @JSONField(serialize = false)
+ private String id;
+
+ @JsonIgnore
+ @JSONField(serialize = false)
+ private String pid;
+
+ @JsonIgnore
+ @JSONField(serialize = false)
+ private String perm;
+
+ private String path;
+
+ private String name;
+
+ private String component;
+
+ private Zmeta meta;
+
+ private String redirect;
+
+ private List children;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zmeta.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zmeta.java
new file mode 100644
index 0000000..97dda3b
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zmeta.java
@@ -0,0 +1,21 @@
+package com.zsvg.vboot.config.security.pojo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class Zmeta implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String title;
+
+ private String affix;
+
+ private String icon;
+
+ private Integer orderNo;
+
+ private Boolean ignoreKeepAlive;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zuser.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zuser.java
new file mode 100644
index 0000000..bbabad2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/pojo/Zuser.java
@@ -0,0 +1,120 @@
+package com.zsvg.vboot.config.security.pojo;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+@Data
+public class Zuser implements UserDetails, Serializable {
+
+ private static final long serialVersionUID = -2487878824333265058L;
+
+ private String id;//用户ID
+
+ private String name;//用户名称
+
+ private Boolean watag;
+
+ private String usnam;//用户名
+
+ @JsonIgnore//前端不需要
+ private long[] permArr;//权限集,用于验证URL权限 比较下哪个方式快1
+
+ @JsonIgnore
+ private List permList;//权限集,用于验证URL权限 比较下哪个方式快2
+
+ @JsonIgnore//前端不需要
+ private String conds;//组织架构集,用户ID,所有上级部门ID,岗位ID,群组ID
+
+ public Zuser(String id, String name, String usnam, long[] perms, String conds) {
+ this.id = id;
+ this.name = name;
+ this.usnam = usnam;
+ this.conds = conds;
+ this.permArr = perms;
+ }
+
+
+ public Zuser() {
+
+ }
+
+ public Zuser(String id, String name, String usnam) {
+ this.id = id;
+ this.name = name;
+ this.usnam = usnam;
+ }
+
+ //------------------------------
+ private boolean isAdmin;
+
+ public boolean isAdmin() {
+ return isAdmin;
+ }
+
+ public void setAdmin(boolean admin) {
+ isAdmin = admin;
+ }
+
+
+ public boolean hasPerm(int pos, long code) {
+ if (isAdmin()) {
+ return true;
+ }
+ if (permArr.length <= pos) {
+ return false;
+ }
+ long ret = permArr[pos] & code;
+ return !(ret == 0);
+ }
+
+ //----------------------------UserDetails------------------------------------------------
+ @JsonIgnore
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ return null;
+ }
+
+ @JsonIgnore
+ @Override
+ public String getPassword() {
+ return null;
+ }
+
+ @JsonIgnore
+ @Override
+ public String getUsername() {
+ return this.getUsnam();
+ }
+
+ @JsonIgnore
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @JsonIgnore
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @JsonIgnore
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @JsonIgnore
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ //@JSONField(serialize = false)
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/web/CorsConfig.java b/vboot-core/src/main/java/com/zsvg/vboot/config/web/CorsConfig.java
new file mode 100644
index 0000000..d61aecd
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/web/CorsConfig.java
@@ -0,0 +1,24 @@
+package com.zsvg.vboot.config.web;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class CorsConfig {
+ @Bean
+ public WebMvcConfigurer corsConfigurer() {
+ return new WebMvcConfigurer() {
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+// .allowedHeaders("Authorization")
+ .allowedOrigins("*")
+ .allowCredentials(true)
+ .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
+ .maxAge(3600);
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/web/RestTemplateConfig.java b/vboot-core/src/main/java/com/zsvg/vboot/config/web/RestTemplateConfig.java
new file mode 100644
index 0000000..192aaa2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/web/RestTemplateConfig.java
@@ -0,0 +1,75 @@
+package com.zsvg.vboot.config.web;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+ @Value("${http.maxTotal}")
+ private Integer maxTotal;
+
+ @Value("${http.defaultMaxPerRoute}")
+ private Integer defaultMaxPerRoute;
+
+ @Value("${http.connectTimeout}")
+ private Integer connectTimeout;
+
+ @Value("${http.connectionRequestTimeout}")
+ private Integer connectionRequestTimeout;
+
+ @Value("${http.socketTimeout}")
+ private Integer socketTimeout;
+
+ @Value("${http.staleConnectionCheckEnabled}")
+ private boolean staleConnectionCheckEnabled;
+
+ @Value("${http.validateAfterInactivity}")
+ private Integer validateAfterInactivity;
+
+
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate(httpRequestFactory());
+ }
+
+ @Bean
+ public ClientHttpRequestFactory httpRequestFactory() {
+ return new HttpComponentsClientHttpRequestFactory(httpClient());
+ }
+
+ @Bean
+ public HttpClient httpClient() {
+ Registry registry = RegistryBuilder.create()
+ .register("http", PlainConnectionSocketFactory.getSocketFactory())
+ .register("https", SSLConnectionSocketFactory.getSocketFactory())
+ .build();
+ PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
+ connectionManager.setMaxTotal(maxTotal); // 最大连接数
+ connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); //单个路由最大连接数
+ connectionManager.setValidateAfterInactivity(validateAfterInactivity); // 最大空间时间
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setSocketTimeout(socketTimeout) //服务器返回数据(response)的时间,超过抛出read timeout
+ .setConnectTimeout(connectTimeout) //连接上服务器(握手成功)的时间,超出抛出connect timeout
+ .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled) // 提交前检测是否可用
+ .setConnectionRequestTimeout(connectionRequestTimeout)//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
+ .build();
+ return HttpClientBuilder.create()
+ .setDefaultRequestConfig(requestConfig)
+ .setConnectionManager(connectionManager)
+ .build();
+ }
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/web/WebSocketConfig.java b/vboot-core/src/main/java/com/zsvg/vboot/config/web/WebSocketConfig.java
new file mode 100644
index 0000000..4f63da2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/web/WebSocketConfig.java
@@ -0,0 +1,19 @@
+package com.zsvg.vboot.config.web;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class WebSocketConfig {
+ /**
+ * ServerEndpointExporter 作用
+ *
+ * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
+ *
+ * @return
+ */
+ //影响单元测试所以先注释了
+// @Bean
+// public ServerEndpointExporter serverEndpointExporter() {
+// return new ServerEndpointExporter();
+// }
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/web/WebSocketServer.java b/vboot-core/src/main/java/com/zsvg/vboot/config/web/WebSocketServer.java
new file mode 100644
index 0000000..9bfb311
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/config/web/WebSocketServer.java
@@ -0,0 +1,92 @@
+package com.zsvg.vboot.config.web;
+
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+//影响单元测试所以先注释了
+//@ServerEndpoint("/webSocket/{sid}")
+@Component
+public class WebSocketServer {
+ //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
+ private static AtomicInteger onlineNum = new AtomicInteger();
+
+ //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
+ private static ConcurrentHashMap sessionPools = new ConcurrentHashMap<>();
+
+ //发送消息
+ public void sendMessage(Session session, String message) throws IOException {
+ if(session != null){
+ synchronized (session) {
+// System.out.println("发送数据:" + message);
+ session.getBasicRemote().sendText(message);
+ }
+ }
+ }
+ //给指定用户发送信息
+ public void sendInfo(String userName, String message){
+ Session session = sessionPools.get(userName);
+ try {
+ sendMessage(session, message);
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ //建立连接成功调用
+ @OnOpen
+ public void onOpen(Session session, @PathParam(value = "sid") String userName){
+ sessionPools.put(userName, session);
+ addOnlineCount();
+ System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);
+ try {
+ sendMessage(session, "欢迎" + userName + "加入连接!");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ //关闭连接时调用
+ @OnClose
+ public void onClose(@PathParam(value = "sid") String userName){
+ sessionPools.remove(userName);
+ subOnlineCount();
+ System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);
+ }
+
+ //收到客户端信息
+ @OnMessage
+ public void onMessage(String message) throws IOException{
+ message = "客户端:" + message + ",已收到";
+ System.out.println(message);
+ for (Session session: sessionPools.values()) {
+ try {
+ sendMessage(session, message);
+ } catch(Exception e){
+ e.printStackTrace();
+ continue;
+ }
+ }
+ }
+
+ //错误时调用
+ @OnError
+ public void onError(Session session, Throwable throwable){
+ System.out.println("发生错误");
+ throwable.printStackTrace();
+ }
+
+ public static void addOnlineCount(){
+ onlineNum.incrementAndGet();
+ }
+
+ public static void subOnlineCount() {
+ onlineNum.decrementAndGet();
+ }
+
+}
+
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCate.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCate.java
new file mode 100644
index 0000000..6183230
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCate.java
@@ -0,0 +1,15 @@
+package com.zsvg.vboot.module.ass.dict.cate;
+
+import lombok.Getter;
+import lombok.Setter;
+import com.zsvg.vboot.common.mvc.entity.BaseCateEntity;
+
+import javax.persistence.Entity;
+
+@Entity
+@Getter
+@Setter
+public class AssDictCate extends BaseCateEntity {
+
+ private String notes;//备注
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateApi.java
new file mode 100644
index 0000000..e49811a
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateApi.java
@@ -0,0 +1,46 @@
+package com.zsvg.vboot.module.ass.dict.cate;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("ass/dict/cate")
+public class AssDictCateApi {
+
+ private String table = "ass_dict_cate";
+
+ @GetMapping
+ public RestResult get(String name) {
+ Sqler sqler = new Sqler(table);
+ sqler.addLike("t.name", name);
+ sqler.addSelect("t.notes,t.ornum");
+ return RestResult.ok(service.findPageData(sqler));
+ }
+
+ @GetMapping("one/{id}")
+ public RestResult getOne(@PathVariable String id) {
+ AssDictCate cate = service.findOne(id);
+ return RestResult.ok(cate);
+ }
+
+ @PostMapping
+ public RestResult post(@RequestBody AssDictCate main) {
+ return RestResult.ok(service.insert(main));
+ }
+
+ @PutMapping
+ public RestResult put(@RequestBody AssDictCate main) {
+ return RestResult.ok(service.update(main));
+ }
+
+ @DeleteMapping("{ids}")
+ public RestResult delete(@PathVariable String[] ids) {
+ return RestResult.ok(service.delete(ids));
+ }
+
+ @Autowired
+ private AssDictCateService service;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateRepo.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateRepo.java
new file mode 100644
index 0000000..0463f55
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateRepo.java
@@ -0,0 +1,8 @@
+package com.zsvg.vboot.module.ass.dict.cate;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AssDictCateRepo extends JpaRepository {
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateService.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateService.java
new file mode 100644
index 0000000..7b79a7d
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/cate/AssDictCateService.java
@@ -0,0 +1,27 @@
+package com.zsvg.vboot.module.ass.dict.cate;
+
+import com.zsvg.vboot.common.mvc.service.BaseCateService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+@Service
+public class AssDictCateService extends BaseCateService {
+
+
+
+
+
+
+ //----------bean注入------------
+ @Autowired
+ private AssDictCateRepo repo;
+
+ @PostConstruct
+ public void initDao() {
+ super.setRepo(repo);
+ }
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictData.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictData.java
new file mode 100644
index 0000000..93717e0
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictData.java
@@ -0,0 +1,23 @@
+package com.zsvg.vboot.module.ass.dict.data;
+
+import lombok.Getter;
+import lombok.Setter;
+import com.zsvg.vboot.common.mvc.entity.BaseEntity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+
+@Entity
+@Getter
+@Setter
+public class AssDictData extends BaseEntity {
+
+ private String notes;//备注
+
+ @Column(length = 32)
+ private String code;//编码
+
+ private Integer ornum;
+
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataApi.java
new file mode 100644
index 0000000..ee2f700
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataApi.java
@@ -0,0 +1,47 @@
+package com.zsvg.vboot.module.ass.dict.data;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+@RestController
+@RequestMapping("ass/dict/data")
+public class AssDictDataApi {
+
+ private String table = "ass_dict_data";
+
+ @GetMapping
+ public RestResult get(String name) {
+ Sqler sqler = new Sqler(table);
+ sqler.addLike("t.name", name);
+ sqler.addSelect("t.notes,t.ornum,t.code");
+ return RestResult.ok(service.findPageData(sqler));
+ }
+
+ @GetMapping("one/{id}")
+ public RestResult getOne(@PathVariable String id) {
+ AssDictData main = service.findOne(id);
+ return RestResult.ok(main);
+ }
+
+ @PostMapping
+ public RestResult post(@RequestBody AssDictData main) {
+ return RestResult.ok(service.insert(main));
+ }
+
+ @PutMapping
+ public RestResult put(@RequestBody AssDictData main) {
+ return RestResult.ok(service.update(main));
+ }
+
+ @DeleteMapping("{ids}")
+ public RestResult delete(@PathVariable String[] ids) {
+ return RestResult.ok(service.delete(ids));
+ }
+
+ @Autowired
+ private AssDictDataService service;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataRepo.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataRepo.java
new file mode 100644
index 0000000..6df3a01
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataRepo.java
@@ -0,0 +1,9 @@
+package com.zsvg.vboot.module.ass.dict.data;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface AssDictDataRepo extends JpaRepository {
+
+}
+
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataService.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataService.java
new file mode 100644
index 0000000..3e30777
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/data/AssDictDataService.java
@@ -0,0 +1,31 @@
+package com.zsvg.vboot.module.ass.dict.data;
+
+import com.zsvg.vboot.common.mvc.service.BaseService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+
+@Service
+public class AssDictDataService extends BaseService {
+
+
+
+
+
+
+
+
+ //----------bean注入------------
+ @Autowired
+ private AssDictDataRepo repo;
+
+ @PostConstruct
+ public void initDao() {
+ super.setRepo(repo);
+ }
+
+
+}
+
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMain.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMain.java
new file mode 100644
index 0000000..052934b
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMain.java
@@ -0,0 +1,22 @@
+package com.zsvg.vboot.module.ass.dict.main;
+
+import lombok.Getter;
+import lombok.Setter;
+import com.zsvg.vboot.common.mvc.entity.BaseMainEntity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+
+@Entity
+@Getter
+@Setter
+public class AssDictMain extends BaseMainEntity {
+
+ private String notes;
+
+ @Column(length = 32)
+ private String code;//编码
+
+ private Integer ornum;
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainApi.java
new file mode 100644
index 0000000..8e45abe
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainApi.java
@@ -0,0 +1,47 @@
+package com.zsvg.vboot.module.ass.dict.main;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+@RestController
+@RequestMapping("ass/dict/main")
+public class AssDictMainApi {
+
+ private String table = "ass_dict_main";
+
+ @GetMapping
+ public RestResult get(String name) {
+ Sqler sqler = new Sqler(table);
+ sqler.addLike("t.name", name);
+ sqler.addSelect("t.notes,t.ornum,t.code");
+ return RestResult.ok(service.findPageData(sqler));
+ }
+
+ @GetMapping("one/{id}")
+ public RestResult getOne(@PathVariable String id) {
+ AssDictMain main = service.findOne(id);
+ return RestResult.ok(main);
+ }
+
+ @PostMapping
+ public RestResult post(@RequestBody AssDictMain main) {
+ return RestResult.ok(service.insert(main));
+ }
+
+ @PutMapping
+ public RestResult put(@RequestBody AssDictMain main) {
+ return RestResult.ok(service.update(main));
+ }
+
+ @DeleteMapping("{ids}")
+ public RestResult delete(@PathVariable String[] ids) {
+ return RestResult.ok(service.delete(ids));
+ }
+
+ @Autowired
+ private AssDictMainService service;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainRepo.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainRepo.java
new file mode 100644
index 0000000..08859ab
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainRepo.java
@@ -0,0 +1,9 @@
+package com.zsvg.vboot.module.ass.dict.main;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface AssDictMainRepo extends JpaRepository {
+
+}
+
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainService.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainService.java
new file mode 100644
index 0000000..9a58138
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/dict/main/AssDictMainService.java
@@ -0,0 +1,31 @@
+package com.zsvg.vboot.module.ass.dict.main;
+
+import com.zsvg.vboot.common.mvc.service.BaseMainService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+
+@Service
+public class AssDictMainService extends BaseMainService {
+
+
+
+
+
+
+
+
+ //----------bean注入------------
+ @Autowired
+ private AssDictMainRepo repo;
+
+ @PostConstruct
+ public void initDao() {
+ super.setRepo(repo);
+ }
+
+
+}
+
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAtt.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAtt.java
new file mode 100644
index 0000000..da80bc0
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAtt.java
@@ -0,0 +1,32 @@
+package com.zsvg.vboot.module.ass.file.att;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+@Entity
+@Data
+public class AssFileAtt {
+ @Id
+ @Column(length = 32)
+ private String id;
+
+ @Column(length = 32)
+ private String address;
+
+ @Column(length = 128)
+ private String pname;
+
+ @Column(length = 128)
+ private String sname;
+
+ @Column(length = 16)
+ private String zsize;
+
+ @Transient
+ private String zimg;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAttHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAttHandler.java
new file mode 100644
index 0000000..b506038
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAttHandler.java
@@ -0,0 +1,329 @@
+package com.zsvg.vboot.module.ass.file.att;
+
+import com.zsvg.vboot.common.util.file.XfileUtil;
+import com.zsvg.vboot.common.util.file.XpdfUtil;
+import com.zsvg.vboot.common.util.lang.XdateUtil;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+import sun.misc.BASE64Decoder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+@Component
+public class AssFileAttHandler {
+
+ @Value("${app.att.path}")
+ private String ATT_PATH;
+
+ public List saveFiles(MultipartFile[] files) throws IOException
+ {
+ List attList = new ArrayList<>();
+ if (files != null)
+ {
+ for (int i = 0; i < files.length; i++)
+ {
+ String fileName = files[i].getOriginalFilename();
+
+ if (!"".equals(fileName))
+ {
+ fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
+ String pName;
+ String sName = "";
+ if(fileName.contains(".")){
+ pName= fileName.substring(0,fileName.lastIndexOf("."));
+ sName = fileName.substring(fileName.lastIndexOf(".")+1);
+ }else{
+ pName=fileName;
+ }
+ String uuid = XstringUtil.getUUID();
+ String newName = uuid +"."+ sName;
+ int code = newName.hashCode();
+ String dirY = XdateUtil.getYYYY();
+ String dirM = XdateUtil.getMM();
+ String dirD = XdateUtil.getDD();
+ String dirX = Integer.toHexString(code & 0xf);
+ String savePath = dirY + "/" + dirM + "/" + dirD + "/" + dirX;
+ File targetFolder = new File(ATT_PATH + "/" + savePath);
+ File targetFile = new File(ATT_PATH + "/" + savePath, newName);
+ if (!targetFolder.exists())
+ {
+ targetFolder.mkdirs();
+ }
+ files[i].transferTo(targetFile);
+ AssFileAtt att = new AssFileAtt();
+ att.setZsize(XfileUtil.getFileSize(files[i].getSize()));
+ att.setPname(pName);
+ att.setAddress(savePath);
+ att.setId(uuid);
+ att.setSname(sName);
+ attList.add(att);
+ }
+ }
+ }
+ return attList;
+ }
+
+ public AssFileAtt saveFile(MultipartFile file) throws IOException
+ {
+ AssFileAtt att = new AssFileAtt();
+
+ String fileName = file.getOriginalFilename();
+ if (!"".equals(fileName))
+ {
+ fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
+ String pName;
+ String sName = "";
+ if(fileName.contains(".")){
+ pName= fileName.substring(0,fileName.lastIndexOf("."));
+ sName = fileName.substring(fileName.lastIndexOf(".")+1);
+ }else{
+ pName=fileName;
+ }
+ String uuid = XstringUtil.getUUID();
+ String newName = uuid +"."+ sName;
+ int code = newName.hashCode();
+ String dirY = XdateUtil.getYYYY();
+ String dirM = XdateUtil.getMM();
+ String dirD = XdateUtil.getDD();
+ String dirX = Integer.toHexString(code & 0xf);
+ String savePath = dirY + "/" + dirM + "/" + dirD + "/" + dirX;
+ File targetFolder = new File(ATT_PATH + "/" + savePath);
+ File targetFile = new File(ATT_PATH + "/" + savePath, newName);
+ if (!targetFolder.exists())
+ {
+ targetFolder.mkdirs();
+ }
+ att.setZsize(XfileUtil.getFileSize(file.getSize()));
+ att.setPname(pName);
+ att.setAddress(savePath);
+ att.setId(uuid);
+ att.setSname(sName);
+ file.transferTo(targetFile);
+// if("jpg".equals(sName)||"JPG".equals(sName)||"png".equals(sName)||"PNG".equals(sName)){
+// Thumbnails.of(ATT_PATH + "/" + savePath+"/"+newName).scale(1f).outputQuality(0.25f).toFile(ATT_PATH + "/" + savePath+"/"+uuid +"_2.jpg");
+// }
+ }
+ return att;
+ }
+
+ public AssFileAtt saveFile2(MultipartFile file) throws IOException
+ {
+ AssFileAtt att = new AssFileAtt();
+
+ String fileName = file.getOriginalFilename();
+ if (!"".equals(fileName))
+ {
+ fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
+ String pName;
+ String sName = "";
+ if(fileName.contains(".")){
+ pName= fileName.substring(0,fileName.lastIndexOf("."));
+ sName = fileName.substring(fileName.lastIndexOf(".")+1);
+ }else{
+ pName=fileName;
+ }
+ String uuid = XstringUtil.getUUID();
+ String newName = uuid +"."+ sName;
+ int code = newName.hashCode();
+ String dirY = XdateUtil.getYYYY();
+ String dirM = XdateUtil.getMM();
+ String dirD = XdateUtil.getDD();
+ String dirX = Integer.toHexString(code & 0xf);
+ String savePath = dirY + "/" + dirM + "/" + dirD + "/" + dirX;
+ File targetFolder = new File(ATT_PATH + "/" + savePath);
+ File targetFile = new File(ATT_PATH + "/" + savePath, newName);
+ if (!targetFolder.exists())
+ {
+ targetFolder.mkdirs();
+ }
+ att.setZsize(XfileUtil.getFileSize(file.getSize()));
+ att.setPname(pName);
+ att.setAddress(savePath);
+ att.setId(uuid);
+ att.setSname(sName);
+ file.transferTo(targetFile);
+ }
+ return att;
+ }
+
+ public AssFileAtt saveImg(String path, String imgData) throws IOException
+ {
+ AssFileAtt att = new AssFileAtt();
+ BASE64Decoder decoder = new BASE64Decoder();
+ //Base64解码
+ byte[] b = decoder.decodeBuffer(imgData);
+ for (int i = 0; i < b.length; ++i)
+ {
+ if (b[i] < 0)
+ {//调整异常数据
+ b[i] += 256;
+ }
+ }
+ //生成jpeg图片
+ String dirY = XdateUtil.getYYYY();
+ String dirM = XdateUtil.getMM();
+ String dirD = XdateUtil.getDD();
+ String uid= XstringUtil.getUUID();
+ String savePath =dirY + "/" + dirM + "/" + dirD + "/" +uid + ".png";
+ byte2File(b, path + "att/kk/" + "/" + dirY + "/" + dirM + "/" + dirD+"/", uid + ".png");
+ att.setAddress(savePath);
+ att.setId(uid);
+ return att;
+ }
+
+ public void download(HttpServletRequest request,
+ HttpServletResponse response, AssFileAtt att) throws Exception
+ {
+
+ response.setContentType("text/html;charset=UTF-8");
+ request.setCharacterEncoding("UTF-8");
+ String realName = att.getPname()+"."+att.getSname();
+ String storeName = att.getAddress() + "/" + att.getId() + realName.substring(realName.lastIndexOf("."));
+ String downLoadPath = ATT_PATH + "/" + storeName;
+
+ long fileLength = new File(downLoadPath).length();
+
+ response.setContentType("application/octet-stream");
+ realName = URLEncoder.encode(realName, "UTF-8");
+ Locale localLanguage = request.getLocale();
+ if (realName.length() > 150)
+ {
+ realName = new String(realName.getBytes("gb2312"), "ISO8859-1");
+ }
+ response.setHeader("Content-disposition", "attachment; filename=" + realName);
+ response.setHeader("Content-Length", String.valueOf(fileLength));
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(downLoadPath));
+ BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
+ byte[] buff = new byte[2048];
+ int bytesRead;
+ while (-1 != (bytesRead = bis.read(buff, 0, buff.length)))
+ {
+ bos.write(buff, 0, bytesRead);
+ }
+ bis.close();
+ bos.close();
+ }
+
+ public void downloadByPath(HttpServletRequest request,
+ HttpServletResponse response, String name,String path) throws Exception
+ {
+
+ response.setContentType("text/html;charset=UTF-8");
+ request.setCharacterEncoding("UTF-8");
+ String downLoadPath = ATT_PATH + "/" + path;
+
+ long fileLength = new File(downLoadPath).length();
+
+ response.setContentType("application/octet-stream");
+ name = URLEncoder.encode(name, "UTF-8");
+ Locale localLanguage = request.getLocale();
+ if (name.length() > 150)
+ {
+ name = new String(name.getBytes("gb2312"), "ISO8859-1");
+ }
+ response.setHeader("Content-disposition", "attachment; filename=" + name);
+ response.setHeader("Content-Length", String.valueOf(fileLength));
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(downLoadPath));
+ BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
+ byte[] buff = new byte[2048];
+ int bytesRead;
+ while (-1 != (bytesRead = bis.read(buff, 0, buff.length)))
+ {
+ bos.write(buff, 0, bytesRead);
+ }
+ bis.close();
+ bos.close();
+ }
+
+ public void downloadWithWatermark(HttpServletRequest request,
+ HttpServletResponse response, AssFileAtt att, String userInfo) throws Exception
+ {
+
+ response.setContentType("text/html;charset=UTF-8");
+ request.setCharacterEncoding("UTF-8");
+ String realName = att.getPname()+"."+att.getSname();
+ String storeName = att.getAddress() + "/" + att.getId() + realName.substring(realName.lastIndexOf("."));
+ String downLoadPath = ATT_PATH + "/" + storeName;
+ String dirM = XdateUtil.getMM();
+ String path2="D:/zsvg/temp/"+dirM+"/"+XstringUtil.getUUID()+".pdf";
+ XpdfUtil.setWatermark(new BufferedOutputStream(new FileOutputStream(new File(path2))),new FileInputStream(downLoadPath), userInfo, 1);
+
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path2));
+
+ long fileLength = new File(path2).length();
+ response.setContentType("application/octet-stream");
+ realName = URLEncoder.encode(realName, "UTF-8");
+ Locale localLanguage = request.getLocale();
+ if (realName.length() > 150)
+ {
+ realName = new String(realName.getBytes("gb2312"), "ISO8859-1");
+ }
+ response.setHeader("Content-disposition", "attachment; filename=" + realName);
+ response.setHeader("Content-Length", String.valueOf(fileLength));
+ BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
+ byte[] buff = new byte[2048];
+ int bytesRead;
+ while (-1 != (bytesRead = bis.read(buff, 0, buff.length)))
+ {
+ bos.write(buff, 0, bytesRead);
+ }
+ bis.close();
+ bos.close();
+ }
+
+
+ private void byte2File(byte[] buf, String filePath, String fileName){
+ BufferedOutputStream bos = null;
+ FileOutputStream fos = null;
+ File file = null;
+ try
+ {
+ File dir = new File(filePath);
+ if (!dir.exists())
+ {
+ dir.mkdirs();
+ }
+ file = new File(filePath + File.separator + fileName);
+ fos = new FileOutputStream(file);
+ bos = new BufferedOutputStream(fos);
+ bos.write(buf);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (bos != null)
+ {
+ try
+ {
+ bos.close();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ if (fos != null)
+ {
+ try
+ {
+ fos.close();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAttRepo.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAttRepo.java
new file mode 100644
index 0000000..eaf1d52
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/att/AssFileAttRepo.java
@@ -0,0 +1,7 @@
+package com.zsvg.vboot.module.ass.file.att;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AssFileAttRepo extends JpaRepository {
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/excel/ExcelHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/excel/ExcelHandler.java
new file mode 100644
index 0000000..227f153
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/file/excel/ExcelHandler.java
@@ -0,0 +1,334 @@
+package com.zsvg.vboot.module.ass.file.excel;
+
+import com.zsvg.vboot.common.util.file.XexcelUtil;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+@SuppressWarnings("unchecked")
+public class ExcelHandler {
+ //excel导出
+// public HSSFWorkbook createXlsWithMapByMap(Map map, List> list)
+// {
+// HSSFWorkbook workbook = new HSSFWorkbook();
+// HSSFSheet sheet = workbook.createSheet();
+// sheet.autoSizeColumn(1, true);
+// //字段设置
+// HSSFRow row0 = sheet.createRow(0);
+// int k = 0;
+// for (String key : map.keySet())
+// {
+// HSSFCell cell0 = row0.createCell(k);
+// cell0.setCellType(HSSFCell.CELL_TYPE_STRING);
+// if(key.contains("_")){
+// key=key.substring(3);
+// }
+// cell0.setCellValue(key);
+// k++;
+// }
+// //字段描述设置
+// HSSFRow row1 = sheet.createRow(1);
+// int l = 0;
+// for (String value : map.values())
+// {
+// HSSFCell cell1 = row1.createCell(l);
+// cell1.setCellType(HSSFCell.CELL_TYPE_STRING);
+// cell1.setCellValue(value);
+// l++;
+// }
+// //先转成jsonarray再设置其余行
+// for (int i = 0; i < list.size(); i++)
+// {
+// HSSFRow row = sheet.createRow(i + 2);
+// int j = 0;
+// for (String key : map.keySet())
+// {
+// if(key.contains("_")){
+// key=key.substring(3);
+// }
+// HSSFCell cell = row.createCell(j);
+// cell.setCellType(HSSFCell.CELL_TYPE_STRING);
+// if (list.get(i).get(key) == null)
+// {
+// cell.setCellValue("");
+// } else
+// {
+// cell.setCellValue("" + list.get(i).get(key));
+// }
+// j++;
+// }
+// }
+// return workbook;
+// }
+
+
+ //excel导出
+ public XSSFWorkbook createXlsxByObjList(List> fieldList, List dataList,Boolean firstLineFlag) throws NoSuchFieldException, IllegalAccessException {
+ XSSFWorkbook workbook = new XSSFWorkbook();
+ DataFormat format = workbook.createDataFormat();
+ XSSFSheet sheet = workbook.createSheet();
+
+ CellStyle numberStyle = workbook.createCellStyle();
+ numberStyle.setDataFormat(format.getFormat("#,#0.00"));
+
+// Font font1 = workbook.createFont();
+// font1.setFontName("Arial");
+// font1.setFontHeightInPoints((short) 11);
+// CellStyle cellStyle=workbook.createCellStyle();
+// cellStyle.setFont(font1);
+// cellStyle.setWrapText(true);//自动换行
+// cellStyle.setAlignment(HorizontalAlignment.CENTER);
+// cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+// cellStyle.setDataFormat(format.getFormat("0.0"));
+ if(firstLineFlag){
+ XSSFRow row0 = sheet.createRow(0);
+ XSSFRow row1 = sheet.createRow(1);
+ for (int i = 0; i < fieldList.size(); i++) {
+ XSSFCell cell0 = row0.createCell(i);
+ cell0.setCellValue(fieldList.get(i).get("field"));
+ XSSFCell cell1 = row1.createCell(i);
+ cell1.setCellValue(fieldList.get(i).get("title"));
+ }
+ }else{
+ XSSFRow row0 = sheet.createRow(0);
+ for (int i = 0; i < fieldList.size(); i++) {
+ XSSFCell cell0 = row0.createCell(i);
+ cell0.setCellValue(fieldList.get(i).get("title"));
+ }
+ }
+
+ //先转成jsonarray再设置其余行
+ for (int i = 0; i < dataList.size(); i++) {
+ XSSFRow row;
+ if(firstLineFlag){
+ row = sheet.createRow(i + 2);
+ }else{
+ row = sheet.createRow(i + 1);
+ }
+ for (int j = 0; j < fieldList.size(); j++) {
+ XSSFCell cell = row.createCell(j);
+ Field field = dataList.get(i).getClass().getDeclaredField(fieldList.get(j).get("field"));
+ field.setAccessible(true);//这里是不是可以再优化,减少每次都反射
+ Object obj = field.get(dataList.get(i));
+ if ("number".equals(fieldList.get(j).get("type"))) {
+ cell.setCellStyle(numberStyle);
+ cell.setCellValue(Double.parseDouble(""+obj));
+ }else{
+ cell.setCellValue(obj == null ? "" : "" + obj);
+ }
+
+ //最后一次的时候调整列宽
+ if (i == dataList.size() - 1&&i<=5000) {
+ if (fieldList.get(j).get("width") != null && !"0".equals(fieldList.get(j).get("width"))) {
+ sheet.setColumnWidth(j, Integer.parseInt(fieldList.get(j).get("width")) * 256);//手动设置
+ } else {
+ sheet.autoSizeColumn(j); //自动调整第N列宽度
+ if ("0".equals(fieldList.get(j).get("width")) || XstringUtil.containChinese("" + obj)) {
+ sheet.setColumnWidth(j, sheet.getColumnWidth(j) * 17 / 10);
+ }
+ if(sheet.getColumnWidth(j)> fieldList, List> mapList,Boolean firstLineFlag) {
+ XSSFWorkbook workbook = new XSSFWorkbook();
+ DataFormat format = workbook.createDataFormat();
+ XSSFSheet sheet = workbook.createSheet();
+ XSSFCellStyle numberStyle = workbook.createCellStyle();
+ numberStyle.setDataFormat(format.getFormat("#,#0.00"));
+
+ XSSFCellStyle integerStyle = workbook.createCellStyle();
+ integerStyle.setDataFormat(format.getFormat("#,#0"));//数据格式只显示整数
+
+ // 设置标题
+ CellStyle greenTitleStyle = getGreenTitleStyle(workbook);
+ if(firstLineFlag){
+ XSSFRow row0 = sheet.createRow(0);
+ row0.setHeight(Short.valueOf("400"));
+ XSSFRow row1 = sheet.createRow(1);
+ for (int i = 0; i < fieldList.size(); i++) {
+ XSSFCell cell0 = row0.createCell(i);
+ cell0.setCellValue(fieldList.get(i).get("field"));
+ cell0.setCellStyle(greenTitleStyle);
+ XSSFCell cell1 = row1.createCell(i);
+ cell1.setCellValue(fieldList.get(i).get("title"));
+ cell1.setCellStyle(greenTitleStyle);
+
+ }
+ }else{
+ XSSFRow row0 = sheet.createRow(0);
+ for (int i = 0; i < fieldList.size(); i++) {
+ XSSFCell cell0 = row0.createCell(i);
+ cell0.setCellValue(fieldList.get(i).get("title"));
+ cell0.setCellStyle(greenTitleStyle);
+
+ }
+ }
+//
+// XSSFCellStyle hssfCellStyleDouble = workbook.createCellStyle();
+// XSSFDataFormat df = workbook.createDataFormat(); // 此处设置数据格式
+// hssfCellStyleDouble.setDataFormat(df.getFormat("#,##0.0"));//保留1位小数点
+//
+
+
+ //先转成jsonarray再设置其余行
+ for (int i = 0; i < mapList.size(); i++) {
+ XSSFRow row;
+ if(firstLineFlag){
+ row = sheet.createRow(i + 2);
+ }else{
+ row = sheet.createRow(i + 1);
+ }
+ for (int j = 0; j < fieldList.size(); j++) {
+ XSSFCell cell = row.createCell(j);
+ String value=mapList.get(i).get(fieldList.get(j).get("field"))+"";
+
+ //if ("number".equals(fieldList.get(j).get("type"))) {
+ if("null".equals(value)){
+ cell.setCellValue("");
+ }else{
+ if(value.matches("^(-?\\d+)(\\.\\d+)?$")){//判断是否为数值
+ if(value.matches("^[-\\+]?[\\d]*$")){//判断是否为整数
+ cell.setCellValue(Double.parseDouble(value));
+ cell.setCellStyle(integerStyle);
+ }else{
+ cell.setCellValue(Double.parseDouble(value));
+ cell.setCellStyle(numberStyle);
+ }
+ }else{
+ cell.setCellValue(value);
+ }
+ }
+ /*}else{
+ cell.setCellValue("null".equals(value)? "" :value);
+ }*/
+
+// //最后一次的时候调整列宽 注意这个一个速度会慢很多。当行数小于5000调整
+ if (i == mapList.size() - 1&&i<=5000) {
+ if (fieldList.get(j).get("width") != null && !"0".equals(fieldList.get(j).get("width"))) {
+ sheet.setColumnWidth(j, Integer.parseInt(fieldList.get(j).get("width")) * 256);//手动设置
+ } else {
+ sheet.autoSizeColumn(j); //自动调整第N列宽度
+ if ("0".equals(fieldList.get(j).get("width")) || XstringUtil.containChinese(value)) {
+ sheet.setColumnWidth(j, sheet.getColumnWidth(j) * 17 / 10);
+ }
+ if(sheet.getColumnWidth(j)> getData(MultipartFile file) throws Exception
+ {
+ Workbook workbook = getWorkbook(file);
+ Sheet sheet = workbook.getSheetAt(0);
+ //第1行是字段名称
+ Row row0 = sheet.getRow(0);
+ //列数
+ int cellNum = sheet.getRow(0).getLastCellNum();
+ //行数
+ int rowNum = sheet.getLastRowNum();
+
+ List> list = new ArrayList>();
+
+ //从第3行开始导入
+ for (int i = 2; i <= rowNum; i++)
+ {
+ Row row = sheet.getRow(i);
+ if (row.getCell(0) == null || "".equals(row.getCell(0)))
+ {
+ break;
+ }
+ Map map = new HashMap();
+ for (int j = 1; j < cellNum; j++)
+ {
+ map.put(XexcelUtil.getCellValue(row0.getCell(j)) + "", XexcelUtil.getCellValue(row.getCell(j)));
+ }
+ list.add(map);
+ }
+ return list;
+ }
+
+
+ public Workbook getWorkbook(MultipartFile file) throws IOException {
+ InputStream in = file.getInputStream();
+ String fileName = file.getOriginalFilename();
+ if (fileName.toLowerCase().endsWith("xls")) {
+ return new HSSFWorkbook(in);
+ }
+ if (fileName.toLowerCase().endsWith("xlsx")) {
+ return new XSSFWorkbook(in);
+ }
+ return null;
+ }
+
+
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMain.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMain.java
new file mode 100644
index 0000000..ad9a285
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMain.java
@@ -0,0 +1,37 @@
+package com.zsvg.vboot.module.ass.num.main;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Data
+public class AssNumMain {
+ @Id
+ @Column(length = 8)
+ private String id;
+
+ @Column(length = 100)
+ private String label;
+
+ @Column(length = 32)
+ private String name;
+
+ @Column(length = 32)
+ private String numod;
+
+ @Column(length = 32)
+ private String nupre;
+
+ private Boolean nflag;
+
+ @Column(length = 8)
+ private String nunex;
+
+ private Integer nulen;
+
+ @Column(length = 8)
+ private String cudat;
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainApi.java
new file mode 100644
index 0000000..75f6036
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainApi.java
@@ -0,0 +1,59 @@
+package com.zsvg.vboot.module.ass.num.main;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("ass/num/main")
+public class AssNumMainApi {
+
+
+ @GetMapping
+ public RestResult get(String name) {
+ Sqler sqler = new Sqler("t.*","as_num_main");
+ sqler.addLike("t.name",name);
+ return RestResult.ok(service.findPageData(sqler)) ;
+ }
+
+ @GetMapping("one/{id}")
+ public RestResult getOne(@PathVariable String id) {
+ AssNumMain main=repo.findById(id).get();
+ return RestResult.ok(main);
+ }
+
+ @PostMapping
+ public synchronized RestResult post(@RequestBody AssNumMain main) {
+ if(repo.existsById(main.getId())){
+ return RestResult.build(201,"编号已存在,请修改编号");
+ }
+ main.setNflag(true);
+ repo.save(main);
+ return RestResult.ok();
+ }
+
+ @PutMapping
+ public RestResult pust(@RequestBody AssNumMain main) {
+ if(XstringUtil.isBlank(main.getNunex())){
+ main.setNflag(true);
+ }
+ repo.save(main);
+ return RestResult.ok();
+ }
+
+ @DeleteMapping("{ids}")
+ public RestResult delete(@PathVariable String[] ids) {
+ for (String id : ids) {
+ repo.deleteById(id);
+ }
+ return RestResult.ok();
+ }
+
+ @Autowired
+ private AssNumMainRepo repo;
+
+ @Autowired
+ private AssNumMainService service;
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainRepo.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainRepo.java
new file mode 100644
index 0000000..5d86ae0
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainRepo.java
@@ -0,0 +1,7 @@
+package com.zsvg.vboot.module.ass.num.main;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AssNumMainRepo extends JpaRepository {
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainService.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainService.java
new file mode 100644
index 0000000..ecc33d3
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/AssNumMainService.java
@@ -0,0 +1,155 @@
+package com.zsvg.vboot.module.ass.num.main;
+
+import com.zsvg.vboot.common.mvc.api.PageData;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+@Service
+public class AssNumMainService {
+
+ public String getDateNum(AssNumMain num, String dateType) {
+ //获取 是否被修改过或新添加的 字段的值
+ //如果 是否被修改过或新添加的=='Y'
+ if (num.getNflag()) {
+ //生成第一个流水号 0001
+ String firstSerialNum = NumUtil.getFirstSerialNum(num.getNulen());
+ //计算下一个流水号 0002
+ String nextSerialNum = NumUtil.getNextSerialNum(firstSerialNum);
+ //获取系统的当前时间 格式yyyyMMdd 20140906
+ String curDate = DateFormatUtils.format(new Date(), dateType);
+
+ //生成客户编码
+ //编码前缀+"-"+利用日期位格式生成当前的日期[yyyyMMdd ]+"-"+0001 c-20110914-0001
+ String back = (num.getNupre() == null ? "" : num.getNupre()) + DateFormatUtils.format(new Date(), dateType) + firstSerialNum;
+ //修改代码规则表
+ //下一个流水号="0002"
+ num.setNunex(nextSerialNum);
+ //当前日期 20140907
+ num.setCudat(curDate);
+ //是否被修改过='N'
+ num.setNflag(false);
+ repo.save(num);
+ return back;
+ } else {
+ //是否被修改过或新添加的=='N'
+ //获取代码规则表中的当前日期字段的值
+ String curDate = num.getCudat();
+ //获取系统的当前日期
+ String sysCurDate = DateFormatUtils.format(new Date(), dateType);
+ //如果代码规则表中的当前日期字段的值==系统的当前日期
+ if (curDate.equals(sysCurDate)) {
+ //获取下一个流水号 ="0002"
+ String nextseq = num.getNunex();
+ //计算新的流水号 0003
+ String nextSerialNum = NumUtil.getNextSerialNum(nextseq);
+ //生成客户编码
+ //编码前缀+"-"+利用日期位格式生成当前的日期[yyyyMMdd ]+"-"+0001
+ String back = (num.getNupre() == null ? "" : num.getNupre()) + DateFormatUtils.format(new Date(), dateType) + nextseq;
+ //修改代码规则表
+ //下一个流水号="0003"
+ num.setNunex(nextSerialNum);
+ //当前日期 20140908
+ //是否被修改过='N'
+ repo.save(num);
+ return back;
+ } else { //如果代码规则表中的当前日期字段的值!=系统的当前日期、
+
+ //生成第一个流水号 0001
+ String firstSerialNum = NumUtil.getFirstSerialNum(num.getNulen());
+ //计算下一个流水号 0002
+ String nextSerialNum = NumUtil.getNextSerialNum(firstSerialNum);
+ //生成客户编码
+ //编码前缀+"-"+利用日期位格式生成当前的日期[yyyyMMdd ]+"-"+0001
+ String back = (num.getNupre() == null ? "" : num.getNupre()) + DateFormatUtils.format(new Date(), dateType) + firstSerialNum;
+ //修改代码规则表
+ //下一个流水号="0002"
+ num.setNunex(nextSerialNum);
+ //当前日期 20110915
+ num.setCudat(sysCurDate);
+ //是否被修改过='N'
+ num.setNflag(false);
+ repo.save(num);
+ return back;
+ }
+ }
+ }
+
+
+ public String getPureNum(AssNumMain num) {
+ if (num.getNflag()) {
+ String firstSerialNum = NumUtil.getFirstSerialNum(num.getNulen());
+ String nextSerialNum = NumUtil.getNextSerialNum(firstSerialNum);
+ num.setNunex(nextSerialNum);
+ num.setNflag(false);
+ repo.save(num);
+ return (num.getNupre() == null ? "" : num.getNupre()) + firstSerialNum;
+ } else {
+ String nextseq = num.getNunex();
+ String nextSerialNum = NumUtil.getNextSerialNum(nextseq);
+ num.setNunex(nextSerialNum);
+ repo.save(num);
+ return (num.getNupre() == null ? "" : num.getNupre()) + nextseq;
+ }
+ }
+
+//
+// UUID
+// 手动改
+// 无日期
+// 年月日YYYYMMDD
+// 年月日YYMMDD
+// 年月YYYYMM
+// 年月YYMM
+// 年YY
+//
+
+ public String getNum(String id){
+ AssNumMain num = repo.findById(id).get();
+ String number = "";
+ switch(num.getNumod()){
+ case "uuid":
+ number = XstringUtil.getUUID();
+ break;
+ case "nodate":
+ number = getPureNum(num);
+ break;
+ case "yyyymmdd":
+ number = getDateNum(num,"yyyyMMdd");
+ break;
+ case "yymmdd":
+ number = getDateNum(num,"yyMMdd");
+ break;
+ case "yyyymm":
+ number = getDateNum(num,"yyyyMM");
+ break;
+ case "yymm":
+ number = getDateNum(num,"yyMM");
+ break;
+ case "yy":
+ number = getDateNum(num,"yy");
+ break;
+ }
+ return number;
+ }
+
+ @Transactional(readOnly = true)
+ public PageData findPageData(Sqler sqler) {
+ return jdbcDao.findPageData(sqler);
+ }
+
+ @Autowired
+ protected JdbcDao jdbcDao;
+
+
+ @Autowired
+ private AssNumMainRepo repo;
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/NumUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/NumUtil.java
new file mode 100644
index 0000000..84910e2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/ass/num/main/NumUtil.java
@@ -0,0 +1,52 @@
+package com.zsvg.vboot.module.ass.num.main;
+
+
+import com.zsvg.vboot.common.util.lang.XdateUtil;
+
+public class NumUtil {
+ // 利用给定的流水位生成第一个流水号
+ public static String getFirstSerialNum(int zlength) {
+ String serialNum = "";
+ //流水号为4里下面取3
+ for (int i = 0; i < zlength - 1; i++) {
+ serialNum = serialNum + "0";
+ }
+ serialNum = serialNum + "1";
+ return serialNum;
+ }
+
+ //根据当前的流水号,生成下一个流水号
+ public static String getNextSerialNum(String curSerialNum) {
+ curSerialNum = "1" + curSerialNum;
+ Integer icurSerialNum = Integer.parseInt(curSerialNum);
+ icurSerialNum++;
+ curSerialNum = icurSerialNum + "";
+ curSerialNum = curSerialNum.substring(1);
+ return curSerialNum;
+ }
+
+ public static String getNum(String numNow, String hintType) {
+ String numNext = "";
+ if("yyyymmxx".equals(hintType)){
+ if(numNow==null){
+ numNext= XdateUtil.getYYYYMM()+getFirstSerialNum(2);
+ }else{
+ String yyyymm=numNow.substring(0,6);
+ if(XdateUtil.getYYYYMM().equals(yyyymm)){
+ numNext= yyyymm+getNextSerialNum(numNow.substring(numNow.length() -2));
+ }else{
+ numNext= XdateUtil.getYYYYMM()+getFirstSerialNum(2);
+ }
+ }
+ }else if("xxxxxx".equals(hintType)){
+ if(numNow==null){
+ numNext= getFirstSerialNum(6);
+ }else if(numNow.length()!=6){
+ numNext= getFirstSerialNum(6);
+ }else{
+ numNext= getNextSerialNum(numNow);
+ }
+ }
+ return numNext;
+ }
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/file/GenAttApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/file/GenAttApi.java
new file mode 100644
index 0000000..3ded41e
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/file/GenAttApi.java
@@ -0,0 +1,48 @@
+package com.zsvg.vboot.module.gen.file;
+
+import com.zsvg.vboot.module.ass.file.att.AssFileAtt;
+import com.zsvg.vboot.module.ass.file.att.AssFileAttRepo;
+import com.zsvg.vboot.module.ass.file.att.AssFileAttHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@RestController
+@RequestMapping("gen/att")
+public class GenAttApi {
+
+ @PostMapping(value="up",produces = "text/html;charset=UTF-8")
+ public String upload(@RequestParam(value = "file", required = false) MultipartFile file) throws Exception {
+ AssFileAtt att = handler.saveFile(file);
+ repo.save(att);
+ return "{\"id\":\"" + att.getId() + "\",\"address\":\"" + att.getAddress() + "\",\"pname\":\"" + att.getPname() + "\",\"sname\":\"" + att.getSname() + "\",\"zsize\":\"" + att.getZsize() + "\",\"zimg\":\"" + att.getZimg() + "\"}";
+ }
+
+ @GetMapping(value="one/{id}")
+ public void getOne(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) throws Exception {
+ AssFileAtt att=repo.findById(id).get();
+ handler.download(request,response,att);
+ }
+
+ @GetMapping(value="pdf")
+ public void pdf(String f, HttpServletRequest request, HttpServletResponse response) throws Exception {
+ AssFileAtt att=repo.findById(f).get();
+ handler.download(request,response,att);
+ }
+
+
+ @GetMapping(value="path")
+ public void downloadByPath(String name, String path, HttpServletRequest request, HttpServletResponse response) throws Exception {
+ handler.downloadByPath(request,response,name,path);
+ }
+
+ @Autowired
+ private AssFileAttRepo repo;
+
+ @Autowired
+ private AssFileAttHandler handler;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/file/GenImgApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/file/GenImgApi.java
new file mode 100644
index 0000000..d0b478d
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/file/GenImgApi.java
@@ -0,0 +1,65 @@
+package com.zsvg.vboot.module.gen.file;
+
+import com.zsvg.vboot.common.util.file.XqcodeUtil;
+import com.zsvg.vboot.module.ass.file.att.AssFileAttHandler;
+import com.zsvg.vboot.module.ass.file.att.AssFileAtt;
+import com.zsvg.vboot.module.ass.file.att.AssFileAttRepo;
+import com.google.zxing.WriterException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+
+@RestController
+@RequestMapping("gen/img")
+public class GenImgApi {
+
+ //{
+ // "code": 0 //0表示成功,其它失败
+ // ,"msg": "" //提示信息 //一般上传失败后返回
+ // ,"data": {
+ // "src": "图片路径"
+ // ,"title": "图片名称" //可选
+ // }
+ //}
+
+ @PostMapping(value="up",produces = "text/html;charset=UTF-8")
+ public String upload(@RequestParam(value = "file", required = false) MultipartFile file) throws Exception {
+ AssFileAtt att = handler.saveFile2(file);
+ repo.save(att);
+ return "{\"code\":\"" + 0 + "\",\"msg\":\"" + "\",\"data\":{\"src\":\"" + "co/img/one/"+att.getId() + "\",\"title\":\"" + att.getPname()+"."+att.getSname() + "\"}}";
+ }
+
+ @GetMapping(value="one/{id}")
+ public void getOne(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) throws Exception {
+ AssFileAtt att=repo.findById(id).get();
+ handler.download(request,response,att);
+ }
+
+ @RequestMapping(value="qr",produces = MediaType.IMAGE_JPEG_VALUE)
+ @ResponseBody
+ public byte[] getImage(String label,Integer size) throws IOException, WriterException {
+ if(size==null||size==0)
+ {
+ size=900;
+ }
+ InputStream inputStream= XqcodeUtil.createQrCode(label, size, "JPEG");
+// File file = new File("D:/qrcode.jpg");
+// FileInputStream inputStream = new FileInputStream(file);
+ byte[] bytes = new byte[inputStream.available()];
+ inputStream.read(bytes, 0, inputStream.available());
+ return bytes;
+ }
+
+ @Autowired
+ private AssFileAttRepo repo;
+
+ @Autowired
+ private AssFileAttHandler handler;
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/num/GenNumApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/num/GenNumApi.java
new file mode 100644
index 0000000..902fbb1
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/num/GenNumApi.java
@@ -0,0 +1,18 @@
+package com.zsvg.vboot.module.gen.num;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("gen/num")
+public class GenNumApi {
+
+ @GetMapping("uuid")
+ public RestResult uuid() {
+ return RestResult.ok(XstringUtil.getUUID());
+ }
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgRece.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgRece.java
new file mode 100644
index 0000000..2e70213
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgRece.java
@@ -0,0 +1,25 @@
+package com.zsvg.vboot.module.gen.org.rece;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Data
+@Table(indexes = {@Index(columnList = "userid"),@Index(columnList = "orgid")})
+public class GenOrgRece {
+
+ @Id
+ @Column(length = 32)
+ private String id;//ID
+
+ @Column(length = 32)
+ private String userid;//用户ID
+
+ @Column(length = 32)
+ private String orgid;//最近使用的组织架构ID
+
+ @Column
+ private Date uptim = new Date();//最近使用时间
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceApi.java
new file mode 100644
index 0000000..7c7fe97
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceApi.java
@@ -0,0 +1,63 @@
+package com.zsvg.vboot.module.gen.org.rece;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.web.XuserUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("gen/org/rece")
+public class GenOrgReceApi {
+
+ @GetMapping
+ public RestResult get(Integer type) {
+ List> mapList = new ArrayList<>();
+ String userId = XuserUtil.getUserId();
+ if ((type & 8) != 0) {//用户
+ Sqler userSqler = new Sqler("t.orgid as id", "gen_org_rece");
+ userSqler.addInnerJoin("u.name", "sys_org_user u", "u.id=t.orgid");
+ userSqler.addInnerJoin("d.name as dept", "sys_org_dept d", "d.id=u.deptid");
+ userSqler.addEqual("t.userid", userId);
+ System.out.println(userSqler.getSql());
+ mapList.addAll(jdbcDao.findMapList(userSqler));
+ }
+ if ((type & 2) != 0) {//部门
+ Sqler deptSqler = new Sqler("t.orgid as id", "gen_org_rece");
+ deptSqler.addInnerJoin("o.name", "sys_org_dept o", "o.id=t.orgid");
+ deptSqler.addEqual("t.userid", userId);
+ mapList.addAll(jdbcDao.findMapList(deptSqler));
+ }
+ if ((type & 4) != 0) {//岗位
+ Sqler postSqler = new Sqler("t.orgid as id", "gen_org_rece");
+ postSqler.addInnerJoin("p.name", "sys_org_post p", "p.id=t.orgid");
+ postSqler.addInnerJoin("d.name as dept", "sys_org_dept d", "d.id=p.deptid");
+ postSqler.addEqual("t.userid", userId);
+ mapList.addAll(jdbcDao.findMapList(postSqler));
+ }
+// sqler.addDescOrder("t.uptim");
+ return RestResult.ok(mapList);
+ }
+
+ @PostMapping
+ public RestResult post(@RequestBody List reces) {
+ if(reces!=null&&reces.size()>0){
+ service.update(reces);
+ }
+ return RestResult.ok();
+ }
+
+
+ @Autowired
+ private GenOrgReceService service;
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceRepo.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceRepo.java
new file mode 100644
index 0000000..537b12d
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceRepo.java
@@ -0,0 +1,8 @@
+package com.zsvg.vboot.module.gen.org.rece;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface GenOrgReceRepo extends JpaRepository {
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceService.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceService.java
new file mode 100644
index 0000000..818e6be
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/rece/GenOrgReceService.java
@@ -0,0 +1,70 @@
+package com.zsvg.vboot.module.gen.org.rece;
+
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import com.zsvg.vboot.common.util.web.XuserUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class GenOrgReceService {
+
+
+ //todo 有时间再优化
+ public int update(List reces) {
+ String userid = XuserUtil.getUserId();
+ for (GenOrgRece rece : reces) {
+ rece.setOrgid(rece.getId());
+ rece.setId(XstringUtil.getUUID());
+ rece.setUserid(userid);
+ }
+
+ //1.如果当前数量小于10,则去数据库查询最新的差额记录数
+ if (reces.size() < 10) {
+ Sqler sqler = new Sqler("t.*", "gen_org_rece", 1, 10 - reces.size());
+ sqler.addDescOrder("t.uptim");
+ sqler.addEqual("t.userid", userid);
+ List list;
+ if ("MYSQL".equals(jdbcDao.getDbType())) {
+ list = jdbcDao.getTp().query(sqler.getMysqlPagingSql(), sqler.getParams(), new BeanPropertyRowMapper<>(GenOrgRece.class));
+ } else {
+ list = jdbcDao.getTp().query(sqler.getOraclePagingSql(), sqler.getParams(), new BeanPropertyRowMapper<>(GenOrgRece.class));
+ }
+ //去重
+ for (GenOrgRece dbRece : list) {
+ boolean flag = false;
+ for (GenOrgRece rece : reces) {
+ if (dbRece.getOrgid().equals(rece.getOrgid())) {
+ flag = true;
+ }
+ }
+ if (!flag) {
+ reces.add(dbRece);
+ }
+ }
+ }
+
+ //2.清空当前用户的最近使用记录
+ jdbcDao.update("delete from gen_org_rece where userid=?", userid);
+
+ //3.更新记录
+ repo.saveAll(reces);
+ return reces.size();
+ }
+
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+
+ @Autowired
+ private GenOrgReceRepo repo;
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/root/GenOrgDeptApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/root/GenOrgDeptApi.java
new file mode 100644
index 0000000..a85aff2
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/root/GenOrgDeptApi.java
@@ -0,0 +1,49 @@
+package com.zsvg.vboot.module.gen.org.root;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.mvc.pojo.Ztree;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("gen/org/dept")
+public class GenOrgDeptApi {
+
+ //查询部门树
+ @GetMapping("tree")
+ public RestResult getTree(String name) {
+ Sqler sqler = new Sqler("sys_org_dept");
+ sqler.addSelect("t.pid");
+ sqler.addLike("t.name", name);
+ sqler.addOrder("t.ornum");
+ sqler.addWhere("t.avtag=1");
+ List list = jdbcDao.findTreeList(sqler);
+ return RestResult.ok(list);
+ }
+
+ //查询部门树
+ @GetMapping("list")
+ public RestResult getList(String name) {
+ Sqler sqler = new Sqler("sys_org_dept");
+ sqler.addLike("t.name", name);
+ sqler.addOrder("t.ornum");
+ sqler.addWhere("t.avtag=1");
+ sqler.addSelect("t.pid");
+ return RestResult.ok(jdbcDao.findMapList(sqler));
+ }
+
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+
+// @Autowired
+// private SysOrgDeptService deptService;
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/root/GenOrgMainApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/root/GenOrgMainApi.java
new file mode 100644
index 0000000..9f470bc
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/org/root/GenOrgMainApi.java
@@ -0,0 +1,61 @@
+package com.zsvg.vboot.module.gen.org.root;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("gen/org/main")
+public class GenOrgMainApi {
+
+ //根据部门ID,查询下级所有的部门,岗位,用户
+ @GetMapping("list")
+ public RestResult list(String deptid, Integer type, String name) {
+ List> mapList = new ArrayList<>();
+ if(XstringUtil.isBlank(name)&&XstringUtil.isBlank(deptid)){
+ return RestResult.ok(mapList);
+ }
+ if ((type & 2) != 0) {//部门
+ Sqler deptSqler = new Sqler("sys_org_dept");
+ if(XstringUtil.isNotBlank(name)){
+ deptSqler.addLike("t.name", name);
+ }else{
+ deptSqler.addEqual("t.pid", deptid);
+ }
+ mapList.addAll(jdbcDao.findMapList(deptSqler));
+ }
+ if ((type & 4) != 0) {//岗位
+ Sqler postSqler = new Sqler("sys_org_post");
+ if(XstringUtil.isNotBlank(name)){
+ postSqler.addLike("t.name", name);
+ }else{
+ postSqler.addEqual("t.deptid", deptid);
+ }
+ mapList.addAll(jdbcDao.findMapList(postSqler));
+ }
+ if ((type & 8) != 0) {//用户
+ Sqler userSqler = new Sqler("sys_org_user");
+ if(XstringUtil.isNotBlank(name)){
+ userSqler.addLike("t.name", name);
+ }else{
+ userSqler.addEqual("t.deptid", deptid);
+ }
+ mapList.addAll(jdbcDao.findMapList(userSqler));
+ }
+ return RestResult.ok(mapList);
+ }
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/sys/auth/GenAuthApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/sys/auth/GenAuthApi.java
new file mode 100644
index 0000000..1167dda
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/sys/auth/GenAuthApi.java
@@ -0,0 +1,70 @@
+package com.zsvg.vboot.module.gen.sys.auth;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.config.security.pojo.Zuser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("gen/auth")
+public class GenAuthApi {
+
+ @PostMapping(value="btns")
+ public RestResult getBtns(HttpServletRequest request, @RequestBody Map btns) {
+ Zuser zuser = null;
+ Map backMap = new HashMap<>();
+ for (String str : btns.keySet()) {
+ if(zuser.isAdmin()){
+ backMap.put(str, true);
+ continue;
+ }
+ backMap.put(str, false);
+ String sql = "select ipos,lcode from sys_auth_perm p where p.id = ?";
+ try{
+ Map map = jdbcDao.findMap(sql, btns.get(str));
+ if (zuser.hasPerm(Integer.parseInt(""+map.get("ipos")) , Long.parseLong(""+map.get("lcode")))) {
+ backMap.put(str, true);
+ }
+ }catch (Exception e){
+
+ }
+ }
+ return RestResult.ok(backMap);
+ }
+
+ //获取用户信息,如果没有登录到不了这里
+ @GetMapping("user")
+ public RestResult getUser(HttpServletRequest request,String id) {
+ Map map = new HashMap<>();
+ Zuser zuser= null;
+ if("sa".equals(id)){
+ //主页滚动通知
+ String noteSql = "select n.notes from sys_por_note n inner join sys_por_note_org o on o.id=n.id where n.label='sa' and n.avtag=1 and o.org in (" + zuser.getConds() + ")";
+ String note = jdbcDao.findOneString(noteSql);
+ map.put("note", note);
+
+ //主页弹框通知
+ String note2Sql = "select n.id,r.org from sys_por_note n inner join sys_por_note_org o on o.id=n.id left join sys_por_note_reader r on r.id=n.id AND r.org = '"+zuser.getId()+"' where n.label='sa2' and n.avtag=1 and o.org in (" + zuser.getConds() + ")";
+ List> note2List = jdbcDao.findMapList(note2Sql);
+ if(note2List.size()>0){
+ if(note2List.get(0).get("org")==null){
+ map.put("note2", note2List.get(0).get("id"));
+ }
+ }
+
+
+ }
+ map.put("zuser", zuser);
+ return RestResult.build(200, "已登录",map);
+ }
+
+
+ @Autowired
+ private JdbcDao jdbcDao;
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/gen/sys/org/GenOrgApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/sys/org/GenOrgApi.java
new file mode 100644
index 0000000..43f4b47
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/gen/sys/org/GenOrgApi.java
@@ -0,0 +1,61 @@
+package com.zsvg.vboot.module.gen.sys.org;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import com.zsvg.vboot.config.security.pojo.Zuser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("gen/org")
+public class GenOrgApi {
+ @GetMapping(value="watag")
+ public RestResult getWatag(HttpServletRequest request) {
+ Zuser zuser = null;
+ String sql = "update sys_org_user set watag=0 where id=?";
+ jdbcDao.update(sql, zuser.getId());
+ zuser.setWatag(false);
+ return RestResult.ok();
+ }
+
+ @GetMapping(value="choose")
+ public RestResult getChoose(String name, String type) {
+ Sqler sqlHelper = new Sqler("id,pid,name","sys_org_main");
+ sqlHelper.addWhere("t.avtag = 1");
+ sqlHelper.addWhere(XstringUtil.isNotBlank(type),"type in ("+type+")");
+ sqlHelper.addLike("name",name);
+ sqlHelper.addEqual("t.label", "ekp");
+ return RestResult.ok(jdbcDao.findInpList(sqlHelper));
+ }
+
+ @GetMapping("search")
+ public RestResult getSearch(String name, String type) {
+ Sqler sqlHelper = new Sqler("t.id,t.name","sys_org_main");
+ sqlHelper.addLeftJoin("t2.name as pid", "sys_org t2", "t2.id=t.pid");
+ sqlHelper.addWhere("t.avtag = 1");
+ sqlHelper.addLike("t.name",name);
+ sqlHelper.addWhere(XstringUtil.isNotBlank(type),"t.type in ("+type+")");
+ return RestResult.ok(jdbcDao.findInpList(sqlHelper));
+ }
+
+
+ @GetMapping("dept/{id}")
+ public RestResult getDept(@PathVariable String id, String type) {
+ Sqler sqlHelper = new Sqler("t.id,t.name","sys_org_main");
+ sqlHelper.addLeftJoin("t2.name as pid", "sys_org t2", "t2.id=t.pid");
+ sqlHelper.addWhere("t.avtag = 1");
+ sqlHelper.addWhere(XstringUtil.isNotBlank(type),"t.type in ("+type+")");
+ sqlHelper.addWhere("t.pid = ?",id);
+ return RestResult.ok(jdbcDao.findInpList(sqlHelper));
+ }
+
+ @Autowired
+ private JdbcDao jdbcDao;
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenu.java b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenu.java
new file mode 100644
index 0000000..4cd8e70
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenu.java
@@ -0,0 +1,80 @@
+package com.zsvg.vboot.module.sys.auth.menu;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Entity
+@Data
+public class SysAuthMenu {
+
+ @Id
+ @Column(length = 32)
+ private String id;
+
+ @Column(length = 32)
+ private String pid;
+// @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
+// @JoinColumn(name = "pid")
+// @OrderBy("ornum ASC")
+
+ @Transient
+ private String pname; //行项目
+
+ @Transient
+ private List children = new ArrayList<>(); //行项目
+
+ @Column(length = 32)
+ private String type;//类型 C:目录,M:菜单,B:按钮
+
+ @Column(length = 64)
+ private String name;//名称
+
+ @Column(length = 32)
+ private String code;//代码
+
+ private Integer ornum;//排序号
+
+ @Column(length = 64)
+ private String icon;//图标
+
+ @Column(length = 64)
+ private String path;//路由地址
+
+ @Column(length = 64)
+ private String comp;//组件路径
+
+ @Column(length = 64)
+ private String perm;//权限标识
+
+ @Column(length = 64)
+ private String redirect;//跳转
+
+ private Boolean extag;//外链标记
+
+ private Boolean catag;//缓存标记
+
+ private Boolean shtag;//是否显示
+
+ private Boolean avtag;//可用标记
+
+ @Column(updatable = false)
+ private Date crtim = new Date();//创建时间
+
+ private Date uptim;//更新时间
+
+ //--------以后扩展用---------
+ @Column(length = 32)
+ private String tcode;
+
+ private Long lcode;
+
+ private Integer ipos;
+
+}
\ No newline at end of file
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuApi.java
new file mode 100644
index 0000000..55907b4
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuApi.java
@@ -0,0 +1,80 @@
+package com.zsvg.vboot.module.sys.auth.menu;
+
+import com.zsvg.vboot.common.mvc.api.RestResult;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("sys/auth/menu")
+public class SysAuthMenuApi {
+
+ @GetMapping("tree")
+ public RestResult getTree(String name, String type) {
+ Sqler sqler = new Sqler("sys_auth_menu");
+ sqler.addLike("t.name", name);
+ sqler.addOrder("t.ornum");
+ sqler.addWhere("t.avtag=1");
+ sqler.addSelect("t.type,t.crtim,t.uptim,t.pid");
+ if(XstringUtil.isNotBlank(type)){
+ if("DM".equals(type)){
+ sqler.addWhere("t.type in ('D','M')");
+ }else{
+ return RestResult.ok(new ArrayList<>());
+ }
+ }
+ List list = service.findTree(sqler);
+ return RestResult.ok(list);
+ }
+
+ //排除了自己
+ @GetMapping("listn")
+ public RestResult getListn( String id) {
+ List list = service.findWithoutItself(id);
+ return RestResult.ok(list);
+ }
+
+ @GetMapping("one/{id}")
+ public RestResult id(@PathVariable String id, HttpServletRequest request) {
+ SysAuthMenu main = service.findById(id);
+ if(main.getPid()!=null){
+ SysAuthMenu parent = service.findById(main.getPid());
+ main.setPname(parent.getName());
+ }
+ return RestResult.ok(main);
+ }
+
+
+ @PostMapping
+ public RestResult post(@RequestBody SysAuthMenu main) {
+ System.out.println("插入");
+ return RestResult.ok(service.insert(main));
+ }
+
+ @PutMapping
+ public RestResult put(@RequestBody SysAuthMenu main) {
+ System.out.println("修改");
+ return RestResult.ok(service.update(main));
+ }
+
+ @DeleteMapping("{ids}")
+ public RestResult delete(@PathVariable String[] ids) {
+ System.out.println(ids);
+ return RestResult.ok(service.delete(ids));
+ }
+
+
+ @Autowired
+ private JdbcDao jdbcDao;
+
+ @Autowired
+ private SysAuthMenuService service;
+
+
+}
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuRepo.java b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuRepo.java
new file mode 100644
index 0000000..b34a70c
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuRepo.java
@@ -0,0 +1,16 @@
+package com.zsvg.vboot.module.sys.auth.menu;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface SysAuthMenuRepo extends JpaRepository {
+
+ List findByNameLikeOrderByOrnum(String name);
+
+ List findByOrderByOrnum();
+
+ List findByPid(String pid);
+
+}
+
diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuService.java b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuService.java
new file mode 100644
index 0000000..309f019
--- /dev/null
+++ b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/auth/menu/SysAuthMenuService.java
@@ -0,0 +1,209 @@
+package com.zsvg.vboot.module.sys.auth.menu;
+
+import cn.hutool.core.util.StrUtil;
+import com.zsvg.vboot.common.mvc.dao.JdbcDao;
+import com.zsvg.vboot.common.mvc.dao.Sqler;
+import com.zsvg.vboot.common.util.lang.XstringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class SysAuthMenuService {
+
+ @Transactional(readOnly = true)
+ public SysAuthMenu findById(String id) {
+
+ return repo.findById(id).get();
+ }
+
+ public SysAuthMenu insert(SysAuthMenu main) {
+ if (main.getId() == null || "".equals(main.getId())) {
+ main.setId(XstringUtil.getUUID());
+ }
+ return repo.save(main);
+ }
+
+
+ public SysAuthMenu update(SysAuthMenu main) {
+ return repo.save(main);
+ }
+
+ public int delete(String[] ids) {
+ Set menuSet = new HashSet<>();
+ for (String id : ids) {
+ menuSet.add(id);
+ List menuList = repo.findByPid(id);
+ addChild(menuList, menuSet);
+ }
+ for (String str : menuSet) {
+ repo.deleteById(str);
+ }
+ return menuSet.size();
+ }
+
+ public void addChild(List menuList, Set menuSet) {
+ for (SysAuthMenu menu : menuList) {
+ menuSet.add(menu.getId());
+ List menus = repo.findByPid(menu.getId());
+ if (menus != null && menus.size() != 0) {
+ addChild(menus, menuSet);
+ }
+ }
+ }
+
+ public List findTree(Sqler sqler) {
+ List list = jdbcDao.getTp().query(sqler.getSql(), sqler.getParams(), new BeanPropertyRowMapper<>(SysAuthMenu.class));
+ return buildByRecursive(list);
+ }
+
+
+ public List findAll(String name) {
+ List list;
+ if (StrUtil.isNotBlank(name)) {
+ list = repo.findByNameLikeOrderByOrnum("%" + name + "%");
+ } else {
+ list = repo.findByOrderByOrnum();
+ }
+ return buildByRecursive(list);
+ }
+
+
+ public List findWithoutItself(String id) {
+ List list = repo.findByOrderByOrnum();
+ List menus = buildByRecursiveWithoutItself(list, id);
+
+ return menus;
+ }
+
+
+ //高性能转换,但是要求顶层有pid,这里假设为0
+ public static List buildTree(List pidList) {
+ Map> pidListMap = pidList.stream().collect(Collectors.groupingBy(SysAuthMenu::getPid));
+ pidList.stream().forEach(item -> item.setChildren(pidListMap.get(item.getId())));
+ //返回结果也改为返回顶层节点的list
+ return pidListMap.get("0");
+ }
+
+// private List getTreeData(List