Merge branch 'dev' of gitee.com:xiejs666/RuoYi-Cloud into master

pull/254/head
xiejs 4 years ago committed by Gitee
commit 9a6d2d089e

@ -12,6 +12,7 @@
## 平台简介
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
(xjs专用版)
* 采用前后端分离的模式,微服务版本前端(基于 [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue))。
* 后端采用Spring Boot、Spring Cloud & Alibaba。

@ -1,12 +0,0 @@
@echo off
echo.
echo [信息] 清理工程target生成路径。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause

@ -1,12 +0,0 @@
@echo off
echo.
echo [信息] 打包Web工程生成war/jar包文件。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause

@ -1,14 +0,0 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Auth工程。
echo.
cd %~dp0
cd ../ruoyi-auth/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-auth.jar
cd bin
pause

@ -1,14 +0,0 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Gateway工程。
echo.
cd %~dp0
cd ../ruoyi-gateway/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-gateway.jar
cd bin
pause

@ -1,14 +0,0 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-File工程。
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-file/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-file.jar
cd bin
pause

@ -1,14 +0,0 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-Gen工程。
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-gen/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-gen.jar
cd bin
pause

@ -1,14 +0,0 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-Job工程。
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-job/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-job.jar
cd bin
pause

@ -1,14 +0,0 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-System工程。
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-system/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-system.jar
cd bin
pause

@ -1,14 +0,0 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Monitor工程。
echo.
cd %~dp0
cd ../ruoyi-visual/ruoyi-monitor/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-visual-monitor.jar
cd bin
pause

@ -17,7 +17,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.5.8</spring-boot.version>
<spring-boot.version>2.5.6</spring-boot.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
<alibaba.nacos.version>2.0.3</alibaba.nacos.version>
@ -40,7 +40,13 @@
<common-pool.version>2.10.0</common-pool.version>
<commons-collections.version>3.2.2</commons-collections.version>
<transmittable-thread-local.version>2.12.2</transmittable-thread-local.version>
<log4j2.version>2.17.1</log4j2.version>
<log4j2.version>2.17.0</log4j2.version>
<!--xjs加的-->
<knife4j.version>3.0.3</knife4j.version>
<hutool.version>5.7.17</hutool.version>
<mybatisplus.version>3.4.3.4</mybatisplus.version>
</properties>
<!-- 依赖声明 -->
@ -197,7 +203,7 @@
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
@ -270,6 +276,7 @@
<module>ruoyi-modules</module>
<module>ruoyi-api</module>
<module>ruoyi-common</module>
<module>xjs-business</module>
</modules>
<packaging>pom</packaging>

@ -0,0 +1,28 @@
package com.xjs.business.api;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.api.domain.CopyWriting;
import com.xjs.business.api.factory.RemoteCopyWritingFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author xiejs
* @desc RPC
* @create 2021-12-27
*/
@FeignClient(contextId = "remoteCopyWritingFeign",
value = ServiceNameConstants.BUSINESS_OPENAPI_SERVICE,
fallbackFactory = RemoteCopyWritingFactory.class)
@FunctionalInterface
public interface RemoteCopyWritingFeign {
/**
*
*
* @return
*/
@GetMapping(value = "/copyWriting/forPRC")
R<CopyWriting> copyWriting();
}

@ -0,0 +1,24 @@
package com.xjs.business.api;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.api.domain.TranslationVo;
import com.xjs.business.api.factory.RemoteTranDictFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author xiejs
* @desc rpc
* @create 2021-12-30
*/
@FeignClient(contextId = "remoteTranDictFeign",
value = ServiceNameConstants.BUSINESS_OPENAPI_SERVICE,
fallbackFactory = RemoteTranDictFactory.class)
public interface RemoteTranDIctFeign {
@GetMapping(value = "/tranDict/tranDictForRPC")
R<TranslationVo> tranDict(@RequestParam("content") String content);
}

@ -0,0 +1,25 @@
package com.xjs.business.api;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.api.domain.TranslationVo;
import com.xjs.business.api.factory.RemoteTranslationFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author xiejs
* @desc rpc
* @create 2021-12-29
*/
@FeignClient(contextId = "remoteTranslationFeign",
value = ServiceNameConstants.BUSINESS_OPENAPI_SERVICE,
fallbackFactory = RemoteTranslationFactory.class)
public interface RemoteTranslationFeign {
@GetMapping(value = "/translation/forRPC")
//get请求传递单个参数需要此注解
R<TranslationVo> translation(@RequestParam("content") String content);
}

@ -0,0 +1,65 @@
package com.xjs.business.api.domain;
import java.io.Serializable;
/**
* @author xiejs
* @desc
* @create 2021-12-27
*/
public class CopyWriting implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
/** 文案内容 */
private String content;
/** 文案来源 */
private String source;
private String createTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "CopyWriting{" +
"id=" + id +
", content='" + content + '\'' +
", source='" + source + '\'' +
", createTime='" + createTime + '\'' +
'}';
}
}

@ -0,0 +1,96 @@
package com.xjs.business.api.domain;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* @author xiejs
* @desc VO
* @create 2021-12-25
*/
public class TranslationVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private String from;
/**
*
*/
private String to;
/**
*
*/
private List<Map<String, String>> transResult;
/**
*
*/
private Long errorCode;
/**
*
*/
private Long elapsedTime;
/**
*
*/
private String type;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public List<Map<String, String>> getTransResult() {
return transResult;
}
public void setTransResult(List<Map<String, String>> transResult) {
this.transResult = transResult;
}
public Long getErrorCode() {
return errorCode;
}
public void setErrorCode(Long errorCode) {
this.errorCode = errorCode;
}
public Long getElapsedTime() {
return elapsedTime;
}
public void setElapsedTime(Long elapsedTime) {
this.elapsedTime = elapsedTime;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

@ -0,0 +1,25 @@
package com.xjs.business.api.factory;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.api.RemoteCopyWritingFeign;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* @author xiejs
* @desc rpc
* @create 2021-12-27
*/
@Component
public class RemoteCopyWritingFactory implements FallbackFactory<RemoteCopyWritingFeign> {
private static final Logger log = LoggerFactory.getLogger(RemoteCopyWritingFactory.class);
@Override
public RemoteCopyWritingFeign create(Throwable cause) {
log.error("api模块文案服务调用失败:{}", cause.getMessage());
return () -> R.fail("文案服务调用失败" + cause.getMessage());
}
}

@ -0,0 +1,24 @@
package com.xjs.business.api.factory;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.api.RemoteTranDIctFeign;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* @author xiejs
* @desc
* @create 2021-12-30
*/
@Component
public class RemoteTranDictFactory implements FallbackFactory<RemoteTranDIctFeign> {
private static final Logger log = LoggerFactory.getLogger(RemoteTranDictFactory.class);
@Override
public RemoteTranDIctFeign create(Throwable cause) {
log.error("api模块文案服务调用失败:{}", cause.getMessage());
return content -> R.fail("文案服务调用失败" + cause.getMessage());
}
}

@ -0,0 +1,25 @@
package com.xjs.business.api.factory;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.api.RemoteTranslationFeign;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* @author xiejs
* @desc
* @create 2021-12-29
*/
@Component
public class RemoteTranslationFactory implements FallbackFactory<RemoteTranslationFeign> {
private static final Logger log = LoggerFactory.getLogger(RemoteTranslationFactory.class);
@Override
public RemoteTranslationFeign create(Throwable cause) {
log.error("api模块翻译服务调用失败:{}", cause.getMessage());
return content -> R.fail("翻译服务调用失败" + cause.getMessage());
}
}

@ -0,0 +1,39 @@
package com.xjs.business.warning;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.warning.domain.ApiRecord;
import com.xjs.business.warning.factory.RemoteWarningCRUDFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* @author xiejs
* @desc rpccrud
* @create 2021-12-31
*/
@FeignClient(contextId = "remoteWarningCRUDFeign",
value = ServiceNameConstants.BUSINESS_WARNING_SERVICE,
fallbackFactory = RemoteWarningCRUDFactory.class)
public interface RemoteWarningCRUDFeign {
@PostMapping("apiwarning")
public R<ApiRecord> saveApiRecordForRPC(@RequestBody ApiRecord apiRecord);
@PutMapping("apiwarning")
public R<ApiRecord> updateApiRecordForRPC(@RequestBody ApiRecord apiRecord);
@GetMapping("apiwarning")
R<List<ApiRecord>> selectApiRecordListForRPC(@SpringQueryMap ApiRecord apiRecord) ;
}

@ -0,0 +1,113 @@
package com.xjs.business.warning.domain;
import java.io.Serializable;
import java.util.Date;
/**
* @author xiejs
* @desc api
* @create 2021-12-31
*/
public class ApiRecord implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键id */
private Long id;
/** api名称 */
private String apiName;
/** api地址 */
private String apiUrl;
/** api每天请求次数 */
private Long dayCount;
/**
*
*/
private Integer requestTime;
/** api总请求次数 */
private Long totalCount;
/** api限制请求次数每天 */
private Long limitCount;
private Date createTime;
private Date updateTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getApiName() {
return apiName;
}
public void setApiName(String apiName) {
this.apiName = apiName;
}
public String getApiUrl() {
return apiUrl;
}
public void setApiUrl(String apiUrl) {
this.apiUrl = apiUrl;
}
public Long getTotalCount() {
return totalCount;
}
public void setTotalCount(Long totalCount) {
this.totalCount = totalCount;
}
public Long getLimitCount() {
return limitCount;
}
public void setLimitCount(Long limitCount) {
this.limitCount = limitCount;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Integer getRequestTime() {
return requestTime;
}
public void setRequestTime(Integer requestTime) {
this.requestTime = requestTime;
}
public Long getDayCount() {
return dayCount;
}
public void setDayCount(Long dayCount) {
this.dayCount = dayCount;
}
}

@ -0,0 +1,45 @@
package com.xjs.business.warning.factory;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.warning.RemoteWarningCRUDFeign;
import com.xjs.business.warning.domain.ApiRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author xiejs
* @desc
* @create 2021-12-31
*/
@Component
public class RemoteWarningCRUDFactory implements FallbackFactory<RemoteWarningCRUDFeign> {
private static final Logger log = LoggerFactory.getLogger(RemoteWarningCRUDFactory.class);
@Override
public RemoteWarningCRUDFeign create(Throwable cause) {
return new RemoteWarningCRUDFeign() {
@Override
public R<ApiRecord> saveApiRecordForRPC(ApiRecord apiRecord) {
log.error("调用预警服务添加接口失败,执行降级处理----"+apiRecord.getApiName());
return R.fail();
}
@Override
public R<ApiRecord> updateApiRecordForRPC(ApiRecord apiRecord) {
log.error("调用预警服务修改接口失败,执行降级处理----"+apiRecord.getApiName());
return R.fail();
}
@Override
public R<List<ApiRecord>> selectApiRecordListForRPC(ApiRecord apiRecord) {
log.error("调用预警服务查询接口失败,执行降级处理----"+apiRecord.getApiName());
return R.fail();
}
};
}
}

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-api-system</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-api/ruoyi-api-system/target/classes">
</dir>
</classpath>
</application>

@ -23,3 +23,5 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#命名空间
namespace: xjs-666

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-auth</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-auth/target/classes">
</dir>
</classpath>
</application>

@ -125,6 +125,12 @@
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
</dependencies>
</project>

@ -21,4 +21,18 @@ public class ServiceNameConstants
* serviceid
*/
public static final String FILE_SERVICE = "ruoyi-file";
/**
* apiserviceid
*/
public static final String BUSINESS_OPENAPI_SERVICE= "xjs-openapi" ;
/**
* serviceid
*/
public static final String BUSINESS_WARNING_SERVICE= "xjs-warning" ;
}

@ -1,5 +1,8 @@
package com.ruoyi.common.core.web.page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.List;
@ -8,20 +11,25 @@ import java.util.List;
*
* @author ruoyi
*/
@ApiModel(value = "表格分页数据对象")
public class TableDataInfo implements Serializable
{
private static final long serialVersionUID = 1L;
/** 总记录数 */
@ApiModelProperty("总记录数")
private long total;
/** 列表数据 */
@ApiModelProperty("列表数据")
private List<?> rows;
/** 消息状态码 */
@ApiModelProperty("消息状态码")
private int code;
/** 消息内容 */
@ApiModelProperty("消息内容")
private String msg;
/**

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-common-core</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-common/ruoyi-common-core/target/classes">
</dir>
</classpath>
</application>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-common-datascope</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-common/ruoyi-common-datascope/target/classes">
</dir>
</classpath>
</application>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-common-datasource</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-common/ruoyi-common-datasource/target/classes">
</dir>
</classpath>
</application>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-common-log</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-common/ruoyi-common-log/target/classes">
</dir>
</classpath>
</application>

@ -1,11 +1,5 @@
package com.ruoyi.common.redis.service;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
@ -13,64 +7,62 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* spring redis
*
*
* @author ruoyi
**/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@SuppressWarnings(value = {"unchecked", "rawtypes"})
@Component
public class RedisService
{
public class RedisService {
@Autowired
public RedisTemplate redisTemplate;
/**
* IntegerString
*
* @param key
* @param key
* @param value
*/
public <T> void setCacheObject(final String key, final T value)
{
public <T> void setCacheObject(final String key, final T value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* IntegerString
*
* @param key
* @param value
* @param timeout
* @param key
* @param value
* @param timeout
* @param timeUnit
*/
public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit)
{
public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
*
*
* @param key Redis
* @param key Redis
* @param timeout
* @return true=false=
*/
public boolean expire(final String key, final long timeout)
{
public boolean expire(final String key, final long timeout) {
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
*
*
* @param key Redis
* @param key Redis
* @param timeout
* @param unit
* @param unit
* @return true=false=
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit)
{
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
@ -80,8 +72,7 @@ public class RedisService
* @param key Redis
* @return
*/
public long getExpire(final String key)
{
public long getExpire(final String key) {
return redisTemplate.getExpire(key);
}
@ -91,8 +82,7 @@ public class RedisService
* @param key
* @return true false
*/
public Boolean hasKey(String key)
{
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
@ -102,8 +92,7 @@ public class RedisService
* @param key
* @return
*/
public <T> T getCacheObject(final String key)
{
public <T> T getCacheObject(final String key) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
@ -113,8 +102,7 @@ public class RedisService
*
* @param key
*/
public boolean deleteObject(final String key)
{
public boolean deleteObject(final String key) {
return redisTemplate.delete(key);
}
@ -124,20 +112,18 @@ public class RedisService
* @param collection
* @return
*/
public long deleteObject(final Collection collection)
{
public long deleteObject(final Collection collection) {
return redisTemplate.delete(collection);
}
/**
* List
*
* @param key
* @param key
* @param dataList List
* @return
*/
public <T> long setCacheList(final String key, final List<T> dataList)
{
public <T> long setCacheList(final String key, final List<T> dataList) {
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
@ -148,24 +134,21 @@ public class RedisService
* @param key
* @return
*/
public <T> List<T> getCacheList(final String key)
{
public <T> List<T> getCacheList(final String key) {
return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* Set
*
* @param key
* @param key
* @param dataSet
* @return
*/
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
{
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext())
{
while (it.hasNext()) {
setOperation.add(it.next());
}
return setOperation;
@ -177,8 +160,7 @@ public class RedisService
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key)
{
public <T> Set<T> getCacheSet(final String key) {
return redisTemplate.opsForSet().members(key);
}
@ -188,8 +170,7 @@ public class RedisService
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
{
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
if (dataMap != null) {
redisTemplate.opsForHash().putAll(key, dataMap);
}
@ -201,32 +182,29 @@ public class RedisService
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key)
{
public <T> Map<String, T> getCacheMap(final String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* Hash
*
* @param key Redis
* @param hKey Hash
* @param key Redis
* @param hKey Hash
* @param value
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
{
public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* Hash
*
* @param key Redis
* @param key Redis
* @param hKey Hash
* @return Hash
*/
public <T> T getCacheMapValue(final String key, final String hKey)
{
public <T> T getCacheMapValue(final String key, final String hKey) {
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
return opsForHash.get(key, hKey);
}
@ -234,23 +212,32 @@ public class RedisService
/**
* Hash
*
* @param key Redis
* @param key Redis
* @param hKeys Hash
* @return Hash
*/
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
{
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/**
*
*
*
* @param pattern
* @return
*/
public Collection<String> keys(final String pattern)
{
public Collection<String> keys(final String pattern) {
return redisTemplate.keys(pattern);
}
/**
* hash
* @author xjs
* @param key redis
* @param hkey hash
*/
public void dHashByKey(String key, String hkey) {
redisTemplate.opsForHash().delete(key, hkey);
}
}

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-common-redis</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-common/ruoyi-common-redis/target/classes">
</dir>
</classpath>
</application>

@ -1,17 +1,14 @@
package com.ruoyi.common.security.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.ruoyi.common.security.config.ApplicationConfig;
import com.ruoyi.common.security.feign.FeignAutoConfiguration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableAsync;
import com.ruoyi.common.security.config.ApplicationConfig;
import com.ruoyi.common.security.feign.FeignAutoConfiguration;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ -20,11 +17,13 @@ import com.ruoyi.common.security.feign.FeignAutoConfiguration;
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.ruoyi.**.mapper")
@MapperScan({"com.ruoyi.**.mapper","com.xjs.**.mapper"})
// 开启线程异步执行
@EnableAsync
// 自动加载类
@Import({ ApplicationConfig.class, FeignAutoConfiguration.class })
//自定义bean扫描添加xjs路径下的bean
@ComponentScan(basePackages = {"com.ruoyi","com.xjs"})
public @interface EnableCustomConfig
{

@ -17,7 +17,7 @@ public @interface EnableRyFeignClients
{
String[] value() default {};
String[] basePackages() default { "com.ruoyi" };
String[] basePackages() default { "com.ruoyi" ,"com.xjs"};
Class<?>[] basePackageClasses() default {};

@ -0,0 +1,45 @@
package com.ruoyi.common.security.service;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
/**
* @author xiejs
* @desc token
* @create 2021-12-30
*/
@Service
@ConfigurationProperties(prefix = "jwt")
public class TokenProperties {
private Long expireTime;
private String loginTokenKey;
private Long refreshTime;
public Long getExpireTime() {
return expireTime;
}
public void setExpireTime(Long expireTime) {
this.expireTime = expireTime;
}
public String getLoginTokenKey() {
return loginTokenKey;
}
public void setLoginTokenKey(String loginTokenKey) {
this.loginTokenKey = loginTokenKey;
}
public Long getRefreshTime() {
return refreshTime;
}
public void setRefreshTime(Long refreshTime) {
this.refreshTime = refreshTime;
}
}

@ -1,11 +1,5 @@
package com.ruoyi.common.security.service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.utils.IdUtils;
@ -16,33 +10,43 @@ import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* token
*
*
* @author ruoyi
*/
@Component
public class TokenService
{
public class TokenService {
@Autowired
private RedisService redisService;
protected static final long MILLIS_SECOND = 1000;
protected final long MILLIS_SECOND = 1000;
protected final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
@Value("${jwt.expireTime}")
private long expireTime;
private final static long expireTime = CacheConstants.EXPIRATION;
private static final String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
@Value("${jwt.refreshTime}")
private long refreshTime;
private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
private final Long MILLIS_MINUTE_TEN = refreshTime * MILLIS_MINUTE;
/**
*
*/
public Map<String, Object> createToken(LoginUser loginUser)
{
public Map<String, Object> createToken(LoginUser loginUser) {
String token = IdUtils.fastUUID();
Long userId = loginUser.getSysUser().getUserId();
String userName = loginUser.getSysUser().getUserName();
@ -70,8 +74,7 @@ public class TokenService
*
* @return
*/
public LoginUser getLoginUser()
{
public LoginUser getLoginUser() {
return getLoginUser(ServletUtils.getRequest());
}
@ -80,8 +83,7 @@ public class TokenService
*
* @return
*/
public LoginUser getLoginUser(HttpServletRequest request)
{
public LoginUser getLoginUser(HttpServletRequest request) {
// 获取请求携带的令牌
String token = SecurityUtils.getToken(request);
return getLoginUser(token);
@ -92,20 +94,15 @@ public class TokenService
*
* @return
*/
public LoginUser getLoginUser(String token)
{
public LoginUser getLoginUser(String token) {
LoginUser user = null;
try
{
if (StringUtils.isNotEmpty(token))
{
try {
if (StringUtils.isNotEmpty(token)) {
String userkey = JwtUtils.getUserKey(token);
user = redisService.getCacheObject(getTokenKey(userkey));
return user;
}
}
catch (Exception e)
{
} catch (Exception e) {
}
return user;
}
@ -113,10 +110,8 @@ public class TokenService
/**
*
*/
public void setLoginUser(LoginUser loginUser)
{
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
{
public void setLoginUser(LoginUser loginUser) {
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
refreshToken(loginUser);
}
}
@ -124,10 +119,8 @@ public class TokenService
/**
*
*/
public void delLoginUser(String token)
{
if (StringUtils.isNotEmpty(token))
{
public void delLoginUser(String token) {
if (StringUtils.isNotEmpty(token)) {
String userkey = JwtUtils.getUserKey(token);
redisService.deleteObject(getTokenKey(userkey));
}
@ -138,12 +131,10 @@ public class TokenService
*
* @param loginUser
*/
public void verifyToken(LoginUser loginUser)
{
public void verifyToken(LoginUser loginUser) {
long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
{
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
refreshToken(loginUser);
}
}
@ -153,8 +144,7 @@ public class TokenService
*
* @param loginUser
*/
public void refreshToken(LoginUser loginUser)
{
public void refreshToken(LoginUser loginUser) {
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
@ -162,8 +152,7 @@ public class TokenService
redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
}
private String getTokenKey(String token)
{
private String getTokenKey(String token) {
return ACCESS_TOKEN + token;
}
}

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-common-security</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-common/ruoyi-common-security/target/classes">
</dir>
</classpath>
</application>

@ -15,6 +15,10 @@
ruoyi-common-swagger系统接口
</description>
<properties>
</properties>
<dependencies>
<!-- SpringBoot Web -->
@ -23,11 +27,10 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
</dependencies>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-common-swagger</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-common/ruoyi-common-swagger/target/classes">
</dir>
</classpath>
</application>

@ -72,9 +72,9 @@
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>

@ -25,6 +25,8 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#命名空间
namespace: xjs-666
sentinel:
# 取消控制台懒加载
eager: true

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-gateway</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-gateway/target/classes">
</dir>
</classpath>
</application>

@ -23,3 +23,5 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#命名空间
namespace: xjs-666

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-modules-file</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-modules/ruoyi-file/target/classes">
</dir>
</classpath>
</application>

@ -1,16 +1,17 @@
package com.ruoyi.gen.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.velocity.VelocityContext;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.constant.GenConstants;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.gen.domain.GenTable;
import com.ruoyi.gen.domain.GenTableColumn;
import org.apache.velocity.VelocityContext;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*

@ -23,3 +23,5 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#命名空间
namespace: xjs-666

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-modules-gen</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-modules/ruoyi-gen/target/classes">
</dir>
</classpath>
</application>

@ -1,28 +0,0 @@
package com.ruoyi.job.task;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.utils.StringUtils;
/**
*
*
* @author ruoyi
*/
@Component("ryTask")
public class RyTask
{
public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
{
System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
}
public void ryParams(String params)
{
System.out.println("执行有参方法:" + params);
}
public void ryNoParams()
{
System.out.println("执行无参方法");
}
}

@ -0,0 +1,41 @@
package com.xjs.job.task;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.core.domain.R;
import com.xjs.business.api.RemoteCopyWritingFeign;
import com.xjs.business.api.domain.CopyWriting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
/**
* @author xiejs
* @desc
* @create 2021-12-27
*/
@Component("CopyWritingTask")
public class CopyWritingTask {
@Resource
private RemoteCopyWritingFeign remoteCopyWritingFeign;
private static final Logger log = LoggerFactory.getLogger(CopyWritingTask.class);
/**
*
*/
public void execute() {
LocalDateTime localDateTime1 = DateUtil.date().toLocalDateTime();
log.info("---------------文案定时任务Start-------------------");
R<CopyWriting> r = remoteCopyWritingFeign.copyWriting();
log.info("文案定时任务结果:code={},msg={},data={}",r.getCode(),r.getMsg(),r.getData());
LocalDateTime localDateTime2 = DateUtil.date().toLocalDateTime();
long between = ChronoUnit.MILLIS.between(localDateTime1, localDateTime2);
log.info("Job耗费时间:{}ms", between);
log.info("---------------文案定时任务end---------------------");
}
}

@ -23,3 +23,5 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#命名空间
namespace: xjs-666

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-modules-job</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-modules/ruoyi-job/target/classes">
</dir>
</classpath>
</application>

@ -2,6 +2,7 @@ package com.ruoyi.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.validation.Validator;
import org.slf4j.Logger;
@ -32,7 +33,7 @@ import com.ruoyi.system.service.ISysUserService;
/**
*
*
*
* @author ruoyi
*/
@Service
@ -63,7 +64,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -76,7 +77,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -89,7 +90,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -102,7 +103,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userName
* @return
*/
@ -114,7 +115,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
* ID
*
*
* @param userId ID
* @return
*/
@ -126,7 +127,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userName
* @return
*/
@ -143,7 +144,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userName
* @return
*/
@ -160,7 +161,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userName
* @return
*/
@ -213,21 +214,22 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
*/
@Override
public void checkUserAllowed(SysUser user)
{
if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin())
{
throw new ServiceException("不允许操作超级管理员用户");
if (StringUtils.isNotNull(user.getUserId())&& user.isAdmin()) {
if("1".equals(user.getStatus())){
throw new ServiceException("不允许停用超级管理员用户");
}
}
}
/**
*
*
*
* @param userId id
*/
@Override
@ -247,7 +249,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -266,7 +268,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -278,7 +280,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -300,7 +302,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userId ID
* @param roleIds
*/
@ -314,7 +316,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -326,7 +328,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -338,7 +340,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userName
* @param avatar
* @return
@ -351,7 +353,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
* @return
*/
@ -363,7 +365,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userName
* @param password
* @return
@ -376,7 +378,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
*/
public void insertUserRole(SysUser user)
@ -402,7 +404,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param user
*/
public void insertUserPost(SysUser user)
@ -428,7 +430,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userId ID
* @param roleIds
*/
@ -454,7 +456,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
* ID
*
*
* @param userId ID
* @return
*/
@ -471,7 +473,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userIds ID
* @return
*/
@ -492,7 +494,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
*
*
*
* @param userList
* @param isUpdateSupport
* @param operName

@ -23,3 +23,5 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#命名空间
namespace: xjs-666

@ -39,6 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and date_format(create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
</if>
</where>
order by update_time desc ,dict_id desc
</select>
<select id="selectDictTypeAll" resultMap="SysDictTypeResult">

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-modules-system</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-modules/ruoyi-system/target/classes">
</dir>
</classpath>
</application>

@ -1,11 +1,11 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
# 开发环境配置
ENV = 'development'
# 若依管理系统/开发环境
VUE_APP_BASE_API = '/dev-api'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
# 页面标题
VUE_APP_TITLE = 管理平台
# 开发环境配置
ENV = 'development'
# 若依管理系统/开发环境
VUE_APP_BASE_API = '/dev-api'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

@ -1,8 +1,8 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
# 生产环境配置
ENV = 'production'
# 若依管理系统/生产环境
VUE_APP_BASE_API = '/prod-api'
# 页面标题
VUE_APP_TITLE = 管理平台
# 生产环境配置
ENV = 'production'
# 若依管理系统/生产环境
VUE_APP_BASE_API = '/prod-api'

@ -1,10 +1,10 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 若依管理系统/测试环境
VUE_APP_BASE_API = '/stage-api'
# 页面标题
VUE_APP_TITLE = 管理平台
NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 若依管理系统/测试环境
VUE_APP_BASE_API = '/stage-api'

@ -1,90 +1,90 @@
{
"name": "ruoyi",
"version": "3.3.0",
"description": "若依管理系统",
"author": "若依",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"keywords": [
"vue",
"admin",
"dashboard",
"element-ui",
"boilerplate",
"admin-template",
"management-system"
],
"repository": {
"type": "git",
"url": "https://gitee.com/y_project/RuoYi-Cloud.git"
},
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.24.0",
"clipboard": "2.0.8",
"core-js": "3.19.1",
"echarts": "4.9.0",
"element-ui": "2.15.6",
"file-saver": "2.0.5",
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.2.1",
"nprogress": "0.2.0",
"quill": "1.3.7",
"screenfull": "5.0.2",
"sortablejs": "1.10.2",
"vue": "2.6.12",
"vue-count-to": "1.0.13",
"vue-cropper": "0.5.5",
"vue-meta": "2.4.0",
"vue-router": "3.4.9",
"vuedraggable": "2.24.3",
"vuex": "3.6.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.6",
"@vue/cli-plugin-eslint": "4.4.6",
"@vue/cli-service": "4.4.6",
"babel-eslint": "10.1.0",
"babel-plugin-dynamic-import-node": "2.3.3",
"chalk": "4.1.0",
"compression-webpack-plugin": "5.0.2",
"connect": "3.6.6",
"eslint": "7.15.0",
"eslint-plugin-vue": "7.2.0",
"lint-staged": "10.5.3",
"runjs": "4.4.2",
"sass": "1.32.13",
"sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1",
"vue-template-compiler": "2.6.12"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
{
"name": "ruoyi",
"version": "3.3.0",
"description": "管理平台",
"author": "若依",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"keywords": [
"vue",
"admin",
"dashboard",
"element-ui",
"boilerplate",
"admin-template",
"management-system"
],
"repository": {
"type": "git",
"url": "https://gitee.com/y_project/RuoYi-Cloud.git"
},
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.24.0",
"clipboard": "2.0.8",
"core-js": "3.19.1",
"echarts": "4.9.0",
"element-ui": "2.15.6",
"file-saver": "2.0.5",
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.2.1",
"nprogress": "0.2.0",
"quill": "1.3.7",
"screenfull": "5.0.2",
"sortablejs": "1.10.2",
"vue": "2.6.12",
"vue-count-to": "1.0.13",
"vue-cropper": "0.5.5",
"vue-meta": "2.4.0",
"vue-router": "3.4.9",
"vuedraggable": "2.24.3",
"vuex": "3.6.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.6",
"@vue/cli-plugin-eslint": "4.4.6",
"@vue/cli-service": "4.4.6",
"babel-eslint": "10.1.0",
"babel-plugin-dynamic-import-node": "2.3.3",
"chalk": "4.1.0",
"compression-webpack-plugin": "5.0.2",
"connect": "3.6.6",
"eslint": "7.15.0",
"eslint-plugin-vue": "7.2.0",
"lint-staged": "10.5.3",
"runjs": "4.4.2",
"sass": "1.32.13",
"sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1",
"vue-template-compiler": "2.6.12"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}

@ -0,0 +1,61 @@
import request from '@/utils/request'
// 查询英语单词列表
export function listWord(query) {
return request({
url: '/english/word/list',
method: 'get',
params: query
})
}
// 查询英语单词详细
export function getWord(id) {
return request({
url: '/english/word/' + id,
method: 'get'
})
}
export function getWordRPC(id) {
return request({
url: '/english/word/rpc/' + id,
method: 'get'
})
}
// 新增英语单词
export function addWord(data) {
return request({
url: '/english/word',
method: 'post',
data: data
})
}
// 修改英语单词
export function updateWord(data) {
return request({
url: '/english/word',
method: 'put',
data: data
})
}
// 删除英语单词
export function delWord(id) {
return request({
url: '/english/word/' + id,
method: 'delete'
})
}
//查询收藏夹英语单词
export function collectWord(query){
return request({
url: '/english/word/collect',
method: 'get',
params: query
})
}

@ -0,0 +1,8 @@
import request from '@/utils/request'
// 登录方法
export function getServiceMonitor() {
return request({
url: '/monitor/servicemonitor'
})
}

@ -0,0 +1,33 @@
import request from '@/utils/request'
// 查询文案api通过api获取文案信息列表
export function listCopyWriting(query) {
return request({
url: '/openapi/copyWriting/list',
method: 'get',
params: query
})
}
// 查询文案api通过api获取文案信息详细
export function getCopyWriting(id) {
return request({
url: '/openapi/copyWriting/' + id,
method: 'get'
})
}
// 删除文案api通过api获取文案信息
export function delCopyWriting(id) {
return request({
url: '/openapi/copyWriting/' + id,
method: 'delete'
})
}
// 删除重复文案信息
export function delRepeatCopyWriting() {
return request({
url: '/openapi/copyWriting/Repeat/',
method: 'delete'
})
}

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 查询日志列表
export function listLog(query) {
return request({
url: '/openapi/log/list',
method: 'get',
params: query
})
}
// 查询日志详细
export function getLog(id) {
return request({
url: '/openapi/log/' + id,
method: 'get'
})
}
// 删除日志
export function delLog(id) {
return request({
url: '/openapi/log/' + id,
method: 'delete'
})
}

@ -0,0 +1,33 @@
import request from '@/utils/request'
// 查询英语一言列表
export function listOneenglish(query) {
return request({
url: '/openapi/oneenglish/list',
method: 'get',
params: query
})
}
// 查询英语一言详细
export function getOneenglish(id) {
return request({
url: '/openapi/oneenglish/' + id,
method: 'get'
})
}
// 删除英语一言
export function delOneenglish(id) {
return request({
url: '/openapi/oneenglish/' + id,
method: 'delete'
})
}
//获取英语一言api接口
export function getOneEnglishApi() {
return request({
url: '/openapi/oneenglish/getOneEnglish'
})
}

@ -0,0 +1,19 @@
import request from '@/utils/request'
// 翻译
export function translation(query) {
return request({
url: '/openapi/translation',
method: 'post',
data: query
})
}
//获取文案
export function getCopyWriting(query) {
return request({
url: '/openapi/copyWriting',
method: 'get',
data: query
})
}

@ -0,0 +1,28 @@
import request from '@/utils/request'
// 查询API预警列表
export function listApiwarning(query) {
return request({
url: '/warning/apiwarning/list',
method: 'get',
params: query
})
}
// 查询API预警详细
export function getApiwarning(id) {
return request({
url: '/warning/apiwarning/' + id,
method: 'get'
})
}
// 修改API预警
export function updateApiwarning(data) {
return request({
url: '/warning/apiwarning/edit',
method: 'put',
data: data
})
}

@ -1,93 +1,93 @@
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
</transition>
</div>
</template>
<script>
import logoImg from '@/assets/logo/logo.png'
import variables from '@/assets/styles/variables.scss'
export default {
name: 'SidebarLogo',
props: {
collapse: {
type: Boolean,
required: true
}
},
computed: {
variables() {
return variables;
},
sideTheme() {
return this.$store.state.settings.sideTheme
}
},
data() {
return {
title: '若依管理系统',
logo: logoImg
}
}
}
</script>
<style lang="scss" scoped>
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
.sidebarLogoFade-enter,
.sidebarLogoFade-leave-to {
opacity: 0;
}
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
background: #2b2f3a;
text-align: center;
overflow: hidden;
& .sidebar-logo-link {
height: 100%;
width: 100%;
& .sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 12px;
}
& .sidebar-title {
display: inline-block;
margin: 0;
color: #fff;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0px;
}
}
}
</style>
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
</router-link>
</transition>
</div>
</template>
<script>
import logoImg from '@/assets/logo/logo.png'
import variables from '@/assets/styles/variables.scss'
export default {
name: 'SidebarLogo',
props: {
collapse: {
type: Boolean,
required: true
}
},
computed: {
variables() {
return variables;
},
sideTheme() {
return this.$store.state.settings.sideTheme
}
},
data() {
return {
title: '管理平台',
logo: logoImg
}
}
}
</script>
<style lang="scss" scoped>
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
.sidebarLogoFade-enter,
.sidebarLogoFade-leave-to {
opacity: 0;
}
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
background: #2b2f3a;
text-align: center;
overflow: hidden;
& .sidebar-logo-link {
height: 100%;
width: 100%;
& .sidebar-logo {
width: 32px;
height: 32px;
vertical-align: middle;
margin-right: 12px;
}
& .sidebar-title {
display: inline-block;
margin: 0;
color: #fff;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0px;
}
}
}
</style>

@ -0,0 +1,202 @@
<template xmlns="http://www.w3.org/1999/html">
<div class="sea_main_con test-5" @mouseenter="onMouseover" @mouseleave="onMouseout">
<div class="infinite-list-wrapper">
<ul
class="list"
v-infinite-scroll="loadMore"
infinite-scroll-disabled="disabled"
infinite-scroll-distance="20"
>
<el-row>
<el-col :span="8" v-for="(say, index) in sayLists" :key="index" class="item-img">
<el-card :body-style="{ padding: '0px' }">
<div style="padding: 14px;">
<span>
<el-tag type="info"
size="medium"
>{{ say.englishWord }}
</el-tag>
</span>
<div class="bottom clearfix">
<time class="time">
<el-tag type="warning"
size="medium"
color=""
>{{ say.chineseWord }}
</el-tag>
</time>
<el-button icon="el-icon-search" circle class="button" @click="popoverVisibles(say.id)"></el-button>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!--</li>-->
</ul>
<div class="load_icon">
<p v-if="loading"><i class="el-icon-loading"/></p>
<p v-if="noMore">~~~~</p>
</div>
</div>
</div>
</template>
<script>
import {collectWord, getWordRPC} from "@/api/business/english/word";
export default {
data() {
return {
loading: false,
seen: true,
currentDate: new Date(),
sayLists: [],
//
everyList: 1,
queryParams: {
pageNum: 1,
pageSize: 21
},
}
},
computed: {
noMore() {
return this.everyList < 1;
},
disabled() {
return this.loading || this.noMore
}
},
methods: {
popoverVisibles(id) {
getWordRPC(id).then(res =>{
this.$notify({
title: res.data.englishWord,
message: res.data.content,
duration: 0
});
})
},
loadMore() {
this.loading = true
setTimeout(() => {
collectWord(this.queryParams).then((response) => {
console.log(response.data)
this.everyList = response.data.records.length;
for (var i = 0; i < response.data.records.length; i++) {
this.sayLists.push(response.data.records[i])
}
}, (error) => {
})
this.queryParams.pageNum += 1;
this.loading = false
}, 150)
},
onMouseover() {
this.seen = true;
},
onMouseout() {
this.seen = false;
}
}
}
</script>
<style scoped class="scss">
.item-img {
margin-left: 60px;
margin-top: 20px;
}
.sea_main_con {
width: 1002px;
height: 800px;
border: 1px #b8b7b7 solid;
overflow-y: scroll;
border-radius: 4px;
margin-left: auto;
margin-right: auto;
margin-top: 2px;
margin-bottom: 5px;
}
.test-5::-webkit-scrollbar {
/*滚动条整体样式*/
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
.test-5::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
background-color: #999093;
background-image: -webkit-linear-gradient(
45deg,
rgba(255, 255, 255, 0.2) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.2) 50%,
rgba(255, 255, 255, 0.2) 75%,
transparent 75%,
transparent
);
}
.test-5::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #ededed;
border-radius: 10px;
}
.time {
font-size: 13px;
color: #999;
}
.bottom {
margin-top: 13px;
line-height: 12px;
}
.button {
padding: 0;
float: right;
}
.image {
width: 100%;
display: block;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
.el-col-8 {
width: 24.3%;
}
.load_icon {
width: 100%;
text-align: center;
}
.load_icon p{
font-size: 10px;
color: #8492a6;
}
</style>

@ -0,0 +1,541 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="英语单词" prop="englishWord">
<el-input
v-model="queryParams.englishWord"
placeholder="英语单词"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="中文" prop="chineseWord">
<el-input
v-model="queryParams.chineseWord"
placeholder="请输入中文"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['english:word:add']"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['english:word:edit']"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['english:word:remove']"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['english:word:export']"
>导出
</el-button>
</el-col>
<el-col :span="1.5">
<router-link :to="'/openapi/english/collect/'" class="link-type">
<el-button
type="warning"
plain
icon="el-icon-star-off"
size="mini"
@click="handleCollect"
v-hasPermi="['english:word:collect']"
>
收藏夹
</el-button>
</router-link>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="wordList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="英语单词" align="center" prop="englishWord" :show-overflow-tooltip="true"/>
<el-table-column label="中文" align="center" prop="chineseWord" :show-overflow-tooltip="true"/>
<el-table-column label="排序" align="center" prop="sort" :show-overflow-tooltip="true"/>
<el-table-column label="收藏" align="center" prop="isCollect">
<template slot-scope="scope">
<dict-tag :options="dict.type.english_collect" :value="scope.row.isCollect"/>
</template>
</el-table-column>
<el-table-column label="置顶" align="center" prop="top">
<template slot-scope="scope">
<dict-tag :options="dict.type.english_top" :value="scope.row.top"/>
</template>
</el-table-column>
<el-table-column label="查看次数" align="center" prop="lookCount" :show-overflow-tooltip="true"/>
<el-table-column label="创建时间" align="center" prop="createTime" :show-overflow-tooltip="true"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" content="点击查看详情" placement="top-start">
<el-button circle
type=""
icon="el-icon-view"
@click="handleView(scope.row,scope.index)"
v-hasPermi="['openapi:word:query']"
></el-button>
</el-tooltip>
<el-button circle
type="primary"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['english:word:edit']"
></el-button>
<el-button circle
type="danger"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['english:word:remove']"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 修改英语单词对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="formEdit" :model="form" :rules="rulesEdit" label-width="80px" v-loading="loadingEdit">
<el-form-item label="英语单词" prop="englishWord">
<el-input v-model="form.englishWord" placeholder="请输入英语单词"/>
</el-form-item>
<el-form-item label="中文" prop="chineseWord">
<el-input v-model="form.chineseWord" placeholder="请输入对应的中文"/>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-slider
v-model="form.sort"
show-input>
</el-slider>
</el-form-item>
<el-form-item label="收藏" prop="isCollect">
<el-select v-model="form.isCollect" placeholder="请选择是否收藏">
<el-option
v-for="dict in dict.type.english_collect"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="置顶" prop="top">
<el-select v-model="form.top" placeholder="请选择置顶">
<el-option
v-for="dict in dict.type.english_top"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFormEdit"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!--添加英语对话框-->
<el-dialog :title="title" :visible.sync="openAdd" width="500px" append-to-body>
<el-form ref="formAdd" :model="form" :rules="rulesAdd" label-width="80px" v-loading="loadingEdit">
<el-form-item label="中英文" prop="content">
<el-input v-model="form.content" placeholder="请输入中文或英文"/>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-slider
v-model="form.sort"
show-input>
</el-slider>
</el-form-item>
<el-form-item label="收藏" prop="isCollect">
<el-select v-model="form.isCollect" placeholder="请选择是否收藏">
<el-option
v-for="dict in dict.type.english_collect"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="置顶" prop="top">
<el-select v-model="form.top" placeholder="请选择置顶">
<el-option
v-for="dict in dict.type.english_top"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFormAdd"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 抽屉 查看详情-->
<el-drawer
title="单词内容"
:visible.sync="drawer"
direction="rtl"
:before-close="handleClose">
<div v-loading="loadingC">
<div class="div1">
{{ form.englishWord }}
</div>
<div class="div2">
{{ form.content }}
</div>
<div class="div2" style="height:320px ">
{{ oneEnglishData.en }}
<el-divider><i class="el-icon-mobile-phone"></i></el-divider>
{{ oneEnglishData.zh }}
</div>
</div>
</el-drawer>
</div>
</template>
<script>
import {listWord, getWord, delWord, addWord, updateWord, getWordRPC} from "@/api/business/english/word";
import {getOneEnglishApi} from "@/api/business/openapi/oneenglish";
export default {
name: "Word",
dicts: ['english_collect', 'english_top'],
data() {
return {
//
loadingC: true,
//
drawer: false,
//
loading: true,
loadingEdit: false,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
wordList: [],
//
title: "",
//
open: false,
openAdd: false,
//
daterangeCreateTime: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
englishWord: null,
chineseWord: null,
createTime: null
},
//
form: {
sort: 0
},
//
oneEnglishData: {},
//
rulesEdit: {
englishWord: [
{required: true, message: "英语单词不能为空", trigger: "blur"}
],
chineseWord: [
{required: true, message: "中文不能为空", trigger: "blur"}
],
isCollect: [
{required: true, message: "是否收藏 1收藏 2不收藏不能为空", trigger: "blur"}
],
top: [
{required: true, message: "置顶 1置顶 2不置顶不能为空", trigger: "blur"}
],
createTime: [
{required: true, message: "创建时间不能为空", trigger: "blur"}
]
},
rulesAdd: {
content: [
{required: true, message: "中英文不能为空", trigger: "blur"}
],
isCollect: [
{required: true, message: "是否收藏 1收藏 2不收藏不能为空", trigger: "blur"}
],
top: [
{required: true, message: "置顶 1置顶 2不置顶不能为空", trigger: "blur"}
],
createTime: [
{required: true, message: "创建时间不能为空", trigger: "blur"}
]
}
};
},
created() {
this.getList();
},
methods: {
//api
getOneEnglishApi() {
getOneEnglishApi().then(res => {
this.oneEnglishData = res.data
})
},
//id
findById(id) {
this.loadingC = true;
getWordRPC(id).then(res => {
this.form = res.data
this.loadingC = false
})
},
//
handleClose(done) {
done();
this.getList();
},
/** 详细按钮操作 */
handleView(row) {
this.drawer = true
this.form = row;
this.findById(row.id)
this.getOneEnglishApi()
},
/** 查询英语单词列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.createTime = this.daterangeCreateTime[0];
this.queryParams.endCreateTime = this.daterangeCreateTime[1];
}
listWord(this.queryParams).then(response => {
this.wordList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.openAdd = false
this.reset();
},
//
reset() {
this.form = {
id: null,
englishWord: null,
chineseWord: null,
sort: null,
isCollect: null,
top: null,
lookCount: null,
createTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.queryParams.createTime=null
this.queryParams.endCreateTime=null
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.openAdd = true;
this.title = "添加英语单词";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getWord(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改英语单词";
});
},
/** 提交按钮 */
submitFormEdit() {
this.$refs["formEdit"].validate(valid => {
if (valid) {
if (this.form.id != null) {
this.loadingEdit = true
updateWord(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.loadingEdit = false
this.open = false;
this.getList();
}).catch(err => {
this.loadingEdit = false
});
}
}
}
);
},
submitFormAdd() {
this.$refs["formAdd"].validate(valid => {
if (valid) {
if (this.form.id == null) {
this.loadingEdit = true
addWord(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.openAdd = false;
this.loadingEdit = false
this.getList();
}).catch(err => {
this.loadingEdit = false
});
}
}
}
);
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除英语单词编号为"' + ids + '"的数据项?').then(function () {
return delWord(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('english/word/export', {
...this.queryParams
}, `word_${new Date().getTime()}.xlsx`)
},
//
handleCollect() {
}
}
};
</script>
<style scoped>
.div1 {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
height: 180px;
margin: 10px;
padding: 30px;
padding-top: 60px;
text-align: center;
text-shadow: 2px 2px 2px grey;
font-size: 30px;
}
.div2 {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
margin: 10px;
padding: 30px;
height: 280px;
padding-top: 100px;
text-align: center;
text-shadow: 2px 2px 2px grey;
font-size: 20px;
}
</style>

@ -0,0 +1,126 @@
<template>
<div>
<el-row :gutter="20">
<el-col :span="12">
<div class="grid-content bg-purple">
<el-tag type="info">jvm版本</el-tag>
{{serviceMonitorInfo.jvmVersion}}
<br>
<el-tag type="info">jre安装路径</el-tag>
{{serviceMonitorInfo.jreHoneDir}}
<br>
<el-tag type="info">jre版本</el-tag>
{{serviceMonitorInfo.jreVersion}}
<br>
<el-tag type="info">jre名称</el-tag>
{{serviceMonitorInfo.jreName}}
<br>
</div>
</el-col>
<el-col :span="12">
<div class="grid-content bg-purple">
<el-tag type="info">系统名称</el-tag>
{{serviceMonitorInfo.osName}}
<br>
<el-tag type="info">系统版本</el-tag>
{{serviceMonitorInfo.osVersion}}
<br>
<el-tag type="info">系统架构</el-tag>
{{serviceMonitorInfo.osArch}}
<br>
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<div class="grid-content bg-purple">
<el-tag type="info">主机名</el-tag>
{{serviceMonitorInfo.hostName}}
<br>
<el-tag type="info">主机地址</el-tag>
{{serviceMonitorInfo.hostAddress}}
<br>
<el-tag type="info">登录名</el-tag>
{{serviceMonitorInfo.userName}}
<br>
<el-tag type="info">用户路径</el-tag>
{{serviceMonitorInfo.homeDir}}
<br>
<el-tag type="info">当前目录</el-tag>
{{serviceMonitorInfo.currentDir}}
<br>
<el-tag type="info">登录语言</el-tag>
{{serviceMonitorInfo.userLanguage}}
<br>
<el-tag type="info">登录区域</el-tag>
{{serviceMonitorInfo.userCountry}}
<br>
</div>
</el-col>
<el-col :span="12">
<div class="grid-content bg-purple">
<el-tag type="info">最大jvm内存</el-tag>
{{serviceMonitorInfo.maxMemory/1024/1024+"M"}}
<br>
<el-tag type="info">已分配内存</el-tag>
{{serviceMonitorInfo.totalMemory/1024/1024+"M"}}
<br>
<el-tag type="info">剩余内存</el-tag>
{{parseFloat(Number(serviceMonitorInfo.freeMemory/1024/1024).toFixed(0))+"M"}}
<br>
<el-tag type="info">最大可用内存</el-tag>
{{parseFloat(Number(serviceMonitorInfo.usableMemory/1024/1024).toFixed(0))+"M"}}
<br>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import {getServiceMonitor} from "@/api/business/monitor/service/monitorservice";
export default {
name: "Online",
data() {
return {
serviceMonitorInfo:{
}
}
},
created() {
this.getServiceMonitor()
},
methods: {
getServiceMonitor() {
getServiceMonitor().then(res =>{
this.serviceMonitorInfo=res.data
})
},
},
};
</script>
<style scoped>
.el-row {
margin: 100px;
padding: 0 20px;
}
.el-col {
border-radius: 4px;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
padding: 0 180px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
}
</style>

@ -0,0 +1,298 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="文案内容" prop="content">
<el-input
v-model="queryParams.content"
placeholder="请输入文案内容"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="文案来源" prop="source">
<el-input
v-model="queryParams.source"
placeholder="请输入文案来源"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="文案类型" prop="type">
<el-select v-model="queryParams.type" placeholder="请选择文案类型" clearable size="small">
<el-option
v-for="dict in dict.type.copywriting_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['openapi:copywriting:delete']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['openapi:copywriting:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
@click="delRepeatCopyWriting"
v-hasPermi="['openapi:copywriting:delete']"
>删除重复文案</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="copyWritingList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="文案内容" align="center" prop="content" :show-overflow-tooltip="true" width="700px"/>
<el-table-column label="文案来源" align="center" prop="source" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180" :show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="文案类型" align="center" prop="type" :show-overflow-tooltip="true">
<template slot-scope="scope">
<dict-tag :options="dict.type.copywriting_type" :value="scope.row.type"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" content="点击查看详情" placement="top-start">
<el-button circle
type=""
icon="el-icon-view"
@click="handleView(scope.row,scope.index)"
v-hasPermi="['openapi:copywriting:query']"
></el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="点击删除" placement="top-start">
<el-button circle
type="danger"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['openapi:copywriting:delete']"
></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 操作日志详细 -->
<el-dialog title="内容详细" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="100px" size="mini">
<el-row>
<el-col :span="24">
<el-form-item label="文案内容:">{{ form.content }}</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listCopyWriting, getCopyWriting,delRepeatCopyWriting, delCopyWriting } from "@/api/business/openapi/copywriting";
export default {
name: "CopyWriting",
dicts: ['copywriting_type'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
// apiapi
copyWritingList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
content: null,
source: null,
createTime: null,
type: null
},
//
form: {},
//
rules: {
content: [
{ required: true, message: "文案内容不能为空", trigger: "blur" }
],
source: [
{ required: true, message: "文案来源不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
},
methods: {
//
delRepeatCopyWriting() {
delRepeatCopyWriting().then(res =>{
this.$modal.msgSuccess("删除"+res.data+"条");
this.getList();
})
},
/** 详细按钮操作 */
handleView(row) {
this.open = true;
this.form = row;
},
/** 查询文案api通过api获取文案信息列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
this.queryParams.createTime = this.daterangeCreateTime[0];
this.queryParams.endCreateTime = this.daterangeCreateTime[1];
}
listCopyWriting(this.queryParams).then(response => {
this.copyWritingList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
content: null,
source: null,
createTime: null,
type: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.queryParams.createTime=null
this.queryParams.endCreateTime=null
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateCopyWriting(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addCopyWriting(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除文案api通过api获取文案信息编号为"' + ids + '"的数据项?').then(function() {
return delCopyWriting(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('openapi/copyWriting/export', {
...this.queryParams
}, `copyWriting_${new Date().getTime()}.xlsx`)
}
}
};
</script>

@ -0,0 +1,204 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="接口名称" prop="apiName">
<el-input
v-model="queryParams.apiName"
placeholder="请输入接口名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['openapi:log:remove']"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['openapi:log:export']"
>导出
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="logList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="接口名称" align="center" prop="apiName" :show-overflow-tooltip="true"/>
<el-table-column label="请求URL" align="center" prop="url" :show-overflow-tooltip="true"/>
<el-table-column label="请求方法" align="center" prop="method" :show-overflow-tooltip="true"/>
<el-table-column label="请求参数" align="center" prop="request" :show-overflow-tooltip="true"/>
<el-table-column label="响应参数" align="center" prop="response" :show-overflow-tooltip="true"/>
<el-table-column label="创建时间" align="center" prop="createTime" :show-overflow-tooltip="true"/>
<el-table-column label="是否请求成功" align="center" prop="isSuccess" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-tag :type="scope.row.isSuccess==='成功'?'success':'danger'" size="small">{{ scope.row.isSuccess }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
circle
type="danger"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['openapi:log:remove']"
>
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import {listLog, getLog, delLog} from "@/api/business/openapi/log";
export default {
name: "Log",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
logList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
apiName: null
},
//
form: {},
//
rules: {}
};
},
created() {
this.getList();
},
methods: {
/** 查询日志列表 */
getList() {
this.loading = true;
listLog(this.queryParams).then(response => {
this.logList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
apiName: null,
url: null,
method: null,
request: null,
response: null,
isSuccess: null,
createTime:null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加日志";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getLog(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改日志";
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除日志编号为"' + ids + '"的数据项?').then(function () {
return delLog(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('openapi/log/export', {
...this.queryParams
}, `log_${new Date().getTime()}.xlsx`)
}
}
};
</script>

@ -0,0 +1,186 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="英文" prop="en">
<el-input
v-model="queryParams.en"
placeholder="请输入英文"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="中文" prop="zh">
<el-input
v-model="queryParams.zh"
placeholder="请输入中文"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['openapi:oneenglish:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['openapi:oneenglish:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="oneenglishList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="英文" align="center" prop="en" />
<el-table-column label="中文" align="center" prop="zh" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px">
<template slot-scope="scope">
<el-button
circle
type="danger"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['openapi:oneenglish:remove']"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listOneenglish, getOneenglish, delOneenglish } from "@/api/business/openapi/oneenglish";
export default {
name: "Oneenglish",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
oneenglishList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
en: null,
zh: null,
},
//
form: {},
//
rules: {
}
};
},
created() {
this.getList();
},
methods: {
/** 查询英语一言列表 */
getList() {
this.loading = true;
listOneenglish(this.queryParams).then(response => {
this.oneenglishList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
en: null,
zh: null,
createTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除英语一言编号为"' + ids + '"的数据项?').then(function () {
return delOneenglish(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('openapi/oneenglish/export', {
...this.queryParams
}, `oneenglish_${new Date().getTime()}.xlsx`)
}
}
}
</script>

@ -0,0 +1,194 @@
<template>
<div class="app-container">
<el-row>
<el-col :span="24" v-loading="loading1">
<div class="grid-content bg-purple" style="height: 180px">
<!-- 文案内容区域-->
<!-- 内容-->
<div class="content_div">
{{responseCopyWriting.content}}
</div>
<!-- 来源-->
<div class="source_div">
{{responseCopyWriting.source}}
</div>
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<!-- 翻译区域-->
<div class="grid-content bg-purple">
<el-row :gutter="15">
<el-form ref="translation" :model="translationData" :rules="translationRules" size="medium"
label-width="100px" label-position="top">
<el-col :span="12">
<el-form-item label="翻译平台" prop="translationType">
<el-select
v-model="translationData.translationType"
placeholder="翻译平台"
clearable
size="small"
style="width: 150px">
<el-option
v-for="dict in dict.type.translation_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="20" >
<el-form-item label="翻译区域" prop="q">
<el-input v-model="translationData.q" type="textarea" placeholder="请输入翻译内容" show-word-limit
:autosize="{minRows: 4, maxRows: 4}" :style="{width: '100%'}"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item size="large">
<el-button type="primary" @click="submitForm"></el-button>
<el-button @click="resetForm"></el-button>
<el-button type="info" icon="el-icon-check" @click="getCopyWriting" circle></el-button>
</el-form-item>
</el-col>
</el-form>
</el-row>
</div>
</el-col>
<el-col :span="12">
<!-- 翻译结果显示区域-->
<div class="grid-content bg-purple ">
<div class="spans" v-loading="loading2">
{{ responseTranslation }}
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import {translation,getCopyWriting} from "@/api/business/openapi/translation";
export default {
dicts: ['translation_type'],
name: "Log",
data() {
return {
//
loading1: true,
loading2: false,
//
responseTranslation: '',
translationData: {
translationType: '',
q: '',
},
//
copyWriting:[],
//
responseCopyWriting:{},
translationRules: {
translationType: [{
required: true,
message: '翻译平台不能为空',
trigger: 'change'
}],
q: [
{
required: true,
message: '请输入翻译内容',
trigger: 'blur'
},
{
min: 1,
max: 120,
message: '长度在 1 到 120 个字符',
trigger: 'blur'
}
],
},
}
},
created() {
this.getCopyWriting()
},
methods: {
//
getCopyWriting() {
this.loading1 = true;
getCopyWriting(this.copyWriting).then(res =>{
this.responseCopyWriting=res.data
this.loading1 = false;
})
},
submitForm() {
this.$refs['translation'].validate(valid => {
if (valid) {
this.loading2 = true;
translation(this.translationData).then(res => {
let result = res.data.transResult
let results = ''
result.forEach(r => {
results = results + ' ' + r.dst;
})
this.responseTranslation = results
this.loading2 = false;
})
}
})
},
resetForm() {
this.$refs['translation'].resetFields()
},
},
};
</script>
<style scoped>
.bg-purple {
box-shadow: 0 0 9px 3px #999;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
height: 500px;
margin-top: 20px;
padding: 50px;
}
.spans {
margin: 50px;
margin-top: 40px;
padding: 50px;
font-family: Georgia;
font-size: 20px;
height: 300px;
box-shadow: 0 0 9px 3px #999;
font-style: italic;
}
.content_div{
float: left;
width: 75%;
text-shadow: 2px 2px 2px grey;
}
.source_div{
float: left;
padding-top: 70px;
width: 25%;
text-shadow: 2px 2px 2px grey;
text-align :right
}
</style>

@ -0,0 +1,219 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="api名称" prop="apiName">
<el-input
v-model="queryParams.apiName"
placeholder="请输入api名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['warning:apiwarning:edit']"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['warning:apiwarning:export']"
>导出
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="apiwarningList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="API名称" align="center" prop="apiName" :show-overflow-tooltip="true"/>
<el-table-column label="API地址" align="center" prop="apiUrl" :show-overflow-tooltip="true"/>
<el-table-column label="API总请求次数" align="center" prop="totalCount" :show-overflow-tooltip="true"/>
<el-table-column label="请求耗费时间" align="center" prop="requestTime" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span>{{scope.row.requestTime+"ms"}}</span>
</template>
</el-table-column>
<el-table-column label="API每天限制请求次数" align="center" prop="limitCount" :show-overflow-tooltip="true"/>
<el-table-column label="API每天请求次数" align="center" prop="dayCount"/>
<el-table-column label="调用时间" align="center" prop="updateTime" width="180"/>
<el-table-column label="创建时间" align="center" prop="createTime" width="180" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button circle
type="primary"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['warning:apiwarning:edit']"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改API预警对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="请求次数" prop="limitCount">
<el-input v-model="form.limitCount" placeholder="请输入api限制请求次数每天"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {listApiwarning, getApiwarning, updateApiwarning} from "@/api/business/warning/apiwarning";
export default {
name: "Apiwarning",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
// API
apiwarningList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
apiName: null,
},
//
form: {},
//
rules: {}
};
},
created() {
this.getList();
},
methods: {
/** 查询API预警列表 */
getList() {
this.loading = true;
listApiwarning(this.queryParams).then(response => {
this.apiwarningList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
apiName: null,
apiUrl: null,
totalCount: null,
requestTime: null,
limitCount: null,
createTime: null,
dayCount: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getApiwarning(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改API预警";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateApiwarning(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 导出按钮操作 */
handleExport() {
this.download('warning/apiwarning/export', {
...this.queryParams
}, `apiwarning_${new Date().getTime()}.xlsx`)
}
}
};
</script>

@ -1,135 +1,135 @@
'use strict'
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
const CompressionPlugin = require('compression-webpack-plugin')
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
const port = process.env.port || process.env.npm_config_port || 80 // 端口
// vue.config.js 配置说明
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
// 这里只列一部分,具体配置参考文档
module.exports = {
// 部署生产环境和开发环境下的URL。
// 默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
// 在npm run build 或 yarn build 时 生成文件的目录名称要和baseUrl的生产环境路径一致默认dist
outputDir: 'dist',
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
assetsDir: 'static',
// 是否开启eslint保存检测有效值ture | false | 'error'
lintOnSave: process.env.NODE_ENV === 'development',
// 如果你不需要生产环境的 source map可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
// webpack-dev-server 相关配置
devServer: {
host: '0.0.0.0',
port: port,
open: true,
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:8080`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
},
disableHostCheck: true
},
css: {
loaderOptions: {
sass: {
sassOptions: { outputStyle: "expanded" }
}
}
},
configureWebpack: {
name: name,
resolve: {
alias: {
'@': resolve('src')
}
},
plugins: [
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
new CompressionPlugin({
test: /\.(js|css|html)?$/i, // 压缩文件格式
filename: '[path].gz[query]', // 压缩后的文件名
algorithm: 'gzip', // 使用gzip压缩
minRatio: 0.8 // 压缩率小于1才会压缩
})
],
},
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
config
.when(process.env.NODE_ENV !== 'development',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single'),
{
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
to: './' //到根目录下
}
}
)
}
}
'use strict'
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
const CompressionPlugin = require('compression-webpack-plugin')
const name = process.env.VUE_APP_TITLE || '管理平台' // 网页标题
const port = process.env.port || process.env.npm_config_port || 88 // 端口
// vue.config.js 配置说明
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
// 这里只列一部分,具体配置参考文档
module.exports = {
// 部署生产环境和开发环境下的URL。
// 默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
// 在npm run build 或 yarn build 时 生成文件的目录名称要和baseUrl的生产环境路径一致默认dist
outputDir: 'dist',
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
assetsDir: 'static',
// 是否开启eslint保存检测有效值ture | false | 'error'
lintOnSave: process.env.NODE_ENV === 'development',
// 如果你不需要生产环境的 source map可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
// webpack-dev-server 相关配置
devServer: {
host: '0.0.0.0',
port: port,
open: true,
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:8080`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
},
disableHostCheck: true
},
css: {
loaderOptions: {
sass: {
sassOptions: { outputStyle: "expanded" }
}
}
},
configureWebpack: {
name: name,
resolve: {
alias: {
'@': resolve('src')
}
},
plugins: [
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
new CompressionPlugin({
test: /\.(js|css|html)?$/i, // 压缩文件格式
filename: '[path].gz[query]', // 压缩后的文件名
algorithm: 'gzip', // 使用gzip压缩
minRatio: 0.8 // 压缩率小于1才会压缩
})
],
},
chainWebpack(config) {
config.plugins.delete('preload')
config.plugins.delete('prefetch')
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
config
.when(process.env.NODE_ENV !== 'development',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single'),
{
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
to: './' //到根目录下
}
}
)
}
}

@ -1,30 +1,30 @@
package com.ruoyi.modules.monitor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
/**
*
*
* @author ruoyi
*/
@EnableAdminServer
@SpringBootApplication
public class RuoYiMonitorApplication
{
public static void main(String[] args)
{
SpringApplication.run(RuoYiMonitorApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 监控中心启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}
package com.ruoyi.modules.monitor;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
*
* @author ruoyi
*/
@EnableAdminServer
@SpringBootApplication
public class RuoYiMonitorApplication
{
public static void main(String[] args)
{
SpringApplication.run(RuoYiMonitorApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 监控中心启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}

@ -23,3 +23,5 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#命名空间
namespace: xjs-666

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
<id>ruoyi-visual-monitor</id>
<classpath>
<dir name="D:/Dev/IdeaPerject/GitHub/RuoYi-Cloud/ruoyi-visual/ruoyi-monitor/target/classes">
</dir>
</classpath>
</application>

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.3.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xjs</groupId>
<artifactId>xjs-business</artifactId>
<packaging>pom</packaging>
<description>业务模块</description>
<name>业务模块</name>
<modules>
<module>xjs-business-openapi</module>
<module>xjs-business-english</module>
<module>xjs-business-common</module>
<module>xjs-business-warning</module>
<module>xjs-business-monitor</module>
</modules>
<properties>
</properties>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
</dependency>
<!-- RuoYi Common DataScope -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datascope</artifactId>
</dependency>
<!-- RuoYi Common Log -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
<!-- RuoYi Common Swagger -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-swagger</artifactId>
</dependency>
<!--/////////////////////本模块专属依赖/////////////////////////-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!--热部署、有毒一加上redis就出问题 -->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>-->
</dependencies>
</project>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xjs-business</artifactId>
<groupId>com.xjs</groupId>
<version>3.3.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>业务模块-通用工具</name>
<artifactId>xjs-business-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

@ -0,0 +1,28 @@
package com.xjs.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author xiejs
* @desc
* @create 2021-12-25
*/
@Data
@ConfigurationProperties(prefix = "baidu.open")
@Component
public class BaiduProperties {
/**
* APP ID
*/
private String appId;
/**
*
*/
private String key;
}

@ -0,0 +1,22 @@
package com.xjs.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author xiejs
* @desc
* @create 2021-12-25
*/
@Configuration
public class FeignConfig{
/**
*
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}

@ -0,0 +1,76 @@
package com.xjs.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author xiejs
* @desc
* @create 2021-12-26
*/
@Configuration
public class JsonConfig {
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
List<SerializerFeature> list = new ArrayList<>();
list.add(SerializerFeature.PrettyFormat);
list.add(SerializerFeature.WriteMapNullValue);
list.add(SerializerFeature.WriteNullStringAsEmpty);
list.add(SerializerFeature.WriteNullListAsEmpty);
list.add(SerializerFeature.QuoteFieldNames);
list.add(SerializerFeature.WriteDateUseDateFormat);
list.add(SerializerFeature.DisableCircularReferenceDetect);
list.add(SerializerFeature.WriteBigDecimalAsPlain);
//返回枚举类型为枚举toString mp通用枚举用到
list.add(SerializerFeature.WriteEnumUsingToString);
fastJsonConfig.setSerializerFeatures(list.toArray(new SerializerFeature[list.size()]));
fastConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converter = fastConverter;
//解决远程调用 ---Content-Type cannot contain wildcard type '*')报错
fastConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8));
//解决mp雪花算法前端精度丢失
fastJsonConfig.setSerializeFilters(new ValueFilter() {
@Override
public Object process(Object object, String name, Object value) {
if ((StringUtils.endsWith(name, "Id") || StringUtils.equals(name,"id")) && value != null
&& value.getClass() == Long.class) {
return String.valueOf(value);
}
return value;
}
});
return new HttpMessageConverters(converter);
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer(){
return builder -> builder.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
}
}

@ -0,0 +1,27 @@
package com.xjs.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author xiejs
* @desc
* @create 2021-12-31
*/
@Configuration
public class MybatisPlusConfig {
/**
* mysql
* @return MybatisPlusInterceptor
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

@ -0,0 +1,21 @@
package com.xjs.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author xiejs
* @desc
* @create 2021-12-27
*/
@Component
@ConfigurationProperties(prefix = "tianxing.open")
@Data
public class TianXingProperties {
/**
* key
*/
private String key;
}

@ -0,0 +1,55 @@
package com.xjs.consts;
/**
* @author xiejs
* @desc api
* @create 2021-12-28
*/
public class ApiConst {
//--------------------name------------------------------
public static final String YOUDAO_FY= "有道翻译";
public static final String BAIDU_FY= "百度翻译";
public static final String TIANXING_PYQ= "天行-朋友圈";
public static final String TIANXING_WYY= "天行-网易云";
public static final String TIANXING_JDTC= "天行-经典台词";
public static final String TIANXING_MMMY= "天行-名人名言";
public static final String TIANXING_TRAN_DICT= "天行-翻译字典";
public static final String TIANXING_ONE_ENGLISH= "天行-英语一言";
public static final String TEN_YY= "Ten-一言";
//-------------------url------------------------------
public static final String BAIDU_FY_URL= "http://api.fanyi.baidu.com/api/trans/vip/translate";
public static final String YOUDAO_FY_URL= "http://fanyi.youdao.com/translate";
public static final String TIANXING_PYQ_URL= "http://api.tianapi.com/pyqwenan/index";
public static final String TIANXING_WYY_URL= "http://api.tianapi.com/hotreview/index";
public static final String TIANXING_JDTC_URL= "http://api.tianapi.com/dialogue/index";
public static final String TIANXING_MMMY_URL= "http://api.tianapi.com/mingyan/index";
public static final String TIANXING_TRAN_DICT_URL= "http://api.tianapi.com/enwords/index";
public static final String TIANXING_ONE_ENGLISH_URL= "http://api.tianapi.com/ensentence/index";
public static final String TEN_YY_URL= "https://tenapi.cn/yiyan/";
}

@ -0,0 +1,23 @@
package com.xjs.consts;
/**
* @author xiejs
* @desc
* @create 2021-12-31
*/
public class EnglishWordConst {
//置顶
public static final Integer TOP = 1;
//不置顶
public static final Integer NO_TOP = 2;
//收藏
public static final Integer COLLECT = 1;
//不收藏
public static final Integer NO_COLLECT = 2;
}

@ -0,0 +1,28 @@
package com.xjs.consts;
/**
* @author xiejs
* @desc redis key
* @create 2021-12-30
*/
public class RedisConst {
//----------------------key------------------------
/**
* key
*/
public static final String TRAN_DICT= "tranDict";
/**
* key
*/
public static final String ONE_ENGLISH= "oneEnglish";
//-------------------有效时间-----------------------
public static final Integer TRAN_DICT_EXPIRE = 7; //天
public static final Integer ONE_ENGLISH_EXPIRE = 3; //分钟
}

@ -0,0 +1,11 @@
package com.xjs.consts;
/**
* @author xiejs
* @desc
* @create 2021-12-26
*/
public class ReqConst {
public static final Integer SUCCESS = 1;
public static final Integer ERROR = 2;
}

@ -0,0 +1,20 @@
package com.xjs.consts;
/**
* @author xiejs
* @desc
* @create 2021-12-28
*/
public class TianXingConst {
//朋友圈
public static final Integer PYQ= 1;
//网易云
public static final Integer WYY= 2;
//经典台词
public static final Integer JDTC= 3;
//名人名言
public static final Integer MMMY= 4;
//Ten-API 一言
public static final Integer YY= 5;
}

@ -0,0 +1,12 @@
package com.xjs.consts;
/**
* @author xiejs
* @desc
* @create 2021-12-25
*/
public interface TranslationTypeConst {
Integer BAIDU = 1;
Integer YOUDAO = 2;
Integer GOOGLE = 3;
}

@ -0,0 +1,33 @@
package com.xjs.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* @author xiejs
* @desc toString mp
* @create 2021-12-27
*/
public enum StatusEnum {
SUCCESS(1,"成功"),
ERROR(2,"失败");
private String desc;
@EnumValue//标记数据库存的值是value
@JsonValue
private final int value;
StatusEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public String toString() {
return desc;
}
}

@ -0,0 +1,24 @@
package com.xjs.exception;
import lombok.extern.log4j.Log4j2;
/**
* @author xiejs
* @desc
* @create 2021-12-27
*/
@Log4j2
public class ApiException extends RuntimeException{
public ApiException() {
super();
}
public ApiException(String message) {
super(message);
log.error("调用第三方API异常----{}",message);
}
public ApiException(String message, Throwable cause) {
super(message, cause);
}
}

@ -0,0 +1,24 @@
package com.xjs.exception;
import lombok.extern.log4j.Log4j2;
/**
* @author xiejs
* @desc
* @create 2021-12-25
*/
@Log4j2
public class BusinessException extends RuntimeException{
public BusinessException() {
super();
}
public BusinessException(String message) {
super(message);
log.error("业务异常----{}",message);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
}

@ -0,0 +1,33 @@
package com.xjs.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author xiejs
* @desc mp
* @create 2021-12-27
*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
//this.setFieldValByName("createTime", new Date(), metaObject);
this.strictInsertFill(metaObject, "createTime", Date.class,new Date()); // 起始版本 3.3.3(推荐)
this.strictInsertFill(metaObject, "updateTime", Date.class,new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
//this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); // 起始版本 3.3.3(推荐)
this.strictInsertFill(metaObject, "updateTime", Date.class,new Date()); // 起始版本 3.3.3(推荐)
}
}

@ -0,0 +1,66 @@
package com.xjs.utils;
/**
* @author xiejs
* @desc
* @create 2021-12-29
*/
public class ChineseUtil {
/**
* String
*
* @param name
*
* @return true
*/
public static boolean checkNameChese(String name) {
boolean res = true;
char[] cTemp = name.toCharArray();
for (int i = 0; i < name.length(); i++) {
if (!isChinese(cTemp[i])) {
res = false;
break;
}
}
return res;
}
/**
*
*
* @param c
*
* @return true
*/
public static boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
return true;
}
return false;
}
/**
*
* @param str
* @return truefalse
*/
public static boolean isAlpha(String str) {
if(str==null) return false;
return str.matches("[a-zA-Z]+");
}
}

@ -0,0 +1,9 @@
package com.xjs.validation;
/**
* @author xiejs
* @desc
* @create 2021-12-30
*/
public interface AddGroup {
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save