1. 修改文件存储方式, 现支持阿里云OSS云存储
2. 修改二维码生成方式, 改成从微信官方获取二维码, 而不是第三方. 这样扫二维码就能直接打开页面
This commit is contained in:
parent
7b710b1875
commit
af00c3cbc6
|
|
@ -25,12 +25,18 @@ import com.mdd.common.mapper.TeacherMapper;
|
||||||
import com.mdd.common.mapper.admin.AdminMapper;
|
import com.mdd.common.mapper.admin.AdminMapper;
|
||||||
import com.mdd.common.mapper.system.SystemRoleMapper;
|
import com.mdd.common.mapper.system.SystemRoleMapper;
|
||||||
import com.mdd.common.exception.OperateException;
|
import com.mdd.common.exception.OperateException;
|
||||||
|
import com.mdd.common.plugin.storage.engine.AliyunStorage;
|
||||||
import com.mdd.common.service.RegisterService;
|
import com.mdd.common.service.RegisterService;
|
||||||
|
import com.mdd.common.plugin.wechat.WxMnpDriver;
|
||||||
import com.mdd.common.util.*;
|
import com.mdd.common.util.*;
|
||||||
import com.google.zxing.WriterException;
|
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -373,25 +379,29 @@ public class TeacherServiceImpl implements ITeacherService {
|
||||||
|
|
||||||
Assert.notNull(teacher, "教师不存在!");
|
Assert.notNull(teacher, "教师不存在!");
|
||||||
|
|
||||||
// 生成唯一邀请码:INV + 时间戳(秒) + 6位随机字符串
|
// 生成固定邀请码:INV + 教师ID + 校验码
|
||||||
String invitationCode;
|
String invitationCode = "INV" + teacherId + String.format("%06d", teacherId % 1000000);
|
||||||
do {
|
|
||||||
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
// 检查邀请码是否已被其他教师使用
|
||||||
String randomStr = ToolUtils.randomString(6).toUpperCase();
|
Teacher existingTeacher = teacherMapper.selectOne(
|
||||||
invitationCode = "INV" + timestamp + randomStr;
|
|
||||||
} while (teacherMapper.selectCount(
|
|
||||||
new QueryWrapper<Teacher>()
|
new QueryWrapper<Teacher>()
|
||||||
.eq("invitation_code", invitationCode)
|
.eq("invitation_code", invitationCode)
|
||||||
.ne("teacher_id", teacherId)) > 0);
|
.ne("teacher_id", teacherId)
|
||||||
|
.last("limit 1"));
|
||||||
|
if (existingTeacher != null) {
|
||||||
|
// 如果冲突,使用时间戳作为补充
|
||||||
|
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
||||||
|
invitationCode = "INV" + teacherId + timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
// 生成二维码内容URL(预报名页面地址)
|
// 生成微信小程序码页面路径(预报名页面)
|
||||||
String qrCodeContent = buildQrCodeUrl(invitationCode);
|
String miniProgramPage = buildMiniProgramPagePath();
|
||||||
|
|
||||||
// 删除旧的二维码文件(如果存在)
|
// 删除旧的二维码文件(如果存在)
|
||||||
deleteOldQrCodeFile(teacher.getQrcodeUrl());
|
deleteOldQrCodeFile(teacher.getQrcodeUrl());
|
||||||
|
|
||||||
// 生成二维码图片并保存
|
// 生成微信小程序码并保存
|
||||||
String qrcodeUrl = generateAndSaveQrCode(invitationCode, qrCodeContent, teacherId);
|
String qrcodeUrl = generateAndSaveQrCode(invitationCode, miniProgramPage, teacherId);
|
||||||
|
|
||||||
// 更新教师表的邀请码和二维码地址
|
// 更新教师表的邀请码和二维码地址
|
||||||
teacher.setInvitationCode(invitationCode);
|
teacher.setInvitationCode(invitationCode);
|
||||||
|
|
@ -403,81 +413,38 @@ public class TeacherServiceImpl implements ITeacherService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建二维码内容URL(预报名页面地址)
|
* 构建微信小程序页面路径
|
||||||
*
|
*
|
||||||
* @param invitationCode 邀请码
|
* @return 小程序页面路径
|
||||||
* @return 完整的预报名页面URL
|
|
||||||
*/
|
*/
|
||||||
private String buildQrCodeUrl(String invitationCode) {
|
private String buildMiniProgramPagePath() {
|
||||||
// 优先从配置中读取预报名H5地址(建议配置为 uniapp H5 根,如:https://xx.com/h5)
|
return "pages/pre_registration/pre_registration";
|
||||||
String h5BaseUrl = ConfigUtils.get("pre_registration", "front_url", "");
|
|
||||||
|
|
||||||
if (h5BaseUrl == null || h5BaseUrl.isEmpty()) {
|
|
||||||
// 如果没有单独配置,尝试从 yml 中读取 like.front-url
|
|
||||||
String frontUrl = YmlUtils.get("like.front-url");
|
|
||||||
if (frontUrl != null && !frontUrl.isEmpty()) {
|
|
||||||
h5BaseUrl = frontUrl;
|
|
||||||
} else {
|
|
||||||
// 再退一步,使用当前请求域名
|
|
||||||
h5BaseUrl = UrlUtils.getRequestUrl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h5BaseUrl == null) {
|
|
||||||
h5BaseUrl = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除末尾的斜杠,方便统一拼接
|
|
||||||
while (h5BaseUrl.endsWith("/")) {
|
|
||||||
h5BaseUrl = h5BaseUrl.substring(0, h5BaseUrl.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
String fullUrl;
|
|
||||||
if (h5BaseUrl.contains("#/")) {
|
|
||||||
// 如果已经配置了完整的 hash 路径(例如:https://xx.com/h5/#/pages/pre_registration/pre_registration)
|
|
||||||
// 这里只负责追加或合并 invitationCode 参数
|
|
||||||
if (h5BaseUrl.contains("?")) {
|
|
||||||
fullUrl = h5BaseUrl + "&invitationCode=" + invitationCode;
|
|
||||||
} else {
|
|
||||||
fullUrl = h5BaseUrl + "?invitationCode=" + invitationCode;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 默认拼接为小程序路径(去除H5的hash模式,以便微信扫码直接进入小程序):
|
|
||||||
// {h5BaseUrl}/pages/pre_registration/pre_registration?invitationCode=xxx
|
|
||||||
fullUrl = h5BaseUrl
|
|
||||||
/*+ "/pages/pre_registration/pre_registration.html"
|
|
||||||
+ "?invitationCode=" + invitationCode*/;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fullUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成二维码图片并保存(方案B:本地存储,预留方案A:OSS上传)
|
* 生成微信小程序码并保存(方案B:本地存储,预留方案A:OSS上传)
|
||||||
*
|
*
|
||||||
* @param invitationCode 邀请码
|
* @param invitationCode 邀请码
|
||||||
* @param qrCodeContent 二维码内容
|
* @param miniProgramPage 小程序页面路径
|
||||||
* @param teacherId 教师ID
|
* @param teacherId 教师ID
|
||||||
* @return 二维码图片的相对路径URL
|
* @return 小程序码图片的相对路径URL
|
||||||
*/
|
*/
|
||||||
private String generateAndSaveQrCode(String invitationCode, String qrCodeContent, Integer teacherId) {
|
private String generateAndSaveQrCode(String invitationCode, String miniProgramPage, Integer teacherId) {
|
||||||
|
// 获取存储引擎配置
|
||||||
|
String engine = ConfigUtils.get("storage", "default", "local");
|
||||||
|
engine = engine == null || engine.isEmpty() ? "local" : engine;
|
||||||
|
|
||||||
|
String qrcodeUrl;
|
||||||
|
String date = TimeUtils.timestampToDate(TimeUtils.timestamp(), "yyyyMMdd");
|
||||||
|
String fileName = "teacher_" + teacherId + "_qrcode.png"; // 使用固定文件名
|
||||||
|
WxMaQrcodeService qrcodeService = WxMnpDriver.mnp().getQrcodeService();
|
||||||
|
File wxCodeFile = null;
|
||||||
try {
|
try {
|
||||||
// 二维码图片尺寸
|
wxCodeFile = qrcodeService.createWxaCodeUnlimit(invitationCode, miniProgramPage, false, "develop", 430, true, null, false);
|
||||||
int qrCodeWidth = 300;
|
|
||||||
int qrCodeHeight = 300;
|
|
||||||
|
|
||||||
// 获取存储引擎配置
|
|
||||||
String engine = ConfigUtils.get("storage", "default", "local");
|
|
||||||
engine = engine == null || engine.isEmpty() ? "local" : engine;
|
|
||||||
|
|
||||||
String qrcodeUrl;
|
|
||||||
String date = TimeUtils.timestampToDate(TimeUtils.timestamp(), "yyyyMMdd");
|
|
||||||
String fileName = "teacher_" + teacherId + "_" + invitationCode + ".png";
|
|
||||||
String fileKey = date + "/" + fileName;
|
|
||||||
|
|
||||||
if ("local".equals(engine)) {
|
if ("local".equals(engine)) {
|
||||||
// ========== 方案B:本地存储 ==========
|
// ========== 方案B:本地存储 ==========
|
||||||
String folder = "qrcode/teacher";
|
String folder = "likeadmin/qrcode/teacher";
|
||||||
String savePath = (folder + "/" + date).replace("\\", "/");
|
String savePath = (folder + "/" + date).replace("\\", "/");
|
||||||
File saveDir = new File(savePath);
|
File saveDir = new File(savePath);
|
||||||
if (!saveDir.exists()) {
|
if (!saveDir.exists()) {
|
||||||
|
|
@ -487,64 +454,54 @@ public class TeacherServiceImpl implements ITeacherService {
|
||||||
}
|
}
|
||||||
|
|
||||||
File qrCodeFile = new File(savePath, fileName);
|
File qrCodeFile = new File(savePath, fileName);
|
||||||
QrCodeUtil.generateQrCodeToFile(qrCodeContent, qrCodeWidth, qrCodeHeight, qrCodeFile.getAbsolutePath());
|
Files.copy(wxCodeFile.toPath(), qrCodeFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
// 返回相对路径
|
// 返回相对路径
|
||||||
qrcodeUrl = folder + "/" + fileKey;
|
qrcodeUrl = folder + "/" + fileName;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// ========== 方案A:OSS上传(预留代码) ==========
|
// ========== 方案A:OSS上传(预留代码) ==========
|
||||||
// 注意:OSS上传需要MultipartFile,这里需要将byte[]转换为临时文件再上传
|
// 注意:OSS上传需要结合具体存储引擎实现,这里先保留文件生成结果
|
||||||
// 或者直接使用OSS的putObject方法上传字节流
|
String folder = "likeadmin/qrcode/teacher";
|
||||||
|
String ossKey = folder + "/" + fileName;
|
||||||
|
|
||||||
// 方案A-1:使用临时文件上传(适用于所有OSS)
|
switch (engine) {
|
||||||
File tempFile = File.createTempFile("qrcode_", ".png");
|
case "aliyun":
|
||||||
try {
|
|
||||||
QrCodeUtil.generateQrCodeToFile(qrCodeContent, qrCodeWidth, qrCodeHeight, tempFile.getAbsolutePath());
|
|
||||||
|
|
||||||
String folder = "qrcode/teacher";
|
|
||||||
String ossKey = folder + "/" + fileKey;
|
|
||||||
|
|
||||||
if ("aliyun".equals(engine)) {
|
|
||||||
// 阿里云OSS上传
|
// 阿里云OSS上传
|
||||||
/*
|
|
||||||
Map<String, String> config = ConfigUtils.getMap("storage", "aliyun");
|
Map<String, String> config = ConfigUtils.getMap("storage", "aliyun");
|
||||||
AliyunStorage aliyunStorage = new AliyunStorage(config);
|
AliyunStorage aliyunStorage = new AliyunStorage(config);
|
||||||
// 需要将File转换为MultipartFile或使用OSS的putObject方法
|
// 需要将File转换为MultipartFile或使用OSS的putObject方法
|
||||||
// 这里使用OSS直接上传字节流的方式
|
// 这里使用OSS直接上传字节流的方式
|
||||||
com.aliyun.oss.OSS ossClient = aliyunStorage.ossClient();
|
com.aliyun.oss.OSS ossClient = aliyunStorage.ossClient();
|
||||||
try {
|
try {
|
||||||
ossClient.putObject(config.get("bucket"), ossKey, new FileInputStream(tempFile));
|
ossClient.putObject(config.get("bucket"), ossKey, java.nio.file.Files.newInputStream(wxCodeFile.toPath()));
|
||||||
qrcodeUrl = ossKey;
|
|
||||||
} finally {
|
} finally {
|
||||||
ossClient.shutdown();
|
ossClient.shutdown();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// TODO: 实现阿里云OSS上传逻辑
|
// TODO: 实现阿里云OSS上传逻辑
|
||||||
qrcodeUrl = ossKey;
|
qrcodeUrl = ossKey;
|
||||||
} else if ("qiniu".equals(engine)) {
|
break;
|
||||||
|
case "qiniu":
|
||||||
// 七牛云上传
|
// 七牛云上传
|
||||||
// TODO: 实现七牛云上传逻辑
|
// TODO: 实现七牛云上传逻辑
|
||||||
qrcodeUrl = ossKey;
|
qrcodeUrl = ossKey;
|
||||||
} else if ("qcloud".equals(engine)) {
|
break;
|
||||||
|
case "qcloud":
|
||||||
// 腾讯云COS上传
|
// 腾讯云COS上传
|
||||||
// TODO: 实现腾讯云COS上传逻辑
|
// TODO: 实现腾讯云COS上传逻辑
|
||||||
qrcodeUrl = ossKey;
|
qrcodeUrl = ossKey;
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
throw new OperateException("不支持的存储引擎: " + engine);
|
throw new OperateException("不支持的存储引擎: " + engine);
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
// 删除临时文件
|
|
||||||
if (tempFile.exists()) {
|
|
||||||
tempFile.delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return qrcodeUrl;
|
return qrcodeUrl;
|
||||||
|
} catch (WxErrorException | IOException e) {
|
||||||
} catch (WriterException | IOException e) {
|
throw new OperateException("生成微信小程序码失败: " + e.getMessage());
|
||||||
throw new OperateException("生成二维码失败: " + e.getMessage());
|
} finally {
|
||||||
|
if (wxCodeFile != null && wxCodeFile.exists()) {
|
||||||
|
wxCodeFile.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -557,16 +514,53 @@ public class TeacherServiceImpl implements ITeacherService {
|
||||||
if (StringUtils.isBlank(oldQrcodeUrl)) {
|
if (StringUtils.isBlank(oldQrcodeUrl)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
String path = oldQrcodeUrl.startsWith("/") ? oldQrcodeUrl.substring(1) : oldQrcodeUrl;
|
// 根据存储引擎判断处理方式
|
||||||
File oldFile = new File(path);
|
String engine = ConfigUtils.get("storage", "default", "local");
|
||||||
if (oldFile.exists() && oldFile.isFile()) {
|
|
||||||
if (!oldFile.delete()) {
|
if ("local".equals(engine)) {
|
||||||
System.err.println("删除旧二维码文件失败: " + path);
|
// 仅对本地存储执行物理删除
|
||||||
|
try {
|
||||||
|
String path = oldQrcodeUrl.startsWith("/") ? oldQrcodeUrl.substring(1) : oldQrcodeUrl;
|
||||||
|
File oldFile = new File(path);
|
||||||
|
if (oldFile.exists() && oldFile.isFile()) {
|
||||||
|
if (!oldFile.delete()) {
|
||||||
|
System.err.println("删除旧二维码文件失败: " + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("删除旧二维码文件时发生异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 对于OSS存储,可以通过配置决定是否删除旧文件
|
||||||
|
// 或者依赖OSS的同名文件覆盖机制,无需显式删除
|
||||||
|
boolean shouldDeleteFromOss = Boolean.parseBoolean(
|
||||||
|
ConfigUtils.get("storage", "delete_old_on_update", "false"));
|
||||||
|
|
||||||
|
if (shouldDeleteFromOss) {
|
||||||
|
// 根据不同OSS类型执行删除操作
|
||||||
|
try {
|
||||||
|
switch (engine) {
|
||||||
|
case "aliyun":
|
||||||
|
// 阿里云OSS删除
|
||||||
|
Map<String, String> config = ConfigUtils.getMap("storage", "aliyun");
|
||||||
|
if (config != null) {
|
||||||
|
AliyunStorage aliyunStorage = new AliyunStorage(config);
|
||||||
|
aliyunStorage.delete(oldQrcodeUrl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "qiniu":
|
||||||
|
// 七牛云删除(预留实现)
|
||||||
|
break;
|
||||||
|
case "qcloud":
|
||||||
|
// 腾讯云COS删除(预留实现)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("删除旧OSS二维码文件时发生异常: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
// 如果不删除旧文件,直接让新文件覆盖即可
|
||||||
System.err.println("删除旧二维码文件时发生异常: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,4 +69,33 @@ public class AliyunStorage {
|
||||||
this.ossClient().deleteObject(this.config.get("bucket"), key);
|
this.ossClient().deleteObject(this.config.get("bucket"), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param key 文件名称
|
||||||
|
* @return 文件字节数组
|
||||||
|
*/
|
||||||
|
public byte[] download(String key) {
|
||||||
|
try {
|
||||||
|
OSS ossClient = this.ossClient();
|
||||||
|
com.aliyun.oss.model.OSSObject ossObject = ossClient.getObject(this.config.get("bucket"), key);
|
||||||
|
if (ossObject != null) {
|
||||||
|
java.io.ByteArrayOutputStream buffer = new java.io.ByteArrayOutputStream();
|
||||||
|
java.io.InputStream inputStream = ossObject.getObjectContent();
|
||||||
|
byte[] data = new byte[1024];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, bytesRead);
|
||||||
|
}
|
||||||
|
inputStream.close();
|
||||||
|
ossObject.close();
|
||||||
|
ossClient.shutdown();
|
||||||
|
return buffer.toByteArray();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,12 @@ public class QcloudStorage {
|
||||||
/**
|
/**
|
||||||
* 鉴权客户端
|
* 鉴权客户端
|
||||||
*
|
*
|
||||||
* @author fzr
|
|
||||||
* @return String
|
* @return String
|
||||||
|
* @author fzr
|
||||||
*/
|
*/
|
||||||
public COSClient cosClient() {
|
public COSClient cosClient() {
|
||||||
String secretId = this.config.get("access_key");
|
String secretId = this.config.get("access_key");
|
||||||
String secretKey = this.config.get("secret_key");
|
String secretKey = this.config.get("secret_key");
|
||||||
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
|
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
|
||||||
Region region = new Region(this.config.get("region"));
|
Region region = new Region(this.config.get("region"));
|
||||||
ClientConfig clientConfig = new ClientConfig(region);
|
ClientConfig clientConfig = new ClientConfig(region);
|
||||||
|
|
@ -53,7 +53,7 @@ public class QcloudStorage {
|
||||||
* 上传文件
|
* 上传文件
|
||||||
*
|
*
|
||||||
* @param multipartFile 文件对象
|
* @param multipartFile 文件对象
|
||||||
* @param key 文件名称 20220331/11.png
|
* @param key 文件名称 20220331/11.png
|
||||||
*/
|
*/
|
||||||
public void upload(MultipartFile multipartFile, String key) {
|
public void upload(MultipartFile multipartFile, String key) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -75,4 +75,33 @@ public class QcloudStorage {
|
||||||
this.cosClient().deleteObject(this.config.get("bucket"), filePath);
|
this.cosClient().deleteObject(this.config.get("bucket"), filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 下载文件
|
||||||
|
// *
|
||||||
|
// * @param key 文件名称
|
||||||
|
// * @return 文件字节数组
|
||||||
|
// */
|
||||||
|
// public byte[] download(String key) {
|
||||||
|
// try {
|
||||||
|
// COSClient cosClient = this.cosClient();
|
||||||
|
// com.qcloud.cos.model.S3Object s3Object = cosClient.getObject(this.config.get("bucket"), key);
|
||||||
|
// if (s3Object != null) {
|
||||||
|
// java.io.ByteArrayOutputStream buffer = new java.io.ByteArrayOutputStream();
|
||||||
|
// java.io.InputStream inputStream = s3Object.getObjectContent();
|
||||||
|
// byte[] data = new byte[1024];
|
||||||
|
// int bytesRead;
|
||||||
|
// while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
|
||||||
|
// buffer.write(data, 0, bytesRead);
|
||||||
|
// }
|
||||||
|
// inputStream.close();
|
||||||
|
// s3Object.close();
|
||||||
|
// cosClient.shutdown();
|
||||||
|
// return buffer.toByteArray();
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,4 +79,46 @@ public class QiniuStorage {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param key 文件名称
|
||||||
|
* @return 文件字节数组
|
||||||
|
*/
|
||||||
|
public byte[] download(String key) {
|
||||||
|
try {
|
||||||
|
String accessKey = this.config.getOrDefault("access_key", "");
|
||||||
|
String secretKey = this.config.getOrDefault("secret_key", "");
|
||||||
|
String bucket = this.config.getOrDefault("bucket", "");
|
||||||
|
String domain = this.config.getOrDefault("domain", "");
|
||||||
|
|
||||||
|
Auth auth = Auth.create(accessKey, secretKey);
|
||||||
|
String downloadUrl = auth.privateDownloadUrl(domain + "/" + key);
|
||||||
|
|
||||||
|
java.net.URL url = new java.net.URL(downloadUrl);
|
||||||
|
java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
conn.setConnectTimeout(5000);
|
||||||
|
conn.setReadTimeout(5000);
|
||||||
|
|
||||||
|
if (conn.getResponseCode() == 200) {
|
||||||
|
java.io.InputStream inputStream = conn.getInputStream();
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
inputStream.close();
|
||||||
|
conn.disconnect();
|
||||||
|
return outputStream.toByteArray();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,20 +54,57 @@ public class QrCodeService {
|
||||||
if (teacher == null || teacher.getQrcodeUrl() == null || teacher.getQrcodeUrl().isEmpty()) {
|
if (teacher == null || teacher.getQrcodeUrl() == null || teacher.getQrcodeUrl().isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String engine = ConfigUtils.get("storage", "default", "local");
|
String engine = ConfigUtils.get("storage", "default", "local");
|
||||||
engine = engine == null || engine.isEmpty() ? "local" : engine;
|
engine = engine == null || engine.isEmpty() ? "local" : engine;
|
||||||
if (!"local".equals(engine)) {
|
|
||||||
return null;
|
if ("local".equals(engine)) {
|
||||||
}
|
// 本地存储处理
|
||||||
String path = teacher.getQrcodeUrl().startsWith("/") ? teacher.getQrcodeUrl().substring(1) : teacher.getQrcodeUrl();
|
String path = teacher.getQrcodeUrl().startsWith("/") ? teacher.getQrcodeUrl().substring(1) : teacher.getQrcodeUrl();
|
||||||
java.io.File file = new java.io.File(path);
|
java.io.File file = new java.io.File(path);
|
||||||
if (!file.exists() || !file.isFile()) {
|
if (!file.exists() || !file.isFile()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return java.nio.file.Files.readAllBytes(file.toPath());
|
return java.nio.file.Files.readAllBytes(file.toPath());
|
||||||
} catch (java.io.IOException e) {
|
} catch (java.io.IOException e) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// OSS存储处理:使用存储引擎的下载方法
|
||||||
|
try {
|
||||||
|
switch (engine) {
|
||||||
|
case "aliyun":
|
||||||
|
// 阿里云OSS下载
|
||||||
|
java.util.Map<String, String> aliyunConfig = ConfigUtils.getMap("storage", "aliyun");
|
||||||
|
if (aliyunConfig != null) {
|
||||||
|
com.mdd.common.plugin.storage.engine.AliyunStorage aliyunStorage = new com.mdd.common.plugin.storage.engine.AliyunStorage(aliyunConfig);
|
||||||
|
return aliyunStorage.download(teacher.getQrcodeUrl());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "qiniu":
|
||||||
|
// 七牛云下载
|
||||||
|
java.util.Map<String, String> qiniuConfig = ConfigUtils.getMap("storage", "qiniu");
|
||||||
|
if (qiniuConfig != null) {
|
||||||
|
com.mdd.common.plugin.storage.engine.QiniuStorage qiniuStorage = new com.mdd.common.plugin.storage.engine.QiniuStorage(qiniuConfig);
|
||||||
|
return qiniuStorage.download(teacher.getQrcodeUrl());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// case "qcloud":
|
||||||
|
// // 腾讯云COS下载
|
||||||
|
// java.util.Map<String, String> cosConfig = ConfigUtils.getMap("storage", "qcloud");
|
||||||
|
// if (cosConfig != null) {
|
||||||
|
// com.mdd.common.plugin.storage.engine.QcloudStorage qcloudStorage = new com.mdd.common.plugin.storage.engine.QcloudStorage(cosConfig);
|
||||||
|
// return qcloudStorage.download(teacher.getQrcodeUrl());
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ public class TeacherController {
|
||||||
|
|
||||||
@PostMapping("/getTeacherInfo")
|
@PostMapping("/getTeacherInfo")
|
||||||
@ApiOperation(value = "根据查询条件获取教师信息")
|
@ApiOperation(value = "根据查询条件获取教师信息")
|
||||||
public AjaxResult<TeacherListedVo> getTeacherInfo(@RequestBody TeacherSearchValidate searchValidate) {
|
public AjaxResult<Object> getTeacherInfo(@RequestBody TeacherSearchValidate searchValidate) {
|
||||||
return iTeacherService.getTeacherInfo(searchValidate);
|
return iTeacherService.getTeacherInfo(searchValidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,5 +25,5 @@ public interface ITeacherService extends IService<Teacher> {
|
||||||
*/
|
*/
|
||||||
PageResult<TeacherListedVo> list(PageValidate pageValidate, TeacherSearchValidate searchValidate);
|
PageResult<TeacherListedVo> list(PageValidate pageValidate, TeacherSearchValidate searchValidate);
|
||||||
|
|
||||||
AjaxResult<TeacherListedVo> getTeacherInfo(TeacherSearchValidate searchValidate);
|
AjaxResult<Object> getTeacherInfo(TeacherSearchValidate searchValidate);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,25 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> impl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AjaxResult<TeacherListedVo> getTeacherInfo(TeacherSearchValidate searchValidate) {
|
public AjaxResult<Object> getTeacherInfo(TeacherSearchValidate searchValidate) {
|
||||||
|
if (searchValidate.getTeacherId() == null && StringUtils.isBlank(searchValidate.getInvitationCode())) {
|
||||||
|
return AjaxResult.failed("教师参数缺失!");
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (searchValidate.getTeacherId() != null) {
|
||||||
|
queryWrapper.eq("teacher_id", searchValidate.getTeacherId());
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(searchValidate.getInvitationCode())) {
|
||||||
|
queryWrapper.eq("invitation_code", searchValidate.getInvitationCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
Teacher teacher = teacherMapper.selectOne(queryWrapper.last("limit 1"));
|
||||||
|
if (teacher == null) {
|
||||||
|
return AjaxResult.failed("教师不存在!");
|
||||||
|
}
|
||||||
|
|
||||||
TeacherListedVo teacherListedVo = new TeacherListedVo();
|
TeacherListedVo teacherListedVo = new TeacherListedVo();
|
||||||
Teacher teacher = teacherMapper.selectOne(new QueryWrapper<Teacher>().eq("teacher_id", searchValidate.getTeacherId()));
|
|
||||||
BeanUtils.copyProperties(teacher, teacherListedVo);
|
BeanUtils.copyProperties(teacher, teacherListedVo);
|
||||||
College college = collegeMapper.selectById(teacherListedVo.getCollegeId());
|
College college = collegeMapper.selectById(teacherListedVo.getCollegeId());
|
||||||
teacherListedVo.setCreateTime(TimeUtils.timestampToDate(teacher.getCreateTime()));
|
teacherListedVo.setCreateTime(TimeUtils.timestampToDate(teacher.getCreateTime()));
|
||||||
|
|
|
||||||
|
|
@ -232,9 +232,9 @@ const submitBtnStyle = {
|
||||||
boxShadow: '0 8rpx 24rpx rgba(59, 130, 246, 0.3)'
|
boxShadow: '0 8rpx 24rpx rgba(59, 130, 246, 0.3)'
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTeacherData = async (teacherId: string) => {
|
const getTeacherData = async (params: { teacherId?: string; invitationCode?: string }) => {
|
||||||
try {
|
try {
|
||||||
const res = await getTeacherInfo({ teacherId: Number(teacherId) })
|
const res = await getTeacherInfo(params)
|
||||||
if (res.code === 1 && res.data) {
|
if (res.code === 1 && res.data) {
|
||||||
formData.teacher = res.data.teacherName
|
formData.teacher = res.data.teacherName
|
||||||
formData.recruitmentTeacherId = res.data.teacherId
|
formData.recruitmentTeacherId = res.data.teacherId
|
||||||
|
|
@ -430,8 +430,16 @@ onMounted(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
onLoad((options: any) => {
|
onLoad((options: any) => {
|
||||||
|
if (options.scene) {
|
||||||
|
getTeacherData({ invitationCode: decodeURIComponent(options.scene) })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (options.invitationCode) {
|
||||||
|
getTeacherData({ invitationCode: options.invitationCode })
|
||||||
|
return
|
||||||
|
}
|
||||||
if (options.teacherId) {
|
if (options.teacherId) {
|
||||||
getTeacherData(options.teacherId)
|
getTeacherData({ teacherId: options.teacherId })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue