diff --git a/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java b/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java new file mode 100644 index 00000000..49e6eea2 --- /dev/null +++ b/opsli-api/src/main/java/org/opsli/api/web/system/options/OptionsApi.java @@ -0,0 +1,152 @@ +/** + * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com + *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + *
+ * http://www.apache.org/licenses/LICENSE-2.0 + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.opsli.api.web.system.options;
+
+
+import org.opsli.api.base.result.ResultVo;
+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.RequestParam;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+import org.opsli.api.wrapper.system.options.OptionsModel;
+
+
+
+/**
+ * @BelongsProject: opsli-boot
+
+ * @BelongsPackage: org.opsli.api.web.sys.options
+
+ * @Author: Parker
+ * @CreateTime: 2021-02-07 18:24:38
+ * @Description: 系统参数
+ *
+ * 对外 API 直接 暴露 @GetMapping 或者 @PostMapping
+ * 对内也推荐 单机版 不需要设置 Mapping 但是调用方法得从Controller写起
+ *
+ * 这样写法虽然比较绕,但是当单体项目想要改造微服务架构时 时非常容易的
+ *
+ *
+ */
+public interface OptionsApi {
+
+ /** 标题 */
+ String TITLE = "系统参数";
+
+ /**
+ * 系统参数 查一条
+ * @param model 模型
+ * @return ResultVo
+ */
+ @GetMapping("/get")
+ ResultVo
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.opsli.api.wrapper.system.options;
+
+
+import java.util.Date;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.opsli.api.base.warpper.ApiWrapper;
+import org.opsli.common.annotation.validation.ValidationArgs;
+import org.opsli.common.annotation.validation.ValidationArgsLenMax;
+import org.opsli.common.enums.ValiArgsType;
+import org.opsli.plugins.excel.annotation.ExcelInfo;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * @BelongsProject: opsli-boot
+
+ * @BelongsPackage: org.opsli.api.wrapper.sys.options
+
+ * @Author: Parker
+ * @CreateTime: 2021-02-07 18:24:38
+ * @Description: 系统参数
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OptionsModel extends ApiWrapper {
+
+
+
+ /** 参数编号 */
+ @ApiModelProperty(value = "参数编号")
+ @ExcelProperty(value = "参数编号", order = 1)
+ @ExcelInfo
+ @ValidationArgs({ValiArgsType.IS_NOT_NULL, ValiArgsType.IS_GENERAL})
+ @ValidationArgsLenMax(100)
+ @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private String optionCode;
+
+
+
+ /** 参数名称 */
+ @ApiModelProperty(value = "参数名称")
+ @ExcelProperty(value = "参数名称", order = 2)
+ @ExcelInfo
+ @ValidationArgs({ValiArgsType.IS_NOT_NULL, ValiArgsType.IS_GENERAL_WITH_CHINESE})
+ @ValidationArgsLenMax(200)
+ @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private String optionName;
+
+
+
+ /** 参数值 */
+ @ApiModelProperty(value = "参数值")
+ @ExcelProperty(value = "参数值", order = 3)
+ @ExcelInfo
+ @ValidationArgsLenMax(500)
+ @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private String optionValue;
+
+
+
+}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OptionHandler.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OptionHandler.java
new file mode 100644
index 00000000..94c6f65c
--- /dev/null
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/handler/OptionHandler.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.opsli.core.cache.pushsub.handler;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.opsli.common.constants.CacheConstants;
+import org.opsli.core.cache.local.CacheUtil;
+import org.opsli.core.cache.pushsub.enums.MsgArgsType;
+import org.opsli.core.cache.pushsub.enums.PushSubType;
+import org.opsli.core.utils.OptionsUtil;
+import org.opsli.plugins.cache.EhCachePlugin;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @BelongsProject: opsli-boot
+ * @BelongsPackage: org.opsli.core.cache.pushsub.handler
+ * @Author: Parker
+ * @CreateTime: 2020-09-15 16:24
+ * @Description: 系统参数消息处理
+ */
+@Slf4j
+public class OptionHandler implements RedisPushSubHandler{
+
+ @Autowired
+ private EhCachePlugin ehCachePlugin;
+
+ @Override
+ public PushSubType getType() {
+ return PushSubType.OPTION;
+ }
+
+ @Override
+ public void handler(JSONObject msgJson) {
+ // 系统参数刷新
+ this.optionHandler(msgJson);
+ }
+
+ /**
+ * 用户数据处理
+ * @param msgJson
+ */
+ private void optionHandler(JSONObject msgJson){
+ JSONObject data = msgJson.getJSONObject(MsgArgsType.OPTION_MODEL_DATA.toString());
+ // 数据为空则不执行
+ if(data == null){
+ return;
+ }
+
+ // 获得参数编号
+ String optionCode = (String) msgJson.get(MsgArgsType.OPTION_CODE.toString());
+ if(StringUtils.isEmpty(optionCode)){
+ return;
+ }
+
+ String cacheKey = CacheUtil.handleKey(OptionsUtil.PREFIX_CODE + optionCode);
+
+ // 先删除
+ ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey);
+ }
+
+
+}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OptionMsgFactory.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OptionMsgFactory.java
new file mode 100644
index 00000000..cb86c6c6
--- /dev/null
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/pushsub/msgs/OptionMsgFactory.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.opsli.core.cache.pushsub.msgs;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.opsli.api.wrapper.system.menu.MenuModel;
+import org.opsli.api.wrapper.system.options.OptionsModel;
+import org.opsli.core.cache.pushsub.enums.MsgArgsType;
+import org.opsli.core.cache.pushsub.enums.PushSubType;
+import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver;
+import org.opsli.plugins.redis.pushsub.entity.BaseSubMessage;
+
+/**
+ * @BelongsProject: opsli-boot
+ * @BelongsPackage: org.opsli.core.cache.pushsub.msgs
+ * @Author: Parker
+ * @CreateTime: 2020-09-15 16:50
+ * @Description: 参数消息
+ */
+
+@Data
+@Accessors(chain = true)
+public final class OptionMsgFactory extends BaseSubMessage{
+
+ /** 通道 */
+ private static final String CHANNEL = RedisPushSubReceiver.BASE_CHANNEL+RedisPushSubReceiver.CHANNEL;
+
+ private OptionMsgFactory(){}
+
+ /**
+ * 构建消息 - 参数
+ */
+ public static BaseSubMessage createOptionMsg(OptionsModel optionsModel){
+ BaseSubMessage baseSubMessage = new BaseSubMessage();
+ // 数据
+ JSONObject jsonObj = new JSONObject();
+ jsonObj.put(MsgArgsType.OPTION_CODE.toString(), optionsModel.getOptionCode());
+ jsonObj.put(MsgArgsType.OPTION_MODEL_DATA.toString(), optionsModel);
+
+ // 参数
+ baseSubMessage.build(CHANNEL,PushSubType.OPTION.toString(),jsonObj);
+ return baseSubMessage;
+ }
+
+
+}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java
new file mode 100644
index 00000000..8c1e7030
--- /dev/null
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/OptionsUtil.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.opsli.core.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.opsli.api.base.result.ResultVo;
+import org.opsli.api.web.system.menu.MenuApi;
+import org.opsli.api.web.system.options.OptionsApi;
+import org.opsli.api.wrapper.system.menu.MenuModel;
+import org.opsli.api.wrapper.system.options.OptionsModel;
+import org.opsli.core.cache.local.CacheUtil;
+import org.opsli.core.cache.pushsub.msgs.MenuMsgFactory;
+import org.opsli.core.cache.pushsub.msgs.OptionMsgFactory;
+import org.opsli.core.msg.CoreMsg;
+import org.opsli.plugins.redis.RedisPlugin;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
+
+/**
+ * @BelongsProject: opsli-boot
+ * @BelongsPackage: org.opsli.core.utils
+ * @Author: Parker
+ * @CreateTime: 2020-09-19 20:03
+ * @Description: 参数工具类
+ */
+@Slf4j
+@Order(UTIL_ORDER)
+@Component
+@Lazy(false)
+public class OptionsUtil {
+
+ /** 前缀 */
+ public static final String PREFIX_CODE = "options:code:";
+
+
+ /** Redis插件 */
+ private static RedisPlugin redisPlugin;
+
+ /** 参数 Api */
+ private static OptionsApi optionsApi;
+
+
+ /**
+ * 根据 optionCode 获得参数
+ * @param optionCode
+ * @return
+ */
+ public static OptionsModel getOptionByCode(String optionCode){
+ // 缓存Key
+ String cacheKey = PREFIX_CODE + optionCode;
+
+ // 先从缓存里拿
+ OptionsModel model = CacheUtil.getTimed(OptionsModel.class, cacheKey);
+ if (model != null){
+ return model;
+ }
+
+ // 拿不到 --------
+ // 防止缓存穿透判断
+ boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
+ if(hasNilFlag){
+ return null;
+ }
+
+ try {
+ // 分布式加锁
+ if(!DistributedLockUtil.lock(cacheKey)){
+ // 无法申领分布式锁
+ log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
+ return null;
+ }
+
+ // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
+ model = CacheUtil.getTimed(OptionsModel.class, cacheKey);
+ if (model != null){
+ return model;
+ }
+
+ // 查询数据库
+ ResultVo
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.opsli.modulars.system.options.entity;
+
+
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.opsli.core.base.entity.BaseEntity;
+
+/**
+ * @BelongsProject: opsli-boot
+ * @BelongsPackage: org.opsli.modulars.sys.options.entity
+ * @Author: Parker
+ * @CreateTime: 2021-02-07 18:24:38
+ * @Description: 系统参数
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class SysOptions extends BaseEntity {
+
+ /** 参数编号 */
+ private String optionCode;
+
+ /** 参数名称 */
+ private String optionName;
+
+ /** 参数值 */
+ private String optionValue;
+
+ // ========================================
+
+
+}
diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/mapper/SysOptionsMapper.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/mapper/SysOptionsMapper.java
new file mode 100644
index 00000000..f81a3244
--- /dev/null
+++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/options/mapper/SysOptionsMapper.java
@@ -0,0 +1,39 @@
+/**
+* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
+*
+* Licensed under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License. You may obtain a copy of
+* the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations under
+* the License.
+*/
+
+package org.opsli.modulars.system.options.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import org.opsli.modulars.system.options.entity.SysOptions;
+
+
+/**
+* @BelongsProject: opsli-boot
+
+* @BelongsPackage: org.opsli.modulars.sys.options.mapper
+
+* @Author: Parker
+* @CreateTime: 2021-02-07 18:24:38
+* @Description: 系统参数 Mapper
+*/
+@Mapper
+public interface SysOptionsMapper extends BaseMapper
+* Licensed under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License. You may obtain a copy of
+* the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations under
+* the License.
+*/
+
+package org.opsli.modulars.system.options.service;
+
+
+import org.opsli.core.base.service.interfaces.CrudServiceInterface;
+
+
+
+import org.opsli.modulars.system.options.entity.SysOptions;
+import org.opsli.api.wrapper.system.options.OptionsModel;
+
+
+/**
+* @BelongsProject: opsli-boot
+
+* @BelongsPackage: org.opsli.modulars.sys.options.service
+
+* @Author: Parker
+* @CreateTime: 2021-02-07 18:24:38
+* @Description: 系统参数 Service
+*/
+public interface ISysOptionsService extends CrudServiceInterface
+* Licensed under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License. You may obtain a copy of
+* the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations under
+* the License.
+*/
+
+package org.opsli.modulars.system.options.service.impl;
+
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.apache.commons.lang3.StringUtils;
+import org.opsli.api.wrapper.system.options.OptionsModel;
+import org.opsli.common.constants.MyBatisConstants;
+import org.opsli.common.exception.ServiceException;
+import org.opsli.core.base.service.impl.CrudServiceImpl;
+import org.opsli.core.msg.CoreMsg;
+import org.opsli.core.utils.OptionsUtil;
+import org.opsli.modulars.system.SystemMsg;
+import org.opsli.modulars.system.options.entity.SysOptions;
+import org.opsli.modulars.system.options.mapper.SysOptionsMapper;
+import org.opsli.modulars.system.options.service.ISysOptionsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+* @BelongsProject: opsli-boot
+
+* @BelongsPackage: org.opsli.modulars.sys.options.service.impl
+
+* @Author: Parker
+* @CreateTime: 2021-02-07 18:24:38
+* @Description: 系统参数 Service Impl
+*/
+@Service
+public class SysOptionsServiceImpl extends CrudServiceImpl
+* Licensed under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License. You may obtain a copy of
+* the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations under
+* the License.
+*/
+
+package org.opsli.modulars.system.options.web;
+
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ReflectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.opsli.api.base.result.ResultVo;
+import org.opsli.api.web.system.options.OptionsApi;
+import org.opsli.api.wrapper.system.options.OptionsModel;
+import org.opsli.common.annotation.ApiRestController;
+import org.opsli.common.annotation.EnableLog;
+import org.opsli.common.annotation.RequiresPermissionsCus;
+import org.opsli.common.utils.WrapperUtil;
+import org.opsli.core.base.controller.BaseRestController;
+import org.opsli.core.persistence.Page;
+import org.opsli.core.persistence.querybuilder.QueryBuilder;
+import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
+import org.opsli.modulars.system.options.entity.SysOptions;
+import org.opsli.modulars.system.options.service.ISysOptionsService;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+
+
+/**
+* @BelongsProject: opsli-boot
+* @BelongsPackage: org.opsli.modulars.sys.options.web
+* @CreateTime: 2021-02-07 18:24:38
+* @Description: 系统参数 Controller
+*
+* @author Parker
+*/
+@Api(tags = "系统参数")
+@Slf4j
+@ApiRestController("/sys/options")
+public class SysOptionsRestController extends BaseRestController