Vue3 + Element-Plus + vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS 父组件实现真正上传(最新保姆级)

Vue3 + Element-Plus + vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS(最新保姆级)父组件实现真正上传

  • 1、效果展示
  • 2、UploadImage.vue 组件封装
  • 3、相关请求封装
  • 4、SwiperConfig.vue 调用组件
  • 5、后端接口

1、效果展示


在这里插入图片描述

如果没有安装插件,请先安装 vue-draggable-plus 插件:

cnpm install vue-draggable-plus

2、UploadImage.vue 组件封装


<template><div class="draggable_image_upload"><VueDraggable class="box-uploader" ref="draggableRef" v-model="curList" :animation="600" easing="ease-out"ghostClass="ghost" draggable="ul" @start="onStart" @update="onUpdate"><!-- 使用element-ui el-upload自带样式 --><ul v-for="(item, index) in curList" :key="index" class="el-upload-list el-upload-list--picture-card"><li class="el-upload-list__item is-success animated":style="{ 'height': props.height + ' !important', 'width': props.width + ' !important', 'margin-right': props.space + ' !important' }"><el-image class="originalImg" :src="item.url" :preview-src-list="[item.url]":style="{ 'height': props.height + ' !important', 'width': props.width + ' !important' }" /><label class="el-upload-list__item-status-label"><el-icon class="el-icon--upload-success el-icon--check"><Check /></el-icon></label><span class="el-upload-list__item-actions"><!-- 预览    --><span class="el-upload-list__item-preview" @click="handleImgPreview('originalImg', index)"><el-icon><ZoomIn /></el-icon></span><!-- 删除    --><span class="el-upload-list__item-delete" @click="onImageRemove(item.url)"><el-icon><Delete /></el-icon></span></span></li></ul><!-- 上传组件 --><el-upload v-model:file-list="curList" :action="UPLOAD_IMG_URL" :multiple="multiple"list-type="picture-card" :accept="accept" :show-file-list="false" :before-upload="beforeImgUpload":on-success="handleImgSuccess" ref="uploadRef" :auto-upload="autoUpload" drag><el-icon :style="{ 'height': props.height + ' !important', 'width': props.width + ' !important' }"><Plus /></el-icon></el-upload></VueDraggable></div>
</template><script name="DraggableImageUpload" setup>
import { UPLOAD_IMG_URL, uploadImageApi } from "@/api/upload/index"; //请求url
import { Check, Delete, Download, Plus, ZoomIn } from '@element-plus/icons-vue';
import { ElMessage } from "element-plus";
import { getCurrentInstance, onMounted, reactive, ref, toRefs, computed } from 'vue';
import { VueDraggable } from 'vue-draggable-plus';const draggableRef = ref(null);const { proxy } = getCurrentInstance();const props = defineProps({accept: {type: String,default: ".jpg,.jpeg,.png"},limit: {type: Number,default: 9999},multiple: {type: Boolean,default: true},autoUpload: {type: Boolean,default: false},height: {type: String,default: "100px"},width: {type: String,default: "100px"},space: {type: String,default: "20px"},modelValue: {type: Array,default: () => []}
});
const {modelValue
} = toRefs(props);const data = reactive({maxImgsLen: 0,imgList: []
});const { maxImgsLen, imgList } = toRefs(data);const emit = defineEmits(["update:modelValue", "upload-failure", "upload-success"]);
const curList = computed({get() {return props.modelValue;},set(newValue) {emit("update:modelValue", newValue);}
});const onStart = () => {console.log('start');
};const onUpdate = () => {console.log(curList.value, 'update++++++++++++++');
};const handleImgPreview = (domClass, index) => {const dom = document.getElementsByClassName(domClass);dom[index].firstElementChild.click(); //调用 el-image 的预览方法
};const onImageRemove = (url) => {const list = [...curList.value];list.forEach((item, index) => {if (url === item.url) {list.splice(index, 1);}});curList.value = list;
};const beforeImgUpload = (rawFile) => {const types = ["image/jpeg", "image/jpg", "image/png"];const size = rawFile.size;const isImage = types.includes(rawFile.type);const isLt5M = size / 1024 / 1024 < 5;if (!isImage) {ElMessage("请上传jpeg、jpg、png类型的图片", {type: "error"});return false;} else if (!isLt5M) {ElMessage("上传图片大小不能超过5MB", {type: "error"});return false;}return true;
};const uploadImage = async (file) => {let res = await uploadImageApi(file);return res.data;
}/*** 提供给外部的上传触发方法*/
const triggerUpload = async () => {for (let i = 0; i < modelValue.value.length; i++) {const file = modelValue.value[i];if (file.status === 'ready') {modelValue.value[i] = {...file,status: 'uploading',message: '上传中',};const formData = new FormData();formData.append('file', file.raw);  // 将 File 对象添加到 FormDataconst uploadedUrl = await uploadImage(formData);modelValue.value[i] = {name: file.name,size: file.size,uid: file.uid,status: 'success',url: uploadedUrl,};}emit('upload-success');}
};/*** 提供给外部的函数*/
defineExpose({triggerUpload,
});function handleImgSuccess() {ElMessage.success("图片上传成功");// This can be extended based on the response structure from the server// For example, you might want to add the uploaded image to your imgListconst uploadedFile = {url: response.url, // Assume the response contains the image URLname: file.name,size: file.size};curList.value.push(uploadedFile); // Add the uploaded image to curList
}
</script><style lang="scss" scoped>
::v-deep(.el-upload-dragger) {padding: 0;display: flex;justify-content: center;align-items: center;
}.draggable_image_upload {.box-uploader {display: flex;flex-wrap: wrap;vertical-align: middle;:deep(.el-upload) {border-radius: 4px;.circle-plus {width: 24px;height: 24px;}&.el-upload-list {&.el-upload__item {width: 100px;height: 100px;margin: 0 17px 17px 0;border-color: #e7e7e7;padding: 3px;}}&.el-upload--picture-card {border-style: dashed;margin-right: 17px;}}.el-upload-list__item {margin: 0 17px 17px 0;border-color: #e7e7e7;padding: 3px;.originalImg {:deep(.el-image__preview) {-o-object-fit: contain;object-fit: contain;}}}ul:nth-child(6n+6) {li {margin-right: 0;}}}
}
</style>

3、相关请求封装

http/index.ts

/** @Date: 2024-08-17 14:18:14* @LastEditors: zhong* @LastEditTime: 2024-09-17 19:22:36* @FilePath: \rentHouseAdmin\src\api\upload\index.ts*/
import axios from 'axios'
import type {AxiosInstance,AxiosError,AxiosRequestConfig,AxiosResponse,
} from 'axios'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/store/modules/user'
import { ResultEnum } from '@/enums/httpEnums'
import { ResultData } from './type'
import { LOGIN_URL } from '@/config/config'
import { RESEETSTORE } from '../reset'
import router from '@/router'export const service: AxiosInstance = axios.create({// 判断环境设置不同的baseURLbaseURL: import.meta.env.PROD ? import.meta.env.VITE_APP_BASE_URL : '/',timeout: ResultEnum.TIMEOUT as number,
})
/*** @description: 请求拦截器* @returns {*}*/
service.interceptors.request.use((config) => {const userStore = useUserStore()const token = userStore.tokenif (token) {config.headers['access-token'] = token}return config},(error: AxiosError) => {ElMessage.error(error.message)return Promise.reject(error)},
)
/*** @description: 响应拦截器* @returns {*}*/
service.interceptors.response.use((response: AxiosResponse) => {const { data } = response// * 登陆失效if (ResultEnum.EXPIRE.includes(data.code)) {RESEETSTORE()ElMessage.error(data.message || ResultEnum.ERRMESSAGE)router.replace(LOGIN_URL)return Promise.reject(data)}if (data.code && data.code !== ResultEnum.SUCCESS) {ElMessage.error(data.message || ResultEnum.ERRMESSAGE)return Promise.reject(data)}return data},(error: AxiosError) => {// 处理 HTTP 网络错误let message = ''// HTTP 状态码const status = error.response?.statusswitch (status) {case 401:message = 'token 失效,请重新登录'breakcase 403:message = '拒绝访问'breakcase 404:message = '请求地址错误'breakcase 500:message = '服务器故障'breakdefault:message = '网络连接故障'}ElMessage.error(message)return Promise.reject(error)},
)/*** @description: 导出封装的请求方法* @returns {*}*/
const http = {get<T>(url: string,params?: object,config?: AxiosRequestConfig,): Promise<ResultData<T>> {return service.get(url, { params, ...config })},post<T>(url: string,data?: object,config?: AxiosRequestConfig,): Promise<ResultData<T>> {return service.post(url, data, config)},put<T>(url: string,data?: object,config?: AxiosRequestConfig,): Promise<ResultData<T>> {return service.put(url, data, config)},delete<T>(url: string,data?: object,config?: AxiosRequestConfig,): Promise<ResultData<T>> {return service.delete(url, { data, ...config })},
}export default http

http/type.ts

// * 请求响应参数(不包含data)
export interface Result {code: numbermessage: stringsuccess?: boolean
}// * 请求响应参数(包含data)
export interface ResultData<T = any> extends Result {data: T
}

index.ts

/** @Date: 2024-08-17 14:18:14* @LastEditors: zhong* @LastEditTime: 2024-09-17 19:22:36* @FilePath: \rentHouseAdmin\src\api\upload\index.ts*/
// 上传基础路径
export const BASE_URL = import.meta.env.PROD? import.meta.env.VITE_APP_BASE_URL: ''
// 图片上传地址
export const UPLOAD_IMG_URL = `/admin/file/upload`
import http from '@/utils/http'/*** @description 上传图片接口* @param params*/
export function uploadImageApi(file: FormData) {return http.post<any[]>(UPLOAD_IMG_URL,file)
}

4、SwiperConfig.vue 调用组件


<!--* @Date: 2024-12-14 15:08:55* @LastEditors: zhong* @LastEditTime: 2024-12-15 20:51:31* @FilePath: \admin\src\views\small\smallSetting\components\SwiperConfig.vue
-->
<template><div class="card main"><div class="left"><div style="text-align: center;margin-bottom: 20px;"><text style="font-size: 20px;">云尚社区</text></div><div class="mt-4"><el-input style="border-radius: 10px;" size="small" placeholder="请输入关键字" :prefix-icon="Search" /></div><div style="margin-top: 10px;"><el-carousel :interval="4000" type="card" class="card" height="100px" indicator-position="none"style="padding: 6px 0;border-radius: 10px;"><el-carousel-item v-for="(item, index) in data" :key="index"><el-image :src="item.settingValue" style="height: 100px;border-radius: 6px;" /></el-carousel-item></el-carousel></div><div class="card menu"><div v-for="(item, index) in menuList" :key="index" class="menu-item"><div style="display: flex; flex-direction: column;"><el-image :src="item.url" style="height: 60px;width: 70px;;border-radius: 6px;" /><el-text style="margin-top: 8px;">{{ item.name }}</el-text></div></div></div></div><el-divider direction="vertical" style="height: 620px;margin-left: 50px;border-width: 2px;">可选配置</el-divider><div class="right"><el-tag type="" size="large" effect="dark">轮播图配置</el-tag><div style="display: flex;margin-top: 20px;"><div v-for="(item, index) in data" :key="index" style="padding-right: 20px;"><el-image :src="item.settingValue" style="height: 80px;width: 160px;;border-radius: 6px;" /></div></div><div style="margin-top: 20px;"><DraggableImageUpload @upload-success="onUploadSuccess" v-model="uploadImageArray" ref="imageUploadRef"height="80px" width="160px" space="20px" /><el-button type="" @click="handleImageUpload" style="margin-top: 20px;">替换</el-button></div></div></div>
</template><script setup>
import DraggableImageUpload from '@/components/UploadImage/UploadImage.vue'
import { getSystemSettingsConfigApi } from '@/api/system';
import { onMounted, ref } from 'vue';
import { Search } from '@element-plus/icons-vue';
const data = ref([]);
const uploadImageArray = ref([]);
const getSystemSettingsConfig = async () => {let res = await getSystemSettingsConfigApi();data.value = res.data.settingMap.one;console.log(data.value);
}onMounted(() => {getSystemSettingsConfig();
})// 菜单信息
const menuList = ref([]);const imageUploadRef = ref(null); // 创建 ref 引用
const handleImageUpload = () => {imageUploadRef.value.triggerUpload();
}// 上传成功回调
const onUploadSuccess = () => {console.log(uploadImageArray.value);
};
</script><style lang="scss" scoped>
::v-deep(li.el-upload-list__item.is-success) {margin-right: 20px;height: 80px;width: 160px;
}::v-deep(.el-upload.el-upload--picture-card) {height: 80px;width: 160px;
}.main {display: flex;justify-content: space-between;padding: 20px;
}.menu {display: flex;align-items: center;justify-content: center;flex-wrap: wrap;/* 自动换行 */gap: 20px;row-gap: 15px;/* 元素间距 */max-height: calc(40px * 2 + 20px * 2 + 50px);/* 限制两排的总高度 */overflow: hidden;/* 超出隐藏 */margin-top: 10px;border-radius: 10px;
}.item {width: calc(25% - 10px);/* 每排最多显示 4 个 */box-sizing: border-box;
}.content {display: flex;flex-direction: column;align-items: center;
}::v-deep(.el-input__wrapper) {height: 26px;border-radius: 20px;
}.left {padding: 10px;height: 600px;background-color: #f8f8f8;width: 400px;
}.right {margin-left: 50px;flex: 1;height: 600px;
}
</style>

5、后端接口


FileUploadController.java

package com.zhong.controller.apartment;import com.zhong.result.Result;
import com.zhong.utils.AliOssUtil;
import io.minio.errors.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;@Tag(name = "文件管理")
@RequestMapping("/admin/file")
@RestController
public class FileUploadController {@Autowiredprivate AliOssUtil ossUtil;@Operation(summary = "上传文件")@PostMapping("/upload")public Result<String> upload(@RequestParam MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {// 获取文件原名String originalFilename = file.getOriginalFilename();// 防止重复上传文件名重复String fileName = null;if (originalFilename != null) {fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.indexOf("."));}// 把文件储存到本地磁盘
//        file.transferTo(new File("E:\\SpringBootBase\\ProjectOne\\big-event\\src\\main\\resources\\flies\\" + fileName));String url = ossUtil.uploadFile(fileName, file.getInputStream());System.out.println();return Result.ok(url);}
}

AliOssUtil.class

package com.zhong.utils;import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.zhong.result.Result;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @ClassName : AliOssUtil* @Description : 阿里云上传服务* @Author : zhx* @Date: 2024-03-1 20:29*/
@Component
@Service
public class AliOssUtil {@Value("${alioss.endpoint}")private String ENDPOINT;@Value("${alioss.bucketName}")private String BUCKETNAME;@Value("${alioss.access_key}")private String ACCESS_KEY;@Value("${alioss.access_key_secret}")private String ACCESS_KEY_SECRET;public String uploadFile(String objectName, InputStream inputStream) {String url = "";// 创建OSSClient实例。System.out.println(ACCESS_KEY);OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY, ACCESS_KEY_SECRET);try {// 创建PutObjectRequest对象。// 生成日期文件夹路径,例如:2022/04/18SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");String dateStr = dateFormat.format(new Date());PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKETNAME, dateStr + "/" + objectName, inputStream);// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。// ObjectMetadata metadata = new ObjectMetadata();// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());// metadata.setObjectAcl(CannedAccessControlList.Private);// putObjectRequest.setMetadata(metadata);// 上传文件。PutObjectResult result = ossClient.putObject(putObjectRequest);url = "https://" + BUCKETNAME + "." + ENDPOINT.substring(ENDPOINT.lastIndexOf("/") + 1) + "/" + dateStr + "/" + objectName;} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}return url;}public  Result deleteFile(String objectName) {System.out.println(objectName);// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY, ACCESS_KEY_SECRET);try {// 删除文件。System.out.println(objectName);System.out.println(objectName.replace(",", "/"));ossClient.deleteObject(BUCKETNAME, objectName.replace(",", "/"));return Result.ok("删除成功!");} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}return Result.fail(555,"上传失败!");}
}

application.yml

alioss: # 阿里云配置endpoint: "https://cn-chengdu.oss.aliyuncs.com"    # Endpoint以西南(成都)为例,其它Region请按实际情况填写。bucketName: ""  # 填写Bucket名称,例如examplebucket。access_key: ""  # 点击头像->Accesskey管理查看 秘钥access_key_secret: "" # 密码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/492774.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

容器化技术全面解析:Docker 与 Containerd 的深入解读

目录 Docker 简介 1. 什么是 Docker&#xff1f; 2. Docker 的核心组件 3. Docker 的主要功能 4. Docker 的优点 5. Docker 的使用场景 Containerd 简介 1. 什么是 Containerd&#xff1f; 2. Containerd 的核心特性 3. Containerd 的架构 4. Containerd 与 Docker 的…

LNMP+discuz论坛

0.准备 文章目录 0.准备1.nginx2.mysql2.1 mysql82.2 mysql5.7 3.php4.测试php访问mysql5.部署 Discuz6.其他 yum源&#xff1a; # 没有wget&#xff0c;用这个 # curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo[rootlocalhost ~]#…

Android Studio的笔记--BusyBox相关

BusyBox 相关 BusyBoxandroid上安装busybox和使用示例一、下载二、移动三、安装和设置环境变量四、使用 busybox源码下载和查看 BusyBox BUSYBOX BUSYBOX链接https://busybox.net/ 点击链接后如图 点击左边菜单栏的Get BusyBix中的Download Source 跳转到busybox 的下载源码…

LabVIEW与PLC点位控制及OPC通讯

在工业自动化中&#xff0c;PLC通过标准协议&#xff08;如Modbus、Ethernet/IP等&#xff09;与OPC Server进行数据交换&#xff0c;LabVIEW作为上位机通过OPC客户端读取PLC的数据并进行监控、控制与处理。通过这种方式&#xff0c;LabVIEW能够实现与PLC的实时通信&#xff0c…

C++ OpenGL学习笔记(1、Hello World空窗口程序)

终于抽出时间系统学习OpenGL 教程&#xff0c;同时也一步一步记录怎样利用openGL进行加速计算。 目录 1、环境准备1.1、库的下载1.2、库的选择及安装 2、OpenGL第一个项目&#xff0c;Hello World!2.1、新建hello world控制台项目2.2、配置openGL环境2.2.1 包含目录配置2.2.2 …

系统移植——Linux 内核顶层 Makefile 详解

一、概述 Linux Kernel网上下载的版本很多NXP等有自己对应的版本。需要从网上直接下载就可以。 二、Linux内核初次编译 编译内核之前需要先在 ubuntu 上安装 lzop 库 sudo apt-get install lzop 在 Ubuntu 中 新 建 名 为 “ alientek_linux ” 的 文 件夹 &#xff0c; …

ubuntu16.04ros-用海龟机器人仿真循线系统

下载安装sudo apt-get install ros-kinetic-turtlebot ros-kinetic-turtlebot-apps ros-kinetic-turtlebot-interactions ros-kinetic-turtlebot-simulator ros-kinetic-kobuki-ftdi sudo apt-get install ros-kinetic-rocon-*echo "source /opt/ros/kinetic/setup.bash…

Connection lease request time out 问题分析

Connection lease request time out 问题分析 问题背景 使用apache的HttpClient&#xff0c;我们知道可以通过setConnectionRequestTimeout()配置从连接池获取链接的超时时间&#xff0c;而Connection lease request time out正是从连接池获取链接超时的报错&#xff0c;这通常…

【文档搜索引擎】在内存中构造出索引结构(上)

文章目录 主要思路正排索引和倒排索引的表示1. 正排索引查询文档详细信息2. 倒排索引中查找关联词3. 新增文档正排索引倒排索引实现词频统计 主要思路 通过 Index 类&#xff0c;在内存中构造出索引结构。这个类要提供的方法&#xff1a; 给定一个 docId&#xff0c;在正排索…

单节点calico性能优化

在单节点上部署calicov3273后&#xff0c;发现资源占用 修改calico以下配置是资源消耗降低 1、因为是单节点&#xff0c;没有跨节点pod网段组网需要&#xff0c;禁用overlay方式网络(ipip&#xff0c;vxlan),使用route方式网络 配置calico-node的环境变量 CALICO_IPV4POOL_I…

tryhackme-Pre Security-HTTP in Detail(HTTP的详细内容)

任务一&#xff1a;What is HTTP(S)?&#xff08;什么是http&#xff08;s&#xff09;&#xff09; 1.What is HTTP? (HyperText Transfer Protocol)&#xff08;什么是 HTTP&#xff1f;&#xff08;超文本传输协议&#xff09;&#xff09; http是你查看网站的时候遵循的…

Javascript面试手撕常见题目(回顾一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词&#xff0c;你可以按照以下步骤进行操作&#xff1a; 将文章转换为小写&#xff1a;这可以确保单词的比较是大小写不敏感的。移除标点符号&#xff1a;标点符号会干扰单词的计数。将文章拆…

算法-Z-order算法

1、学习背景 激光雷达点云是无序的&#xff0c;Transformer只能对有序的数据进行处理&#xff0c;为了将Transformer用在点云处理中&#xff0c;需要将无序的点云转换成有序的数据&#xff0c;另外&#xff0c;由于Transformer会用到局部注意力机制&#xff0c;所以将无序的数据…

ElasticSearch 数据聚合与运算

1、数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现数据的统计、分析和运算。实现这些统计功能的比数据库的 SQL 要方便的多&#xff0c;而且查询速度非常快&#xff0c;可以实现近实时搜索效果。 注意&#xff1a; 参加聚合的字段必须是 keywor…

三、使用langchain搭建RAG:金融问答机器人--检索增强生成

经过前面2节数据准备后&#xff0c;现在来构建检索 加载向量数据库 from langchain.vectorstores import Chroma from langchain_huggingface import HuggingFaceEmbeddings import os# 定义 Embeddings embeddings HuggingFaceEmbeddings(model_name"m3e-base")#…

SSH连接成功,但VSCode连接不成功

环境 在实验室PC上连接服务器234 解决方案&#xff1a;在VSCode中重新添加远程主机 删除旧的VSCode Server 在远程主机上&#xff0c;VSCode会安装一个‘vscode-server’服务来支持远程开发&#xff0c;有时旧的‘vscode-server’文件可能会导致问题&#xff0c;删除旧的&am…

scala中正则表达式的使用

正则表达式&#xff1a; 基本概念 在 Scala 中&#xff0c;正则表达式是用于处理文本模式匹配的强大工具。它通过java.util.regex.Pattern和java.util.regex.Matcher这两个 Java 类来实现&#xff08;因为 Scala 运行在 Java 虚拟机上&#xff0c;可以无缝使用 Java 类库&…

COMSOL with Matlab

文章目录 基本介绍COMSOL with MatlabCOMSOL主Matlab辅Matlab为主Comsol为辅 操作步骤常用指令mphopenmphgeommghmeshmphmeshstatsmphnavigatormphplot常用指令mphsavemphlaunchModelUtil.clear 实例教学自动另存新档**把语法套用到边界条件**把语法套用到另存新档 函数及其微分…

小鹏“飞行汽车”上海首飞,如何保障智能出行的安全性?

近日&#xff0c;小鹏汇天的“陆地航母”飞行汽车在上海陆家嘴成功完成首飞&#xff0c;标志着飞行汽车时代在中国正式拉开序幕。作为一项突破性的科技创新&#xff0c;飞行汽车不仅将重塑我们的出行方式&#xff0c;还将深刻改变城市的交通格局。此次飞行不仅证明了飞行汽车的…

Service Discovery in Microservices 客户端/服务端服务发现

原文链接 Client Side Service Discovery in Microservices - GeeksforGeeks 原文链接 Server Side Service Discovery in Microservices - GeeksforGeeks 目录 服务发现介绍 Server-Side 服务发现 实例&#xff1a; Client-Side 服务发现 实例&#xff1a; 服务发现介绍…