diff --git a/common.sql b/common.sql index 79f1e59..3745f7b 100644 --- a/common.sql +++ b/common.sql @@ -14,7 +14,7 @@ create table sys_config type int default 1 null comment '配置类型', config_desc varchar(256) null comment '描述' ) - comment '系统配置(v3)' charset = utf8; + comment '系统配置(v3)' charset = utf8mb4; create index sys_config__index_key on sys_config (`key`); @@ -40,7 +40,7 @@ create table sys_schedule plat_exec_time datetime null comment '计划执行时间', schedule_desc varchar(256) null comment '任务描述' ) - comment '系统分布式任务(v3)'; + comment '系统分布式任务(v3)' charset = utf8mb4; create index index_status on sys_schedule (status); diff --git a/common/README.md b/common/README.md index a76cec1..c52477b 100644 --- a/common/README.md +++ b/common/README.md @@ -8,7 +8,8 @@ keray: global-switch: # 全局开启json解析 data: true # 接口qps配置 time: true # 接口时长统计 - + log: + all: true #api日志 ``` ## cache使用 diff --git a/common/src/main/java/com/keray/common/BEntity.java b/common/src/main/java/com/keray/common/BEntity.java new file mode 100644 index 0000000..c4b58df --- /dev/null +++ b/common/src/main/java/com/keray/common/BEntity.java @@ -0,0 +1,11 @@ +package com.keray.common; + +import com.baomidou.mybatisplus.extension.activerecord.Model; + +/** + * @author by keray + * date:2020/7/15 9:38 上午 + */ +public class BEntity> extends Model implements IBEntity{ + +} diff --git a/common/src/main/java/com/keray/common/IBEntity.java b/common/src/main/java/com/keray/common/IBEntity.java new file mode 100644 index 0000000..01c3390 --- /dev/null +++ b/common/src/main/java/com/keray/common/IBEntity.java @@ -0,0 +1,9 @@ +package com.keray.common; + +/** + * @author by keray + * date:2020/7/15 9:38 上午 + */ +public interface IBEntity> { + +} diff --git a/common/src/main/java/com/keray/common/IBMapper.java b/common/src/main/java/com/keray/common/IBMapper.java new file mode 100644 index 0000000..590fad0 --- /dev/null +++ b/common/src/main/java/com/keray/common/IBMapper.java @@ -0,0 +1,117 @@ +package com.keray.common; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.TypeUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.enums.SqlMethod; +import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.session.SqlSession; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * @author by keray + * date:2019/7/25 16:56 + */ +public interface IBMapper> extends BaseMapper { + + /** + * 根据 whereEntity 条件,更新记录 + * + * @param entity 实体对象 (set 条件值,可以为 null) + * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) + * @return + */ + @Override + int update(@Param(Constants.ENTITY) B entity, @Param(Constants.WRAPPER) Wrapper updateWrapper); + + /** + *

+ *

作者 keray

+ *

时间: 2019/10/24 17:43

+ * 查询sum + *

+ * + * @param wrapper + * @return

{@link String}

+ * @throws + */ + Double selectSum(@Param(Constants.WRAPPER) Wrapper wrapper); + + /** + * 插入一条记录 + * + * @param entity 实体对象 + * @return + */ + @Override + int insert(B entity); + + + /** + *

+ * 插入(批量) + *

+ * + * @param entityList 实体对象列表 + * @param batchSize 插入批次数量 + * @return boolean + */ + @Transactional(rollbackFor = Exception.class) + default boolean insertBatch(List entityList, int batchSize) { + if (CollUtil.isEmpty(entityList)) { + throw new IllegalArgumentException("Error: entityList must not be empty"); + } + try (SqlSession batchSqlSession = sqlSessionBatch()) { + int size = entityList.size(); + String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE); + for (int i = 0; i < size; i++) { + batchSqlSession.insert(sqlStatement, entityList.get(i)); + if (i >= 1 && i % batchSize == 0) { + batchSqlSession.flushStatements(); + } + } + batchSqlSession.flushStatements(); + } catch (Throwable e) { + throw new MybatisPlusException("Error: Cannot execute insertBatch Method. Cause", e); + } + return true; + } + + + default boolean exits(Wrapper wrapper) { + return selectCount(wrapper) > 0; + } + /** + *

+ * 批量操作 SqlSession + *

+ */ + default SqlSession sqlSessionBatch() { + return SqlHelper.sqlSessionBatch(currentModelClass()); + } + /** + * 获取SqlStatement + * + * @param sqlMethod 方法 + * @return String + */ + default String sqlStatement(SqlMethod sqlMethod) { + return SqlHelper.table(currentModelClass()).getSqlStatement(sqlMethod.getMethod()); + } + + /** + *

+ * 获取当前class + *

+ */ + default Class currentModelClass() { + return (Class) TypeUtil.getTypeArgument(this.getClass().getInterfaces()[0].getGenericInterfaces()[0]); + } + +} diff --git a/common/src/main/java/com/keray/common/IBSEntity.java b/common/src/main/java/com/keray/common/IBSEntity.java new file mode 100644 index 0000000..0c0569e --- /dev/null +++ b/common/src/main/java/com/keray/common/IBSEntity.java @@ -0,0 +1,13 @@ +package com.keray.common; + +import java.io.Serializable; + +/** + * @author by keray + * date:2020/7/15 9:39 上午 + */ +public interface IBSEntity, ID extends Serializable> extends IBEntity { + ID getId(); + + void setId(ID id); +} diff --git a/common/src/main/java/com/keray/common/IBSMapper.java b/common/src/main/java/com/keray/common/IBSMapper.java new file mode 100644 index 0000000..e59fcdc --- /dev/null +++ b/common/src/main/java/com/keray/common/IBSMapper.java @@ -0,0 +1,65 @@ +package com.keray.common; + +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import org.apache.ibatis.annotations.Param; + +import java.io.Serializable; +import java.util.Collection; + +/** + * @author by keray + * date:2020/7/15 9:39 上午 + */ +public interface IBSMapper, ID extends Serializable> extends IBMapper { + + /** + * 插入一条记录 + * + * @param entity 实体对象 + * @return + */ + @Override + int insert(BS entity); + + /** + * 根据 ID 修改 + * + * @param entity 实体对象 + * @return + */ + @Override + int updateById(@Param(Constants.ENTITY) BS entity); + + + @Override + BS selectById(Serializable id); + + default boolean contains(String id) { + return selectCount(Wrappers.query().eq("id", id)) == 1; + } + + /** + * 删除(根据ID 批量删除) + * + * @param id 主键ID列表(不能为 null 以及 empty) + */ + @Override + default int deleteById(Serializable id) { + return this.delete(Wrappers.update().eq("id", id)); + } + + /** + * 删除(根据ID 批量删除) + * + * @param idList 主键ID列表(不能为 null 以及 empty) + */ + @Override + default int deleteBatchIds(@Param(Constants.COLLECTION) Collection idList) { + return this.delete(Wrappers.update().in("id", idList)); + } + + default Boolean canDelete(@Param("ids") Collection ids) { + return true; + } +} diff --git a/common/src/main/java/com/keray/common/SysThreadPool.java b/common/src/main/java/com/keray/common/SysThreadPool.java index 2627b2c..bf09ad7 100644 --- a/common/src/main/java/com/keray/common/SysThreadPool.java +++ b/common/src/main/java/com/keray/common/SysThreadPool.java @@ -8,7 +8,7 @@ * date:2019/9/16 11:49 */ public class SysThreadPool { - private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(100, 1000, 10, + private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(100, 1000, 10, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(10000000), r -> { Thread t = new Thread(r); diff --git a/common/src/main/java/com/keray/common/config/ApiLogServletInvocableHandlerMethodHandler.java b/common/src/main/java/com/keray/common/config/ApiLogServletInvocableHandlerMethodHandler.java new file mode 100644 index 0000000..f6342d3 --- /dev/null +++ b/common/src/main/java/com/keray/common/config/ApiLogServletInvocableHandlerMethodHandler.java @@ -0,0 +1,117 @@ +package com.keray.common.config; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.keray.common.IBaseEntity; +import com.keray.common.Result; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.MethodParameter; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.HandlerMethod; + +import javax.servlet.http.HttpServletRequest; +import java.util.function.Consumer; + +/** + * @author by keray + * date:2020/6/3 10:08 上午 + */ +@Slf4j +@Configuration +@ConfigurationProperties(prefix = "api.log") +public class ApiLogServletInvocableHandlerMethodHandler implements ServletInvocableHandlerMethodHandler { + + @Getter + @Setter + private Boolean all = false; + + @Override + public Integer order() { + return 0; + } + + @Override + public Object work(HandlerMethod handlerMethod, Object[] args, NativeWebRequest request, ServletInvocableHandlerMethodCallback callback) throws Exception { + long start = System.nanoTime(); + for (Object o : args) { + if (o instanceof IBaseEntity) { + ((IBaseEntity) o).clearBaseField(); + } + } + Consumer logFail = result -> { + try { + if (result instanceof Result.FailResult || result instanceof Exception || all) { + String url = null; + String flag = null; + try { + HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class); + if (servletRequest != null) { + url = servletRequest.getRequestURL().toString(); + if (StrUtil.isBlank(url)) { + url = "错误"; + } + flag = servletRequest.getHeader("X-User-Agent"); + if (StrUtil.isBlank(flag)) { + flag = servletRequest.getHeader("User-Agent"); + } + if (StrUtil.isBlank(flag)) { + flag = "未知"; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + apiLog(result instanceof Result.FailResult || result instanceof Exception, result, url, flag, args, handlerMethod.getMethodParameters(), start); + } + } catch (Exception e) { + e.printStackTrace(); + } + }; + try { + Object result = callback.get(); + logFail.accept(result); + return result; + } catch (Exception e) { + logFail.accept(e); + throw e; + } + } + + private void apiLog(boolean fail, Object result, String url, String flag, Object[] args, MethodParameter[] parameters, long start) { + StringBuilder builder = new StringBuilder(); + if (fail) { + builder.append(System.lineSeparator()).append("============接口异常============").append(System.lineSeparator()); + } else { + builder.append(System.lineSeparator()).append("============api start============").append(System.lineSeparator()); + } + builder.append(" flag:").append(flag).append(System.lineSeparator()); + builder.append(" url:").append(url).append(System.lineSeparator()); + builder.append(" args:").append(System.lineSeparator()); + for (int i = 0; i < parameters.length; i++) { + String json = "json解析失败"; + try { + json = args[i] == null ? null : JSON.toJSONString(args[i]); + } catch (Exception ignore) { + } + builder.append(parameters[i].getParameterName()).append("=").append(json).append(System.lineSeparator()); + } + if (result instanceof Result.FailResult) { + builder.append("result:").append(StrUtil.format("code={},message={}", ((Result) result).getCode(), ((Result.FailResult) result).getMessage())).append(System.lineSeparator()); + } else if (result instanceof Result.SuccessResult){ + builder.append("result:").append(JSON.toJSONString(((Result.SuccessResult) result).getData())).append(System.lineSeparator()); + } else { + builder.append("result:").append(result.getClass()).append(System.lineSeparator()); + } + builder.append(String.format("============end time=ns:%s ============",System.nanoTime() - start)); + builder.append(System.lineSeparator()); + if (fail) { + log.error(builder.toString()); + } else { + log.info(builder.toString()); + } + } +} diff --git a/common/src/main/java/com/keray/common/config/IDelegatingWebMvcConfiguration.java b/common/src/main/java/com/keray/common/config/IDelegatingWebMvcConfiguration.java index 2ded6c3..6b48303 100644 --- a/common/src/main/java/com/keray/common/config/IDelegatingWebMvcConfiguration.java +++ b/common/src/main/java/com/keray/common/config/IDelegatingWebMvcConfiguration.java @@ -1,6 +1,8 @@ package com.keray.common.config; +import cn.hutool.core.collection.CollUtil; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.annotation.Order; @@ -9,6 +11,12 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod; +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; + /** * @author by keray * date:2020/4/19 12:59 上午 @@ -20,6 +28,22 @@ public class IDelegatingWebMvcConfiguration extends DelegatingWebMvcConfiguration { + ServletInvocableHandlerMethodHandler[] handlers = null; + + @Resource + private ApplicationContext applicationContext; + + @PostConstruct + public void initHandler() { + Collection handlerMethodHandlers = applicationContext + .getBeansOfType(ServletInvocableHandlerMethodHandler.class).values(); + if (CollUtil.isNotEmpty(handlerMethodHandlers)) { + ServletInvocableHandlerMethodHandler[] array = handlerMethodHandlers.toArray(new ServletInvocableHandlerMethodHandler[]{}); + Arrays.sort(array, Comparator.comparing(ServletInvocableHandlerMethodHandler::order)); + handlers = array; + } + } + @Override protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() { return new RequestMappingHandlerAdapter() { @@ -30,7 +54,7 @@ public int getOrder() { @Override protected ServletInvocableHandlerMethod createInvocableHandlerMethod(HandlerMethod handlerMethod) { - return new IServletInvocableHandlerMethod(handlerMethod); + return new IServletInvocableHandlerMethod(handlerMethod, handlers); } }; } diff --git a/common/src/main/java/com/keray/common/config/IServletInvocableHandlerMethod.java b/common/src/main/java/com/keray/common/config/IServletInvocableHandlerMethod.java index 12f3e8d..3079491 100644 --- a/common/src/main/java/com/keray/common/config/IServletInvocableHandlerMethod.java +++ b/common/src/main/java/com/keray/common/config/IServletInvocableHandlerMethod.java @@ -1,18 +1,13 @@ package com.keray.common.config; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSON; -import com.keray.common.IBaseEntity; -import com.keray.common.Result; import lombok.extern.slf4j.Slf4j; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod; -import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; -import java.util.function.Consumer; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; /** * @author by keray @@ -21,82 +16,32 @@ @Slf4j(topic = "api-error") public class IServletInvocableHandlerMethod extends ServletInvocableHandlerMethod { - public IServletInvocableHandlerMethod(HandlerMethod handlerMethod) { + private final ServletInvocableHandlerMethodHandler[] handlers; + + + public IServletInvocableHandlerMethod(HandlerMethod handlerMethod, ServletInvocableHandlerMethodHandler[] handlers) { super(handlerMethod); + this.handlers = handlers; } @Override public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); - for (Object o : args) { - if (o instanceof IBaseEntity) { - ((IBaseEntity) o).clearBaseField(); - } - } - if (logger.isTraceEnabled()) { - logger.trace("Arguments: " + Arrays.toString(args)); - } - Consumer logFail = result -> { - try { - if (result instanceof Result.FailResult || result instanceof Exception) { - String url = null; - String flag = null; - try { - HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class); - if (servletRequest != null) { - url = servletRequest.getRequestURL().toString(); - if (StrUtil.isBlank(url)) { - url = "错误"; - } - flag = servletRequest.getHeader("X-User-Agent"); - if (StrUtil.isBlank(flag)) { - flag = servletRequest.getHeader("User-Agent"); - } - if (StrUtil.isBlank(flag)) { - flag = "未知"; - } - } - } catch (Exception e) { - e.printStackTrace(); - } - logFail(result, url, flag, args); + if (handlers != null) { + final AtomicInteger index = new AtomicInteger(0); + AtomicReference callback1 = new AtomicReference<>(null); + ServletInvocableHandlerMethodCallback callback = () -> { + index.getAndIncrement(); + if (index.get() == handlers.length) { + return doInvoke(args); } - } catch (Exception e) { - e.printStackTrace(); - } - }; - try { - Object result = doInvoke(args); - logFail.accept(result); - return result; - } catch (Exception e) { - logFail.accept(e); - throw e; - } - } - - private void logFail(Object result, String url, String flag, Object[] args) { - StringBuilder builder = new StringBuilder(); - builder.append("\n").append("============接口异常============").append("\n"); - builder.append(" flag:").append(flag).append("\n"); - builder.append(" url:").append(url).append("\n"); - builder.append(" args:").append("\n"); - for (int i = 0; i < getMethodParameters().length; i++) { - String json = "json解析失败"; - try { - json = args[i] == null ? null : JSON.toJSONString(args[i]); - } catch (Exception ignore) { - } - builder.append(getMethodParameters()[i].getParameterName()).append("=").append(json).append("\n"); - } - if (result instanceof Result.FailResult) { - builder.append("result:").append(StrUtil.format("code={},message={}", ((Result) result).getCode(), ((Result.FailResult) result).getMessage())).append("\n"); + return handlers[index.get()].work(this, args, request, callback1.get()); + }; + callback1.set(callback); + return handlers[index.get()].work(this, args, request, callback); } else { - builder.append("result:").append(result.getClass()).append("\n"); + return doInvoke(args); } - builder.append("============end============"); - builder.append("\n"); - log.error(builder.toString()); } } diff --git a/common/src/main/java/com/keray/common/config/MybatisPlusSqlInjector.java b/common/src/main/java/com/keray/common/config/MybatisPlusSqlInjector.java index e2d36cc..7f58104 100644 --- a/common/src/main/java/com/keray/common/config/MybatisPlusSqlInjector.java +++ b/common/src/main/java/com/keray/common/config/MybatisPlusSqlInjector.java @@ -184,12 +184,12 @@ public void insert(JoinPoint joinPoint) { private static final class ILogicSelectOne extends BaseAbstractLogicMethod { @Override public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { - SqlMethod sqlMethod = SqlMethod.SELECT_ONE; - SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(sqlMethod.getSql(), +// SqlMethod sqlMethod = SqlMethod.SELECT_ONE; + SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format("", sqlFirst(), this.sqlSelectColumns(tableInfo, true), tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), sqlComment()), modelClass); - return this.addSelectMappedStatementForTable(mapperClass, sqlMethod.getMethod(), sqlSource, tableInfo); + return this.addSelectMappedStatementForTable(mapperClass, "selectOne", sqlSource, tableInfo); } } diff --git a/common/src/main/java/com/keray/common/config/ServletInvocableHandlerMethodCallback.java b/common/src/main/java/com/keray/common/config/ServletInvocableHandlerMethodCallback.java new file mode 100644 index 0000000..94f7ae9 --- /dev/null +++ b/common/src/main/java/com/keray/common/config/ServletInvocableHandlerMethodCallback.java @@ -0,0 +1,9 @@ +package com.keray.common.config; + +/** + * @author by keray + * date:2020/6/3 9:49 上午 + */ +public interface ServletInvocableHandlerMethodCallback { + Object get() throws Exception; +} diff --git a/common/src/main/java/com/keray/common/config/ServletInvocableHandlerMethodHandler.java b/common/src/main/java/com/keray/common/config/ServletInvocableHandlerMethodHandler.java new file mode 100644 index 0000000..89ed7d7 --- /dev/null +++ b/common/src/main/java/com/keray/common/config/ServletInvocableHandlerMethodHandler.java @@ -0,0 +1,19 @@ +package com.keray.common.config; + +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.HandlerMethod; + +/** + * @author by keray + * date:2020/6/3 9:34 上午 + */ +public interface ServletInvocableHandlerMethodHandler { + + default Integer order() { + return Integer.MAX_VALUE; + } + + default Object work(HandlerMethod handlerMethod, Object[] args, NativeWebRequest request, ServletInvocableHandlerMethodCallback callback) throws Exception { + return callback.get(); + } +} diff --git a/common/src/main/java/com/keray/common/config/SpringMvcConfig.java b/common/src/main/java/com/keray/common/config/SpringMvcConfig.java index 5431108..0274d51 100644 --- a/common/src/main/java/com/keray/common/config/SpringMvcConfig.java +++ b/common/src/main/java/com/keray/common/config/SpringMvcConfig.java @@ -54,9 +54,6 @@ public class SpringMvcConfig implements WebMvcConfigurer { @Autowired(required = false) private ApiDataInterceptor apiDataInterceptor; - @Autowired(required = false) - private ApiTimeInterceptor apiTimeInterceptor; - @Resource(name = "mvcConversionService") private FormattingConversionService formattingConversionService; @@ -66,9 +63,6 @@ public void addInterceptors(InterceptorRegistry registry) { if (apiDataInterceptor != null) { registry.addInterceptor(apiDataInterceptor); } - if (apiTimeInterceptor != null) { - registry.addInterceptor(apiTimeInterceptor); - } } /** diff --git a/common/src/main/java/com/keray/common/service/service/BSService.java b/common/src/main/java/com/keray/common/service/service/BSService.java new file mode 100644 index 0000000..2619456 --- /dev/null +++ b/common/src/main/java/com/keray/common/service/service/BSService.java @@ -0,0 +1,190 @@ +package com.keray.common.service.service; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.keray.common.CommonResultCode; +import com.keray.common.IBSEntity; +import com.keray.common.IBSMapper; +import com.keray.common.exception.BizRuntimeException; +import org.apache.ibatis.annotations.Param; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author by keray + * date:2019/7/25 16:03 + */ +public interface BSService, ID extends Serializable> extends BService { + /** + * 获取基础模块操作mapper + * + * @return + */ + IBSMapper getMapper(); + + + /** + * 修改 + * + * @param entity update实体 + * @return + */ + default Boolean update(BS entity) { + if (ObjectUtil.isEmpty(entity.getId())) { + throw new BizRuntimeException("update必须拥有Id", CommonResultCode.dataChangeError.getCode()); + } + return getMapper().updateById(entity) == 1; + } + + /** + * 基础实体修改 + * 不推荐重写 + * + * @param entity update实体 + * @return + */ + default boolean simpleUpdate(BS entity) { + if (ObjectUtil.isEmpty(entity.getId())) { + throw new BizRuntimeException("update必须拥有Id", CommonResultCode.dataChangeError.getCode()); + } + return getMapper().updateById(entity) == 1; + } + + /** + * 删除 + * + * @param id 实体id + * @return + */ + default Boolean delete(String id) { + if (!this.canDelete(Collections.singletonList(id))) { + throw new BizRuntimeException(CommonResultCode.dataNotAllowDelete); + } + return getMapper().deleteById(id) == 1; + } + + /** + * 批量逻辑删除 + * + * @param ids 实体id + * @return + */ + @Transactional(rollbackFor = RuntimeException.class) + default Boolean delete(Collection ids) { + if (CollUtil.isEmpty(ids)) { + throw new BizRuntimeException(CommonResultCode.illegalArgument); + } + if (ids.size() == 1) { + return delete((String) ((List) ids).get(0)); + } + ids = ids.stream().distinct().collect(Collectors.toList()); + if (!this.canDelete(ids)) { + throw new BizRuntimeException(CommonResultCode.dataNotAllowDelete); + } + if (getMapper().deleteBatchIds(ids) != ids.size()) { + throw new BizRuntimeException(CommonResultCode.dataChangeError); + } + return true; + } + + /** + * 通过id查询数据 + * + * @param id 实体id + * @return T + */ + default BS getById(String id) { + return getMapper().selectById(id); + } + + /** + * 分页查询 + * + * @param pager 分页参数 + * @return 分页数据 + */ + default IPage page(Page pager) { + return this.page(pager, null); + } + + /** + * 分页查询 + * + * @param pager 分页参数 + * @param queryWrapper + * @return 分页数据 + */ + default IPage page(Page pager, @Param(Constants.WRAPPER) Wrapper queryWrapper) { + return getMapper().selectPage(pager, queryWrapper); + } + + + /** + * 根据 entity 条件,查询全部记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @return + */ + default List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper) { + return getMapper().selectList(queryWrapper); + } + + + /** + * 根据 entity 条件,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @return + */ + default BS selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper) { + return getMapper().selectOne(queryWrapper); + } + + /** + * 根据 Wrapper 条件,查询总记录数 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper) { + return getMapper().selectCount(queryWrapper); + } + + /** + *

+ *

作者 keray

+ *

时间: 2019/9/16 14:14

+ * 是否存在id + *

+ * + * @param id + * @return

{@link boolean}

+ * @throws + */ + default boolean contains(String id) { + return getMapper().contains(id); + } + + /** + *

+ *

作者 keray

+ *

时间: 2019/11/25 10:24 AM

+ * 实体删除时校验是否能被删除 + *

+ * + * @param keys ids | codes | 其他 子类自行实现 + * @return

{@link boolean}

+ * @throws + */ + default Boolean canDelete(Collection keys) { + return getMapper().canDelete(keys); + } +} diff --git a/common/src/main/java/com/keray/common/service/service/BService.java b/common/src/main/java/com/keray/common/service/service/BService.java new file mode 100644 index 0000000..07abb61 --- /dev/null +++ b/common/src/main/java/com/keray/common/service/service/BService.java @@ -0,0 +1,106 @@ +package com.keray.common.service.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.keray.common.IBEntity; +import com.keray.common.IBMapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * @author by keray + * date:2019/7/25 16:03 + */ +public interface BService> { + /** + * 获取基础模块操作mapper + * + * @return + */ + IBMapper getMapper(); + /** + * 添加 + * + * @param entity insert实体 + * @return + */ + default Boolean insert(B entity) { + return getMapper().insert(entity) == 1; + } + + /** + *

+ * 插入(批量) + *

+ * + * @param entityList 实体对象列表 + * @param batchSize 插入批次数量 + * @return boolean + */ + default boolean insertBatch(List entityList, int batchSize) { + return getMapper().insertBatch(entityList, batchSize); + } + + @Transactional(rollbackFor = Exception.class) + default boolean insertBatch(List entityList) { + return getMapper().insertBatch(entityList, 50); + } + + /** + * 分页查询 + * + * @param pager 分页参数 + * @return 分页数据 + */ + default IPage page(Page pager) { + return this.page(pager, null); + } + + /** + * 分页查询 + * + * @param pager 分页参数 + * @param queryWrapper + * @return 分页数据 + */ + default IPage page(Page pager, @Param(Constants.WRAPPER) Wrapper queryWrapper) { + return getMapper().selectPage(pager, queryWrapper); + } + + + /** + * 根据 entity 条件,查询全部记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @return + */ + default List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper){ + return getMapper().selectList(queryWrapper); + } + + + /** + * 根据 entity 条件,查询一条记录 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + * @return + */ + default B selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper){ + return getMapper().selectOne(queryWrapper); + } + + /** + * 根据 Wrapper 条件,查询总记录数 + * + * @param queryWrapper 实体对象封装操作类(可以为 null) + */ + default Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper){ + return getMapper().selectCount(queryWrapper); + } + + +} diff --git a/common/src/main/java/com/keray/common/service/service/impl/BSServiceImpl.java b/common/src/main/java/com/keray/common/service/service/impl/BSServiceImpl.java new file mode 100644 index 0000000..9f707b7 --- /dev/null +++ b/common/src/main/java/com/keray/common/service/service/impl/BSServiceImpl.java @@ -0,0 +1,14 @@ +package com.keray.common.service.service.impl; + +import com.keray.common.IBSEntity; +import com.keray.common.service.service.BSService; + +import java.io.Serializable; + +/** + * @author by keray + * date:2019/7/25 16:03 + */ +public abstract class BSServiceImpl, ID extends Serializable> extends BServiceImpl implements BSService { + +} diff --git a/common/src/main/java/com/keray/common/service/service/impl/BServiceImpl.java b/common/src/main/java/com/keray/common/service/service/impl/BServiceImpl.java new file mode 100644 index 0000000..0931e34 --- /dev/null +++ b/common/src/main/java/com/keray/common/service/service/impl/BServiceImpl.java @@ -0,0 +1,12 @@ +package com.keray.common.service.service.impl; + +import com.keray.common.IBEntity; +import com.keray.common.service.service.BService; + +/** + * @author by keray + * date:2019/7/25 16:03 + */ +public abstract class BServiceImpl> implements BService { + +} diff --git a/common/src/main/java/com/keray/common/service/service/impl/SysConfigService.java b/common/src/main/java/com/keray/common/service/service/impl/SysConfigService.java index fd94cd2..1cedd30 100644 --- a/common/src/main/java/com/keray/common/service/service/impl/SysConfigService.java +++ b/common/src/main/java/com/keray/common/service/service/impl/SysConfigService.java @@ -27,9 +27,7 @@ import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -135,8 +133,7 @@ public void updateValue(String key, String value) { */ @PostConstruct public void initDiamond() { - Field[] fields = this.getClass().getDeclaredFields(); - for (Field field : fields) { + for (Field field : getFields(this.getClass(), new LinkedList<>())) { DiamondSupport diamondSupport = field.getAnnotation(DiamondSupport.class); if (diamondSupport != null) { log.info("diamond 扫描字段:key={},name={},type={}", diamondSupport.key(), diamondSupport.name(), field.getType().getSimpleName()); @@ -146,6 +143,14 @@ public void initDiamond() { this.loadConfig(); } + public List getFields(Class clazz, List fields) { + if (clazz == null) { + return fields; + } + fields.addAll(Arrays.asList(clazz.getDeclaredFields())); + return getFields(clazz.getSuperclass(), fields); + } + /** *

*

作者 keray

diff --git a/common/src/main/java/com/keray/common/support/ApiTimeInterceptor.java b/common/src/main/java/com/keray/common/support/ApiTimeInterceptor.java index ed73858..47e2b3a 100644 --- a/common/src/main/java/com/keray/common/support/ApiTimeInterceptor.java +++ b/common/src/main/java/com/keray/common/support/ApiTimeInterceptor.java @@ -1,7 +1,9 @@ package com.keray.common.support; -import com.keray.common.annotation.ApiTimeRecord; import com.keray.common.SysThreadPool; +import com.keray.common.annotation.ApiTimeRecord; +import com.keray.common.config.ServletInvocableHandlerMethodCallback; +import com.keray.common.config.ServletInvocableHandlerMethodHandler; import com.keray.common.support.api.time.dao.ApiTimeRecordDao; import com.keray.common.support.api.time.model.ApiTimeRecordModel; import com.keray.common.utils.CommonUtil; @@ -9,13 +11,11 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; +import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -28,40 +28,48 @@ @Component("apiTimeInterceptor") @ConditionalOnProperty(value = "keray.api.time", havingValue = "true") @Slf4j -public class ApiTimeInterceptor extends HandlerInterceptorAdapter { +public class ApiTimeInterceptor implements ServletInvocableHandlerMethodHandler { @Resource(name = "apiTimeRecord") - private ApiTimeRecordDao apiTimeRecordDao; + private ApiTimeRecordDao apiTimeRecordDao; - private final ThreadLocal timeRecord = new ThreadLocal<>(); @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - if (handler instanceof HandlerMethod) { - HandlerMethod method = ((HandlerMethod) handler); - ApiTimeRecord record = method.getMethodAnnotation(ApiTimeRecord.class); - if (record == null) { - record = CommonUtil.getClassAllAnnotation(((HandlerMethod) handler).getMethod().getDeclaringClass(), ApiTimeRecord.class); - } - if (record != null) { - TimeData data = new TimeData(); - data.start = System.currentTimeMillis(); - timeRecord.set(data); - // api接口开启了记录 - data.gt = record.gt(); - if ("".equals(record.value())) { - data.title = method.getMethod().getName(); - } else { - data.title = record.value(); - } + public Integer order() { + return 0; + } + + @Override + public Object work(HandlerMethod handlerMethod, Object[] args, NativeWebRequest request, ServletInvocableHandlerMethodCallback callback) throws Exception { + TimeData data = preHandle(handlerMethod); + try { + return callback.get(); + } finally { + postHandle(data, request.getNativeRequest(HttpServletRequest.class) , handlerMethod); + } + } + + public TimeData preHandle(HandlerMethod handler) { + ApiTimeRecord record = handler.getMethodAnnotation(ApiTimeRecord.class); + if (record == null) { + record = CommonUtil.getClassAllAnnotation(handler.getMethod().getDeclaringClass(), ApiTimeRecord.class); + } + if (record != null) { + TimeData data = new TimeData(); + data.start = System.currentTimeMillis(); + // api接口开启了记录 + data.gt = record.gt(); + if ("".equals(record.value())) { + data.title = handler.getMethod().getName(); + } else { + data.title = record.value(); } + return data; } - return true; + return null; } - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { - TimeData data = timeRecord.get(); + private void postHandle(TimeData data, HttpServletRequest request, HandlerMethod handlerMethod) { if (data != null) { data.end = System.currentTimeMillis(); String url; @@ -73,7 +81,6 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response, String finalUrl = url; SysThreadPool.execute(() -> { if (data.end - data.start > data.gt) { - HandlerMethod handlerMethod = (HandlerMethod) handler; apiTimeRecordDao.insert(ApiTimeRecordModel.builder() .execTime((int) (data.end - data.start)) .gt(data.gt) @@ -87,12 +94,6 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response, } } - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - timeRecord.remove(); - super.afterCompletion(request, response, handler, ex); - } - private static class TimeData { String title; int gt; diff --git a/project-demo/pom.xml b/project-demo/pom.xml index ed72338..d6cefe4 100644 --- a/project-demo/pom.xml +++ b/project-demo/pom.xml @@ -75,6 +75,12 @@ com.nimbusds nimbus-jose-jwt 4.22 + + + json-smart + net.minidev + + diff --git a/project-demo/src/main/java/com/keray/WebStart.java b/project-demo/src/main/java/com/keray/WebStart.java index 2b5e13f..c7a1e60 100644 --- a/project-demo/src/main/java/com/keray/WebStart.java +++ b/project-demo/src/main/java/com/keray/WebStart.java @@ -22,7 +22,8 @@ @SpringBootApplication @EnableTransactionManagement @MapperScan(value = { - "com.keray.common.service.mapper" + "com.keray.common.service.mapper", + "com.keray.mapper" }) @EnableConfigurationProperties @EnableCaching diff --git a/project-demo/src/main/java/com/keray/conf/DiamondConfig.java b/project-demo/src/main/java/com/keray/conf/DiamondConfig.java new file mode 100644 index 0000000..39a0cd4 --- /dev/null +++ b/project-demo/src/main/java/com/keray/conf/DiamondConfig.java @@ -0,0 +1,20 @@ +package com.keray.conf; + +import com.keray.common.annotation.DiamondSupport; +import com.keray.common.service.service.impl.SysConfigService; +import lombok.Getter; +import lombok.Setter; +import org.springframework.context.annotation.Configuration; + +/** + * @author by keray + * date:2020/6/1 3:32 下午 + */ +@Configuration +public class DiamondConfig extends SysConfigService { + + @DiamondSupport(name = "网站标题", key = "sys-web-title") + @Getter + @Setter + private String webTitle; +} diff --git a/project-demo/src/main/java/com/keray/conf/UserContext.java b/project-demo/src/main/java/com/keray/conf/UserContext.java new file mode 100644 index 0000000..404d88a --- /dev/null +++ b/project-demo/src/main/java/com/keray/conf/UserContext.java @@ -0,0 +1,53 @@ +package com.keray.conf; + +import com.keray.common.IUserContext; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author by keray + * date:2020/6/26 10:35 上午 + */ +@Configuration +public class UserContext implements IUserContext { + @Override + public String currentUserId() { + return null; + } + + @Override + public void setCurrentUserId(String userId) { + + } + + @Override + public String currentMerchantsCode() { + return null; + } + + @Override + public void setCurrentMerchantsCode(String merchantsCode) { + + } + + @Override + public String currentIp() { + return null; + } + + @Override + public HttpServletRequest currentRequest() { + return null; + } + + @Override + public void setCurrentRequest(HttpServletRequest request) { + + } + + @Override + public void setCurrentIp(String ip) { + + } +} diff --git a/project-demo/src/main/java/com/keray/mapper/PlusMapper.java b/project-demo/src/main/java/com/keray/mapper/PlusMapper.java new file mode 100644 index 0000000..4d0ddd0 --- /dev/null +++ b/project-demo/src/main/java/com/keray/mapper/PlusMapper.java @@ -0,0 +1,11 @@ +package com.keray.mapper; + +import com.keray.common.IBaseMapper; +import com.keray.model.PlusModel; + +/** + * @author by keray + * date:2020/6/26 10:15 上午 + */ +public interface PlusMapper extends IBaseMapper { +} diff --git a/project-demo/src/main/java/com/keray/model/PlusModel.java b/project-demo/src/main/java/com/keray/model/PlusModel.java new file mode 100644 index 0000000..6109c08 --- /dev/null +++ b/project-demo/src/main/java/com/keray/model/PlusModel.java @@ -0,0 +1,19 @@ +package com.keray.model; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.keray.common.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author by keray + * date:2020/6/26 10:11 上午 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@TableName("plus") +public class PlusModel extends BaseEntity { + + private String name; + +} diff --git a/project-demo/src/main/resources/application.yml b/project-demo/src/main/resources/application.yml index fab8c8c..0cb8354 100644 --- a/project-demo/src/main/resources/application.yml +++ b/project-demo/src/main/resources/application.yml @@ -114,7 +114,14 @@ logging: mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl - +keray: + schedule: true # 定时任务配置 + api: + json: + open: true # json解析 + global-switch: true # 全局开启json解析 + data: true # 接口qps配置 + time: false # 接口时长统计 --- #########################################################################daily################################################################### diff --git a/project-demo/src/test/java/com/keray/AppTest.java b/project-demo/src/test/java/com/keray/AppTest.java index cbbf3bc..c903b86 100644 --- a/project-demo/src/test/java/com/keray/AppTest.java +++ b/project-demo/src/test/java/com/keray/AppTest.java @@ -1,20 +1,27 @@ package com.keray; -import static org.junit.Assert.assertTrue; - +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.keray.mapper.PlusMapper; +import com.keray.model.PlusModel; import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = WebStart.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class AppTest { + + @Resource + private PlusMapper plusMapper; -/** - * Unit test for simple App. - */ -public class AppTest -{ - /** - * Rigorous Test :-) - */ @Test - public void shouldAnswerWithTrue() - { - assertTrue( true ); + public void selectOneTest() { + System.out.println(plusMapper.selectOne( + Wrappers.lambdaQuery(new PlusModel()) + .eq(PlusModel::getName, "keray") + )); } } diff --git a/vue-element-admin-4.0.0/src/icons/svg/setting.svg b/vue-element-admin-4.0.0/src/icons/svg/setting.svg new file mode 100644 index 0000000..9b6c7f5 --- /dev/null +++ b/vue-element-admin-4.0.0/src/icons/svg/setting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vue-element-admin-4.0.0/src/main.js b/vue-element-admin-4.0.0/src/main.js index 375a6b6..db5f374 100644 --- a/vue-element-admin-4.0.0/src/main.js +++ b/vue-element-admin-4.0.0/src/main.js @@ -9,6 +9,9 @@ import './styles/element-variables.scss' import '@/styles/index.scss' // global css +import '@/styles/common.css' +import '@/styles/color.css' + import App from './App' import store from './store' import router from './router' diff --git a/vue-element-admin-4.0.0/src/router/index.js b/vue-element-admin-4.0.0/src/router/index.js index a883d39..fe454bf 100644 --- a/vue-element-admin-4.0.0/src/router/index.js +++ b/vue-element-admin-4.0.0/src/router/index.js @@ -7,10 +7,7 @@ Vue.use(Router) import Layout from '@/layout' /* Router Modules */ -import componentsRouter from './modules/components' -import chartsRouter from './modules/charts' -import tableRouter from './modules/table' -import nestedRouter from './modules/nested' +import settingRouter from './modules/setting' /** note: sub-menu only appear when children.length>=1 * detail see https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html @@ -82,31 +79,6 @@ export const constantRoutes = [ meta: { title: 'dashboard', icon: 'dashboard', noCache: true, affix: true } } ] - }, - { - path: '/documentation', - component: Layout, - children: [ - { - path: 'index', - component: () => import('@/views/documentation/index'), - name: 'Documentation', - meta: { title: 'documentation', icon: 'documentation', affix: true } - } - ] - }, - { - path: '/guide', - component: Layout, - redirect: '/guide/index', - children: [ - { - path: 'index', - component: () => import('@/views/guide/index'), - name: 'Guide', - meta: { title: 'guide', icon: 'guide', noCache: true } - } - ] } ] @@ -156,232 +128,8 @@ export const asyncRoutes = [ ] }, - { - path: '/icon', - component: Layout, - children: [ - { - path: 'index', - component: () => import('@/views/svg-icons/index'), - name: 'Icons', - meta: { title: 'icons', icon: 'icon', noCache: true } - } - ] - }, - /** when your routing map is too long, you can split it into small modules **/ - componentsRouter, - chartsRouter, - nestedRouter, - tableRouter, - - { - path: '/example', - component: Layout, - redirect: '/example/list', - name: 'Example', - meta: { - title: 'example', - icon: 'example' - }, - children: [ - { - path: 'create', - component: () => import('@/views/example/create'), - name: 'CreateArticle', - meta: { title: 'createArticle', icon: 'edit' } - }, - { - path: 'edit/:id(\\d+)', - component: () => import('@/views/example/edit'), - name: 'EditArticle', - meta: { title: 'editArticle', noCache: true }, - hidden: true - }, - { - path: 'list', - component: () => import('@/views/example/list'), - name: 'ArticleList', - meta: { title: 'articleList', icon: 'list' } - } - ] - }, - - { - path: '/tab', - component: Layout, - children: [ - { - path: 'index', - component: () => import('@/views/tab/index'), - name: 'Tab', - meta: { title: 'tab', icon: 'tab' } - } - ] - }, - - { - path: '/error', - component: Layout, - redirect: 'noredirect', - name: 'ErrorPages', - meta: { - title: 'errorPages', - icon: '404' - }, - children: [ - { - path: '401', - component: () => import('@/views/errorPage/401'), - name: 'Page401', - meta: { title: 'page401', noCache: true } - }, - { - path: '404', - component: () => import('@/views/errorPage/404'), - name: 'Page404', - meta: { title: 'page404', noCache: true } - } - ] - }, - - { - path: '/error-log', - component: Layout, - redirect: 'noredirect', - children: [ - { - path: 'log', - component: () => import('@/views/errorLog/index'), - name: 'ErrorLog', - meta: { title: 'errorLog', icon: 'bug' } - } - ] - }, - - { - path: '/excel', - component: Layout, - redirect: '/excel/export-excel', - name: 'Excel', - meta: { - title: 'excel', - icon: 'excel' - }, - children: [ - { - path: 'export-excel', - component: () => import('@/views/excel/exportExcel'), - name: 'ExportExcel', - meta: { title: 'exportExcel' } - }, - { - path: 'export-selected-excel', - component: () => import('@/views/excel/selectExcel'), - name: 'SelectExcel', - meta: { title: 'selectExcel' } - }, - { - path: 'export-merge-header', - component: () => import('@/views/excel/mergeHeader'), - name: 'MergeHeader', - meta: { title: 'mergeHeader' } - }, - { - path: 'upload-excel', - component: () => import('@/views/excel/uploadExcel'), - name: 'UploadExcel', - meta: { title: 'uploadExcel' } - } - ] - }, - - { - path: '/zip', - component: Layout, - redirect: '/zip/download', - alwaysShow: true, - meta: { title: 'zip', icon: 'zip' }, - children: [ - { - path: 'download', - component: () => import('@/views/zip/index'), - name: 'ExportZip', - meta: { title: 'exportZip' } - } - ] - }, - - { - path: '/pdf', - component: Layout, - redirect: '/pdf/index', - children: [ - { - path: 'index', - component: () => import('@/views/pdf/index'), - name: 'PDF', - meta: { title: 'pdf', icon: 'pdf' } - } - ] - }, - { - path: '/pdf/download', - component: () => import('@/views/pdf/download'), - hidden: true - }, - - { - path: '/theme', - component: Layout, - redirect: 'noredirect', - children: [ - { - path: 'index', - component: () => import('@/views/theme/index'), - name: 'Theme', - meta: { title: 'theme', icon: 'theme' } - } - ] - }, - - { - path: '/clipboard', - component: Layout, - redirect: 'noredirect', - children: [ - { - path: 'index', - component: () => import('@/views/clipboard/index'), - name: 'ClipboardDemo', - meta: { title: 'clipboardDemo', icon: 'clipboard' } - } - ] - }, - - { - path: '/i18n', - component: Layout, - children: [ - { - path: 'index', - component: () => import('@/views/i18n-demo/index'), - name: 'I18n', - meta: { title: 'i18n', icon: 'international' } - } - ] - }, - - { - path: 'external-link', - component: Layout, - children: [ - { - path: 'https://github.com/PanJiaChen/vue-element-admin', - meta: { title: 'externalLink', icon: 'link' } - } - ] - }, + settingRouter, { path: '*', redirect: '/404', hidden: true } ] diff --git a/vue-element-admin-4.0.0/src/router/modules/charts.js b/vue-element-admin-4.0.0/src/router/modules/charts.js deleted file mode 100644 index 7293490..0000000 --- a/vue-element-admin-4.0.0/src/router/modules/charts.js +++ /dev/null @@ -1,36 +0,0 @@ -/** When your routing table is too long, you can split it into small modules**/ - -import Layout from '@/layout' - -const chartsRouter = { - path: '/charts', - component: Layout, - redirect: 'noredirect', - name: 'Charts', - meta: { - title: 'charts', - icon: 'chart' - }, - children: [ - { - path: 'keyboard', - component: () => import('@/views/charts/keyboard'), - name: 'KeyboardChart', - meta: { title: 'keyboardChart', noCache: true } - }, - { - path: 'line', - component: () => import('@/views/charts/line'), - name: 'LineChart', - meta: { title: 'lineChart', noCache: true } - }, - { - path: 'mixchart', - component: () => import('@/views/charts/mixChart'), - name: 'MixChart', - meta: { title: 'mixChart', noCache: true } - } - ] -} - -export default chartsRouter diff --git a/vue-element-admin-4.0.0/src/router/modules/components.js b/vue-element-admin-4.0.0/src/router/modules/components.js deleted file mode 100644 index 889c371..0000000 --- a/vue-element-admin-4.0.0/src/router/modules/components.js +++ /dev/null @@ -1,102 +0,0 @@ -/** When your routing table is too long, you can split it into small modules**/ - -import Layout from '@/layout' - -const componentsRouter = { - path: '/components', - component: Layout, - redirect: 'noredirect', - name: 'ComponentDemo', - meta: { - title: 'components', - icon: 'component' - }, - children: [ - { - path: 'tinymce', - component: () => import('@/views/components-demo/tinymce'), - name: 'TinymceDemo', - meta: { title: 'tinymce' } - }, - { - path: 'markdown', - component: () => import('@/views/components-demo/markdown'), - name: 'MarkdownDemo', - meta: { title: 'markdown' } - }, - { - path: 'json-editor', - component: () => import('@/views/components-demo/jsonEditor'), - name: 'JsonEditorDemo', - meta: { title: 'jsonEditor' } - }, - { - path: 'splitpane', - component: () => import('@/views/components-demo/splitpane'), - name: 'SplitpaneDemo', - meta: { title: 'splitPane' } - }, - { - path: 'avatar-upload', - component: () => import('@/views/components-demo/avatarUpload'), - name: 'AvatarUploadDemo', - meta: { title: 'avatarUpload' } - }, - { - path: 'dropzone', - component: () => import('@/views/components-demo/dropzone'), - name: 'DropzoneDemo', - meta: { title: 'dropzone' } - }, - { - path: 'sticky', - component: () => import('@/views/components-demo/sticky'), - name: 'StickyDemo', - meta: { title: 'sticky' } - }, - { - path: 'count-to', - component: () => import('@/views/components-demo/countTo'), - name: 'CountToDemo', - meta: { title: 'countTo' } - }, - { - path: 'mixin', - component: () => import('@/views/components-demo/mixin'), - name: 'ComponentMixinDemo', - meta: { title: 'componentMixin' } - }, - { - path: 'back-to-top', - component: () => import('@/views/components-demo/backToTop'), - name: 'BackToTopDemo', - meta: { title: 'backToTop' } - }, - { - path: 'drag-dialog', - component: () => import('@/views/components-demo/dragDialog'), - name: 'DragDialogDemo', - meta: { title: 'dragDialog' } - }, - { - path: 'drag-select', - component: () => import('@/views/components-demo/dragSelect'), - name: 'DragSelectDemo', - meta: { title: 'dragSelect' } - }, - { - path: 'dnd-list', - component: () => import('@/views/components-demo/dndList'), - name: 'DndListDemo', - meta: { title: 'dndList' } - }, - { - path: 'drag-kanban', - component: () => import('@/views/components-demo/dragKanban'), - name: 'DragKanbanDemo', - meta: { title: 'dragKanban' } - } - ] -} - -export default componentsRouter diff --git a/vue-element-admin-4.0.0/src/router/modules/nested.js b/vue-element-admin-4.0.0/src/router/modules/nested.js deleted file mode 100644 index ee165c8..0000000 --- a/vue-element-admin-4.0.0/src/router/modules/nested.js +++ /dev/null @@ -1,66 +0,0 @@ -/** When your routing table is too long, you can split it into small modules**/ - -import Layout from '@/layout' - -const nestedRouter = { - path: '/nested', - component: Layout, - redirect: '/nested/menu1/menu1-1', - name: 'Nested', - meta: { - title: 'nested', - icon: 'nested' - }, - children: [ - { - path: 'menu1', - component: () => import('@/views/nested/menu1/index'), // Parent router-view - name: 'Menu1', - meta: { title: 'menu1' }, - redirect: '/nested/menu1/menu1-1', - children: [ - { - path: 'menu1-1', - component: () => import('@/views/nested/menu1/menu1-1'), - name: 'Menu1-1', - meta: { title: 'menu1-1' } - }, - { - path: 'menu1-2', - component: () => import('@/views/nested/menu1/menu1-2'), - name: 'Menu1-2', - redirect: '/nested/menu1/menu1-2/menu1-2-1', - meta: { title: 'menu1-2' }, - children: [ - { - path: 'menu1-2-1', - component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), - name: 'Menu1-2-1', - meta: { title: 'menu1-2-1' } - }, - { - path: 'menu1-2-2', - component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), - name: 'Menu1-2-2', - meta: { title: 'menu1-2-2' } - } - ] - }, - { - path: 'menu1-3', - component: () => import('@/views/nested/menu1/menu1-3'), - name: 'Menu1-3', - meta: { title: 'menu1-3' } - } - ] - }, - { - path: 'menu2', - name: 'Menu2', - component: () => import('@/views/nested/menu2/index'), - meta: { title: 'menu2' } - } - ] -} - -export default nestedRouter diff --git a/vue-element-admin-4.0.0/src/router/modules/setting.js b/vue-element-admin-4.0.0/src/router/modules/setting.js new file mode 100644 index 0000000..bc52c32 --- /dev/null +++ b/vue-element-admin-4.0.0/src/router/modules/setting.js @@ -0,0 +1,29 @@ +/** When your routing table is too long, you can split it into small modules**/ + +import Layout from '@/layout' + +const settingRouter = { + path: '/setting', + component: Layout, + redirect: '/table/complex-table', + name: 'setting', + meta: { + title: '设置', + icon: 'setting' + }, + children: [ + { + path: 'set-ksc', + component: () => import('@/views/setting/kSchudle'), + name: 'setKsc', + meta: { title: 'K类定时任务' } + }, + { + path: 'set-conf', + component: () => import('@/views/table/dragTable'), + name: 'setConf', + meta: { title: '动态配置' } + } + ] +} +export default settingRouter diff --git a/vue-element-admin-4.0.0/src/router/modules/table.js b/vue-element-admin-4.0.0/src/router/modules/table.js deleted file mode 100644 index b54fb42..0000000 --- a/vue-element-admin-4.0.0/src/router/modules/table.js +++ /dev/null @@ -1,41 +0,0 @@ -/** When your routing table is too long, you can split it into small modules**/ - -import Layout from '@/layout' - -const tableRouter = { - path: '/table', - component: Layout, - redirect: '/table/complex-table', - name: 'Table', - meta: { - title: 'Table', - icon: 'table' - }, - children: [ - { - path: 'dynamic-table', - component: () => import('@/views/table/dynamicTable/index'), - name: 'DynamicTable', - meta: { title: 'dynamicTable' } - }, - { - path: 'drag-table', - component: () => import('@/views/table/dragTable'), - name: 'DragTable', - meta: { title: 'dragTable' } - }, - { - path: 'inline-edit-table', - component: () => import('@/views/table/inlineEditTable'), - name: 'InlineEditTable', - meta: { title: 'inlineEditTable' } - }, - { - path: 'complex-table', - component: () => import('@/views/table/complexTable'), - name: 'ComplexTable', - meta: { title: 'complexTable' } - } - ] -} -export default tableRouter diff --git a/vue-element-admin-4.0.0/src/styles/color.css b/vue-element-admin-4.0.0/src/styles/color.css new file mode 100644 index 0000000..e7ad58f --- /dev/null +++ b/vue-element-admin-4.0.0/src/styles/color.css @@ -0,0 +1,68 @@ +/* 文字颜色 */ +.f-c-000 { + color: #000000; +} +.f-c-666 { + color: #666666; +} + +.f-c-fff { + color: #ffffff; +} + +.f-c-333 { + color: #333333; +} + +.f-c-grey { + color: #9598A2; +} + +.f-c-9d { + color: #9D9D9D; +} + +.f-c-9b { + color: #9b9b9b; +} + +.f-c-a6a { + color: #A6A6A6; +} + +.f-c-d6d { + color: #D6D6D6; +} +.f-c-999 { + color: #999; +} +.f-c-97 { + color: #979797; +} +.f-c-75 { + color: #757575; +} +.f-c-f23 { + color: #FF2323; +} + +/* 背景色 */ +.b-c-fff { + background-color: #ffffff; +} + +.b-c-666 { + background-color: #666; +} + +.b-c-f1f { + background-color: #f1f1f1; +} + +.b-c-dcd { + background-color: #dcdcdc; +} + +.b-c-bdb { + background-color: #BDBDBD; +} diff --git a/vue-element-admin-4.0.0/src/styles/common.css b/vue-element-admin-4.0.0/src/styles/common.css new file mode 100644 index 0000000..3c5da5e --- /dev/null +++ b/vue-element-admin-4.0.0/src/styles/common.css @@ -0,0 +1,412 @@ +@media only screen and (max-width: 3840px), +only screen and (max-device-width:3840px) { + + html, + body { + font-size: 48px; + } +} + +@media only screen and (max-width: 2560px), +only screen and (max-device-width:2560px) { + + html, + body { + font-size: 32px; + } +} + +@media only screen and (max-width: 2048px), +only screen and (max-device-width:2048px) { + + html, + body { + font-size: 25.6px; + } +} + +@media only screen and (max-width: 1920px), +only screen and (max-device-width:1920px) { + + html, + body { + font-size: 24px; + } +} + +@media only screen and (max-width: 1768px), +only screen and (max-device-width:1768px) { + + html, + body { + font-size: 22.1px; + } +} + +@media only screen and (max-width: 1680px), +only screen and (max-device-width:1680px) { + + html, + body { + font-size: 21px; + } +} + +@media only screen and (max-width: 1600px), +only screen and (max-device-width:1600px) { + + html, + body { + font-size: 20px; + } +} + +@media only screen and (max-width: 1440px), +only screen and (max-device-width:1440px) { + + html, + body { + font-size: 18px; + } +} + +@media only screen and (max-width: 1366px), +only screen and (max-device-width:1366px) { + + html, + body { + font-size: 17.75px; + } +} + +@media only screen and (max-width: 1280px), +only screen and (max-device-width:1280px) { + + html, + body { + font-size: 16px; + } +} + +@media only screen and (max-width: 1200px), +only screen and (max-device-width:1200px) { + + html, + body { + font-size: 23.04px; + } +} + +@media only screen and (max-width: 1024px), +only screen and (max-device-width:1024px) { + + html, + body { + font-size: 19.6608px; + } +} + +/* @media only screen and (max-width: 800px), +only screen and (max-device-width:800px) { + + html, + body { + font-size: 10px; + } +} + + +@media only screen and (max-width: 720px), +only screen and (max-device-width:720px) { + + html, + body { + font-size: 9px; + } +} */ +/* +@media only screen and (max-width: 640px), +only screen and (max-device-width:640px) { + + html, + body { + font-size: 8px; + } +} + +@media only screen and (max-width: 600px), +only screen and (max-device-width:600px) { + + html, + body { + font-size: 7.5px; + } +} + +@media only screen and (max-width: 540px), +only screen and (max-device-width:540px) { + + html, + body { + font-size: 6.75px; + } +} + +@media only screen and (max-width: 480px), +only screen and (max-device-width:480px) { + + html, + body { + font-size: 6px; + } +} */ + +/*布局*/ +* { + /* font-family: 'Microsoft YaHei'; */ + box-sizing: border-box; + padding: 0; + margin: 0; +} + +.marginAuto { + margin: 0 auto !important; +} + +.i-xy-center, +.i-yx-center { + display: inline-flex; + align-items: center; + justify-content: center; +} + +.i-yx-center { + flex-direction: column; +} + +.xy-center, +.yx-center { + display: flex; + align-items: center; + justify-content: center; +} + +.yx-center { + flex-direction: column; +} + +.i-xy-between, +.i-yx-between { + display: inline-flex; + align-items: center; + justify-content: space-between; +} + +.i-yx-between { + flex-direction: column; +} + +.xy-between, +.yx-between { + display: flex; + align-items: center; + justify-content: space-between; +} + +.flexWarp { + flex-wrap: wrap; +} + +.yx-between { + flex-direction: column; +} + +.jf-start { + justify-content: flex-start; +} + +.jf-end { + justify-content: flex-end; +} + +.al-start { + align-items: flex-start; +} + +.al-end { + align-items: flex-end; +} + +.al-str { + align-items: stretch; +} + +.auto-grow { + flex-grow: 1; +} + +.full-width { + width: 100%; +} + +.full-height { + height: 100%; +} + +.hidden { + display: none; +} + +.no-wrap-text { + white-space: nowrap; +} + +.one-wrap { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.two-wrap { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} +.three-wrap { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; +} + +.third-wrap { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; +} + +.text-center { + text-align: center; +} + +.pointer { + cursor: pointer; +} +.wait { + cursor: wait; +} +.no-mouse { + cursor: not-allowed; +} +/*其他*/ + +.border-radius-box { + border-radius: 0.5rem; +} + +.bold { + font-weight: bold; +} + +.left-title { + margin-right: 0.33rem; +} + +.member-header { + border-radius: 50%; + overflow: hidden; +} + + +.fontSize5 { + font-size: 0.5rem; +} + +.fontSize53 { + font-size: 0.53rem; +} + +.fontSize58 { + font-size: 0.58rem; +} + +.fontSize67 { + font-size: 0.67rem; +} + +.fontSize75 { + font-size: 0.75rem; +} + +.fontSize76 { + font-size: 0.76rem; +} + +.fontSize92 { + font-size: 0.92rem; +} + +.p { + line-height: 0.75rem; +} + +.textCenter { + text-align: center; +} + +.textJustify { + text-align: justify; +} + +.FW600 { + font-weight: 600; +} +.FW300 { + font-weight: 300; +} +.Color333 { + color: #333; +} + +.Color666 { + color: #666; +} + +.bgColor666 { + background: #666; +} + +.flex { + display: flex; + flex-wrap: wrap; +} + +.between { + display: flex; + justify-content: space-between; +} + +.FW600 { + font-weight: 600; +} + +.color9d { + color: #9D9D9D; +} + +.padding-1rem { + padding: 1rem; +} + +.positionAbsolute { + position: absolute +} + +.positionRelative { + position: relative +} \ No newline at end of file diff --git a/vue-element-admin-4.0.0/src/views/setting/kSchudle.vue b/vue-element-admin-4.0.0/src/views/setting/kSchudle.vue new file mode 100644 index 0000000..5875e1b --- /dev/null +++ b/vue-element-admin-4.0.0/src/views/setting/kSchudle.vue @@ -0,0 +1,19 @@ + + + + +