feat: 发布1.4.1版本

This commit is contained in:
2025-10-23 18:01:46 +08:00
parent 13e8b3ab93
commit 1146959052
30 changed files with 664 additions and 1057 deletions
+4 -30
View File
@@ -8,7 +8,10 @@
#### 项目源码
https://github.com/odboy-tianjun/cutejava
[https://github.com/odboy-tianjun/cutejava](https://github.com/odboy-tianjun/cutejava)
#### 项目文档
[https://cutejava-doc.odboy.cn/](https://cutejava-doc.odboy.cn/)
#### 编码规范
@@ -52,35 +55,6 @@ https://github.com/odboy-tianjun/cutejava
- 存储管理:本地存储、Minio存储
- 服务监控:监控服务器的负载情况
#### 前端基础组件
> 组件所在路径:cutejava-front/src/views/components/dev
- CuteSimpleTable 简单表格
- CuteDragTable 支持拖拽的表格
- CuteFormDialog 支持表单的对话框
- CuteFormDrawer 支持表单的抽屉
- CuteRichTextEditor 富文本编辑器
- CuteOneKeyCopy 一键复制
- CuteMarkdown Markdown编辑器
- CuteJavaEditor Java编辑器(已弃用)
- CuteYamlEditor Yaml编辑器(已弃用)
- CuteCodeEditor 多语言编辑器(支持yaml、java、go、swift、dockerfile、groovy、lua、perl、python、ruby、sql、xml、vue)
#### 前端业务组件
> 组件所在路径:cutejava-front/src/views/components/business
- CuteDeptTree 部门树
- CuteProductLineSelect 产品线选择框
- CuteProductLineSelectPro 产品线级联选择框
- CuteUserSelect 用户多选框
![CuteBusiness](./cutejava-front/docs/images/CuteBusiness.png)
- CuteFileUpload 上传文件到OSS, 必须结合Minio使用(上传完成后必须销毁组件)
![CuteFileUpload](./cutejava-front/docs/images/CuteFileUpload.png)
- CuteFileDragUpload 支持拖拽上传文件到OSS, 必须结合Minio使用(上传完成后必须销毁组件)
![CuteFileDragUpload](./cutejava-front/docs/images/CuteFileDragUpload.png)
#### 系统模块
- cutejava-framework:系统基础框架。提供核心功能,如:权限、数据权限、异常处理、缓存、工具类、接口限流、接口防重、接口幂等。
-34
View File
@@ -1,34 +0,0 @@
#!/bin/bash
is_weekend() {
day=$(date +%u)
[ "$day" -eq 6 ] || [ "$day" -eq 7 ]
}
if is_weekend; then
# 如果是周末,使用当前时间
git add .
git commit -m "$1"
git push
else
# 如果不是周末,设置为最近的周末时间
day=$(date +%u)
if [ "$day" -le 5 ]; then
# 周一到周五,设置为即将到来的周六
days_until_saturday=$((6 - day))
weekend_date=$(date -d "$days_until_saturday days" "+%Y-%m-%d 12:00:00")
else
# 周日,使用昨天(周六)
weekend_date=$(date -d "yesterday" "+%Y-%m-%d 12:00:00")
fi
export GIT_AUTHOR_DATE="$weekend_date"
export GIT_COMMITTER_DATE="$weekend_date"
git add .
git commit -m "$1"
git push
unset GIT_AUTHOR_DATE
unset GIT_COMMITTER_DATE
fi
+1 -1
View File
@@ -176,7 +176,7 @@ recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2022 Odboy
Copyright 2019 Zheng Jie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "cutejava-front",
"version": "1.4.0",
"version": "1.4.1",
"description": "CuteJava 前端源码",
"author": "Odboy",
"license": "Apache-2.0",
@@ -10,6 +10,7 @@
:disabled="disabled"
:options="deptOptions"
style="width: 100%"
placeholder="请选择产品线"
@change="handleChange"
/>
</template>
@@ -31,7 +31,7 @@
import UserService from '@/api/system/user'
export default {
name: 'CuteOneUserSelect',
name: 'CuteSingleUserSelect',
props: {
value: {
type: String,
@@ -15,7 +15,7 @@ export default {
props: {
desc: {
type: String,
required: true,
required: false,
default: '暂无匹配数据'
}
}
@@ -17,7 +17,7 @@
截图并下载
</el-button>
</div>
<div id="elementIdSelector">
<div id="elementIdSelector" style="padding: 15px">
<slot />
</div>
</div>
@@ -3,7 +3,7 @@
<!-- @change 编辑区发生变化的回调事件 -->
<!-- @save ctrl + s 的回调事件(保存按键,同样触发该回调) -->
<cute-markdown
:content="markdown.content"
:content="content"
@change="onChange"
@save="onSave"
/>
@@ -18,11 +18,8 @@ export default {
components: { CuteMarkdown },
data() {
return {
markdown: {
height: '200px',
content: '初始化内容'
}
}
},
methods: {
onChange(text, markdown) {
@@ -0,0 +1,91 @@
<template>
<div style="padding: 50px">
<el-divider>CuteSearchForm</el-divider>
<cute-search-form :model="searchFormModel" @submit="handleSearchFormSubmit" @reset="handleSearchFormReset">
<template v-slot:suffix>
<el-form-item label="模糊查询" prop="blurry">
<el-input v-model="searchFormModel.blurry" clearable />
</el-form-item>
</template>
<template v-slot:operation>
<el-button type="primary">查询后置按钮</el-button>
</template>
</cute-search-form>
<el-divider>CuteHorizontalScrollBar</el-divider>
<cute-horizontal-scroll-bar>
<div style="width: 3000px;min-width: 3000px">模拟超长内容</div>
</cute-horizontal-scroll-bar>
<el-divider>CuteVerticalScrollBar</el-divider>
<cute-vertical-scroll-bar>
<div style="height: 3000px;min-height: 3000px">模拟超高内容</div>
</cute-vertical-scroll-bar>
<el-divider>CuteLink</el-divider>
<cute-link title="百度一下" href="https://www.baidu.com" />
<el-divider>CuteNoData</el-divider>
<cute-no-data desc="自定义提示语" />
<el-divider>CutePreviewDrawer <el-button type="primary" @click="handleCutePreviewDrawerShow">显示</el-button></el-divider>
<cute-preview-drawer ref="cpd" title="预览抽屉">
<p>预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉</p>
</cute-preview-drawer>
<el-divider>截屏:包裹要截屏的组件</el-divider>
<cute-screen-shot>
<cute-search-form :model="searchFormModel" @submit="handleSearchFormSubmit" @reset="handleSearchFormReset">
<template v-slot:suffix>
<el-form-item label="模糊查询" prop="blurry">
<el-input v-model="searchFormModel.blurry" clearable />
</el-form-item>
</template>
<template v-slot:operation>
<el-button type="primary">查询后置按钮</el-button>
</template>
</cute-search-form>
</cute-screen-shot>
<el-divider>CuteSectionTitle</el-divider>
<cute-section-title title="段落标题">
<el-button type="danger">操作按钮</el-button>
</cute-section-title>
</div>
</template>
<script>
import CuteSearchForm from '@/views/components/dev/CuteSearchForm.vue'
import CuteHorizontalScrollBar from '@/views/components/dev/CuteHorizontalScrollBar.vue'
import CuteVerticalScrollBar from '@/views/components/dev/CuteVerticalScrollBar.vue'
import CuteLink from '@/views/components/dev/CuteLink.vue'
import CuteNoData from '@/views/components/dev/CuteNoData.vue'
import CutePreviewDrawer from '@/views/components/dev/CutePreviewDrawer.vue'
import CuteScreenShot from '@/views/components/dev/CuteScreenShot.vue'
import CuteSectionTitle from '@/views/components/dev/CuteSectionTitle.vue'
export default {
name: 'CuteOtherDemo',
components: {
CuteSectionTitle,
CuteScreenShot,
CutePreviewDrawer,
CuteNoData,
CuteLink,
CuteVerticalScrollBar,
CuteHorizontalScrollBar,
CuteSearchForm
},
data() {
return {
searchFormModel: {}
}
},
methods: {
handleSearchFormSubmit(data) {
console.log('handleSearchFormSubmit', data)
},
handleSearchFormReset() {
console.log('handleSearchFormReset')
},
handleCutePreviewDrawerShow() {
this.$refs.cpd.show()
}
}
}
</script>
@@ -1,9 +1,6 @@
<template>
<div class="app-container">
<cute-rich-text-editor
:read-only="false"
@change="onChange"
/>
<cute-rich-text-editor :read-only="false" @change="onChange" />
</div>
</template>
@@ -13,13 +10,6 @@ import CuteRichTextEditor from '@/views/components/dev/CuteRichTextEditor'
export default {
name: 'CuteRichTextEditorDemo',
components: { CuteRichTextEditor },
data() {
return {
html: {
height: '200px'
}
}
},
methods: {
onChange(html, text) {
console.log('onChange:html', html)
@@ -312,6 +312,7 @@ export default {
},
created() {
this.crud.msg.add = '新增成功,默认密码:123456'
console.log('======== this.dict', this.dict)
},
mounted: function() {
const that = this
+1 -1
View File
@@ -176,7 +176,7 @@ recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2022-2025 Odboy
Copyright 2019 Zheng Jie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,50 +0,0 @@
// /*
// * Copyright 2021-2025 Odboy
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
// package cn.odboy.framework.exception.thirdapi;
//
// 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;
//
// /**
// * 用于捕捉三方异常
// *
// * @author odboy
// */
// @Inherited
// @Documented
// @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
// @Retention(RetentionPolicy.RUNTIME)
// public @interface ThirdApiExceptionCatch {
// /**
// * 模块名称
// */
// String modelName();
//
// /**
// * 接口描述
// */
// String description();
//
// /**
// * 是否抛出异常
// */
// boolean throwException() default true;
// }
@@ -1,148 +0,0 @@
// /*
// * Copyright 2021-2025 Odboy
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
// package cn.odboy.framework.exception.thirdapi;
//
// import cn.hutool.core.date.TimeInterval;
// import cn.odboy.framework.exception.thirdapi.vo.KubernetesApiExceptionVo;
// import cn.odboy.framework.exception.web.BadRequestException;
// import cn.odboy.util.CsReturnValueHandleUtil;
// import cn.odboy.util.LogFmtUtil;
// import com.alibaba.fastjson2.JSON;
// import com.aliyun.tea.TeaException;
// import io.kubernetes.client.openapi.ApiException;
// import lombok.extern.slf4j.Slf4j;
// import org.aspectj.lang.ProceedingJoinPoint;
// import org.aspectj.lang.annotation.Around;
// import org.aspectj.lang.annotation.Aspect;
// import org.gitlab4j.api.GitLabApiException;
// import org.springframework.stereotype.Component;
//
// /**
// * DingtalkApi调用异常
// *
// * @author odboy
// * @date 2025-05-07
// */
// @Slf4j
// @Aspect
// @Component
// public class ThirdExceptionCatchAspect {
// @Around("@annotation(thirdApiExceptionCatch)")
// public Object aroundDingtalkApiExceptionCatch(ProceedingJoinPoint joinPoint, ThirdApiExceptionCatch thirdApiExceptionCatch) throws Throwable {
// return handleThirdApiException(joinPoint, thirdApiExceptionCatch);
// }
//
// /**
// * 三方服务调用异常处理
// */
// private Object handleThirdApiException(ProceedingJoinPoint joinPoint, ThirdApiExceptionCatch annotation) {
// if ("dingtalk".equals(annotation.modelName())) {
// return handleDingtalkApiException(joinPoint, annotation);
// }
// if ("gitlab".equals(annotation.modelName())) {
// return handleGitlabApiException(joinPoint, annotation);
// }
// if ("kubernetes".equals(annotation.modelName())) {
// return handleKubernetesApiException(joinPoint, annotation);
// }
// return null;
// }
//
// private Object handleDingtalkApiException(ProceedingJoinPoint joinPoint, ThirdApiExceptionCatch annotation) {
// TimeInterval timeInterval = new TimeInterval();
// try {
// Object result = joinPoint.proceed();
// log.info("接口 [{}] 执行耗时: {} ms", annotation.description(), timeInterval.intervalMs());
// return result;
// } catch (TeaException teaException) {
// if (!com.aliyun.teautil.Common.empty(teaException.code) && !com.aliyun.teautil.Common.empty(teaException.message)) {
// String exceptionMessage = annotation.description() + "失败, code={}, message={}";
// log.error(exceptionMessage, teaException.code, teaException.message, teaException);
// if (annotation.throwException()) {
// throw new BadRequestException(LogFmtUtil.format(exceptionMessage, teaException.code, teaException.message));
// }
// }
// String exceptionMessage = annotation.description() + "失败";
// log.error(exceptionMessage, teaException);
// if (annotation.throwException()) {
// throw new BadRequestException(exceptionMessage);
// }
// } catch (Throwable exception) {
// TeaException err = new TeaException(exception.getMessage(), exception);
// if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// String exceptionMessage = annotation.description() + "失败, code={}, message={}";
// log.error(exceptionMessage, err.code, err.message, err);
// if (annotation.throwException()) {
// throw new BadRequestException(LogFmtUtil.format(exceptionMessage, err.code, err.message));
// }
// }
// String exceptionMessage = annotation.description() + "失败";
// log.error(exceptionMessage, exception);
// if (annotation.throwException()) {
// throw new BadRequestException(exceptionMessage);
// }
// }
// return CsReturnValueHandleUtil.getDefaultValue(joinPoint);
// }
//
// private Object handleGitlabApiException(ProceedingJoinPoint joinPoint, ThirdApiExceptionCatch annotation) {
// TimeInterval timeInterval = new TimeInterval();
// try {
// Object result = joinPoint.proceed();
// log.info("接口 [{}] 执行耗时: {} ms", annotation.description(), timeInterval.intervalMs());
// return result;
// } catch (GitLabApiException gitLabApiException) {
// String exceptionMessage = annotation.description() + "失败,原因:" + gitLabApiException.getMessage();
// log.error(exceptionMessage, gitLabApiException);
// if (annotation.throwException()) {
// throw new BadRequestException(exceptionMessage);
// }
// } catch (Throwable exception) {
// String exceptionMessage = annotation.description() + "失败";
// log.error(exceptionMessage, exception);
// if (annotation.throwException()) {
// throw new BadRequestException(exceptionMessage);
// }
// }
// return CsReturnValueHandleUtil.getDefaultValue(joinPoint);
// }
//
// private Object handleKubernetesApiException(ProceedingJoinPoint joinPoint, ThirdApiExceptionCatch annotation) {
// TimeInterval timeInterval = new TimeInterval();
// try {
// Object result = joinPoint.proceed();
// log.info("接口 [{}] 执行耗时: {} ms", annotation.description(), timeInterval.intervalMs());
// return result;
// } catch (ApiException e) {
// String responseBody = e.getResponseBody();
// log.error("接口 [{}] 执行异常,耗时: {} ms,异常信息: {}", annotation.description(), timeInterval.intervalMs(), responseBody, e);
// if (annotation.throwException()) {
// KubernetesApiExceptionVo actionExceptionBody = JSON.parseObject(responseBody, KubernetesApiExceptionVo.class);
// if (actionExceptionBody != null) {
// throw new BadRequestException(annotation.description() + "失败, 原因:" + actionExceptionBody.getReason());
// }
// throw new BadRequestException(annotation.description() + "失败");
// }
// } catch (Throwable e) {
// log.error("接口 [{}] 执行异常,耗时: {} ms", annotation.description(), timeInterval.intervalMs(), e);
// if (annotation.throwException()) {
// throw new BadRequestException(annotation.description() + "失败");
// }
// }
// return CsReturnValueHandleUtil.getDefaultValue(joinPoint);
// }
// }
@@ -1,46 +0,0 @@
//
// /*
// * Copyright 2021-2025 Odboy
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
// package cn.odboy.framework.exception.thirdapi.vo;
//
// import cn.odboy.base.CsObject;
// import lombok.Data;
// import lombok.EqualsAndHashCode;
//
// /**
// * Kubernetes异常信息
// *
// * @author odboy
// * @date 2025-08-03
// */
// @Data
// @EqualsAndHashCode(callSuper = false)
// public class KubernetesApiExceptionVo extends CsObject {
// private String kind;
// private String apiVersion;
// private String status;
// private String message;
// private String reason;
// private Details details;
// private int code;
//
// @Data
// public static class Details {
// private String name;
// private String kind;
// }
// }
@@ -36,5 +36,5 @@ public @interface ExecutionTimeStatisticsFace {
/**
* 是否展示异常日志
*/
boolean errorLog() default false;
boolean showErrLog() default true;
}
@@ -24,7 +24,7 @@ import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
/**
* DingtalkApi调用异常
* 执行时间统计
*
* @author odboy
* @date 2025-05-07
@@ -41,7 +41,7 @@ public class ExecutionTimeStatisticsFaceAspect {
log.info("[{}] 接口执行成功,耗时: {} ms", executionTimeStatisticsFace.description(), timeInterval.intervalMs());
return proceed;
} catch (Exception e) {
if (executionTimeStatisticsFace.errorLog()) {
if (executionTimeStatisticsFace.showErrLog()) {
log.info("[{}] 接口执行失败,耗时: {} ms", executionTimeStatisticsFace.description(), timeInterval.intervalMs());
}
throw e;
@@ -39,36 +39,8 @@ public @interface CsMpQuery {
*/
CsMpQTypeEnum type() default CsMpQTypeEnum.EQUAL;
/**
* 连接查询的属性名, 如User类中的dept
*/
String joinName() default "";
/**
* 默认左连接
*/
Join join() default Join.LEFT;
/**
* 多字段模糊搜索, 仅支持String类型字段, 多个用逗号隔开, 如@MpQuery(blurry = "email,username")
*/
String blurry() default "";
/**
* 适用于简单连接查询, 复杂的请自定义该注解, 或者使用sql查询
*/
enum Join {
/**
* 左连接
*/
LEFT,
/**
* 右连接
*/
RIGHT,
/**
* 内连接
*/
INNER
}
}
@@ -27,12 +27,12 @@ import java.util.Collection;
import java.util.List;
/**
* 公共抽象Mapper接口类
* 公共抽象Service接口类
*
* @author odboy
* @date 2022-04-03
*/
public interface CsMpEasyService<T> extends IService<T> {
public interface CsMpService<T> extends IService<T> {
<G> int saveFeatureClazz(G resources);
<G> int saveFeatureClazzList(List<G> resources);
@@ -53,10 +53,7 @@ public class RedisConfiguration extends CachingConfigurerSupport {
/**
* 自动识别json对象白名单配置(仅允许解析的包名, 范围越小越安全)<br/> 未配置可能导致, 登录失败, 反复登录等问题
*/
private static final String[] WHITELIST_STR =
{"org.springframework", "cn.odboy.system.dal.dataobject", "cn.odboy.system.dal.model",
"cn.odboy.pipeline" + ".dal.dataobject", "cn.odboy.pipeline.dal.model",
"cn.odboy.pipeline.framework.pipeline.model", "cn.odboy.framework.exception.thirdapi.vo"};
private static final String[] WHITELIST_STR = {"org.springframework", "cn.odboy.system.dal.dataobject", "cn.odboy.system.dal.model", "cn.odboy.pipeline" + ".dal.dataobject", "cn.odboy.pipeline.dal.model", "cn.odboy.pipeline.framework.pipeline.model", "cn.odboy.framework.exception.thirdapi.vo"};
/**
* 设置 redis 数据默认过期时间,默认2小时 设置@cacheable 序列化方式
@@ -65,8 +62,7 @@ public class RedisConfiguration extends CachingConfigurerSupport {
public RedisCacheConfiguration redisCacheConfiguration() {
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
fastJsonRedisSerializer)).entryTtl(Duration.ofHours(2));
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofHours(2));
return configuration;
}
@@ -1,97 +0,0 @@
///*
// * Copyright 2021-2025 Odboy
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//package cn.odboy.framework.redis;
//
//import cn.hutool.core.util.StrUtil;
//import cn.odboy.util.CsSystemUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.redisson.Redisson;
//import org.redisson.api.RedissonClient;
//import org.redisson.client.codec.StringCodec;
//import org.redisson.config.Config;
//import org.redisson.config.EqualJitterDelay;
//import org.redisson.config.SingleServerConfig;
//import org.redisson.config.TransportMode;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.autoconfigure.AutoConfigureBefore;
//import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//
//import java.time.Duration;
//
//@Slf4j
//@Configuration
//@AutoConfigureBefore(RedisAutoConfiguration.class)
//public class RedissonConfiguration {
//
// @Value("${spring.redis.host}")
// private String redisHost;
//
// @Value("${spring.redis.port}")
// private int redisPort;
//
// @Value("${spring.redis.database}")
// private int redisDatabase;
//
// @Value("${spring.redis.password:}")
// private String redisPassword;
//
// @Value("${spring.redis.timeout:5000}")
// private int timeout;
//
// @Value("${spring.redis.lettuce.pool.max-active:64}")
// private int connectionPoolSize;
//
// @Value("${spring.redis.lettuce.pool.min-idle:16}")
// private int connectionMinimumIdleSize;
//
// @Bean
// public RedissonClient redissonClient() {
// Config config = new Config();
// config.setThreads(CsSystemUtil.getCpuCount());
// config.setNettyThreads(0);
// config.setCodec(new StringCodec());
// config.setTransportMode(TransportMode.NIO);
// SingleServerConfig singleServerConfig = config.useSingleServer();
// singleServerConfig.setAddress("redis://" + redisHost + ":" + redisPort);
// singleServerConfig.setDatabase(redisDatabase);
// singleServerConfig.setTimeout(timeout);
// singleServerConfig.setConnectionPoolSize(connectionPoolSize);
// singleServerConfig.setConnectionMinimumIdleSize(connectionMinimumIdleSize);
// if (StrUtil.isNotBlank(redisPassword)) {
// singleServerConfig.setPassword(redisPassword);
// }
// singleServerConfig.setIdleConnectionTimeout(10000);
// singleServerConfig.setConnectTimeout(10000);
// singleServerConfig.setTimeout(3000);
// singleServerConfig.setRetryAttempts(3);
// // singleServerConfig.setRetryInterval(1500);
// singleServerConfig.setRetryDelay(new EqualJitterDelay(Duration.ofSeconds(3), Duration.ofSeconds(5)));
// singleServerConfig.setSubscriptionsPerConnection(5);
// singleServerConfig.setSubscriptionConnectionMinimumIdleSize(1);
// singleServerConfig.setSubscriptionConnectionPoolSize(50);
// singleServerConfig.setConnectionMinimumIdleSize(32);
// singleServerConfig.setConnectionPoolSize(64);
// singleServerConfig.setDnsMonitoringInterval(5000);
// RedissonClient redissonClient = Redisson.create(config);
// log.info("Redisson客户端 初始化完毕");
// return redissonClient;
// }
//}
//
//
@@ -21,7 +21,7 @@ import cn.odboy.framework.exception.web.BadRequestException;
import java.util.concurrent.atomic.AtomicLong;
/**
* 分布式id生成工具
* 分布式id生成工具(不建议用,仅供参考)
*
* @author odboy
* @date 2025-04-05
@@ -1,48 +0,0 @@
/*
* Copyright 2021-2025 Odboy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.odboy.util;
/**
* 适配 logger 占位符
*
* @author odboy
* @date 2025-01-13
*/
public class LogFmtUtil {
/**
* 替换字符串中的占位符 {} 为传入的参数
*
* @param message 消息模板
* @param args 替换占位符的参数
* @return 替换后的消息
*/
public static String format(String message, Object... args) {
if (message == null || args == null || args.length == 0) {
return message;
}
// 使用 String.format 替换占位符
return String.format(message.replace("{}", "%s"), args);
}
public static void main(String[] args) {
// 示例用法
String messageTemplate = "获取dingtalk accessToken失败, code={}, message={}";
String formattedMessage = format(messageTemplate, 400, "Bad Request");
// 输出: 获取dingtalk accessToken失败, code=400, message=Bad Request
System.out.println(formattedMessage);
}
}
@@ -27,11 +27,17 @@ public class HealthCheckPointer implements CsHealthCheckPointService {
@Autowired
private SystemDictService systemDictService;
/**
* 系统准备就绪
*/
@Override
public ResponseEntity<?> doReadiness() {
return ResponseEntity.ok(null);
}
/**
* 系统是否正常
*/
@Override
public ResponseEntity<?> doLiveness() {
return ResponseEntity.ok(systemDictService.getById(1));
@@ -193,8 +193,8 @@ app:
private-key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
# 鉴权
jwt:
# 必须使用最少88位的Base64对该令牌进行编码
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
# 必须使用最少88位的Base64对该令牌进行编码 cn.odboy.util.CsBase64SecretUtil
base64-secret: YzE5ZWNjMjlkMGY4NDc4MDlmYzE0Y2I0MTk4YTQ4YjY5NTU0OGQxODNjNjQ0MmU1YjBmZTYwYjljYzI0M2M4MTJkZjk3Y2ZlYjg3ZTQxMjM4MjEwY2ZiYzE4YmFiYmZlZDVhM2M1YmI3M2FmNDFmNWJmM2MyMTM1ZDNhMmRmYzY=
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 14400000
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
+10 -8
View File
@@ -24,7 +24,7 @@ CREATE TABLE `demo_time_table_copy1` (
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of demo_time_table_copy1
@@ -42,7 +42,7 @@ CREATE TABLE `demo_user_time_logic_table` (
`update_time` datetime NOT NULL COMMENT '修改时间',
`available` tinyint(1) NOT NULL DEFAULT 1 COMMENT '数据有效性',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of demo_user_time_logic_table
@@ -59,7 +59,7 @@ CREATE TABLE `demo_user_time_table` (
`update_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '修改人',
`update_time` datetime NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of demo_user_time_table
@@ -219,7 +219,7 @@ CREATE TABLE `qrtz_scheduler_state` (
-- Records of qrtz_scheduler_state
-- ----------------------------
INSERT INTO `qrtz_scheduler_state` VALUES ('ClusteredScheduler', 'DESKTOP-FM44BLS1742558233429', 1742558255052, 20000);
INSERT INTO `qrtz_scheduler_state` VALUES ('cutejava', 'auto', 1760951912083, 10000);
INSERT INTO `qrtz_scheduler_state` VALUES ('cutejava', 'auto', 1761211053605, 10000);
-- ----------------------------
-- Table structure for qrtz_simple_triggers
@@ -509,7 +509,7 @@ CREATE TABLE `system_menu` (
UNIQUE INDEX `uniq_title`(`title` ASC) USING BTREE,
INDEX `idx_pid`(`pid` ASC) USING BTREE,
INDEX `idx_sys_menu_menu_id`(`menu_id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 150 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统菜单' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 151 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统菜单' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of system_menu
@@ -520,7 +520,7 @@ INSERT INTO `system_menu` VALUES (3, 1, 3, 1, '角色管理', 'Role', 'system/ro
INSERT INTO `system_menu` VALUES (5, 1, 3, 1, '菜单管理', 'Menu', 'system/menu/index', 5, 'menu', 'menu', b'0', b'0', b'0', 'menu:list', 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (6, 1, 3, 0, '系统监控', NULL, NULL, 11, 'monitor', 'monitor', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (9, 6, 0, 1, 'SQL监控', 'DruidSqlConsole', 'system/druidSql/index', 18, 'sqlMonitor', 'druid-console', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (10, NULL, 15, 0, '组件管理', NULL, NULL, 999, 'zujian', 'components', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (10, NULL, 16, 0, '组件管理', NULL, NULL, 999, 'zujian', 'components', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (11, 10, 0, 1, '图标库', 'Icons', 'components/icons/index', 51, 'icon', 'icon', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (14, 36, 0, 1, '邮件工具', 'Email', 'system/email/index', 35, 'email', 'email', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (18, 36, 3, 1, '存储管理', 'Storage', 'system/storage/index', 34, 'qiniu', 'storage', b'0', b'0', b'0', 'storage:list', 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
@@ -574,6 +574,7 @@ INSERT INTO `system_menu` VALUES (128, 10, 0, 1, '演示:Markdown编辑器', 'Cu
INSERT INTO `system_menu` VALUES (129, 10, 0, 1, '演示:富文本编辑器', 'CuteRichTextEditorDemo', 'componentsDemo/CuteRichTextEditorDemo', 999, 'menu', 'cuteRichTextEditorDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (130, 10, 0, 1, '演示:文件上传', 'CuteFileUploadDemo', 'componentsDemo/CuteFileUploadDemo', 999, 'menu', 'cuteFileUploadDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (132, 10, 0, 1, '演示:文件拖拽上传', 'CuteFileDragUploadDemo', 'componentsDemo/CuteFileDragUploadDemo', 999, 'menu', 'cuteFileDragUploadDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
INSERT INTO `system_menu` VALUES (150, 10, 0, 1, '演示:其他基础组件', 'CuteOtherDemo', 'componentsDemo/CuteOtherDemo', 999, 'menu', 'cuteOtherDemo', b'0', b'0', b'0', NULL, 'admin', 'admin', '2021-03-20 22:04:13', '2021-03-20 22:04:13');
-- ----------------------------
-- Table structure for system_operation_log
@@ -592,7 +593,7 @@ CREATE TABLE `system_operation_log` (
`exception_detail` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '审计日志' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '审计日志' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of system_operation_log
@@ -675,7 +676,7 @@ CREATE TABLE `system_quartz_log` (
`exception_detail` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '异常详情',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务日志' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务日志' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of system_quartz_log
@@ -827,6 +828,7 @@ INSERT INTO `system_roles_menus` VALUES (130, 1);
INSERT INTO `system_roles_menus` VALUES (130, 2);
INSERT INTO `system_roles_menus` VALUES (132, 1);
INSERT INTO `system_roles_menus` VALUES (132, 2);
INSERT INTO `system_roles_menus` VALUES (150, 1);
-- ----------------------------
-- Table structure for system_user