将获取二维码图片以及URL的逻辑独立抽出来, 方便两个系统调用同一套逻辑

This commit is contained in:
mirage 2026-02-28 15:57:54 +08:00
parent 1f7bfde802
commit d1aab1459f
6 changed files with 104 additions and 70 deletions

View File

@ -31,13 +31,14 @@
</el-select>
</el-form-item>
<el-form-item label="角色" prop="roleId">
<!-- 非超管账号, 在编辑时置灰 -->
<el-select
v-model="formData.roleId"
class="flex-1"
multiple
placeholder="请选择角色"
clearable
:disabled="!isSuperAdmin"
:disabled="!isSuperAdmin && mode === 'edit'"
>
<el-option
v-for="(item, index) in optionsData.role"

View File

@ -14,6 +14,7 @@ import com.mdd.common.core.PageResult;
import com.mdd.common.aop.NotPower;
import com.mdd.common.entity.system.SystemRole;
import com.mdd.admin.vo.teacher.TeacherOptionVo;
import com.mdd.common.service.QrCodeService;
import com.mdd.common.validator.annotation.IDMust;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -31,6 +32,8 @@ public class TeacherController {
@Resource
ITeacherService iTeacherService;
@Resource
QrCodeService qrCodeService;
@GetMapping("/list")
@ApiOperation(value = "教师信息扩展列表")
@ -102,13 +105,13 @@ public class TeacherController {
@GetMapping("/qrcode")
@ApiOperation(value = "获取二维码图片URL", notes = "获取指定教师的二维码图片访问地址")
public AjaxResult<Object> getQrCodeUrl(@Validated @IDMust() @RequestParam("id") Integer id) {
return iTeacherService.getQrCodeUrl(id);
return qrCodeService.getQrCodeUrl(id);
}
@GetMapping("/qrcode/image")
@ApiOperation(value = "获取二维码图片流", notes = "带鉴权返回教师二维码图片,用于前端展示与下载")
public ResponseEntity<byte[]> getQrCodeImage(@Validated @IDMust() @RequestParam("id") Integer id) {
byte[] bytes = iTeacherService.getQrCodeImageBytes(id);
byte[] bytes = qrCodeService.getQrCodeImageBytes(id);
if (bytes == null || bytes.length == 0) {
return ResponseEntity.notFound().build();
}

View File

@ -74,23 +74,6 @@ public interface ITeacherService {
*/
AjaxResult<Object> generateInvitationCode(Integer teacherId);
/**
* 获取二维码图片URL
*
* @param teacherId 教师ID
* @return AjaxResult<String> 返回二维码图片的绝对URL
* @author gyp
*/
AjaxResult<Object> getQrCodeUrl(Integer teacherId);
/**
* 获取二维码图片字节流用于带鉴权的图片展示与下载
*
* @param teacherId 教师ID
* @return 图片字节数组不存在时返回 null
*/
byte[] getQrCodeImageBytes(Integer teacherId);
/**
* 教师下拉选项列表仅id和姓名
*/

View File

@ -548,56 +548,6 @@ public class TeacherServiceImpl implements ITeacherService {
}
}
/**
* 获取二维码图片URL
*
* @param teacherId 教师ID
* @return AjaxResult<String> 返回二维码图片的绝对URL
*/
@Override
public AjaxResult<Object> getQrCodeUrl(Integer teacherId) {
Teacher teacher = teacherMapper.selectOne(
new QueryWrapper<Teacher>()
.eq("teacher_id", teacherId)
.last("limit 1"));
Assert.notNull(teacher, "教师不存在!");
if (teacher.getQrcodeUrl() == null || teacher.getQrcodeUrl().isEmpty()) {
return AjaxResult.failed("该教师尚未生成二维码,请先生成邀请码");
}
// 转换为后台端可访问的绝对URL/adminapi/uploads/**
String absoluteUrl = UrlUtils.toAdminAbsoluteUrl(teacher.getQrcodeUrl());
return AjaxResult.success(absoluteUrl);
}
@Override
public byte[] getQrCodeImageBytes(Integer teacherId) {
Teacher teacher = teacherMapper.selectOne(
new QueryWrapper<Teacher>()
.eq("teacher_id", teacherId)
.last("limit 1"));
if (teacher == null || teacher.getQrcodeUrl() == null || teacher.getQrcodeUrl().isEmpty()) {
return null;
}
String engine = ConfigUtils.get("storage", "default", "local");
engine = engine == null || engine.isEmpty() ? "local" : engine;
if (!"local".equals(engine)) {
return null;
}
String path = teacher.getQrcodeUrl().startsWith("/") ? teacher.getQrcodeUrl().substring(1) : teacher.getQrcodeUrl();
java.io.File file = new java.io.File(path);
if (!file.exists() || !file.isFile()) {
return null;
}
try {
return java.nio.file.Files.readAllBytes(file.toPath());
} catch (java.io.IOException e) {
return null;
}
}
/**
* 删除旧的二维码文件
*

View File

@ -0,0 +1,73 @@
package com.mdd.common.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mdd.common.core.AjaxResult;
import com.mdd.common.entity.Teacher;
import com.mdd.common.mapper.TeacherMapper;
import com.mdd.common.util.ConfigUtils;
import com.mdd.common.util.UrlUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
@Service
public class QrCodeService {
@Resource
private TeacherMapper teacherMapper;
/**
* 获取二维码图片URL
*
* @param teacherId 教师ID
* @return AjaxResult<String> 返回二维码图片的绝对URL
*/
public AjaxResult<Object> getQrCodeUrl(Integer teacherId) {
Teacher teacher = teacherMapper.selectOne(
new QueryWrapper<Teacher>()
.eq("teacher_id", teacherId)
.last("limit 1"));
Assert.notNull(teacher, "教师不存在!");
if (teacher.getQrcodeUrl() == null || teacher.getQrcodeUrl().isEmpty()) {
return AjaxResult.failed("该教师尚未生成二维码,请先生成邀请码");
}
// 转换为后台端可访问的绝对URL/adminapi/uploads/**
String absoluteUrl = UrlUtils.toAdminAbsoluteUrl(teacher.getQrcodeUrl());
return AjaxResult.success(absoluteUrl);
}
/**
* 获取二维码图片字节流用于带鉴权的图片展示与下载
*
* @param teacherId 教师ID
* @return 图片字节数组不存在时返回 null
*/
public byte[] getQrCodeImageBytes(Integer teacherId) {
Teacher teacher = teacherMapper.selectOne(
new QueryWrapper<Teacher>()
.eq("teacher_id", teacherId)
.last("limit 1"));
if (teacher == null || teacher.getQrcodeUrl() == null || teacher.getQrcodeUrl().isEmpty()) {
return null;
}
String engine = ConfigUtils.get("storage", "default", "local");
engine = engine == null || engine.isEmpty() ? "local" : engine;
if (!"local".equals(engine)) {
return null;
}
String path = teacher.getQrcodeUrl().startsWith("/") ? teacher.getQrcodeUrl().substring(1) : teacher.getQrcodeUrl();
java.io.File file = new java.io.File(path);
if (!file.exists() || !file.isFile()) {
return null;
}
try {
return java.nio.file.Files.readAllBytes(file.toPath());
} catch (java.io.IOException e) {
return null;
}
}
}

View File

@ -2,12 +2,16 @@ package com.mdd.front.controller;
import com.mdd.common.core.AjaxResult;
import com.mdd.common.core.PageResult;
import com.mdd.common.service.QrCodeService;
import com.mdd.common.validator.annotation.IDMust;
import com.mdd.front.service.ITeacherService;
import com.mdd.front.validate.common.PageValidate;
import com.mdd.front.validate.teacher.TeacherSearchValidate;
import com.mdd.front.vo.teacher.TeacherListedVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -20,6 +24,8 @@ public class TeacherController {
@Resource
ITeacherService iTeacherService;
@Resource
private QrCodeService qrCodeService;
@GetMapping("/list")
@ApiOperation(value = "教师信息扩展列表")
@ -34,4 +40,22 @@ public class TeacherController {
public AjaxResult<TeacherListedVo> getTeacherInfo(@RequestBody TeacherSearchValidate searchValidate) {
return iTeacherService.getTeacherInfo(searchValidate);
}
@GetMapping("/qrcode")
@ApiOperation(value = "获取二维码图片URL", notes = "获取指定教师的二维码图片访问地址")
public AjaxResult<Object> getQrCodeUrl(@Validated @IDMust() @RequestParam("id") Integer id) {
return qrCodeService.getQrCodeUrl(id);
}
@GetMapping("/qrcode/image")
@ApiOperation(value = "获取二维码图片流", notes = "带鉴权返回教师二维码图片,用于前端展示与下载")
public ResponseEntity<byte[]> getQrCodeImage(@Validated @IDMust() @RequestParam("id") Integer id) {
byte[] bytes = qrCodeService.getQrCodeImageBytes(id);
if (bytes == null || bytes.length == 0) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok()
.contentType(MediaType.IMAGE_PNG)
.body(bytes);
}
}