This commit is contained in:
@@ -28,11 +28,39 @@ public class CaptchaController {
|
||||
|
||||
private final BladeRedis bladeRedis;
|
||||
|
||||
/**
|
||||
* 获取图形验证码
|
||||
*/
|
||||
@GetMapping("/oauth/captcha")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "获取图形验证码", description = "返回验证码图片和key")
|
||||
public R<java.util.Map<String, String>> getCaptcha() {
|
||||
// 生成唯一key
|
||||
String key = java.util.UUID.randomUUID().toString().replace("-", "");
|
||||
|
||||
// 生成4位随机验证码
|
||||
String code = generateCode(4);
|
||||
|
||||
// 存储验证码到Redis,有效期5分钟
|
||||
String cacheKey = CacheNames.CAPTCHA_KEY + key;
|
||||
bladeRedis.setEx(cacheKey, code.toLowerCase(), Duration.ofMinutes(5));
|
||||
|
||||
// 生成验证码图片(简单的base64图片)
|
||||
String image = generateCaptchaImage(code);
|
||||
|
||||
// 返回结果
|
||||
java.util.Map<String, String> result = new java.util.HashMap<>();
|
||||
result.put("key", key);
|
||||
result.put("image", image);
|
||||
|
||||
return R.data(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
*/
|
||||
@PostMapping("/send")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "发送短信验证码", description = "传入手机号")
|
||||
public R send(@Parameter(description = "手机号", required = true) @RequestParam String phone) {
|
||||
// 验证手机号格式
|
||||
@@ -78,4 +106,62 @@ public class CaptchaController {
|
||||
}
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码图片(Base64格式)
|
||||
* 使用 SVG 格式生成验证码,避免字体依赖问题
|
||||
*
|
||||
* @param code 验证码文本
|
||||
* @return Base64编码的图片
|
||||
*/
|
||||
private String generateCaptchaImage(String code) {
|
||||
Random random = new Random();
|
||||
StringBuilder svg = new StringBuilder();
|
||||
|
||||
svg.append("<svg xmlns='http://www.w3.org/2000/svg' width='120' height='40'>");
|
||||
|
||||
// 背景
|
||||
svg.append("<rect width='120' height='40' fill='#f8f9fa'/>");
|
||||
|
||||
// 绘制验证码字符
|
||||
for (int i = 0; i < code.length(); i++) {
|
||||
char c = code.charAt(i);
|
||||
int x = 15 + i * 25;
|
||||
int y = 25 + random.nextInt(5) - 2;
|
||||
int rotate = random.nextInt(30) - 15;
|
||||
|
||||
// 随机颜色
|
||||
String color = String.format("#%02x%02x%02x",
|
||||
random.nextInt(100),
|
||||
random.nextInt(100),
|
||||
random.nextInt(100));
|
||||
|
||||
svg.append(String.format(
|
||||
"<text x='%d' y='%d' font-size='28' font-weight='bold' fill='%s' transform='rotate(%d %d %d)'>%c</text>",
|
||||
x, y, color, rotate, x, y, c
|
||||
));
|
||||
}
|
||||
|
||||
// 添加干扰线
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int x1 = random.nextInt(120);
|
||||
int y1 = random.nextInt(40);
|
||||
int x2 = random.nextInt(120);
|
||||
int y2 = random.nextInt(40);
|
||||
String color = String.format("#%02x%02x%02x",
|
||||
random.nextInt(200) + 50,
|
||||
random.nextInt(200) + 50,
|
||||
random.nextInt(200) + 50);
|
||||
|
||||
svg.append(String.format(
|
||||
"<line x1='%d' y1='%d' x2='%d' y2='%d' stroke='%s' stroke-width='1'/>",
|
||||
x1, y1, x2, y2, color
|
||||
));
|
||||
}
|
||||
|
||||
svg.append("</svg>");
|
||||
|
||||
// 转换为 Base64
|
||||
return "data:image/svg+xml;base64," + java.util.Base64.getEncoder().encodeToString(svg.toString().getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,4 +75,13 @@ public class MartialDeductionItemController extends BladeController {
|
||||
return R.status(deductionItemService.removeByIds(Func.toLongList(ids)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新排序
|
||||
*/
|
||||
@PostMapping("/update-order")
|
||||
@Operation(summary = "更新排序", description = "传入排序数据")
|
||||
public R updateOrder(@RequestBody List<MartialDeductionItem> sortData) {
|
||||
return R.status(deductionItemService.updateOrder(sortData));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.springblade.modules.martial.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springblade.modules.martial.pojo.entity.MartialDeductionItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DeductionItem 服务类
|
||||
*
|
||||
@@ -10,4 +12,12 @@ import org.springblade.modules.martial.pojo.entity.MartialDeductionItem;
|
||||
*/
|
||||
public interface IMartialDeductionItemService extends IService<MartialDeductionItem> {
|
||||
|
||||
/**
|
||||
* 批量更新排序
|
||||
*
|
||||
* @param sortData 排序数据
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateOrder(List<MartialDeductionItem> sortData);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.springblade.modules.martial.mapper.MartialDeductionItemMapper;
|
||||
import org.springblade.modules.martial.service.IMartialDeductionItemService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DeductionItem 服务实现类
|
||||
*
|
||||
@@ -14,4 +16,23 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class MartialDeductionItemServiceImpl extends ServiceImpl<MartialDeductionItemMapper, MartialDeductionItem> implements IMartialDeductionItemService {
|
||||
|
||||
@Override
|
||||
public boolean updateOrder(List<MartialDeductionItem> sortData) {
|
||||
if (sortData == null || sortData.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 批量更新排序
|
||||
for (MartialDeductionItem item : sortData) {
|
||||
if (item.getId() != null && item.getSortOrder() != null) {
|
||||
MartialDeductionItem updateItem = new MartialDeductionItem();
|
||||
updateItem.setId(item.getId());
|
||||
updateItem.setSortOrder(item.getSortOrder());
|
||||
this.updateById(updateItem);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user