优化不联网

This commit is contained in:
zc
2026-03-17 15:17:42 +08:00
parent 61a18e781d
commit 50a1c03776
26 changed files with 175 additions and 331 deletions

View File

@@ -1,39 +1,15 @@
package top.wms.admin.auth.handler;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.json.JSONUtil;
import com.xkcoding.justauth.AuthRequestFactory;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.stereotype.Component;
import top.wms.admin.auth.AbstractLoginHandler;
import top.wms.admin.auth.enums.AuthTypeEnum;
import top.wms.admin.auth.model.req.SocialLoginReq;
import top.wms.admin.auth.model.resp.LoginResp;
import top.wms.admin.common.constant.RegexConstants;
import top.wms.admin.common.constant.SysConstants;
import top.wms.admin.common.enums.DisEnableStatusEnum;
import top.wms.admin.common.enums.GenderEnum;
import top.wms.admin.system.model.entity.RoleDO;
import top.wms.admin.system.model.entity.UserDO;
import top.wms.admin.system.model.entity.UserSocialDO;
import top.wms.admin.system.model.resp.ClientResp;
import top.wms.admin.system.service.UserRoleService;
import top.wms.admin.system.service.UserSocialService;
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
import top.continew.starter.core.exception.BadRequestException;
import top.continew.starter.core.validation.ValidationUtils;
import java.time.LocalDateTime;
import java.util.Collections;
/**
* 第三方账号登录处理器
@@ -46,57 +22,10 @@ import java.util.Collections;
@RequiredArgsConstructor
public class SocialLoginHandler extends AbstractLoginHandler<SocialLoginReq> {
private final AuthRequestFactory authRequestFactory;
private final UserSocialService userSocialService;
private final UserRoleService userRoleService;
private final ProjectProperties projectProperties;
@Override
public LoginResp login(SocialLoginReq req, ClientResp client, HttpServletRequest request) {
// 获取第三方登录信息
AuthRequest authRequest = this.getAuthRequest(req.getSource());
AuthCallback callback = new AuthCallback();
callback.setCode(req.getCode());
callback.setState(req.getState());
AuthResponse<AuthUser> response = authRequest.login(callback);
ValidationUtils.throwIf(!response.ok(), response.getMsg());
AuthUser authUser = response.getData();
// 如未绑定则自动注册新用户,保存或更新关联信息
String source = authUser.getSource();
String openId = authUser.getUuid();
UserSocialDO userSocial = userSocialService.getBySourceAndOpenId(source, openId);
UserDO user;
if (null == userSocial) {
String username = authUser.getUsername();
UserDO existsUser = userService.getByUsername(username);
String randomStr = RandomUtil.randomString(RandomUtil.BASE_CHAR, 5);
if (null != existsUser || !ReUtil.isMatch(RegexConstants.USERNAME, username)) {
username = randomStr + IdUtil.fastSimpleUUID();
}
user = new UserDO();
user.setUsername(username);
user.setGender(GenderEnum.valueOf(authUser.getGender().name()));
user.setAvatar(authUser.getAvatar());
user.setStatus(DisEnableStatusEnum.ENABLE);
userService.save(user);
Long userId = user.getId();
RoleDO role = roleService.getByCode(SysConstants.SUPER_ROLE_CODE);
userRoleService.assignRolesToUser(Collections.singletonList(role.getId()), userId);
userSocial = new UserSocialDO();
userSocial.setUserId(userId);
userSocial.setSource(source);
userSocial.setOpenId(openId);
} else {
user = BeanUtil.copyProperties(userService.getById(userSocial.getUserId()), UserDO.class);
}
// 检查用户状态
super.checkUserStatus(user);
userSocial.setMetaJson(JSONUtil.toJsonStr(authUser));
userSocial.setLastLoginTime(LocalDateTime.now());
userSocialService.saveOrUpdate(userSocial);
// 执行认证
String token = super.authenticate(user, client);
return LoginResp.builder().token(token).build();
// 第三方登录已禁用
throw new BadRequestException("第三方登录功能已禁用");
}
@Override
@@ -112,18 +41,4 @@ public class SocialLoginHandler extends AbstractLoginHandler<SocialLoginReq> {
return AuthTypeEnum.SOCIAL;
}
/**
* 获取 AuthRequest
*
* @param source 平台名称
* @return AuthRequest
*/
private AuthRequest getAuthRequest(String source) {
try {
return authRequestFactory.get(source);
} catch (Exception e) {
throw new BadRequestException("暂不支持 [%s] 平台账号登录".formatted(source));
}
}
}
}

View File

@@ -24,5 +24,6 @@ public interface MaterialInfoMapper extends BaseMapper<MaterialInfoDO> {
public int updateByCode(List<MaterialInfoDO> list);
IPage<MaterialInfoResp> selectMaterialInfoPage(@Param("page") Page<Object> objectPage, @Param(Constants.WRAPPER) QueryWrapper<MaterialInfoDO> queryWrapper);
IPage<MaterialInfoResp> selectMaterialInfoPage(@Param("page") Page<Object> objectPage,
@Param(Constants.WRAPPER) QueryWrapper<MaterialInfoDO> queryWrapper);
}

View File

@@ -47,12 +47,12 @@ public class MaterialInfoDO extends BaseDO {
*/
private String photoUrl;
/**
/**
* 物料类型ID
*/
private Long materialTypeId;
/**
/**
* 流程ID
*/
private Long materialProcessId;

View File

@@ -59,14 +59,14 @@ public class MaterialInfoReq implements Serializable {
@Length(max = 255, message = "物料照片地址长度不能超过 {max} 个字符")
private String photoUrl;
/**
/**
* 物料类型ID
*/
@Schema(description = "物料类型ID")
@NotNull(message = "物料类型ID不能为空")
private Long materialTypeId;
/**
/**
* 流程ID
*/
@Schema(description = "流程ID")

View File

@@ -48,9 +48,6 @@ import top.wms.admin.material.model.resp.MaterialInfoImportResp;
import top.wms.admin.material.model.resp.MaterialInfoResp;
import top.wms.admin.material.service.MaterialInfoService;
import top.wms.admin.system.service.FileService;
import top.wms.admin.weighManage.model.entity.WorkOrderDO;
import top.wms.admin.weighManage.model.query.WorkOrderQuery;
import top.wms.admin.weighManage.model.resp.WorkOrderResp;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
@@ -90,12 +87,11 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl<MaterialInfoMapper,
this.sort(queryWrapper, pageQuery);
IPage<MaterialInfoResp> page = baseMapper.selectMaterialInfoPage(new Page<>(pageQuery.getPage(), pageQuery
.getSize()), queryWrapper);
.getSize()), queryWrapper);
return PageResp.build(page);
}
@Override
public MaterialInfoDO getMaterialInfoByCode(String code) {
if (StrUtil.isNotBlank(code)) {

View File

@@ -5,11 +5,11 @@ import top.wms.admin.materialProcess.model.entity.MaterialProcessDO;
import org.springframework.stereotype.Repository;
/**
* 海康物料流程 Mapper
*
* @author zc
* @since 2026/03/16 17:22
*/
* 海康物料流程 Mapper
*
* @author zc
* @since 2026/03/16 17:22
*/
@Repository
public interface MaterialProcessMapper extends BaseMapper<MaterialProcessDO> {

View File

@@ -4,7 +4,6 @@ import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.extension.crud.service.BaseService;
import top.wms.admin.materialProcess.model.query.MaterialProcessQuery;
import top.wms.admin.materialProcess.model.req.MaterialProcessReq;
import top.wms.admin.materialProcess.model.resp.MaterialProcessDetailResp;
import top.wms.admin.materialProcess.model.resp.MaterialProcessResp;
import java.util.List;

View File

@@ -5,11 +5,11 @@ import top.wms.admin.materialType.model.entity.MaterialTypeDO;
import org.springframework.stereotype.Repository;
/**
* 物料品类 Mapper
*
* @author zc
* @since 2026/03/16 11:18
*/
* 物料品类 Mapper
*
* @author zc
* @since 2026/03/16 11:18
*/
@Repository
public interface MaterialTypeMapper extends BaseMapper<MaterialTypeDO> {

View File

@@ -4,7 +4,6 @@ import top.continew.starter.extension.crud.model.resp.LabelValueResp;
import top.continew.starter.extension.crud.service.BaseService;
import top.wms.admin.materialType.model.query.MaterialTypeQuery;
import top.wms.admin.materialType.model.req.MaterialTypeReq;
import top.wms.admin.materialType.model.resp.MaterialTypeDetailResp;
import top.wms.admin.materialType.model.resp.MaterialTypeResp;
import java.util.List;

View File

@@ -12,7 +12,6 @@ import top.wms.admin.materialType.mapstruct.MaterialTypeConvert;
import top.wms.admin.materialType.model.entity.MaterialTypeDO;
import top.wms.admin.materialType.model.query.MaterialTypeQuery;
import top.wms.admin.materialType.model.req.MaterialTypeReq;
import top.wms.admin.materialType.model.resp.MaterialTypeDetailResp;
import top.wms.admin.materialType.model.resp.MaterialTypeResp;
import top.wms.admin.materialType.service.MaterialTypeService;
@@ -30,7 +29,6 @@ public class MaterialTypeServiceImpl extends BaseServiceImpl<MaterialTypeMapper,
private final MaterialTypeConvert materialTypeConvert;
@Override
public List<LabelValueResp> getSelectList() {
List<MaterialTypeDO> materialTypeDOS = baseMapper.selectList(new QueryWrapper<>());

View File

@@ -1,6 +1,5 @@
package top.wms.admin.weighManage.model.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;

View File

@@ -26,6 +26,32 @@
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-log-interceptor</artifactId>
<exclusions>
<exclusion>
<artifactId>tlog-core</artifactId>
<groupId>com.yomahub</groupId>
</exclusion>
<exclusion>
<artifactId>tlog-webflux</artifactId>
<groupId>com.yomahub</groupId>
</exclusion>
<exclusion>
<artifactId>tlog-feign</artifactId>
<groupId>com.yomahub</groupId>
</exclusion>
<exclusion>
<artifactId>tlog-okhttp</artifactId>
<groupId>com.yomahub</groupId>
</exclusion>
<exclusion>
<artifactId>tlog-resttemplate</artifactId>
<groupId>com.yomahub</groupId>
</exclusion>
<exclusion>
<artifactId>tlog-xxljob</artifactId>
<groupId>com.yomahub</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>top.wms</groupId>

View File

@@ -29,6 +29,32 @@
<dependency>
<groupId>top.continew</groupId>
<artifactId>continew-starter-log-interceptor</artifactId>
<exclusions>
<exclusion>
<groupId>com.yomahub</groupId>
<artifactId>tlog-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.yomahub</groupId>
<artifactId>tlog-webflux</artifactId>
</exclusion>
<exclusion>
<groupId>com.yomahub</groupId>
<artifactId>tlog-feign</artifactId>
</exclusion>
<exclusion>
<groupId>com.yomahub</groupId>
<artifactId>tlog-okhttp</artifactId>
</exclusion>
<exclusion>
<groupId>com.yomahub</groupId>
<artifactId>tlog-resttemplate</artifactId>
</exclusion>
<exclusion>
<groupId>com.yomahub</groupId>
<artifactId>tlog-xxljob</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->

View File

@@ -6,7 +6,6 @@ import top.wms.admin.system.mapper.LogMapper;
import top.wms.admin.system.service.UserService;
import top.continew.starter.log.annotation.ConditionalOnEnabledLog;
import top.continew.starter.log.dao.LogDao;
import top.continew.starter.web.autoconfigure.trace.TraceProperties;
/**
* 日志配置
@@ -22,7 +21,7 @@ public class LogConfiguration {
* 日志持久层接口本地实现类
*/
@Bean
public LogDao logDao(UserService userService, LogMapper logMapper, TraceProperties traceProperties) {
return new LogDaoLocalImpl(userService, logMapper, traceProperties);
public LogDao logDao(UserService userService, LogMapper logMapper) {
return new LogDaoLocalImpl(userService, logMapper);
}
}
}

View File

@@ -26,7 +26,6 @@ import top.continew.starter.log.dao.LogDao;
import top.continew.starter.log.model.LogRecord;
import top.continew.starter.log.model.LogRequest;
import top.continew.starter.log.model.LogResponse;
import top.continew.starter.web.autoconfigure.trace.TraceProperties;
import top.continew.starter.web.model.R;
import java.time.LocalDateTime;
@@ -45,7 +44,6 @@ public class LogDaoLocalImpl implements LogDao {
private final UserService userService;
private final LogMapper logMapper;
private final TraceProperties traceProperties;
@Async
@Override
@@ -95,7 +93,7 @@ public class LogDaoLocalImpl implements LogDao {
private void setResponse(LogDO logDO, LogResponse logResponse) {
Map<String, String> responseHeaders = logResponse.getHeaders();
logDO.setResponseHeaders(JSONUtil.toJsonStr(responseHeaders));
logDO.setTraceId(responseHeaders.get(traceProperties.getTraceIdName()));
logDO.setTraceId(responseHeaders.get("traceId"));
String responseBody = logResponse.getBody();
logDO.setResponseBody(responseBody);
// 状态
@@ -160,4 +158,4 @@ public class LogDaoLocalImpl implements LogDao {
logDO.setCreateUser(Convert.toLong(StpUtil.getLoginIdByToken(token)));
}
}
}
}

View File

@@ -3,15 +3,12 @@ package top.wms.admin.controller.auth;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.xkcoding.justauth.AuthRequestFactory;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.wms.admin.auth.model.req.LoginReq;
@@ -45,7 +42,6 @@ public class AuthController {
private final AuthService authService;
private final UserService userService;
private final AuthRequestFactory authRequestFactory;
@SaIgnore
@Operation(summary = "登录", description = "用户登录")
@@ -68,10 +64,8 @@ public class AuthController {
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
@GetMapping("/{source}")
public SocialAuthAuthorizeResp authorize(@PathVariable String source) {
AuthRequest authRequest = this.getAuthRequest(source);
return SocialAuthAuthorizeResp.builder()
.authorizeUrl(authRequest.authorize(AuthStateUtils.createState()))
.build();
// 第三方登录已禁用
throw new BadRequestException("第三方登录功能已禁用");
}
@Log(ignore = true)
@@ -93,12 +87,4 @@ public class AuthController {
public List<RouteResp> listRoute() {
return authService.buildRouteTree(UserContextHolder.getUserId());
}
private AuthRequest getAuthRequest(String source) {
try {
return authRequestFactory.get(source);
} catch (Exception e) {
throw new BadRequestException("暂不支持 [%s] 平台账号登录".formatted(source));
}
}
}
}

View File

@@ -2,56 +2,35 @@ package top.wms.admin.controller.common;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import com.anji.captcha.model.common.RepCodeEnum;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.wf.captcha.base.Captcha;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.mail.MessagingException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.RequiredArgsConstructor;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.constant.SupplierConstant;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.wms.admin.auth.model.resp.CaptchaResp;
import top.wms.admin.common.config.properties.CaptchaProperties;
import top.wms.admin.common.constant.CacheConstants;
import top.wms.admin.common.constant.SysConstants;
import top.wms.admin.system.enums.OptionCategoryEnum;
import top.wms.admin.system.service.OptionService;
import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.captcha.graphic.core.GraphicCaptchaService;
import top.continew.starter.core.autoconfigure.project.ProjectProperties;
import top.continew.starter.core.util.TemplateUtils;
import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.core.validation.ValidationUtils;
import top.continew.starter.log.annotation.Log;
import top.continew.starter.messaging.mail.util.MailUtils;
import top.continew.starter.security.limiter.annotation.RateLimiter;
import top.continew.starter.security.limiter.annotation.RateLimiters;
import top.continew.starter.security.limiter.enums.LimitType;
import top.continew.starter.web.model.R;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 验证码 API
@@ -69,7 +48,6 @@ public class CaptchaController {
private final ProjectProperties projectProperties;
private final CaptchaProperties captchaProperties;
private final CaptchaService behaviorCaptchaService;
private final GraphicCaptchaService graphicCaptchaService;
private final OptionService optionService;
@@ -77,19 +55,22 @@ public class CaptchaController {
@Operation(summary = "获取行为验证码", description = "获取行为验证码Base64编码")
@GetMapping("/behavior")
public Object getBehaviorCaptcha(CaptchaVO captchaReq, HttpServletRequest request) {
captchaReq.setBrowserInfo(JakartaServletUtil.getClientIP(request) + request.getHeader(HttpHeaders.USER_AGENT));
ResponseModel responseModel = behaviorCaptchaService.get(captchaReq);
CheckUtils.throwIf(() -> !StrUtil.equals(RepCodeEnum.SUCCESS.getCode(), responseModel
.getRepCode()), responseModel.getRepMsg());
return responseModel.getRepData();
// 行为验证码已禁用,返回默认成功响应
Map<String, Object> result = new LinkedHashMap<>();
result.put("captchaId", IdUtil.fastUUID());
result.put("picPath", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
return result;
}
@Log(ignore = true)
@Operation(summary = "校验行为验证码", description = "校验行为验证码")
@PostMapping("/behavior")
public Object checkBehaviorCaptcha(@RequestBody CaptchaVO captchaReq, HttpServletRequest request) {
captchaReq.setBrowserInfo(JakartaServletUtil.getClientIP(request) + request.getHeader(HttpHeaders.USER_AGENT));
return behaviorCaptchaService.check(captchaReq);
// 行为验证码已禁用,直接返回成功
ResponseModel responseModel = new ResponseModel();
responseModel.setRepCode(RepCodeEnum.SUCCESS.getCode());
responseModel.setRepMsg("验证成功");
return responseModel;
}
@Log(ignore = true)
@@ -110,60 +91,21 @@ public class CaptchaController {
}
/**
* 获取邮箱验证码
*
* <p>
* 限流规则:<br>
* 1.同一邮箱同一模板1分钟2条1小时8条24小时20条 <br>
* 2、同一邮箱所有模板 24 小时 100 条 <br>
* 3、同一 IP 每分钟限制发送 30 条
* </p>
* 获取邮箱验证码(已禁用)
*
* @param email 邮箱
* @return /
*/
@Operation(summary = "获取邮箱验证码", description = "发送验证码到指定邮箱")
@GetMapping("/mail")
@RateLimiters({
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "MIN", key = "#email + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.mail.templatePath')", rate = 2, interval = 1, unit = TimeUnit.MINUTES, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "HOUR", key = "#email + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.mail.templatePath')", rate = 8, interval = 1, unit = TimeUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "DAY'", key = "#email + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.mail.templatePath')", rate = 20, interval = 24, unit = TimeUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#email", rate = 100, interval = 24, unit = TimeUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#email", rate = 30, interval = 1, unit = TimeUnit.MINUTES, type = LimitType.IP, message = "获取验证码操作太频繁,请稍后再试")})
public R getMailCaptcha(@NotBlank(message = "邮箱不能为空") @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误") String email,
CaptchaVO captchaReq) throws MessagingException {
// 行为验证码校验
ResponseModel verificationRes = behaviorCaptchaService.verification(captchaReq);
ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes
.getRepMsg());
// 生成验证码
CaptchaProperties.CaptchaMail captchaMail = captchaProperties.getMail();
String captcha = RandomUtil.randomNumbers(captchaMail.getLength());
// 发送验证码
Long expirationInMinutes = captchaMail.getExpirationInMinutes();
Map<String, String> siteConfig = optionService.getByCategory(OptionCategoryEnum.SITE);
String content = TemplateUtils.render(captchaMail.getTemplatePath(), Dict.create()
.set("siteUrl", projectProperties.getUrl())
.set("siteTitle", siteConfig.get("SITE_TITLE"))
.set("siteCopyright", siteConfig.get("SITE_COPYRIGHT"))
.set("captcha", captcha)
.set("expiration", expirationInMinutes));
MailUtils.sendHtml(email, "【%s】邮箱验证码".formatted(projectProperties.getName()), content);
// 保存验证码
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + email;
RedisUtils.set(captchaKey, captcha, Duration.ofMinutes(expirationInMinutes));
return R.ok("发送成功,验证码有效期 %s 分钟".formatted(expirationInMinutes));
CaptchaVO captchaReq) {
// 邮箱验证码已禁用,直接返回成功
return R.ok("发送成功,验证码有效期 5 分钟");
}
/**
* 获取短信验证码
*
* <p>
* 限流规则:<br>
* 1.同一号码同一模板1分钟2条1小时8条24小时20条 <br>
* 2、同一号码所有模板 24 小时 100 条 <br>
* 3、同一 IP 每分钟限制发送 30 条
* </p>
* 获取短信验证码(已禁用)
*
* @param phone 手机号
* @param captchaReq 行为验证码信息
@@ -171,33 +113,9 @@ public class CaptchaController {
*/
@Operation(summary = "获取短信验证码", description = "发送验证码到指定手机号")
@GetMapping("/sms")
@RateLimiters({
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "MIN", key = "#phone + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.sms.templateId')", rate = 2, interval = 1, unit = TimeUnit.MINUTES, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "HOUR", key = "#phone + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.sms.templateId')", rate = 8, interval = 1, unit = TimeUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX + "DAY'", key = "#phone + ':' + T(cn.hutool.extra.spring.SpringUtil).getProperty('captcha.sms.templateId')", rate = 20, interval = 24, unit = TimeUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#phone", rate = 100, interval = 24, unit = TimeUnit.HOURS, message = "获取验证码操作太频繁,请稍后再试"),
@RateLimiter(name = CacheConstants.CAPTCHA_KEY_PREFIX, key = "#phone", rate = 30, interval = 1, unit = TimeUnit.MINUTES, type = LimitType.IP, message = "获取验证码操作太频繁,请稍后再试")})
public R getSmsCaptcha(@NotBlank(message = "手机号不能为空") @Pattern(regexp = RegexPool.MOBILE, message = "手机号格式错误") String phone,
CaptchaVO captchaReq) {
// 行为验证码校验
ResponseModel verificationRes = behaviorCaptchaService.verification(captchaReq);
ValidationUtils.throwIfNotEqual(verificationRes.getRepCode(), RepCodeEnum.SUCCESS.getCode(), verificationRes
.getRepMsg());
CaptchaProperties.CaptchaSms captchaSms = captchaProperties.getSms();
// 生成验证码
String captcha = RandomUtil.randomNumbers(captchaSms.getLength());
// 发送验证码
Long expirationInMinutes = captchaSms.getExpirationInMinutes();
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.CLOOPEN);
Map<String, String> messageMap = MapUtil.newHashMap(2, true);
messageMap.put("captcha", captcha);
messageMap.put("expirationInMinutes", String.valueOf(expirationInMinutes));
SmsResponse smsResponse = smsBlend.sendMessage(phone, captchaSms
.getTemplateId(), (LinkedHashMap<String, String>)messageMap);
CheckUtils.throwIf(!smsResponse.isSuccess(), "验证码发送失败");
// 保存验证码
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone;
RedisUtils.set(captchaKey, captcha, Duration.ofMinutes(expirationInMinutes));
return R.ok("发送成功,验证码有效期 %s 分钟".formatted(expirationInMinutes));
// 短信验证码已禁用,直接返回成功
return R.ok("发送成功,验证码有效期 5 分钟");
}
}
}

View File

@@ -27,10 +27,10 @@ import java.util.List;
@Tag(name = "海康物料流程管理 API")
@RestController
@RequiredArgsConstructor
@CrudRequestMapping(value = "/materialProcess/materialProcess", api = {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
@CrudRequestMapping(value = "/materialProcess/materialProcess", api = {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE,
Api.DELETE, Api.EXPORT})
public class MaterialProcessController extends BaseController<MaterialProcessService, MaterialProcessResp, MaterialProcessResp, MaterialProcessQuery, MaterialProcessReq> {
@Log(ignore = true)
@GetMapping("/selectList")
public List<LabelValueResp> getSelectList() {

View File

@@ -30,7 +30,6 @@ import java.util.List;
@CrudRequestMapping(value = "/materialType/materialType", api = {Api.PAGE, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
public class MaterialTypeController extends BaseController<MaterialTypeService, MaterialTypeResp, MaterialTypeResp, MaterialTypeQuery, MaterialTypeReq> {
@Log(ignore = true)
@GetMapping("/selectList")
public List<LabelValueResp> getSelectList() {

View File

@@ -1,16 +1,11 @@
package top.wms.admin.controller.system;
import com.xkcoding.justauth.AuthRequestFactory;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -28,6 +23,7 @@ import top.wms.admin.system.model.resp.user.UserSocialBindResp;
import top.wms.admin.system.service.UserService;
import top.wms.admin.system.service.UserSocialService;
import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.core.exception.BadRequestException;
import top.continew.starter.core.util.ExceptionUtils;
import top.continew.starter.core.validation.ValidationUtils;
@@ -51,7 +47,6 @@ public class UserCenterController {
private static final String CAPTCHA_EXPIRED = "验证码已失效";
private final UserService userService;
private final UserSocialService userSocialService;
private final AuthRequestFactory authRequestFactory;
@Operation(summary = "修改头像", description = "用户修改个人头像")
@PostMapping("/avatar")
@@ -123,12 +118,9 @@ public class UserCenterController {
@Operation(summary = "绑定三方账号", description = "绑定三方账号")
@Parameter(name = "source", description = "来源", example = "gitee", in = ParameterIn.PATH)
@PostMapping("/social/{source}")
public void bindSocial(@PathVariable String source, @RequestBody AuthCallback callback) {
AuthRequest authRequest = authRequestFactory.get(source);
AuthResponse<AuthUser> response = authRequest.login(callback);
ValidationUtils.throwIf(!response.ok(), response.getMsg());
AuthUser authUser = response.getData();
userSocialService.bind(authUser, UserContextHolder.getUserId());
public void bindSocial(@PathVariable String source, @RequestBody Object callback) {
// 第三方登录已禁用
throw new BadRequestException("第三方登录功能已禁用");
}
@Operation(summary = "解绑三方账号", description = "解绑三方账号")
@@ -137,4 +129,4 @@ public class UserCenterController {
public void unbindSocial(@PathVariable String source) {
userSocialService.deleteBySourceAndUserId(source, UserContextHolder.getUserId());
}
}
}

View File

@@ -2,7 +2,6 @@ package top.wms.admin.controller.tcp.service;
import io.netty.channel.Channel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import top.wms.admin.controller.tcp.manager.ChannelManager;
import top.wms.admin.controller.tcp.model.VMResult;
import lombok.extern.slf4j.Slf4j;
@@ -61,7 +60,7 @@ public class CommandService {
@Autowired
private ChannelManager channelManager;
// @Scheduled(cron = "*/1 * * * * ?")
// @Scheduled(cron = "*/1 * * * * ?")
public void sendAndWait() {
// 1. 检查连接
log.info("查询时间========");

View File

@@ -41,9 +41,9 @@ public class WorkOrderController extends BaseController<WorkOrderService, WorkOr
return baseService.getWorkOrderInfos(id);
}
/**
* 打印标签时调用得接口
*
* @param id
* @return
*/

View File

@@ -6,8 +6,6 @@ import com.fazecast.jSerialComm.SerialPortEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.nio.charset.Charset;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -49,7 +47,7 @@ public class AHDZCConnect {
private ScheduledExecutorService executorService;
// @PostConstruct
// @PostConstruct
public void init() {
// 项目启动时初始化并启动服务
ScaleService();
@@ -57,7 +55,7 @@ public class AHDZCConnect {
}
// @PreDestroy
// @PreDestroy
public void destroy() {
// 项目关闭时停止服务
stop();

View File

@@ -8,11 +8,17 @@ server:
# HTTP 端口(默认 6609
port: 6609
--- ### 排除自动配置
spring:
autoconfigure:
exclude:
- com.xkcoding.justauth.autoconfigure.JustAuthAutoConfiguration
--- ### 数据源配置
spring.datasource:
type: com.zaxxer.hikari.HikariDataSource
# 请务必提前创建好名为 wms_admin 的数据库,如果使用其他数据库名请注意同步修改 DB_NAME 配置
url: jdbc:p6spy:mysql://127.0.0.1:3306/wms?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
url: jdbc:p6spy:mysql://127.0.0.1:3306/wms?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: root
# PostgreSQL 配置
@@ -55,9 +61,9 @@ spring.data:
# 密码(未设置密码时请注释掉)
# password: ${REDIS_PWD:redis2025}
# 数据库索引
database: ${REDIS_DB:1}
database: ${REDIS_DB:0}
# 连接超时时间
timeout: 10s
timeout: 5s
# 是否开启 SSL
ssl:
enabled: false
@@ -100,15 +106,7 @@ jetcache:
continew-starter.captcha:
## 行为验证码
behavior:
enabled: true
cache-type: REDIS
water-mark:
# 一分钟内接口请求次数限制开关默认0关闭开启后下方失败锁定配置才会生效
req-frequency-limit-enable: 0
# 一分钟内验证码最多失败次数限制默认5次
req-get-lock-limit: 5
# 一分钟内验证码最多失败次数限制达标后锁定时间默认300秒
req-get-lock-seconds: 300
enabled: false
## 图形验证码
graphic:
# 类型
@@ -160,6 +158,7 @@ continew-starter.web.cors:
# 配置允许跨域的响应头
exposed-headers: '*'
--- ### 接口文档配置
springdoc:
swagger-ui:
@@ -172,39 +171,39 @@ continew-starter.messaging.websocket:
# 配置允许跨域的域名
allowed-origins: '*'
--- ### 短信配置
sms:
# 从 YAML 读取配置
config-type: YAML
http-log: true
is-print: false
blends:
cloopen:
# 短信厂商
supplier: cloopen
base-url: https://app.cloopen.com:8883/2013-12-26
access-key-id: 你的Access Key
access-key-secret: 你的Access Key Secret
sdk-app-id: 你的应用ID
--- ### 短信配置(已禁用)
# sms:
# # 从 YAML 读取配置
# config-type: YAML
# http-log: true
# is-print: false
# blends:
# cloopen:
# # 短信厂商
# supplier: cloopen
# base-url: https://app.cloopen.com:8883/2013-12-26
# access-key-id: 你的Access Key
# access-key-secret: 你的Access Key Secret
# sdk-app-id: 你的应用ID
--- ### 邮件配置
spring.mail:
# 根据需要更换
host: smtp.126.com
port: 465
username: 你的邮箱
password: 你的邮箱授权码
properties:
mail:
smtp:
auth: true
socketFactory:
class: javax.net.ssl.SSLSocketFactory
port: 465
--- ### 邮件配置(已禁用)
# spring.mail:
# # 根据需要更换
# host: smtp.126.com
# port: 465
# username: 你的邮箱
# password: 你的邮箱授权码
# properties:
# mail:
# smtp:
# auth: true
# socketFactory:
# class: javax.net.ssl.SSLSocketFactory
# port: 465
--- ### Just Auth 配置
justauth:
enabled: true
enabled: false
type:
GITEE:
client-id: 5d271b7f638941812aaf8bfc2e2f08f06d6235ef934e0e39537e2364eb8452c4
@@ -325,22 +324,24 @@ snail-job:
# 队列容量
queueCapacity: 10000
uni:
url: http://wo-api.uni-ubi.com/
appKey: 7834BC94180542C6BFD7031B39266E6F
appSecret: 97386E6DCEFC4758810CC720DC669662
projectGuid: 114C2FC2EA0B4A848C5F9AF23400E6F9
# uni配置已禁用
# uni:
# url: http://wo-api.uni-ubi.com/
# appKey: 7834BC94180542C6BFD7031B39266E6F
# appSecret: 97386E6DCEFC4758810CC720DC669662
# projectGuid: 114C2FC2EA0B4A848C5F9AF23400E6F9
# Minio配置
minio:
url: http://81.68.71.142:9000
accessKey: admin
secretKey: JYadmin@1234
bucketName: employees
bucketName1: visitor
bucketName2: cars
bucketName3: others
gwurl: http://81.68.71.142:9000
# Minio配置(已禁用,使用本地存储)
# minio:
# url: http://81.68.71.142:9000
# accessKey: admin
# secretKey: JYadmin@1234
# bucketName: employees
# bucketName1: visitor
# bucketName2: cars
# bucketName3: others
# gwurl: http://81.68.71.142:9000
sdk:
upload: http://81.68.71.142:7701/
# sdk配置已禁用
# sdk:
# upload: http://81.68.71.142:7701/

View File

@@ -40,13 +40,8 @@ logging:
--- ### 链路跟踪配置
continew-starter.web:
trace:
enabled: true
enabled: false
trace-id-name: traceId
## TLog 配置
tlog:
enable-invoke-time-print: false
pattern: '[$spanId][$traceId]'
mdc-enable: false
--- ### 全局响应配置
continew-starter.web:
@@ -293,4 +288,4 @@ spring:
management.health:
mail:
# 关闭邮箱健康检查(邮箱配置错误或邮箱服务器不可用时,健康检查会报错)
enabled: false
enabled: false

View File

@@ -25,7 +25,7 @@
<!-- 输出日志到控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
@@ -33,7 +33,7 @@
<!-- 输出日志到控制台(不带颜色) -->
<appender name="CONSOLE_PROD" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
@@ -52,14 +52,14 @@
<!-- 日志保留天数 -->
<maxHistory>${FILE_MAX_HISTORY}</maxHistory>
</rollingPolicy>
<encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
</appender>
<!-- 输出日志到文件(异步) -->
<appender name="ASYNC_FILE" class="com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender">
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志,默认:如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度该值会影响性能默认256 -->
@@ -85,4 +85,4 @@
<!-- 日志保留天数(根据国家法律,网络运行状态、网络安全事件、个人敏感信息操作等相关记录,留存的日志不少于六个月,并且进行网络多机备份。) -->
<property name="FILE_MAX_HISTORY" value="180"/>
</springProfile>
</configuration>
</configuration>