Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
xingyu 2023-01-12 20:28:15 +08:00
commit 70970eeb18
24 changed files with 520 additions and 285 deletions

View File

@ -191,19 +191,19 @@ ps核心功能已经实现正在对接微信小程序中...
| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.7.7 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | |
| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.15 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.3 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.6.1 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
| [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 | |
| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.18.0 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.24 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.6 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.5 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.8.0 | [文档](https://doc.iocoder.cn/bpm/) |
| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.12.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.9 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.10 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | |
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.5.3.Final | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.24 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
@ -227,7 +227,7 @@ ps核心功能已经实现正在对接微信小程序中...
| [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.9.4 |
| [pinia](https://pinia.vuejs.org/) | vuex5 | 2.0.28 |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
| [vxe-table](https://vxetable.cn/) | vue最强表单 | 4.3.7 |
| [vxe-table](https://vxetable.cn/) | vue最强表单 | 4.3.9 |
### [管理后台 uni-app 跨端](./yudao-ui-admin-uniapp)

View File

@ -1344,6 +1344,7 @@ CREATE TABLE `jimu_report_share` (
`last_update_time` datetime NULL DEFAULT NULL COMMENT '最后更新时间',
`term_of_validity` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '有效期(0:永久有效1:1天2:7天)',
`status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否过期(0未过期1已过期)',
`preview_lock_status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '密码锁状态',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积木报表预览权限表' ROW_FORMAT = Dynamic;

View File

@ -32,7 +32,7 @@
<resilience4j.version>1.7.1</resilience4j.version>
<!-- 监控相关 -->
<skywalking.version>8.12.0</skywalking.version>
<spring-boot-admin.version>2.7.9</spring-boot-admin.version>
<spring-boot-admin.version>2.7.10</spring-boot-admin.version>
<opentracing.version>0.33.0</opentracing.version>
<!-- Test 测试相关 -->
<podam.version>7.2.11.RELEASE</podam.version>
@ -41,10 +41,11 @@
<!-- Bpm 工作流相关 -->
<flowable.version>6.8.0</flowable.version>
<!-- 工具类相关 -->
<jsoup.version>1.15.3</jsoup.version>
<lombok.version>1.18.24</lombok.version>
<mapstruct.version>1.5.3.Final</mapstruct.version>
<hutool.version>5.8.11</hutool.version>
<easyexcel.verion>3.1.4</easyexcel.verion>
<easyexcel.verion>3.1.5</easyexcel.verion>
<velocity.version>2.3</velocity.version>
<screw.version>1.0.5</screw.version>
<fastjson.version>1.2.83</fastjson.version>
@ -63,7 +64,7 @@
<minio.version>8.4.6</minio.version>
<aliyun-java-sdk-core.version>4.6.3</aliyun-java-sdk-core.version>
<aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version>
<tencentcloud-sdk-java.version>3.1.660</tencentcloud-sdk-java.version>
<tencentcloud-sdk-java.version>3.1.667</tencentcloud-sdk-java.version>
<justauth.version>1.4.0</justauth.version>
<jimureport.version>1.5.6</jimureport.version>
<xercesImpl.version>2.12.2</xercesImpl.version>
@ -522,6 +523,12 @@
<version>${ip2region.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<!-- 三方云服务相关 -->
<dependency>
<groupId>com.squareup.okio</groupId>

View File

@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.mybatis.core.mapper;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -10,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
@ -92,8 +92,22 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
entities.forEach(this::insert);
}
/**
* 批量插入适合大量数据插入
*
* @param entities 实体们
* @param size 插入数量 Db.saveBatch 默认为1000
*/
default void insertBatch(Collection<T> entities, int size) {
Db.saveBatch(entities, size);
}
default void updateBatch(T update) {
update(update, new QueryWrapper<>());
}
default void updateBatch(Collection<T> entities, int size) {
Db.updateBatchById(entities, size);
}
}

View File

@ -67,6 +67,11 @@
<scope>provided</scope> <!-- 设置为 provided主要是 GlobalExceptionHandler 使用 -->
</dependency>
<!-- xss -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -2,15 +2,22 @@ package cn.iocoder.yudao.framework.web.config;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.web.core.clean.JsoupXssCleaner;
import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter;
import cn.iocoder.yudao.framework.web.core.filter.DemoFilter;
import cn.iocoder.yudao.framework.web.core.filter.XssFilter;
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler;
import cn.iocoder.yudao.framework.web.core.json.XssStringJsonDeserializer;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
@ -48,7 +55,7 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
* 设置 API 前缀仅仅匹配 controller 包下的
*
* @param configurer 配置
* @param api API 配置
* @param api API 配置
*/
private void configurePathMatch(PathMatchConfigurer configurer, WebProperties.Api api) {
AntPathMatcher antPathMatcher = new AntPathMatcher(".");
@ -104,8 +111,9 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
* 创建 XssFilter Bean解决 Xss 安全问题
*/
@Bean
public FilterRegistrationBean<XssFilter> xssFilter(XssProperties properties, PathMatcher pathMatcher) {
return createFilterBean(new XssFilter(properties, pathMatcher), WebFilterOrderEnum.XSS_FILTER);
@ConditionalOnBean(XssCleaner.class)
public FilterRegistrationBean<XssFilter> xssFilter(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) {
return createFilterBean(new XssFilter(properties, pathMatcher, xssCleaner), WebFilterOrderEnum.XSS_FILTER);
}
/**
@ -117,6 +125,32 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER);
}
/**
* Xss 清理者
*
* @return XssCleaner
*/
@Bean
@ConditionalOnMissingBean(XssCleaner.class)
public XssCleaner xssCleaner() {
return new JsoupXssCleaner();
}
/**
* 注册 Jackson 的序列化器用于处理 json 类型参数的 xss 过滤
*
* @return Jackson2ObjectMapperBuilderCustomizer
*/
@Bean
@ConditionalOnMissingBean(name = "xssJacksonCustomizer")
@ConditionalOnBean(ObjectMapper.class)
@ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) {
// 在反序列化时进行 xss 过滤可以替换使用 XssStringJsonSerializer在序列化时进行处理
return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner));
}
private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
bean.setOrder(order);

View File

@ -0,0 +1,80 @@
package cn.iocoder.yudao.framework.web.core.clean;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Safelist;
/**
* jsonp 过滤字符串
*/
public class JsoupXssCleaner implements XssCleaner {
private final Safelist safelist;
/**
* 用于在 src 属性使用相对路径时强制转换为绝对路径 为空时不处理值应为绝对路径的前缀包含协议部分
*/
private final String baseUri;
/**
* 无参构造默认使用 {@link JsoupXssCleaner#buildSafelist} 方法构建一个安全列表
*/
public JsoupXssCleaner() {
this.safelist = buildSafelist();
this.baseUri = "";
}
public JsoupXssCleaner(Safelist safelist) {
this.safelist = safelist;
this.baseUri = "";
}
public JsoupXssCleaner(String baseUri) {
this.safelist = buildSafelist();
this.baseUri = baseUri;
}
public JsoupXssCleaner(Safelist safelist, String baseUri) {
this.safelist = safelist;
this.baseUri = baseUri;
}
/**
* 构建一个 Xss 清理的 Safelist 规则
* 基于 Safelist#relaxed() 的基础上:
* 1. 扩展支持了 style class 属性
* 2. a 标签额外支持了 target 属性
* 3. img 标签额外支持了 data 协议便于支持 base64
*
* @return Safelist
*/
private Safelist buildSafelist() {
// 使用 jsoup 提供的默认的
Safelist relaxedSafelist = Safelist.relaxed();
// 富文本编辑时一些样式是使用 style 来进行实现的
// 比如红色字体 style="color:red;", 所以需要给所有标签添加 style 属性
// 注意style 属性会有注入风险 <img STYLE="background-image:url(javascript:alert('XSS'))">
relaxedSafelist.addAttributes(":all", "style", "class");
// 保留 a 标签的 target 属性
relaxedSafelist.addAttributes("a", "target");
// 支持img 为base64
relaxedSafelist.addProtocols("img", "src", "data");
// 保留相对路径, 保留相对路径时必须提供对应的 baseUri 属性否则依然会被删除
// WHITELIST.preserveRelativeLinks(false);
// 移除 a 标签和 img 标签的一些协议限制这会导致 xss 防注入失效 <img src=javascript:alert("xss")>
// 虽然可以重写 WhiteList#isSafeAttribute 来处理但是有隐患所以暂时不支持相对路径
// WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto");
// WHITELIST.removeProtocols("img", "src", "http", "https");
return relaxedSafelist;
}
@Override
public String clean(String html) {
return Jsoup.clean(html, baseUri, safelist, new Document.OutputSettings().prettyPrint(false));
}
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.framework.web.core.clean;
/**
* html 文本中的有 Xss 风险的数据进行清理
*/
public interface XssCleaner {
/**
* 清理有 Xss 风险的文本
*
* @param html html
* @return 清理后的 html
*/
String clean(String html);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.framework.web.core.filter;
import cn.iocoder.yudao.framework.web.config.XssProperties;
import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
import lombok.AllArgsConstructor;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
@ -13,7 +14,7 @@ import java.io.IOException;
/**
* Xss 过滤器
*
* <p>
* Xss 不了解的胖友可以看看 http://www.iocoder.cn/Fight/The-new-girl-asked-me-why-AJAX-requests-are-not-secure-I-did-not-answer/
*
* @author 芋道源码
@ -30,10 +31,12 @@ public class XssFilter extends OncePerRequestFilter {
*/
private final PathMatcher pathMatcher;
private final XssCleaner xssCleaner;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
filterChain.doFilter(new XssRequestWrapper(request), response);
filterChain.doFilter(new XssRequestWrapper(request, xssCleaner), response);
}
@Override

View File

@ -1,21 +1,10 @@
package cn.iocoder.yudao.framework.web.core.filter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HTMLFilter;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedHashMap;
import java.util.Map;
/**
@ -24,113 +13,79 @@ import java.util.Map;
* @author 芋道源码
*/
public class XssRequestWrapper extends HttpServletRequestWrapper {
private final XssCleaner xssCleaner;
/**
* 基于线程级别的 HTMLFilter 对象因为它线程非安全
*/
private static final ThreadLocal<HTMLFilter> HTML_FILTER = ThreadLocal.withInitial(() -> {
HTMLFilter htmlFilter = new HTMLFilter();
// 反射修改 encodeQuotes 属性为 false避免 " 被转移成 &quot; 字符
ReflectUtil.setFieldValue(htmlFilter, "encodeQuotes", false);
return htmlFilter;
});
public XssRequestWrapper(HttpServletRequest request) {
public XssRequestWrapper(HttpServletRequest request, XssCleaner xssCleaner) {
super(request);
this.xssCleaner = xssCleaner;
}
private static String filterXss(String content) {
if (StrUtil.isEmpty(content)) {
return content;
// ============================ parameter ============================
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = new LinkedHashMap<>();
Map<String, String[]> parameters = super.getParameterMap();
for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
String[] values = entry.getValue();
for (int i = 0; i < values.length; i++) {
values[i] = xssCleaner.clean(values[i]);
}
map.put(entry.getKey(), values);
}
return HTML_FILTER.get().filter(content);
}
// ========== IO 流相关 ==========
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
// 如果非 json 请求不进行 Xss 处理
if (!ServletUtils.isJsonRequest(this)) {
return super.getInputStream();
}
// 读取内容并过滤
String content = IoUtil.readUtf8(super.getInputStream());
content = filterXss(content);
final ByteArrayInputStream newInputStream = new ByteArrayInputStream(content.getBytes());
// 返回 ServletInputStream
return new ServletInputStream() {
@Override
public int read() {
return newInputStream.read();
}
@Override
public boolean isFinished() {
return true;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {}
};
}
// ========== Param 相关 ==========
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return filterXss(value);
return map;
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (ArrayUtil.isEmpty(values)) {
return values;
if (values == null) {
return null;
}
// 过滤处理
for (int i = 0; i < values.length; i++) {
values[i] = filterXss(values[i]);
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = xssCleaner.clean(values[i]);
}
return values;
return encodedValues;
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> valueMap = super.getParameterMap();
if (CollUtil.isEmpty(valueMap)) {
return valueMap;
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) {
return null;
}
// 过滤处理
for (Map.Entry<String, String[]> entry : valueMap.entrySet()) {
String[] values = entry.getValue();
for (int i = 0; i < values.length; i++) {
values[i] = filterXss(values[i]);
}
}
return valueMap;
return xssCleaner.clean(value);
}
// ========== Header 相关 ==========
// ============================ attribute ============================
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (value instanceof String) {
xssCleaner.clean((String) value);
}
return value;
}
// ============================ header ============================
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return filterXss(value);
if (value == null) {
return null;
}
return xssCleaner.clean(value);
}
// ============================ queryString ============================
@Override
public String getQueryString() {
String value = super.getQueryString();
if (value == null) {
return null;
}
return xssCleaner.clean(value);
}
}

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.framework.web.core.json;
import cn.iocoder.yudao.framework.web.core.clean.XssCleaner;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
/**
* XSS 过滤 jackson 反序列化器
* 在反序列化的过程中会对字符串进行 XSS 过滤
*
* @author Hccake
*/
@Slf4j
@AllArgsConstructor
public class XssStringJsonDeserializer extends StringDeserializer {
private final XssCleaner xssCleaner;
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
if (p.hasToken(JsonToken.VALUE_STRING)) {
return xssCleaner.clean(p.getText());
}
JsonToken t = p.currentToken();
// [databind#381]
if (t == JsonToken.START_ARRAY) {
return _deserializeFromArray(p, ctxt);
}
// need to gracefully handle byte[] data, as base64
if (t == JsonToken.VALUE_EMBEDDED_OBJECT) {
Object ob = p.getEmbeddedObject();
if (ob == null) {
return null;
}
if (ob instanceof byte[]) {
return ctxt.getBase64Variant().encode((byte[]) ob, false);
}
// otherwise, try conversion using toString()...
return ob.toString();
}
// 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML)
if (t == JsonToken.START_OBJECT) {
return ctxt.extractScalarFromObject(p, this, _valueClass);
}
if (t.isScalarValue()) {
String text = p.getValueAsString();
return xssCleaner.clean(text);
}
return (String) ctxt.handleUnexpectedToken(_valueClass, p);
}
}

View File

@ -11,9 +11,11 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
import java.util.List;
@ -37,7 +39,7 @@ public interface CodegenConvert {
@Mappings({
@Mapping(source = "name", target = "columnName"),
@Mapping(source = "type", target = "dataType"),
@Mapping(source = "columnType", target = "dataType", qualifiedByName = "getType"),
@Mapping(source = "comment", target = "columnComment"),
@Mapping(source = "metaInfo.nullable", target = "nullable"),
@Mapping(source = "keyFlag", target = "primaryKey"),
@ -47,6 +49,11 @@ public interface CodegenConvert {
})
CodegenColumnDO convert(TableField bean);
@Named("getType")
default String getType(IColumnType jdbcType) {
return jdbcType.getType();
}
// ========== CodegenTableDO 相关 ==========
// List<CodegenTableRespVO> convertList02(List<CodegenTableDO> list);

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnu
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@ -42,6 +43,7 @@ public class CodegenColumnDO extends BaseDO {
private String columnName;
/**
* 字段类型
* 关联 {@link TableField#getColumnType()}}
*/
private String dataType;
/**

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.service;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.generator.IDatabaseQuery.DefaultDatabaseQuery;
import com.baomidou.mybatisplus.generator.query.DefaultQuery;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
@ -19,7 +19,7 @@ public class DefaultDatabaseQueryTest {
ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, null, null, null, null);
DefaultDatabaseQuery query = new DefaultDatabaseQuery(builder);
DefaultQuery query = new DefaultQuery(builder);
long time = System.currentTimeMillis();
List<TableInfo> tableInfos = query.queryTables();

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.visualization.framework.jmreport.config;
import cn.iocoder.yudao.framework.security.config.SecurityProperties;
import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
import cn.iocoder.yudao.module.visualization.framework.jmreport.core.service.JmReportTokenServiceImpl;
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
@ -18,8 +19,8 @@ public class JmReportConfiguration {
@Bean
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public JmReportTokenServiceI jmReportTokenService(OAuth2TokenApi oAuth2TokenApi) {
return new JmReportTokenServiceImpl(oAuth2TokenApi);
public JmReportTokenServiceI jmReportTokenService(OAuth2TokenApi oAuth2TokenApi, SecurityProperties securityProperties) {
return new JmReportTokenServiceImpl(oAuth2TokenApi, securityProperties);
}
}

View File

@ -1,7 +1,10 @@
package cn.iocoder.yudao.module.visualization.framework.jmreport.core.service;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.security.config.SecurityProperties;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
@ -10,6 +13,10 @@ import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
import lombok.RequiredArgsConstructor;
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
import org.springframework.http.HttpHeaders;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
/**
* {@link JmReportTokenServiceI} 实现类提供积木报表的 Token 校验用户信息的查询等功能
@ -19,8 +26,37 @@ import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
@RequiredArgsConstructor
public class JmReportTokenServiceImpl implements JmReportTokenServiceI {
/**
* 积木 token head
*/
private static final String JM_TOKEN_HEADER = "X-Access-Token";
/**
* auth 相关格式
*/
private static final String AUTHORIZATION_FORMAT = SecurityFrameworkUtils.AUTHORIZATION_BEARER + " %s";
private final OAuth2TokenApi oauth2TokenApi;
private final SecurityProperties securityProperties;
/**
* 自定义 API 数据集appian自定义 Header解决 Token 传递
* 参考 <a href="http://report.jeecg.com/2222224">api数据集token机制详解</a> 文档
*
* @return head
*/
@Override
public HttpHeaders customApiHeader() {
// 读取积木标标系统的 token
HttpServletRequest request = ServletUtils.getRequest();
String token = request.getHeader(JM_TOKEN_HEADER);
// 设置到 yudao 系统的 token
HttpHeaders headers = new HttpHeaders();
headers.add(securityProperties.getTokenHeader(), String.format(AUTHORIZATION_FORMAT, token));
return headers;
}
/**
* 校验 Token 是否有效即验证通过
*
@ -29,8 +65,40 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI {
*/
@Override
public Boolean verifyToken(String token) {
Long userId = SecurityFrameworkUtils.getLoginUserId();
if (!Objects.isNull(userId)) {
return true;
}
return buildLoginUserByToken(token) != null;
}
/**
* 获得用户编号
* <p>
* 虽然方法名获得的是 username实际对应到项目中是用户编号
*
* @param token JmReport 前端传递的 token
* @return 用户编号
*/
@Override
public String getUsername(String token) {
Long userId = SecurityFrameworkUtils.getLoginUserId();
if (ObjectUtil.isNotNull(userId)) {
return String.valueOf(userId);
}
LoginUser user = buildLoginUserByToken(token);
return user == null ? null : String.valueOf(user.getId());
}
/**
* 基于 token 构建登录用户
*
* @param token token
* @return 返回 token 对应的用户信息
*/
private LoginUser buildLoginUserByToken(String token) {
if (StrUtil.isEmpty(token)) {
return false;
return null;
}
// TODO 如下的实现不算特别优雅主要咱是不想搞的太复杂所以参考对应的 Filter 先实现了
@ -41,7 +109,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI {
try {
OAuth2AccessTokenCheckRespDTO accessToken = oauth2TokenApi.checkAccessToken(token);
if (accessToken == null) {
return false;
return null;
}
user = new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType())
.setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes());
@ -49,7 +117,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI {
// do nothing如果报错说明认证失败则返回 false 即可
}
if (user == null) {
return false;
return null;
}
SecurityFrameworkUtils.setLoginUser(user, WebFrameworkUtils.getRequest());
@ -57,21 +125,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI {
// 目的基于 LoginUser 获得到的租户编号设置到 Tenant 上下文避免查询数据库时的报错
TenantContextHolder.setIgnore(false);
TenantContextHolder.setTenantId(user.getTenantId());
return true;
}
/**
* 获得用户编号
*
* 虽然方法名获得的是 username实际对应到项目中是用户编号
*
* @param token JmReport 前端传递的 token
* @return 用户编号
*/
@Override
public String getUsername(String token) {
Long userId = SecurityFrameworkUtils.getLoginUserId();
return userId != null ? String.valueOf(userId) : null;
return user;
}
}

View File

@ -34,7 +34,7 @@
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.9.4 |
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.28 |
| [vueuse](https://vueuse.org/) | 常用工具集 | 9.10.0 |
| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.7 |
| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.9 |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.6 |
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |

View File

@ -1,6 +1,6 @@
{
"name": "yudao-ui-admin-vue3",
"version": "1.6.6-snapshot.1901",
"version": "1.6.6-snapshot.1911",
"description": "基于vue3、vite4、element-plus、typesScript",
"author": "xingyu",
"private": false,
@ -50,14 +50,14 @@
"vue-i18n": "9.2.2",
"vue-router": "^4.1.6",
"vue-types": "^5.0.2",
"vxe-table": "^4.3.7",
"vxe-table": "^4.3.9",
"web-storage-cache": "^1.1.1",
"xe-utils": "^3.5.7"
},
"devDependencies": {
"@commitlint/cli": "^17.4.0",
"@commitlint/cli": "^17.4.1",
"@commitlint/config-conventional": "^17.4.0",
"@iconify/json": "^2.2.2",
"@iconify/json": "^2.2.5",
"@intlify/unplugin-vue-i18n": "^0.8.1",
"@purge-icons/generated": "^0.9.0",
"@types/intro.js": "^5.1.0",
@ -66,8 +66,8 @@
"@types/nprogress": "^0.2.0",
"@types/qrcode": "^1.5.0",
"@types/qs": "^6.9.7",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"@typescript-eslint/parser": "^5.48.0",
"@typescript-eslint/eslint-plugin": "^5.48.1",
"@typescript-eslint/parser": "^5.48.1",
"@vitejs/plugin-legacy": "^3.0.1",
"@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0",
@ -75,14 +75,14 @@
"consola": "^2.15.3",
"eslint": "^8.31.0",
"eslint-config-prettier": "^8.6.0",
"eslint-define-config": "^1.13.0",
"eslint-define-config": "^1.14.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.8.0",
"lint-staged": "^13.1.0",
"postcss": "^8.4.20",
"postcss": "^8.4.21",
"postcss-html": "^1.5.0",
"postcss-scss": "^4.0.6",
"prettier": "^2.8.1",
"prettier": "^2.8.2",
"rimraf": "^3.0.2",
"rollup": "^3.9.1",
"sass": "^1.57.1",
@ -91,7 +91,7 @@
"stylelint-config-prettier": "^9.0.4",
"stylelint-config-recommended": "^9.0.0",
"stylelint-config-standard": "^29.0.0",
"stylelint-order": "^5.0.0",
"stylelint-order": "^6.0.1",
"terser": "^5.16.1",
"typescript": "4.9.4",
"vite": "4.0.4",
@ -104,7 +104,7 @@
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vite-plugin-windicss": "^1.8.10",
"vue-tsc": "^1.0.22",
"vue-tsc": "^1.0.24",
"windicss": "^3.5.6"
},
"engines": {

View File

@ -1,10 +1,10 @@
lockfileVersion: 5.4
specifiers:
'@commitlint/cli': ^17.4.0
'@commitlint/cli': ^17.4.1
'@commitlint/config-conventional': ^17.4.0
'@iconify/iconify': ^3.0.1
'@iconify/json': ^2.2.2
'@iconify/json': ^2.2.5
'@intlify/unplugin-vue-i18n': ^0.8.1
'@purge-icons/generated': ^0.9.0
'@types/intro.js': ^5.1.0
@ -13,8 +13,8 @@ specifiers:
'@types/nprogress': ^0.2.0
'@types/qrcode': ^1.5.0
'@types/qs': ^6.9.7
'@typescript-eslint/eslint-plugin': ^5.48.0
'@typescript-eslint/parser': ^5.48.0
'@typescript-eslint/eslint-plugin': ^5.48.1
'@typescript-eslint/parser': ^5.48.1
'@vitejs/plugin-legacy': ^3.0.1
'@vitejs/plugin-vue': ^4.0.0
'@vitejs/plugin-vue-jsx': ^3.0.0
@ -34,7 +34,7 @@ specifiers:
element-plus: 2.2.28
eslint: ^8.31.0
eslint-config-prettier: ^8.6.0
eslint-define-config: ^1.13.0
eslint-define-config: ^1.14.0
eslint-plugin-prettier: ^4.2.1
eslint-plugin-vue: ^9.8.0
intro.js: ^6.0.0
@ -44,10 +44,10 @@ specifiers:
mitt: ^3.0.0
nprogress: ^0.2.0
pinia: ^2.0.28
postcss: ^8.4.20
postcss: ^8.4.21
postcss-html: ^1.5.0
postcss-scss: ^4.0.6
prettier: ^2.8.1
prettier: ^2.8.2
qrcode: ^1.5.1
qs: ^6.11.0
rimraf: ^3.0.2
@ -58,7 +58,7 @@ specifiers:
stylelint-config-prettier: ^9.0.4
stylelint-config-recommended: ^9.0.0
stylelint-config-standard: ^29.0.0
stylelint-order: ^5.0.0
stylelint-order: ^6.0.1
terser: ^5.16.1
typescript: 4.9.4
url: ^0.11.0
@ -75,9 +75,9 @@ specifiers:
vue: 3.2.45
vue-i18n: 9.2.2
vue-router: ^4.1.6
vue-tsc: ^1.0.22
vue-tsc: ^1.0.24
vue-types: ^5.0.2
vxe-table: ^4.3.7
vxe-table: ^4.3.9
web-storage-cache: ^1.1.1
windicss: ^3.5.6
xe-utils: ^3.5.7
@ -109,14 +109,14 @@ dependencies:
vue-i18n: 9.2.2_vue@3.2.45
vue-router: 4.1.6_vue@3.2.45
vue-types: 5.0.2_vue@3.2.45
vxe-table: 4.3.7_vue@3.2.45+xe-utils@3.5.7
vxe-table: 4.3.9_vue@3.2.45+xe-utils@3.5.7
web-storage-cache: 1.1.1
xe-utils: 3.5.7
devDependencies:
'@commitlint/cli': 17.4.0_@types+node@18.11.18
'@commitlint/cli': 17.4.1
'@commitlint/config-conventional': 17.4.0
'@iconify/json': 2.2.2
'@iconify/json': 2.2.5
'@intlify/unplugin-vue-i18n': 0.8.1_vue-i18n@9.2.2
'@purge-icons/generated': 0.9.0
'@types/intro.js': 5.1.0
@ -125,23 +125,23 @@ devDependencies:
'@types/nprogress': 0.2.0
'@types/qrcode': 1.5.0
'@types/qs': 6.9.7
'@typescript-eslint/eslint-plugin': 5.48.0_k73wpmdolxikpyqun3p36akaaq
'@typescript-eslint/parser': 5.48.0_iukboom6ndih5an6iafl45j2fe
'@typescript-eslint/eslint-plugin': 5.48.1_3jon24igvnqaqexgwtxk6nkpse
'@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe
'@vitejs/plugin-legacy': 3.0.1_terser@5.16.1+vite@4.0.4
'@vitejs/plugin-vue': 4.0.0_vite@4.0.4+vue@3.2.45
'@vitejs/plugin-vue-jsx': 3.0.0_vite@4.0.4+vue@3.2.45
autoprefixer: 10.4.13_postcss@8.4.20
autoprefixer: 10.4.13_postcss@8.4.21
consola: 2.15.3
eslint: 8.31.0
eslint-config-prettier: 8.6.0_eslint@8.31.0
eslint-define-config: 1.13.0
eslint-plugin-prettier: 4.2.1_32m5uc2milwdw3tnkcq5del26y
eslint-define-config: 1.14.0
eslint-plugin-prettier: 4.2.1_iu5s7nk6dw7o3tajefwfiqfmge
eslint-plugin-vue: 9.8.0_eslint@8.31.0
lint-staged: 13.1.0
postcss: 8.4.20
postcss: 8.4.21
postcss-html: 1.5.0
postcss-scss: 4.0.6_postcss@8.4.20
prettier: 2.8.1
postcss-scss: 4.0.6_postcss@8.4.21
prettier: 2.8.2
rimraf: 3.0.2
rollup: 3.9.1
sass: 1.57.1
@ -150,7 +150,7 @@ devDependencies:
stylelint-config-prettier: 9.0.4_stylelint@14.16.1
stylelint-config-recommended: 9.0.0_stylelint@14.16.1
stylelint-config-standard: 29.0.0_stylelint@14.16.1
stylelint-order: 5.0.0_stylelint@14.16.1
stylelint-order: 6.0.1_stylelint@14.16.1
terser: 5.16.1
typescript: 4.9.4
vite: 4.0.4_zxbrnrc4iyldik6mikh3pswz4i
@ -163,7 +163,7 @@ devDependencies:
vite-plugin-svg-icons: 2.0.1_vite@4.0.4
vite-plugin-vue-setup-extend: 0.4.0_vite@4.0.4
vite-plugin-windicss: 1.8.10_vite@4.0.4
vue-tsc: 1.0.22_typescript@4.9.4
vue-tsc: 1.0.24_typescript@4.9.4
windicss: 3.5.6
packages:
@ -506,14 +506,14 @@ packages:
'@babel/helper-validator-identifier': 7.19.1
to-fast-properties: 2.0.0
/@commitlint/cli/17.4.0_@types+node@18.11.18:
resolution: {integrity: sha512-SEY4sYe8yVlgxPP7X0wJb96DBAGBPsCsy6QbqJt/UECbIAjDeDV5xXBV4jnS7T/qMC10sk6Ub9kDhEX0VWvblw==}
/@commitlint/cli/17.4.1:
resolution: {integrity: sha512-W8OJwz+izY+fVwyUt1HveCDmABMZNRVZHSVPw/Bh9Y62tp11SmmQaycgbsYLMiMy7JGn4mAJqEGlSHS9Uti9ZQ==}
engines: {node: '>=v14'}
hasBin: true
dependencies:
'@commitlint/format': 17.4.0
'@commitlint/lint': 17.4.0
'@commitlint/load': 17.4.0_@types+node@18.11.18
'@commitlint/load': 17.4.1
'@commitlint/read': 17.4.0
'@commitlint/types': 17.4.0
execa: 5.1.1
@ -524,7 +524,6 @@ packages:
transitivePeerDependencies:
- '@swc/core'
- '@swc/wasm'
- '@types/node'
dev: true
/@commitlint/config-conventional/17.4.0:
@ -585,14 +584,15 @@ packages:
'@commitlint/types': 17.4.0
dev: true
/@commitlint/load/17.4.0_@types+node@18.11.18:
resolution: {integrity: sha512-wDKNvAJqukqZqKmhRlf3KNo/12QGo1AQcd80EbV01SxtGvyHOsJ/g+/IbrZpopZv8rvzmEVktcpfDYH6ITepFA==}
/@commitlint/load/17.4.1:
resolution: {integrity: sha512-6A7/LhIaQpL4ieciIDcVvK2d5z/UI1GBrtDaHm6sQSCL0265clB2/F7XKQNTJHXv9yG4LByT2r+QCpM4GugIfw==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/config-validator': 17.4.0
'@commitlint/execute-rule': 17.4.0
'@commitlint/resolve-extends': 17.4.0
'@commitlint/types': 17.4.0
'@types/node': 18.11.18
chalk: 4.1.2
cosmiconfig: 8.0.0
cosmiconfig-typescript-loader: 4.2.0_bxtyj3et3xbsdyxhh3oblnfbj4
@ -605,7 +605,6 @@ packages:
transitivePeerDependencies:
- '@swc/core'
- '@swc/wasm'
- '@types/node'
dev: true
/@commitlint/message/17.4.0:
@ -682,14 +681,14 @@ packages:
'@jridgewell/trace-mapping': 0.3.9
dev: true
/@csstools/selector-specificity/2.0.2_2xshye3abirqjlplmebvmaxyna:
/@csstools/selector-specificity/2.0.2_wajs5nedgkikc5pcuwett7legi:
resolution: {integrity: sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==}
engines: {node: ^12 || ^14 || >=16}
peerDependencies:
postcss: ^8.2
postcss-selector-parser: ^6.0.10
dependencies:
postcss: 8.4.20
postcss: 8.4.21
postcss-selector-parser: 6.0.11
dev: true
@ -964,8 +963,8 @@ packages:
dependencies:
'@iconify/types': 2.0.0
/@iconify/json/2.2.2:
resolution: {integrity: sha512-G9HVJz3uvQGNEirk9oI7xYnWb7ygEfTUZ+PVp81qgNp8bu5UOtXaxjTGw78NyNAC2OlryH5tSEp95Dqbt4LLQQ==}
/@iconify/json/2.2.5:
resolution: {integrity: sha512-AIbJTRF9HJz7FJ8t7058huwDXHaFEY4a4f6uuPtctEQ8/I3ybrX66iZMgoLD1kLaamU4tzZPlZ6tSpA3pM8LZg==}
dependencies:
'@iconify/types': 2.0.0
pathe: 1.0.0
@ -986,8 +985,8 @@ packages:
vue-i18n:
optional: true
dependencies:
'@intlify/message-compiler': 9.3.0-beta.12
'@intlify/shared': 9.3.0-beta.12
'@intlify/message-compiler': 9.3.0-beta.14
'@intlify/shared': 9.3.0-beta.14
jsonc-eslint-parser: 1.4.1
source-map: 0.6.1
vue-i18n: 9.2.2_vue@3.2.45
@ -1016,11 +1015,11 @@ packages:
'@intlify/shared': 9.2.2
source-map: 0.6.1
/@intlify/message-compiler/9.3.0-beta.12:
resolution: {integrity: sha512-A8/s7pb3v8nf6HG77qFPJntxgQKI9GXxGnkn7aO+b03/X/GkF/4WceDSAIk3i+yLeIgszeBn9GZ23tSg4sTEHA==}
/@intlify/message-compiler/9.3.0-beta.14:
resolution: {integrity: sha512-PlZ3pl+YYuql54Nq+26wv6ohIa8Ig6ALrvQI+f2zZKUtkupb49M4wyVN3bDQbFlgYVE7/u3n19BJSY8lEuX5Eg==}
engines: {node: '>= 14'}
dependencies:
'@intlify/shared': 9.3.0-beta.11
'@intlify/shared': 9.3.0-beta.14
source-map: 0.6.1
dev: true
@ -1028,13 +1027,8 @@ packages:
resolution: {integrity: sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==}
engines: {node: '>= 14'}
/@intlify/shared/9.3.0-beta.11:
resolution: {integrity: sha512-CtbotesxTRiC3bRyXyv1NG39fkqJ790f8z8xFaeIXSZpOdiyxoh5BIyypCzSFQZDGLwz0Q9gyWbW1XpxQJm68Q==}
engines: {node: '>= 14'}
dev: true
/@intlify/shared/9.3.0-beta.12:
resolution: {integrity: sha512-WsmaS54sA8xuwezPKpa/OMoaX1v2VF2fCgAmYS6prDr2ir0CkUFWPm9A8ilmxzv4nkS61/v8+vf4lGGkn5uBdA==}
/@intlify/shared/9.3.0-beta.14:
resolution: {integrity: sha512-mJ/rFan+4uVsBAQSCAJnpQaPvSjQ49mJMNmGelTUbTDAmgf0oexYxwqtKOlFFyY3hmQ8lUDYaGQKuYrFgRuHnA==}
engines: {node: '>= 14'}
dev: true
@ -1054,7 +1048,7 @@ packages:
optional: true
dependencies:
'@intlify/bundle-utils': 3.4.0_vue-i18n@9.2.2
'@intlify/shared': 9.3.0-beta.12
'@intlify/shared': 9.3.0-beta.14
'@rollup/pluginutils': 4.2.1
'@vue/compiler-sfc': 3.2.45
debug: 4.3.4
@ -1285,8 +1279,8 @@ packages:
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
dev: false
/@typescript-eslint/eslint-plugin/5.48.0_k73wpmdolxikpyqun3p36akaaq:
resolution: {integrity: sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ==}
/@typescript-eslint/eslint-plugin/5.48.1_3jon24igvnqaqexgwtxk6nkpse:
resolution: {integrity: sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
'@typescript-eslint/parser': ^5.0.0
@ -1296,10 +1290,10 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/parser': 5.48.0_iukboom6ndih5an6iafl45j2fe
'@typescript-eslint/scope-manager': 5.48.0
'@typescript-eslint/type-utils': 5.48.0_iukboom6ndih5an6iafl45j2fe
'@typescript-eslint/utils': 5.48.0_iukboom6ndih5an6iafl45j2fe
'@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe
'@typescript-eslint/scope-manager': 5.48.1
'@typescript-eslint/type-utils': 5.48.1_iukboom6ndih5an6iafl45j2fe
'@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe
debug: 4.3.4
eslint: 8.31.0
ignore: 5.2.1
@ -1312,8 +1306,8 @@ packages:
- supports-color
dev: true
/@typescript-eslint/parser/5.48.0_iukboom6ndih5an6iafl45j2fe:
resolution: {integrity: sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==}
/@typescript-eslint/parser/5.48.1_iukboom6ndih5an6iafl45j2fe:
resolution: {integrity: sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@ -1322,9 +1316,9 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 5.48.0
'@typescript-eslint/types': 5.48.0
'@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.4
'@typescript-eslint/scope-manager': 5.48.1
'@typescript-eslint/types': 5.48.1
'@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
debug: 4.3.4
eslint: 8.31.0
typescript: 4.9.4
@ -1332,16 +1326,16 @@ packages:
- supports-color
dev: true
/@typescript-eslint/scope-manager/5.48.0:
resolution: {integrity: sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==}
/@typescript-eslint/scope-manager/5.48.1:
resolution: {integrity: sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.48.0
'@typescript-eslint/visitor-keys': 5.48.0
'@typescript-eslint/types': 5.48.1
'@typescript-eslint/visitor-keys': 5.48.1
dev: true
/@typescript-eslint/type-utils/5.48.0_iukboom6ndih5an6iafl45j2fe:
resolution: {integrity: sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g==}
/@typescript-eslint/type-utils/5.48.1_iukboom6ndih5an6iafl45j2fe:
resolution: {integrity: sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '*'
@ -1350,8 +1344,8 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.4
'@typescript-eslint/utils': 5.48.0_iukboom6ndih5an6iafl45j2fe
'@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
'@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe
debug: 4.3.4
eslint: 8.31.0
tsutils: 3.21.0_typescript@4.9.4
@ -1360,13 +1354,13 @@ packages:
- supports-color
dev: true
/@typescript-eslint/types/5.48.0:
resolution: {integrity: sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==}
/@typescript-eslint/types/5.48.1:
resolution: {integrity: sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@typescript-eslint/typescript-estree/5.48.0_typescript@4.9.4:
resolution: {integrity: sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==}
/@typescript-eslint/typescript-estree/5.48.1_typescript@4.9.4:
resolution: {integrity: sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
typescript: '*'
@ -1374,8 +1368,8 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 5.48.0
'@typescript-eslint/visitor-keys': 5.48.0
'@typescript-eslint/types': 5.48.1
'@typescript-eslint/visitor-keys': 5.48.1
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
@ -1386,17 +1380,17 @@ packages:
- supports-color
dev: true
/@typescript-eslint/utils/5.48.0_iukboom6ndih5an6iafl45j2fe:
resolution: {integrity: sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ==}
/@typescript-eslint/utils/5.48.1_iukboom6ndih5an6iafl45j2fe:
resolution: {integrity: sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
'@types/json-schema': 7.0.11
'@types/semver': 7.3.13
'@typescript-eslint/scope-manager': 5.48.0
'@typescript-eslint/types': 5.48.0
'@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.4
'@typescript-eslint/scope-manager': 5.48.1
'@typescript-eslint/types': 5.48.1
'@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4
eslint: 8.31.0
eslint-scope: 5.1.1
eslint-utils: 3.0.0_eslint@8.31.0
@ -1406,11 +1400,11 @@ packages:
- typescript
dev: true
/@typescript-eslint/visitor-keys/5.48.0:
resolution: {integrity: sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==}
/@typescript-eslint/visitor-keys/5.48.1:
resolution: {integrity: sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.48.0
'@typescript-eslint/types': 5.48.1
eslint-visitor-keys: 3.3.0
dev: true
@ -1498,30 +1492,30 @@ packages:
vue: 3.2.45
dev: true
/@volar/language-core/1.0.22:
resolution: {integrity: sha512-hiJeCOqxNdtG/04FRGLGI9H9DVz2l6cTqPDBzwqplHXAWfMxjzUaGUrn9sfTG7YMFNZUgK4EYxJnRfhqdtbSFQ==}
/@volar/language-core/1.0.24:
resolution: {integrity: sha512-vTN+alJiWwK0Pax6POqrmevbtFW2dXhjwWiW/MW4f48eDYPLdyURWcr8TixO7EN/nHsUBj2udT7igFKPtjyAKg==}
dependencies:
'@volar/source-map': 1.0.22
'@volar/source-map': 1.0.24
muggle-string: 0.1.0
dev: true
/@volar/source-map/1.0.22:
resolution: {integrity: sha512-cv4gypHSP4MWVR82ed/+1IpI6794qAl0Q0+KJ+VGMVF8rVugsiF9QbyMCgjel9wNRsssQsazzsf6txOR9vHQiw==}
/@volar/source-map/1.0.24:
resolution: {integrity: sha512-Qsv/tkplx18pgBr8lKAbM1vcDqgkGKQzbChg6NW+v0CZc3G7FLmK+WrqEPzKlN7Cwdc6XVL559Nod8WKAfKr4A==}
dependencies:
muggle-string: 0.1.0
dev: true
/@volar/typescript/1.0.22:
resolution: {integrity: sha512-VPyEicealSD4gqlE5/UQ1j3ietsO6Hfat40KtUEh/K+XEZ7h02b1KgFV64YEuBkBOaZ5hgvRW/WXKtQgXCl7Iw==}
/@volar/typescript/1.0.24:
resolution: {integrity: sha512-f8hCSk+PfKR1/RQHxZ79V1NpDImHoivqoizK+mstphm25tn/YJ/JnKNjZHB+o21fuW0yKlI26NV3jkVb2Cc/7A==}
dependencies:
'@volar/language-core': 1.0.22
'@volar/language-core': 1.0.24
dev: true
/@volar/vue-language-core/1.0.22:
resolution: {integrity: sha512-Ki0G/ZdBj2/GLw+/VVH3n9XR/JL6krMIth02EekFn6JV4PGN3mNxbvoh6lOPSDZLR6biOU5nJPnnjpKy8nuXhw==}
/@volar/vue-language-core/1.0.24:
resolution: {integrity: sha512-2NTJzSgrwKu6uYwPqLiTMuAzi7fAY3yFy5PJ255bGJc82If0Xr+cW8pC80vpjG0D/aVLmlwAdO4+Ya2BI8GdDg==}
dependencies:
'@volar/language-core': 1.0.22
'@volar/source-map': 1.0.22
'@volar/language-core': 1.0.24
'@volar/source-map': 1.0.24
'@vue/compiler-dom': 3.2.45
'@vue/compiler-sfc': 3.2.45
'@vue/reactivity': 3.2.45
@ -1530,11 +1524,11 @@ packages:
vue-template-compiler: 2.7.14
dev: true
/@volar/vue-typescript/1.0.22:
resolution: {integrity: sha512-2T1o5z86PAev31OMtVOv/qp4P3ZVl9ln/2KTmykQE8Fh4A5F+868MW4nf5J7XQ6RNyx7RH9LhzgjvbqJpAfiYw==}
/@volar/vue-typescript/1.0.24:
resolution: {integrity: sha512-9a25oHDvGaNC0okRS47uqJI6FxY4hUQZUsxeOUFHcqVxZEv8s17LPuP/pMMXyz7jPygrZubB/qXqHY5jEu/akA==}
dependencies:
'@volar/typescript': 1.0.22
'@volar/vue-language-core': 1.0.22
'@volar/typescript': 1.0.24
'@volar/vue-language-core': 1.0.24
dev: true
/@vue/babel-helper-vue-transform-on/1.0.2:
@ -1583,7 +1577,7 @@ packages:
'@vue/shared': 3.2.45
estree-walker: 2.0.2
magic-string: 0.25.9
postcss: 8.4.20
postcss: 8.4.21
source-map: 0.6.1
/@vue/compiler-ssr/3.2.45:
@ -2066,7 +2060,7 @@ packages:
hasBin: true
dev: true
/autoprefixer/10.4.13_postcss@8.4.20:
/autoprefixer/10.4.13_postcss@8.4.21:
resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
@ -2078,7 +2072,7 @@ packages:
fraction.js: 4.2.0
normalize-range: 0.1.2
picocolors: 1.0.0
postcss: 8.4.20
postcss: 8.4.21
postcss-value-parser: 4.2.0
dev: true
@ -3013,12 +3007,12 @@ packages:
eslint: 8.31.0
dev: true
/eslint-define-config/1.13.0:
resolution: {integrity: sha512-d0BfmPGBcMusfiz6QY/piAhWaEyJriJtvk9SHfuJzI7am9k4ce07SfmPkpcR0ckXNyu4FBons10akOO2Tx+X+Q==}
/eslint-define-config/1.14.0:
resolution: {integrity: sha512-NREt5SzMwKmLAY28YdaqIiTSJxfPpuZ+1ZLJxY2Wbj02dYF4QX81z0q9MPMjZB8C+SlCu66qAhcPpFJyhXOiuA==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13', pnpm: '>= 7.0.0'}
dev: true
/eslint-plugin-prettier/4.2.1_32m5uc2milwdw3tnkcq5del26y:
/eslint-plugin-prettier/4.2.1_iu5s7nk6dw7o3tajefwfiqfmge:
resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
engines: {node: '>=12.0.0'}
peerDependencies:
@ -3031,7 +3025,7 @@ packages:
dependencies:
eslint: 8.31.0
eslint-config-prettier: 8.6.0_eslint@8.31.0
prettier: 2.8.1
prettier: 2.8.2
prettier-linter-helpers: 1.0.0
dev: true
@ -4506,7 +4500,7 @@ packages:
dev: false
/nanoid/3.3.4:
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/nanoid/-/nanoid-3.3.4.tgz}
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
@ -4848,8 +4842,8 @@ packages:
dependencies:
htmlparser2: 8.0.1
js-tokens: 8.0.0
postcss: 8.4.20
postcss-safe-parser: 6.0.0_postcss@8.4.20
postcss: 8.4.21
postcss-safe-parser: 6.0.0_postcss@8.4.21
dev: true
/postcss-media-query-parser/0.2.3:
@ -4868,22 +4862,22 @@ packages:
resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==}
dev: true
/postcss-safe-parser/6.0.0_postcss@8.4.20:
/postcss-safe-parser/6.0.0_postcss@8.4.21:
resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.3.3
dependencies:
postcss: 8.4.20
postcss: 8.4.21
dev: true
/postcss-scss/4.0.6_postcss@8.4.20:
/postcss-scss/4.0.6_postcss@8.4.21:
resolution: {integrity: sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.4.19
dependencies:
postcss: 8.4.20
postcss: 8.4.21
dev: true
/postcss-selector-parser/6.0.10:
@ -4902,12 +4896,12 @@ packages:
util-deprecate: 1.0.2
dev: true
/postcss-sorting/7.0.1_postcss@8.4.20:
resolution: {integrity: sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==}
/postcss-sorting/8.0.1_postcss@8.4.21:
resolution: {integrity: sha512-go9Zoxx7KQH+uLrJ9xa5wRErFeXu01ydA6O8m7koPXkmAN7Ts//eRcIqjo0stBR4+Nir2gMYDOWAOx7O5EPUZA==}
peerDependencies:
postcss: ^8.3.9
postcss: ^8.4.20
dependencies:
postcss: 8.4.20
postcss: 8.4.21
dev: true
/postcss-value-parser/4.2.0:
@ -4924,8 +4918,8 @@ packages:
supports-color: 3.2.3
dev: true
/postcss/8.4.20:
resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/postcss/-/postcss-8.4.20.tgz}
/postcss/8.4.21:
resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.4
@ -4983,8 +4977,8 @@ packages:
fast-diff: 1.2.0
dev: true
/prettier/2.8.1:
resolution: {integrity: sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==}
/prettier/2.8.2:
resolution: {integrity: sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==}
engines: {node: '>=10.13.0'}
hasBin: true
dev: true
@ -5428,7 +5422,7 @@ packages:
dev: true
/source-map-js/1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/source-map-js/-/source-map-js-1.0.2.tgz}
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
/source-map-resolve/0.5.3:
@ -5636,13 +5630,13 @@ packages:
stylelint-config-recommended: 9.0.0_stylelint@14.16.1
dev: true
/stylelint-order/5.0.0_stylelint@14.16.1:
resolution: {integrity: sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==}
/stylelint-order/6.0.1_stylelint@14.16.1:
resolution: {integrity: sha512-C9gJDZArRBZvn+4MPgggwYTp7dK49WPnYa5+6tBEkZnW/YWj4xBVNJdQjIik14w5orlF9RqFpYDHN0FPWIFOSQ==}
peerDependencies:
stylelint: ^14.0.0
dependencies:
postcss: 8.4.20
postcss-sorting: 7.0.1_postcss@8.4.20
postcss: 8.4.21
postcss-sorting: 8.0.1_postcss@8.4.21
stylelint: 14.16.1
dev: true
@ -5651,7 +5645,7 @@ packages:
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
dependencies:
'@csstools/selector-specificity': 2.0.2_2xshye3abirqjlplmebvmaxyna
'@csstools/selector-specificity': 2.0.2_wajs5nedgkikc5pcuwett7legi
balanced-match: 2.0.0
colord: 2.9.3
cosmiconfig: 7.1.0
@ -5674,10 +5668,10 @@ packages:
micromatch: 4.0.5
normalize-path: 3.0.0
picocolors: 1.0.0
postcss: 8.4.20
postcss: 8.4.21
postcss-media-query-parser: 0.2.3
postcss-resolve-nested-selector: 0.1.1
postcss-safe-parser: 6.0.0_postcss@8.4.20
postcss-safe-parser: 6.0.0_postcss@8.4.21
postcss-selector-parser: 6.0.11
postcss-value-parser: 4.2.0
resolve-from: 5.0.0
@ -6211,7 +6205,7 @@ packages:
dependencies:
'@types/node': 18.11.18
esbuild: 0.16.5
postcss: 8.4.20
postcss: 8.4.21
resolve: 1.22.1
rollup: 3.9.1
sass: 1.57.1
@ -6281,14 +6275,14 @@ packages:
he: 1.2.0
dev: true
/vue-tsc/1.0.22_typescript@4.9.4:
resolution: {integrity: sha512-xSxwgWR3czhv7sLKHWu6lzj9Xq6AtsCURVL45AY4TLGFszv2L2YlMgygXvqslyCM5bz9cyoIKSaZnzHqHTHjzA==}
/vue-tsc/1.0.24_typescript@4.9.4:
resolution: {integrity: sha512-mmU1s5SAqE1nByQAiQnao9oU4vX+mSdsgI8H57SfKH6UVzq/jP9+Dbi2GaV+0b4Cn361d2ln8m6xeU60ApiEXg==}
hasBin: true
peerDependencies:
typescript: '*'
dependencies:
'@volar/vue-language-core': 1.0.22
'@volar/vue-typescript': 1.0.22
'@volar/vue-language-core': 1.0.24
'@volar/vue-typescript': 1.0.24
typescript: 4.9.4
dev: true
@ -6314,8 +6308,8 @@ packages:
'@vue/server-renderer': 3.2.45_vue@3.2.45
'@vue/shared': 3.2.45
/vxe-table/4.3.7_vue@3.2.45+xe-utils@3.5.7:
resolution: {integrity: sha512-v+d7eEQ5uqtVTQCts4xkW0S15LZcIuEukYHGXI53SdoUj2gLFggPYAxQr1y659CM/ESRWPz9LNVHpd97KkjGHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/vxe-table/-/vxe-table-4.3.7.tgz}
/vxe-table/4.3.9_vue@3.2.45+xe-utils@3.5.7:
resolution: {integrity: sha512-Ns7Ooa7lOHBpks90i0k0BMNyxfMpUo39ryxTgKE41X3xVnI9tGQs2U6+klfDlsuqYfmG3ibyzHN3OCrWbbKo4Q==}
peerDependencies:
vue: ^3.2.28
xe-utils: ^3.5.0

View File

@ -129,7 +129,7 @@ input, textarea{
}
.el-scrollbar__view{
overflow-x: hidden;
// overflow-x: hidden;
}
.el-rate{

View File

@ -136,8 +136,8 @@
<script>
import {getCache, getKeyDefineList, getKeyList, getKeyValue, deleteKey, deleteKeys} from "@/api/infra/redis";
import echarts from "echarts";
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
export default {
name: "Server",
data () {

View File

@ -10,6 +10,6 @@ export const smsLogin = data => http.post('/member/auth/sms-login', data)
//微信小程序的一键登录
export const weixinMiniAppLogin = data => http.post('/member/auth/weixin-mini-app-login', data)
//刷新令牌
export const refreshToken = data => http.post('/member/auth/refresh-token', data)
export const refreshToken = data => http.post('/member/auth/refresh-token', {data})
//退出登录
export const logout = data => http.post('/member/auth/logout', data)

View File

@ -1,5 +1,6 @@
const getters = {
accessToken: state => state.user.accessToken,
refreshToken: state => state.user.refreshToken,
userInfo: state => state.user.userInfo,
hasLogin: state => !!state.user.accessToken
}

View File

@ -30,13 +30,16 @@ module.exports = vm => {
if (!isRefreshToken) {
isRefreshToken = true
// 1. 如果获取不到刷新令牌,则只能执行登出操作
if (!vm.$store.getters.refreshToken()) {
if (!vm.$store.getters.refreshToken) {
vm.$store.commit('CLEAR_LOGIN_INFO')
return Promise.reject(res)
}
// 2. 进行刷新访问令牌
try {
const refreshTokenRes = await refreshToken()
let param = {}
let refreshToken = uni.getStorageSync('REFRESH_TOKEN');
param.refreshToken = refreshToken;
const refreshTokenRes = await refreshToken(param)
// 2.1 刷新成功,则回放队列的请求 + 当前请求
vm.$store.commit('SET_TOKEN', refreshTokenRes.data)
requestList.forEach(cb => cb())