OSS文件上传
1、我们这个系统对接的阿里云OSS需要先对接小鹏OSS系统获取accessKeyId、accessKeySecret,这个可以忽略
aliyun:oss:endpoint: https://oss-cn-hangzhou.aliyuncs.combucketName: xp-xpd-experiencedomain: https://xp-xpd-experience.oss-cn-hangzhou.aliyuncs.com# 目录权限,不能瞎写,msedprod msedtestfolder: msedtest# 上传文件大小maxSizeStr: 3000# redis过期时间(单位:分钟)timeoutKey: 1ossRedisKey: oss:file:keyauth:idTokenUrl: https://ldap.test.xiaopeng.com/oidc/tokenclientId: xp-msed-api-bootclientSecret: ecDLIIhReieMYgvHQgrant_type: client_credentialsstsAccessKeyUrl: http://apisix-gw-ali-hd1.test.xiaopeng.com/voyager-authhub/api/sts/get_tokenpoliceName: XpMsedApiBootTESTOss
2、接口
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)@Operation(summary = "单文件上传")public Result<SysFileRecordVO> uploadFile(@RequestPart MultipartFile file, @RequestParam(value = "folderName", defaultValue = "", required = false) String folderName,@RequestParam(defaultValue = "OTHER", required = false) FileTypeEnum fileType) {return R.successWithData(sysFileRecordService.upload(file, folderName, fileType), "文件上传成功!");}@GetMapping(value = "/previewFile")@Operation(summary = "OSS文件预览")public Result<String> previewFile(@RequestParam(value = "fileName") String fileName) {String url = sysFileRecordService.getUrl(fileName);return R.successWithData(url);}@PostMapping(value = "/uploads", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)@Operation(summary = "多文件上传")Result<List<SysFileRecordVO>> uploadFile(@RequestPart MultipartFile[] files, @RequestParam(defaultValue = "OTHER", required = false) FileTypeEnum fileType) {return R.successWithData(sysFileRecordService.uploads(files, fileType), "文件上传成功!");}@GetMapping(value = "/downloadById/{id}")@Operation(summary = "根据id下载文件")@Parameters({@Parameter(description = "id", in = ParameterIn.PATH, name = "id"), @Parameter(description = "名称", name = "name")})ResponseEntity<byte[]> downloadById(@PathVariable Integer id, String name) {return sysFileRecordService.downloadById(id, name);}@Operation(summary = "文件预览")@GetMapping(value = "/filePreview/{path}")@Parameter(description = "文件路径", name = "path", in = ParameterIn.PATH)public ResponseEntity<byte[]> filePreview(@PathVariable("path") String path) {return sysFileRecordService.filePreview(path);}
service层
@Slf4j
@Primary
@Service(value = "sysOssFileRecordServiceImpl")
@ConditionalOnProperty(name = "oss.env.oss", havingValue = "true", matchIfMissing = true)
public class SysOssFileRecordServiceImpl extends ServiceImpl<SysFileRecordMapper, SysFileRecord> implements SysFileRecordService {@Autowiredprivate OssConfig ossConfig;@Autowiredprivate OssAuthConfig ossAuthConfig;@Autowiredprivate CacheService cacheService;@Override@Transactional(rollbackFor = Exception.class)public SysFileRecordVO upload(MultipartFile file, String folderName, FileTypeEnum fileTypeEnum) {String ossRedisKey = ossConfig.getOssRedisKey();String securityToken = (String) cacheService.hGet(ossRedisKey, "securityToken");String accessKeyIdKey = (String) cacheService.hGet(ossRedisKey, "accessKeyId");String accessKeySecretKey = (String) cacheService.hGet(ossRedisKey, "accessKeySecret");if (StringUtils.isBlank(accessKeyIdKey) && StringUtils.isBlank(accessKeySecretKey)) {Map<String, String> map = getAccessKeyIdSecret();accessKeyIdKey = map.get("accessKeyId");accessKeySecretKey = map.get("accessKeySecret");securityToken = map.get("securityToken");}// Map<String, String> map = getAccessKeyIdSecret();// String accessKeyIdKey = map.get("accessKeyId");// String accessKeySecretKey = map.get("accessKeySecret");// String securityToken = map.get("securityToken");log.info("accessKeyIdKey:{}", accessKeyIdKey);log.info("accessKeySecretKey:{}", accessKeySecretKey);log.info("securityToken:{}", securityToken);log.info("file:{}", file);if (file == null) {throw new ServiceException("文件不能为空");}String originalFilename = file.getOriginalFilename();if (StringUtils.isEmpty(originalFilename)) {throw new ServiceException("文件不能为空");}log.info("originalFilename:{}", originalFilename);// 默认限制2Mfloat maxSize = 2;try {maxSize = Float.parseFloat(ossConfig.getMaxSizeStr());} catch (NumberFormatException e) {log.error("图片允许的大小设置不正确", e);throw new ServiceException("图片允许的大小设置不正确");}if (file.getSize() > (maxSize * 1024 * 1024)) {throw new ServiceException("上传的文件不能大于" + maxSize + "MB");}// 保存文件try {String fileName = saveFile(file, folderName);// 上传阿里云ossString endpoint = ossConfig.getEndpoint();String bucketName = ossConfig.getBucketName();String folder = ossConfig.getFolder();log.info("bucketName:{}", bucketName);log.info("endpoint:{}", endpoint);log.info("folder:{}", folder);OSS ossClient = AliyunOssUtil.getOSSClient(accessKeyIdKey, accessKeySecretKey, endpoint, securityToken);File ossFile = new File(fileName);Map<String, String> upload = AliyunOssUtil.upload(ossClient, ossFile, bucketName, folder, folderName);log.info("upload:{}", upload);fileName = upload.get("resultStr");AssertUtil.isNotBlank(fileName, "小鹏OSS上传失败");/*if (StringUtils.isBlank(fileName)) {throw new ServiceException("小鹏OSS上传失败");}*/log.info("fileName:{}", fileName);String fileNameEncode = Base64.encode(fileName);SysFileRecordVO sysFileRecordVO = new SysFileRecordVO();sysFileRecordVO.setFilePath(fileNameEncode);sysFileRecordVO.setFileName(originalFilename);return sysFileRecordVO;} catch (Exception e) {e.printStackTrace();throw new ServiceException("上传失败");}}@Overridepublic ResponseEntity<byte[]> downloadFile(String path, String name, boolean isPreview) {String ossRedisKey = ossConfig.getOssRedisKey();path = Base64.decodeStr(path);String securityToken = (String) cacheService.hGet(ossRedisKey, "securityToken");String accessKeyIdKey = (String) cacheService.hGet(ossRedisKey, "accessKeyId");String accessKeySecretKey = (String) cacheService.hGet(ossRedisKey, "accessKeySecret");if (StringUtils.isBlank(accessKeyIdKey) && StringUtils.isBlank(accessKeySecretKey)) {Map<String, String> map = getAccessKeyIdSecret();accessKeyIdKey = map.get("accessKeyId");accessKeySecretKey = map.get("accessKeySecret");securityToken = map.get("securityToken");}String endpoint = ossConfig.getEndpoint();String bucketName = ossConfig.getBucketName();OSSClient ossClient = new OSSClient(endpoint, accessKeyIdKey, accessKeySecretKey, securityToken);OSSObject ossObject = ossClient.getObject(bucketName, path);try {boolean found = ossClient.doesObjectExist(bucketName, path); // 检查文件是否存在if (found) {InputStream inputStream = ossObject.getObjectContent();ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] readBuffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(readBuffer)) != -1) {byteArrayOutputStream.write(readBuffer, 0, bytesRead);}byte[] fileBytes = byteArrayOutputStream.toByteArray();// 根据isPreview标志来设置响应头HttpHeaders headers = new HttpHeaders();if (isPreview) {// 预览模式,根据文件扩展名设置合适的Content-TypeString contentType = getContentTypeByFileName(path);headers.setContentType(MediaType.parseMediaType(contentType));} else {// 下载模式,设置Content-Disposition为附件// 对文件名进行URL编码,并指定编码方式if (StringUtils.isBlank(name)) {int i = path.lastIndexOf("/");path = path.substring(i + 1);} else {path = name;}String encodedFileName = URLEncoder.encode(path, "UTF-8").replaceAll("\\+", "%20");headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName);// headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);}// 关闭输入流和输出流inputStream.close();byteArrayOutputStream.close();return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);}return ResponseEntity.notFound().build();} catch (IOException e) {throw new RuntimeException(e);} finally {ossClient.shutdown();}}// 根据文件名获取文件的MIME类型private String getContentTypeByFileName(String fileName) {String lowerCaseName = fileName.toLowerCase();if (lowerCaseName.endsWith(".pdf")) {return MediaType.APPLICATION_PDF_VALUE;} else if (lowerCaseName.endsWith(".jpg") || lowerCaseName.endsWith(".jpeg")) {return MediaType.IMAGE_JPEG_VALUE;} else if (lowerCaseName.endsWith(".png")) {return MediaType.IMAGE_PNG_VALUE;} else if (lowerCaseName.endsWith(".gif")) {return MediaType.IMAGE_GIF_VALUE;} else if (lowerCaseName.endsWith(".ppt")) {return "application/vnd.openxmlformats-officedocument.presentationml.presentation";} else if (lowerCaseName.endsWith(".xlsx") || lowerCaseName.endsWith(".xls")) {return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";} else if (lowerCaseName.endsWith(".docx") || lowerCaseName.endsWith(".doc")) {return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";} else {// 如果文件类型未知,则使用默认的二进制类型return MediaType.APPLICATION_OCTET_STREAM_VALUE;}}/*** 获取文件临时访问路径** @param fileName 文件名* @return YouTube:乌鲁木齐中路纪录片*/@Overridepublic String getUrl(String fileName) {String ossRedisKey = ossConfig.getOssRedisKey();String accessKeyIdKey = (String) cacheService.hGet(ossRedisKey, "accessKeyId");String accessKeySecretKey = (String) cacheService.hGet(ossRedisKey, "accessKeySecret");String securityToken = (String) cacheService.hGet(ossRedisKey, "securityToken");if (StringUtils.isBlank(accessKeyIdKey) && StringUtils.isBlank(accessKeySecretKey)) {Map<String, String> map = getAccessKeyIdSecret();accessKeyIdKey = map.get("accessKeyId");accessKeySecretKey = map.get("accessKeySecret");securityToken = map.get("securityToken");}String endpoint = ossConfig.getEndpoint();String bucketName = ossConfig.getBucketName();OSSClient ossClient = new OSSClient(endpoint, accessKeyIdKey, accessKeySecretKey, securityToken);// 设置URL过期时间为1小时Date expiration = new Date(new Date().getTime() + 3600 * 1000);GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fileName);generatePresignedUrlRequest.setExpiration(expiration);URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);return url.toString();}public String saveFile(MultipartFile file, String folderName) throws Exception {String fileName = file.getOriginalFilename();String imageName = fileName.substring(fileName.lastIndexOf("."));// String pathRoot = ossConfig.getPathRoot();// String baseImage = ossConfig.getBaseImage();String uuid = UUID.randomUUID().toString().replaceAll("-", "");// if (pathRoot == null || StringUtils.isEmpty(pathRoot)) {// pathRoot = ResourceUtils.getURL("classpath:").getPath();// }String filePath = DateUtil.formatDate(new Date(), "yyyyMMdd") + "/";String path = filePath + uuid + imageName;if (StringUtils.isNotBlank(folderName)) {path = filePath + fileName;}try {File tempFile = new File(path);if (!tempFile.getParentFile().exists()) {tempFile.getParentFile().mkdirs();}CommonUtil.saveMultipartFile(file, path);} catch (Exception e) {throw new Exception("上传失败,请检查目录是否可写");}return path;}public Map<String, String> getAccessKeyIdSecret() {String clientId = ossAuthConfig.getClientId();log.info("clientId:{}", clientId);String clientSecret = ossAuthConfig.getClientSecret();log.info("clientSecret:{}", clientSecret);String idTokenUrl = ossAuthConfig.getIdTokenUrl();log.info("idTokenUrl:{}", idTokenUrl);String obj = OSSAccessKeyUtils.getIdToken(clientId, clientSecret, idTokenUrl);log.info("obj:{}", obj);if (StringUtils.isBlank(obj)) {throw new ServiceException("获取ID Token失败");}JSONObject jsonObject = new JSONObject(obj);String idToken = (String) jsonObject.get("id_token");log.info("idToken:{}", idToken);String stsAccessKeyUrl = ossAuthConfig.getStsAccessKeyUrl();log.info("stsAccessKeyUrl:{}", stsAccessKeyUrl);String policeName = ossAuthConfig.getPoliceName();log.info("policeName:{}", policeName);Long timeoutKey = ossConfig.getTimeoutKey();log.info("timeoutKey:{}", timeoutKey);JSONObject stsObj = OSSAccessKeyUtils.getStsToken(idToken, policeName, stsAccessKeyUrl);log.info("stsObj:{}", stsObj);if (stsObj == null) {throw new ServiceException("获取STS Token失败");}JSONObject dataObj = (JSONObject) stsObj.get("data");String accessKeyId = (String) dataObj.get("AccessKeyId");String accessKeySecret = (String) dataObj.get("AccessKeySecret");String expiration = (String) dataObj.get("Expiration");String securityToken = (String) dataObj.get("SecurityToken");log.info("accessKeyId:{}", accessKeyId);log.info("accessKeySecret:{}", accessKeySecret);log.info("expiration:{}", expiration);log.info("securityToken:{}", securityToken);String ossRedisKey = ossConfig.getOssRedisKey();cacheService.hPut(ossRedisKey, "accessKeyId", accessKeyId);cacheService.hPut(ossRedisKey, "accessKeySecret", accessKeySecret);cacheService.hPut(ossRedisKey, "expiration", expiration);cacheService.hPut(ossRedisKey, "securityToken", securityToken);cacheService.expire(ossRedisKey, timeoutKey == null ? 2 : timeoutKey, TimeUnit.MINUTES);Map<String, String> result = Maps.newHashMap();result.put("accessKeyId", accessKeyId);result.put("accessKeySecret", accessKeySecret);result.put("securityToken", securityToken);log.info("result:{}", result);return result;}}
需要的工具类
package com.ruiyada.common.core.utils;import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.model.VoidResult;
import com.aliyuncs.exceptions.ClientException;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;/*** 阿里云OSS存储工具** Created by FSQ* CopyRight https://www.fuint.cn*/
@Slf4j
public class AliyunOssUtil {private static final Logger logger = LoggerFactory.getLogger(AliyunOssUtil.class);/*** 获取阿里云OSS客户端对象** @param accessKeyId 访问键值* @param accessKeySecret 访问秘钥* @param endpoint 存储endPoint* @return ossClient*/public static OSS getOSSClient(String accessKeyId, String accessKeySecret, String endpoint) {return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);}public static OSS getOSSClient(String accessKeyId, String accessKeySecret, String endpoint, String securityToken) throws ClientException {return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);}/*** 创建存储空间** @param ossClient OSS连接* @param bucketName 存储空间* @return*/public static String createBucketName(OSS ossClient, String bucketName) {// 存储空间final String bucketNames = bucketName;if (!ossClient.doesBucketExist(bucketName)) {// 创建存储空间Bucket bucket = ossClient.createBucket(bucketName);logger.info("创建存储空间成功");return bucket.getName();}return bucketNames;}/*** 创建模拟文件夹** @param ossClient oss连接* @param bucketName 存储bucket* @param folder 文件夹* @return 文件夹名*/public static String createFolder(OSS ossClient, String bucketName, String folder) {// 文件夹名final String keySuffixWithSlash = folder;// 判断文件夹是否存在,不存在则创建if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {// 创建文件夹ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));logger.info("创建文件夹成功");// 得到文件夹名OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);String fileDir = object.getKey();return fileDir;}return keySuffixWithSlash;}/*** 上传图片至OSS** @param ossClient oss连接* @param file 上传文件(文件全路径如:D:\\image\\cake.jpg)* @return String 返回文件url*/public static Map<String, String> upload(OSS ossClient, File file, String bucketName, String folder, String folderName) {String resultStr = null;// 先创建存储空间和文件夹// createBucketName(ossClient, bucketName);// createFolder(ossClient, bucketName, folder);Map<String, String> resultMap = Maps.newHashMap();try {InputStream is = new FileInputStream(file);String fileName = file.getName();// String date = DateUtil.formatDate(new Date(), "yyyyMMdd");String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));String path = "";if (StringUtils.isNotBlank(folderName)) {path = folder + "/" + folderName + "/" + date + "/" + fileName;} else {path = folder + "/" + date + "/" + fileName;}PutObjectResult putObjectResult = ossClient.putObject(bucketName, path, is);String versionId = putObjectResult.getVersionId();String requestId = putObjectResult.getRequestId();if (StringUtils.isNotBlank(folderName)) {resultStr = folder + "/" + folderName + "/" + date + "/" + fileName;} else {resultStr = folder + "/" + date + "/" + fileName;}resultMap.put("versionId", versionId);resultMap.put("requestId", requestId);resultMap.put("resultStr", resultStr);} catch (Exception e) {e.printStackTrace();logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);}return resultMap;}/*** 根据key删除OSS上的文件** @param ossClient oss连接* @param key Bucket下的文件的路径名+文件名 如:"upload/cake.jpg"*/public static void deleteFile(OSS ossClient, String bucketName, String folder, String key) {boolean found = ossClient.doesObjectExist(bucketName, key); // 这行判断为true,说明文件存在if (found) {// ossClient.deleteObject(bucketName, folder + key);VoidResult voidResult = ossClient.deleteObject(bucketName, key);log.info("删除文件返回结果:" + voidResult);}logger.info("删除" + bucketName + "下的文件" + folder + key + "成功");}public static Map<String, String> uploadInputStream(OSS ossClient, File file, String bucketName, String folder, String folderName) {String resultStr = null;// 先创建存储空间和文件夹Map<String, String> resultMap = Maps.newHashMap();try {InputStream is = new FileInputStream(file);String fileName = file.getName();// String date = DateUtil.formatDate(new Date(), "yyyyMMdd");String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));String path = "";if (StringUtils.isNotBlank(folderName)) {path = folder + "/" + folderName + "/" + date + "/" + fileName;} else {path = folder + "/" + date + "/" + fileName;}PutObjectResult putObjectResult = ossClient.putObject(bucketName, path, is);String versionId = putObjectResult.getVersionId();String requestId = putObjectResult.getRequestId();if (StringUtils.isNotBlank(folderName)) {resultStr = folder + "/" + folderName + "/" + date + "/" + fileName;} else {resultStr = folder + "/" + date + "/" + fileName;}resultMap.put("versionId", versionId);resultMap.put("requestId", requestId);resultMap.put("resultStr", resultStr);} catch (Exception e) {e.printStackTrace();logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);}return resultMap;}}
相关文章:
OSS文件上传
1、我们这个系统对接的阿里云OSS需要先对接小鹏OSS系统获取accessKeyId、accessKeySecret,这个可以忽略 aliyun:oss:endpoint: https://oss-cn-hangzhou.aliyuncs.combucketName: xp-xpd-experiencedomain: https://xp-xpd-experience.oss-cn-hangzhou.aliyuncs.co…...
时序预测算法TimeXer代码解析
在时序预测领域,如何有效地利用外部变量(exogenous variables)来提升内部变量(endogenous variables)的预测性能一直是一个挑战。 在上一篇文章中,我结合论文为大家解读了TimeXer框架,今天&…...
【无标题】建议用坚果云直接同步zotero,其他方法已经过时,容易出现bug
created: 2024-12-06T16:07:45 (UTC 08:00) tags: [] source: https://zotero-chinese.com/user-guide/sync author: 数据与文件的同步 | Zotero 中文社区 Excerpt Zotero 中文社区,Zotero 中文维护小组,Zotero 插件,Zotero 中文 CSL 样式 数…...
Hive 分桶表的创建与填充操作详解
Hive 分桶表的创建与填充操作详解 在 Hive 数据处理中,分桶表是一个极具实用价值的功能,它相较于非分桶表能够实现更高效的采样,并且后续还可能支持诸如 Map 端连接等节省时间的操作。不过,值得注意的是,在向表写入数…...
docker怎么commit tag push?
在 Docker 中,commit、tag 和 push 是用于创建和推送自定义镜像到仓库的三个不同步骤。以下是每个命令的详细说明和使用方法: ### 1. docker commit 当你对一个运行中的容器做了修改,并希望将这些修改保存为一个新的镜像时,可以使…...
全面替换VMware,南昌大学一卡通的硬核智慧
将一昼夜分为十二时辰 是古人的博大智慧 晨光熹微,门扉轻启,负笈而行 智慧校园的“十二时辰”启幕新章 一、数字南大:一卡通打卡校园十二时辰 时辰轮转,一时有一时的使命师生们是如何高效、便捷地度过每个时辰?一张充…...
SpringMVC ,ioc和aop
IOC和AOP IOC 控制反转,将应用程序的控制权交给spring容器管理,而不是应用程序本身 1.创建一个mapper,测试用, 就写个普通方法 public class UserMapper {public void addUser(){System.out.println("dao层新增");} …...
3GPP R18 LTM(L1/L2 Triggered Mobility)是什么鬼?(三) RACH-less LTM cell switch
这篇看下RACH-less LTM cell switch。 相比于RACH-based LTM,RACH-less LTM在进行LTM cell switch之前就要先知道target cell的TA信息,进而才能进行RACH-less过程,这里一般可以通过UE自行测量或者通过RA过程获取,而这里的RA一般是通过PDCCH order过程触发。根据38.300中的描…...
Ansys Maxwell:Qi 无线充电组件
Qi 无线充电采用感应充电技术,无需物理连接器或电缆,即可将电力从充电站传输到兼容设备。由 WPC 管理的 Qi 标准确保了不同无线充电产品之间的互操作性。以下是 Qi v1.3 标准的核心功能: Qi v1.3 标准的主要特点 身份验证:确保充…...
Neo4j 图数据库安装与操作指南(以mac为例)
目录 一、安装前提条件 1.1 Java环境 1.2 Homebrew(可选) 二、下载并安装Neo4j 2.1 从官方网站下载 2.1.1 访问Neo4j的官方网站 2.1.2 使用Homebrew安装 三、配置Neo4j 3.1 设置环境变量(可选) 3.2 打开配置文件(bash_profile) 3.2.1 打开终端…...
基于MFC绘制门电路
MFC绘制门电路 1. 设计内容、方法与难点 本课题设计的内容包括了基本门电路中与门和非门的绘制、选中以及它们之间的连接。具体采用的方法是在OnDraw函数里面进行绘制,并设计元器件基类,派生出与门和非门,并组合了一个引脚类,在…...
Gitee上获取renren-fast-vue install并run dev错误处理
目的:获取一个手脚架、越简约越好、越干净越好、于是看上了renren-fast-vue… 前端:vue2 后端:jdk1.8 mysql 5.7 SpringBoot单体架构 一开始只是下载前后端项目到本地,一堆乱七八糟的错误,网上找的资料也参差不齐… …...
sdk项目的git 标记新tag的版本号
在 Git 中,tag 是用来标记某个特定的提交点(通常是发布版本或重要的里程碑)的工具。通过 git tag,你可以为版本号创建标记,帮助团队跟踪不同版本的代码。 如果你想创建一个新的版本号标签,可以按照以下步骤…...
学习日志022 -- python事件机制
作业: 1】思维导图 2】完成闹钟 main.py import sysfrom PySide6.QtCore import QTimerEvent, QTime,Qt from PySide6.QtGui import QMovie,QMouseEvent from PySide6.QtWidgets import QApplication, QWidget from Form import Ui_Formclass MyWidget(Ui_Form,Q…...
JAVA八股文-运行篇-创建项目运行(1)
前置环境搭建:jdk、maven、idea、linux环境 一、创建一个java项目 File->New->Project 二、填写基本信息 三、完成,写了一段代码 四、打包 五、本地运行,运行和debug二选一 六、上传至linux环境 七、linux环境下命令执行 7.1 指定Main方法类 …...
Vue Web开发(二)
1. 项目搭建 1.1. 首页架子搭建 使用Element ui中的Container布局容器,选择倒数第二个样式,将代码复制到Home.vue。 1.1.1.下载less (1)下载less样式 npm i less (2)下载less编辑解析器 npm i less…...
Midjourney Describe API 的对接和使用
Midjourney Describe API 的对接和使用 Midjourney Describe API 的主要功能是通过上传图片,获取对图片的描述。使用该 API,只需要传递图片文件地址,API 会返回图片的详细描述。无需繁琐的参数设置,即可获得高质量的图片描述。 …...
MySQL是怎么加锁的
1. 全局锁 1.1 什么是全局锁? 全局锁是一种一次性锁住整个数据库的锁定机制。一旦加上全局锁,整个数据库的所有表都会处于只读状态,这意味着所有修改操作(如INSERT、UPDATE、DELETE)都会被阻塞。 常用的SQL命令&…...
burp suite 5
声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…...
硬件和自驾功能
1 硬件 指令集架构 (ISA): ARM v6, v7, v8:这些是 ARM 公司设计的不同版本的指令集架构 (ISA)。ARM v6 和 v7 属于 32 位架构,而 ARM v8 则引入了 64 位支持(即 ARMv8-A)和 32 位向后兼容模式。需要强调的是ÿ…...
uviewplus中的时间单选框up-datetime-picker的在uni-app+vue3的使用方法
uviewplus中的时间单选框up-datetime-picker的使用方法 前言 在实际开发中,我们经常需要使用时间选择器来让用户选择特定的时间。本文将详细介绍uviewplus中up-datetime-picker组件的使用方法,特别是在处理年月选择时的一些关键实现,因为官方有很多相关的功能和方法…...
车联网安全学习之TBOX
Telematics BOX,简称 T-BOX,也称远程信息处理控制单元(Telematics Control Unit, TCU),集成GPS、外部通信接口、电子处理单元、微控制器、移动通信单元和存储器等功能模块。 TBOX 提供的功能有网络接入、OTA、远程控制…...
【教程】创建NVIDIA Docker共享使用主机的GPU
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 这套是我跑完整理的。直接上干货,复制粘贴即可! # 先安装toolkit sudo apt-get update sudo apt-get install -y ca-certifica…...
tomcat 运行加载机制解析
tomcat 运行加载机制 从tomcat jar包的加载顺序: tomcat的具体运行加载 可以从 start、setclasspath、catalina文件中看出来: start.bat执行 去找bin目录下的catalina.bat,catalina 或去找 bin\setenv.bat以获取标准环境变量,然后去找bin\…...
基于JWT跨语言开发分布式业务系统的挑战与实践:多语言协作的最佳方案
在现代分布式架构下,开发团队往往由来自不同技术栈和开发语言的工程师组成。如何有效地管理这些开发人员的协作,尤其是在实现跨语言的认证与授权机制时,成为了开发者面临的一个重大挑战。JSON Web Token(JWT)作为一种轻…...
Unity在运行状态下,当物体Mesh网格发生变化时,如何让MeshCollider碰撞体也随之实时同步变化?
旧版源代码地址:https://download.csdn.net/download/qq_41603955/90087225?spm1001.2014.3001.5501 旧版效果展示: 新版加上MeshCollider后的效果: 注意:在Unity中,当你动态地更改物体的Mesh时,通常期望…...
数组能排成的最小数
题目描述 输入一个正整数数组,把数组里所有整数拼接起来排成一个数,打印出能拼接出的所有数字中最小的一个。 例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字为321323 分析 3和32哪个数字排前面呢&…...
RNN模型介绍
RNN模型介绍 1.RNN模型介绍1.1什么是RNN模型1.2RNN模型作用1.3RNN模型分类 2.传统RNN模型2.1RNN结构图2.2RNN优缺点 3.LSTM模型3.1什么是LSTM模型3.2LSTM内部结构图3.3使用Pytorch构建LSTM模型3.4LSTM优缺点 4.GRU模型4.1什么是GRU模型4.2GRU内部图4.3使用Pytorch构建GRU模型4.…...
Maven最佳实践
Maven 是一种广泛使用的 Java 项目构建自动化工具。它简化了构建过程并帮助管理依赖关系,使开发人员的工作更轻松。Maven 详细介绍可以参考我写的这篇 Maven 核心概念总结 。 这篇文章不会涉及到 Maven 概念的介绍,主要讨论一些最佳实践、建议和技巧&am…...
Redis的高可用之哨兵模式
Redis哨兵主要是解决Redis主从同步时主数据库宕机问题,使其能够自动进行故障恢复,提高Redis系统的高可用性。 1. 哨兵的作用: 监控:哨兵通过心跳机制监控主库和从库的存活性。 选主:当主库宕机时,哨兵会选举出一个领…...
C# 设计模式--观察者模式 (Observer Pattern)
定义 观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。观察者模式的核心在于解耦主题(被观察者)和观察者之间的依赖关系。 …...
如何使用Java编写Jmeter函数
Jmeter 自带有各种功能丰富的函数,可以帮助我们进行测试,但有时候提供的这些函数并不能满足我们的要求,这时候就需要我们自己来编写一个自定义的函数了。例如我们在测试时,有时候需要填入当前的时间,虽然我们可以使用p…...
Hive 窗口函数与分析函数深度解析:开启大数据分析的新维度
Hive 窗口函数与分析函数深度解析:开启大数据分析的新维度 在当今大数据蓬勃发展的时代,Hive 作为一款强大的数据仓库工具,其窗口函数和分析函数犹如一把把精巧的手术刀,助力数据分析师们精准地剖析海量数据,挖掘出深…...
Echart折线图属性设置 vue2
Echart折线图 官方配置项手册 Documentation - Apache ECharts 下面代码包含:设置标题、线条样式、图例圆圈的样式、显示名称格式、图片保存、增加Y轴目标值 updateChart(data) {const sortedData data.slice().sort((a, b) > new Date(a.deviceTime) - ne…...
蓝桥杯2117砍竹子(简单易懂 包看包会版)
问题描述 这天, 小明在砍竹子, 他面前有 n 棵竹子排成一排, 一开始第 i 棵竹子的 高度为 hi. 他觉得一棵一棵砍太慢了, 决定使用魔法来砍竹子。魔法可以对连续的一 段相同高度的竹子使用, 假设这一段竹子的高度为 H, 那么 用一次魔法可以 把这一段竹子的高度都变为 ⌊H2⌋…...
华为 生产网解决方案,加速制造业数字化转型
华为推出新一代融合架构的生产网解决方案,加速制造业数字化转型-企业频道-东方网 智慧生产网解决方案-华为企业业务 华为面向制造行业升级生产网解决方案。全新一代融合架构,解决了生产数据的孤岛化、烟囱式、数据的价值无法发挥等问题,以促…...
原型模式(Prototype Pattern)——对象克隆、深克隆与浅克隆及适用场景
原型模式(Prototype Pattern)是设计模式中的一种创建型模式,目的是通过复制现有的对象来创建新的对象,而不是通过传统的实例化方式。原型模式常常用于需要创建大量类似对象的场景,可以提高性能并减少资源的消耗。下面将…...
基于Transformer架构的扩散模型
Scalable Diffusion Models with Transformers 本文介绍一篇发表于2023年国际计算机视觉大会(ICCV)的研究论文,该论文提出了一种基于Transformer架构的扩散模型,称为Diffusion Transformers (DiTs)。 通过用Transformer替代传统的…...
服务器上部署前端页面-实现IP+端口/index.html在线访问你的网页
首先一点,不管是那个框架开发的网页前端,最后都需要Build,构建完毕以后都是原始的HTML CSS JS 三样文件! 所以不管用原始的三剑客(HTML CSS JS)开发的前端还是用各类框架开发的前端界面(只是让开发简单…...
2024年华中杯数学建模B题使用行车轨迹估计交通信号灯周期问题解题全过程文档及程序
2024年华中杯数学建模 B题 使用行车轨迹估计交通信号灯周期问题 原题再现 某电子地图服务商希望获取城市路网中所有交通信号灯的红绿周期,以便为司机提供更好的导航服务。由于许多信号灯未接入网络,无法直接从交通管理部门获取所有信号灯的数据&#x…...
【C语言】SWP 文件:临时缓存文件
SWP 文件:临时缓存文件(紧急保护机制) 在 Linux 系统(包括 Ubuntu)中,SWP 文件是一种临时缓存文件,主要用于在编辑器(如 Vim)中紧急保护未保存的工作内容。当系统或编辑…...
【日常记录-Git】git switch
1. 简介 git switch是Git 2.23.0版本引入的一个新命令,用于切换分支和恢复工作树文件。其旨在提供一个更清晰、更直观的分支切换体验,以替代git checkout命令中用于分支切换的部分功能。 2. 常规操作 2.1 切换到已存在的分支 git switch <分支名>…...
Qt学习笔记第51到60讲
第51讲 记事本实现打开功能 回到第24个功能文件Notepad,给UI中的各个控件添加槽函数。 ①开始按钮 void Widget::on_btnOpen_clicked() {QString fileNameQFileDialog::getOpenFileName(this,tr("Open File"),"E:\\6_Qt Projects\\24_Notepad\\fi…...
灵途科技亮相2024世界传感器大会 分享光纤光源技术突破
12月1日至2日,2024世界传感器大会(WSS)在郑州国际会展中心隆重举办,泛自动驾驶领域光电感知专家灵途科技受邀参加“光纤传感器与激光雷达”分论坛,并在大会上带来《激光雷达用一体化光纤光源》专题演讲,同与…...
LeetCode刷题 -- 分治快排
目录 颜色分类题目解析算法原理代码 排序数组题目解析算法原理代码 数组中第K个最大元素题目解析算法原理代码 LCR 159. 库存管理 III题目解析算法原理代码 颜色分类 题目链接 题目解析 数组分为三块 算法原理 1.如果nums[i] 0,left, i下标对应元素交换,…...
pyqtgraph绘制实时更新数据的图
PyQtGraph是一个基于PyQt和NumPy的Python库,它专为实时数据可视化而设计。以绘制0~2π范围的ysin(x)为例,基本用法的代码如下: # codingutf-8import pyqtgraph as pg from pyqtgraph.Qt import QtGui, QtCore import numpy as np# pyqtgraph…...
使用 MATLAB 绘制三维散点图:根据坐标和距离映射点的颜色和大小
在数据可视化中,三维散点图是一种非常直观的方式来展示数据的分布。MATLAB 提供了强大的 scatter3 函数,可以用来绘制三维散点图,而通过调整点的颜色和大小,可以进一步增强图形的表现力。 在本篇博客中,我们将逐步讲解…...
ubuntu离线安装docker
首先下载对应的版本amd64 就是x86的 https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/amd64/需要挑选其他版本 https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/下载之后上传到服务器目录,分别执行以下文件 sudo dpkg -…...
iOS如何操作更新推送证书
最近收到一份邮件,应该如何操作呢,证书还是跟以前一样冲钥匙串直接申请吗 Hello, As we announced in October, the Certification Authority (CA) for Apple Push Notification service (APNs) is changing. APNs will update the server certificates in sandbox on January…...
# issue 8 TCP内部原理和UDP编程
TCP 通信三大步骤: 1 三次握手建立连接; 2 开始通信,进行数据交换; 3 四次挥手断开连接; 一、TCP内部原理--三次握手 【第一次握手】套接字A∶"你好,套接字B。我这儿有数据要传给你,建立连接吧。" 【第二次…...