当前位置: 首页 > news >正文

vue实现文件预览和文件上传、下载、预览——多图、模型、dwg图纸、文档(word、excel、ppt、pdf)

整体思路(模型特殊不考虑,别人封装不具备参考性)

  1. 图片上传采用单独的组件,其他三种类型采用一个上传组件(仅仅文件格式不同)
  2. 文件上传采用前端直接上传阿里云的方式
  3. 图片预览使用elementUI自带的image预览
  4. dwg预览采用 kkfileview 方式,需要后台部署,前端使用 npm install js-base64 ,应该支持所有文件的预览,我们这里仅用作CAD文件的预览
  5. 文档类型的直接在浏览器打开预览,如果不支持需要拼接前缀 "https://view.officeapps.live.com/op/view.aspx?src="
  6. 图片下载为压缩包
  7. 文档类的相同方法下载

上传

在这里插入图片描述

        <el-formstyle="width: 650px":model="form":rules="rules"ref="form"label-width="180px"class="demo-form":disabled="type == 3"><el-form-item label="样板格式" prop="modelType"><el-radio-group v-model="form.modelType"><el-radio label="1">图片样板</el-radio><el-radio label="2">三维样板</el-radio><el-radio label="3">图纸样板</el-radio><el-radio label="4">文档样板</el-radio></el-radio-group></el-form-item><!-- 1 图片样板 2 三维样板 3 图纸样板 4 文档样板 --><el-form-itemv-if="form.modelType == 1"label="样板文件上传"prop="url"><ImageUploadv-model="form.url"tip="请上传图片:":limit="10":showIcon="type == 3 ? true : false"></ImageUpload></el-form-item><el-form-itemv-if="form.modelType != 1"label="样板文件上传"prop="url"><ModelUploadv-if="type != 3"v-model="form.url":limit="1":fileSize="form.modelType == 3 ? 50 : form.modelType == 4 ? 10 : 5120":isShowUploadModel="true"ref="videoUploadRef"@input="uploadTemplate":fileType="form.modelType == 3? ['.dwg']: form.modelType == 4? ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf']: ['.rvt', '.ifc', '.obj', '.stl', '.fbx', '.3DS']"></ModelUpload><div v-else class="blue point" @click="preview(form)">{{ form.url?.split("/")[form.url?.split("/").length - 1] }}</div></el-form-item>

ModelUpload.vue

<template><div class="component-upload-image"><el-uploadaction="":http-request="beforeUpload"class="avatar-uploader":limit="limit":on-remove="handleDelete":on-error="handleUploadError":on-exceed="handleExceed"name="file":show-file-list="true":file-list="fileList"ref="uploadRef":on-preview="handlePreview":data="otherQuery"><el-buttonsize="small"type="primary"v-if="!modelFlag":disabled="disabled">点击上传</el-button><!-- 上传提示 --><div class="el-upload__tip" slot="tip" v-if="showTip"><template v-if="fileSize">大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b></template><template v-if="fileType">文件类型支持<b style="color: #f56c6c">{{ fileType.join(" / ") }}</b> 格式</template></div><el-progressv-if="modelFlag == true"type="circle":percentage="modelUploadPercent"style="margin-top: 7px"></el-progress></el-upload></div>
</template><script>
export default {props: {value: [String, Object, Array],// 图片数量限制limit: {type: Number,default: 1,},// 大小限制(MB)fileSize: {type: Number,default: 5120,},fileType: {type: Array,default: () => [".rvt", ".ifc", ".dwg", ".obj", ".stl", ".fbx", ".3DS"],},// 是否显示提示isShowTip: {type: Boolean,default: true,},// 是否显示进度条isShowUploadModel: {type: Boolean,default: false,},// 是否显示重新上传按钮isShowBtn: {type: Boolean,default: true,},// 是否禁用上传按钮disabled: {type: Boolean,default: false,},},data() {return {number: 0,hideUpload: false,fileList: [],otherQuery: {}, //上传文件传递额外参数uploadList: [],modelFlag: false,modelUploadPercent: 0,isCancel: false,};},watch: {value: {handler(val) {if (val) {console.log(val, "val");if (typeof val == "string") {// 首先将值转为数组const list = Array.isArray(val) ? val : this.value.split(",");// 然后将数组转为对象数组this.fileList = list.map((item) => {if (typeof item === "string") {item = {name: item.substring(item.lastIndexOf("/") + 14),url: item,};}return item;});} else {val.forEach((el) => {el.name = el.fileName;});this.fileList = val;}} else {this.fileList = [];return [];}},deep: true,immediate: true,},},computed: {// 是否显示提示showTip() {return this.isShowTip && (this.fileType || this.fileSize);},},methods: {//自定义上传方法..Upload(file, data) {console.log(file);let OSS = require("ali-oss");let client = new OSS({region: data.region,accessKeyId: data.accessKeyId,accessKeySecret: data.accessKeySecret,// accessKeyId: "",// accessKeySecret: "",bucket: "cscec83-openfile",});// let cdnUrl = data.cdnUrl;let cdnUrl = "https://cscec83-openfile.oss-cn-shanghai.aliyuncs.com/";this.number++;this.isCancel = false;const progress = (p, _checkpoint) => {console.log(p);// console.log(_checkpoint);this.modelFlag = true;this.modelUploadPercent = Number((Number(p) * 100).toFixed(1));console.log(this.isCancel);if (this.isCancel) {client.cancel();}};let fileName = "model/" + new Date().getTime() + file.file.name;client.multipartUpload(fileName, file.file, {progress,// 设置并发上传的分片数量。// parallel: 4,// 设置分片大小。默认值为1 MB,最小值为100 KB。partSize: 5 * 1024 * 1024,}).then((res) => {// console.log(res, "res");this.modelFlag = false;if (res.name) {let obj = {fileName: res.name,name: res.name,size: this.otherQuery.size,url: cdnUrl + res.name,};console.log(cdnUrl + res.name);this.uploadList.push(obj);if (this.uploadList.length === this.number) {this.fileList = this.fileList.concat(this.uploadList);this.uploadList = [];this.number = 0;// let list = this.fileList.map((item) => {//   return {//     ...item,//     modelUrl: item.url,//   };// });this.$emit("input", this.fileList);}} else {this.$modal.msgError("上传失败,请重试");this.cancel();}}).catch((err) => {console.log(err);if (err.name == "cancel") {this.$message("上传取消");} else {this.$modal.msgError(err);}this.cancel();});},handleDelete(file) {const findex = this.fileList.map((f) => f.fileName).indexOf(file.fileName);if (findex > -1) {this.fileList.splice(findex, 1);this.$emit("input", this.fileList);}this.cancel();},// 上传前loading加载beforeUpload(file) {console.log(this.fileType, file.file.name);this.otherQuery = {};this.isCancel = false;var fileSize = file.file.size / 1024 / 1024 < this.fileSize; //控制大小  修改50的值即可let fileType = file.file.name.substring(file.file.name.lastIndexOf("."));let isContinue = true;if (this.fileType.indexOf(fileType) == -1 //控制格式) {this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);this.fileList = [];isContinue = false;}if (!fileSize) {this.$modal.msgError(`上传视频大小不能超过 ${this.fileSize} MB!`);this.fileList = [];isContinue = false;}this.otherQuery.fileName = file.file.name;this.otherQuery.size = (file.file.size / 1024 / 1024).toFixed(2);if (!isContinue) return;this.$axios.get("/file/ossFile/getOssParameter").then((res) => {if (res.code == 200) {this.Upload(file, res.data);}});},// 预览handlePreview(file) {window.open(file.url, "_blank");},// 文件个数超出handleExceed() {this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);},// 上传失败handleUploadError() {this.$modal.msgError("上传失败,请重试");// this.loading.close();},cancel(type) {this.isCancel = true;this.modelFlag = false;},},
};
</script>
<style scoped lang="css">
::v-deep.hideUpload .el-upload--picture-card {display: none;
}::v-deep .el-upload--picture-card {width: 104px;height: 104px;line-height: 104px;
}::v-deep .el-upload-list--picture-card .el-upload-list__item {width: 104px;height: 104px;
}.avatar-uploader-icon {border: 1px dashed #d9d9d9 !important;
}.avatar-uploader .el-upload {border: 1px dashed #d9d9d9 !important;border-radius: 6px !important;position: relative !important;overflow: hidden !important;
}.avatar-uploader .el-upload:hover {border: 1px dashed #d9d9d9 !important;border-color: #409eff;
}.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 300px;height: 178px;line-height: 178px;text-align: center;
}.avatar {width: 300px;height: 178px;display: block;
}
</style>

ImageUpload.vue

<template><div class="component-upload-image"><el-uploadmultiple:action="uploadImgUrl"list-type="picture-card":on-success="handleUploadSuccess":before-upload="handleBeforeUpload":limit="limit":on-error="handleUploadError":on-exceed="handleExceed"name="file":disabled="showIcon":on-remove="handleRemove":show-file-list="true":headers="headers":file-list="fileList":on-preview="handlePictureCardPreview":class="{hideUpload: this.fileList.length >= this.limit || this.showIcon,}"><i class="el-icon-plus"></i></el-upload><!-- 上传提示 --><div class="el-upload__tip" slot="tip" v-if="showTip">{{ tip }}<template v-if="fileSize">大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b></template><template v-if="fileType">格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b></template></div><el-dialog:visible.sync="dialogVisible"title="预览"width="800"append-to-body><img:src="dialogImageUrl"style="display: block; max-width: 100%; margin: 0 auto"/></el-dialog></div>
</template><script>
export default {props: {value: [String, Object, Array],// 图片数量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 10,},// 文件类型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array,default: () => ["png", "jpg", "jpeg"],},tip: {type: String,},// 是否显示提示isShowTip: {type: Boolean,default: true,},// 是否禁用添加图片按钮showIcon: {type: Boolean,default: false,},},data() {return {number: 0,uploadList: [],dialogImageUrl: "",dialogVisible: false,hideUpload: false,uploadImgUrl: "/prod-api" + "/file/upload", // 上传的图片服务器地址headers: {Authorization: this.$store.state.token,},fileList: [],};},watch: {value: {handler(val) {if (val) {// 首先将值转为数组const list = Array.isArray(val) ? val : this.value.split(",");// 然后将数组转为对象数组this.fileList = list.map((item) => {if (typeof item === "string") {item = { name: item, url: item };}return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true,},},computed: {// 是否显示提示showTip() {return this.isShowTip && (this.fileType || this.fileSize);},},methods: {// 删除图片handleRemove(file, fileList) {const findex = this.fileList.map((f) => f.name).indexOf(file.name);if (findex > -1) {this.fileList.splice(findex, 1);this.$emit("input", this.listToString(this.fileList));}},// 上传成功回调handleUploadSuccess(res) {this.uploadList.push({ name: res.data.url, url: res.data.url });if (this.uploadList.length === this.number) {this.fileList = this.fileList.concat(this.uploadList);this.uploadList = [];this.number = 0;this.$emit("input", this.listToString(this.fileList));this.$modal.closeLoading();}},// 上传前loading加载handleBeforeUpload(file) {let isImg = false;if (this.fileType.length) {let fileExtension = "";if (file.name.lastIndexOf(".") > -1) {fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);}isImg = this.fileType.some((type) => {if (file.type.indexOf(type) > -1) return true;if (fileExtension && fileExtension.indexOf(type) > -1) return true;return false;});} else {isImg = file.type.indexOf("image") > -1;}if (!isImg) {this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);return false;}if (this.fileSize) {const isLt = file.size / 1024 / 1024 < this.fileSize;if (!isLt) {this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);return false;}}this.$modal.loading("正在上传图片,请稍候...");this.number++;},// 文件个数超出handleExceed() {this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);},// 上传失败handleUploadError() {this.$modal.msgError("上传图片失败,请重试");this.$modal.closeLoading();},// 预览handlePictureCardPreview(file) {this.dialogImageUrl = file.url;this.dialogVisible = true;},// 对象转成指定字符串分隔listToString(list, separator) {let strs = "";separator = separator || ",";for (let i in list) {strs += list[i].url + separator;}return strs != "" ? strs.substr(0, strs.length - 1) : "";},},
};
</script>
<style scoped >
::v-deep.hideUpload .el-upload--picture-card {display: none;
}::v-deep .el-upload--picture-card {width: 86px;height: 86px;line-height: 86px;
}::v-deep .el-upload-list--picture-card .el-upload-list__item {width: 86px;height: 86px;
}::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {transition: all 0s;
}::v-deep .el-list-enter,
.el-list-leave-active {opacity: 0;transform: translateY(0);
}
</style>

预览和下载

在这里插入图片描述

<template><div id="index"><el-card shadow="always" style="margin-top: 20px"><div class="model pd-16"><div class="flex mb-20"><div class="title-left bold size-22">工程样板</div><divclass="flex_r point border-blue blue plr-10 ptb-4 bg-white radius-4 size-14"@click="toTemplate">查看更多 <i class="el-icon-right"></i></div></div><div class="flex_l"><divclass="center mr-20 plr-20 ptb-10"@click="changeTab(1)":style="tab == 1? 'background: linear-gradient(210.65deg, #5FA4FE 0%, #367EF8 100%);border-radius: 25px;color:#fff': ''"><img:src="`${tab == 1? require('../../assets/img/zhi-tab-1-1.png'): require('../../assets/img/zhi-tab-1.png')}`"alt=""style="width: 27px"/><div class="ml-16 size-18">图片区</div></div><divclass="center mr-20 plr-20 ptb-10"@click="changeTab(2)":style="tab == 2? 'background: linear-gradient(210.65deg, #5FA4FE 0%, #367EF8 100%);border-radius: 25px;color:#fff': ''"><img:src="`${tab == 2? require('../../assets/img/zhi-tab-4-1.png'): require('../../assets/img/zhi-tab-4.png')}`"alt=""style="width: 27px"/><div class="ml-16 size-18">三维模型区</div></div><divclass="center mr-20 plr-20 ptb-10"@click="changeTab(3)":style="tab == 3? 'background: linear-gradient(210.65deg, #5FA4FE 0%, #367EF8 100%);border-radius: 25px;color:#fff': ''"><img:src="`${tab == 3? require('../../assets/img/zhi-tab-3-1.png'): require('../../assets/img/zhi-tab-3.png')}`"alt=""style="width: 27px"/><div class="ml-16 size-18">图纸区</div></div><divclass="center mr-20 plr-20 ptb-10"@click="changeTab(4)":style="tab == 4? 'background: linear-gradient(210.65deg, #5FA4FE 0%, #367EF8 100%);border-radius: 25px;color:#fff': ''"><img:src="`${tab == 4? require('../../assets/img/zhi-tab-2-1.png'): require('../../assets/img/zhi-tab-2.png')}`"alt=""style="width: 27px"/><div class="ml-16 size-18">文档区</div></div></div><el-row :gutter="20" class="mt-30"><div v-if="templateList.length == 0" class="text-center"><img src="../../assets/img/null.png" alt="" style="width: 4rem" /><div>暂无数据</div></div><el-col :span="6" v-for="(item, i) in templateList" :key="i + 'c'"><el-card shadow="hover" class="point course mb-12"><el-imagev-if="tab == 1"style="width: 100%; height: 170px; border-radius: 5px"mode="aspectFill":src="item.pictureUrl":preview-src-list="[item.url.split(',')]"></el-image><img@click="preview(item)"v-if="tab == 2 || tab == 3 || tab == 4":src="tab == 4? require(`../../assets/img/doc-${item.docType || 'word'}.png`): item.pictureUrl"style="width: 100%; height: 170px; border-radius: 5px"mode="aspectFill"/><div class="flex mtb-10 mlr-12"><div class="line-1 mr-10">{{ item.modelName }}</div><imgstyle="width: 22px"src="../../assets/img/download.png"alt=""@click.stop="download(item)"/></div></el-card></el-col></el-row></div></el-card><modelPop ref="modelPopRef"></modelPop></div></div>
</template><script>
// npm install js-base64
import { Base64 } from "js-base64";
export default {// layout: "default-all",data() {return {tab: 1,templateList: [],};},mounted() { this.getTemplateList();},methods: {changeTab(tab) {this.tab = tab;this.getTemplateList();},// 下载download(item) {// 1 图片样板 2 三维样板 3 图纸样板 4 文档样板if (this.tab == 1) {this.$downloadZip.zip("/qualityTrain/sample/downloadAndZip?sampleId=" + item.sampleId,item.modelName + "样板文件.zip");} else if (this.tab == 2 || this.tab == 3) {window.open(item.url);} else if (this.tab == 4) {fetch(item.url).then((res) => res.blob()).then((blob) => {const a = document.createElement("a");const objectUrl = window.URL.createObjectURL(blob);a.download =item.modelName +(item.docType == "ppt"? ".ppt": item.docType == "excel"? ".xls": item.docType == "word"? ".doc": ".pdf");a.href = objectUrl;a.click();});}},getTemplateList() {this.$axios.get("/qualityTrain/sample/homePage", {params: {modelType: this.tab,},}).then((res) => {this.templateList = res.data;});},// 预览preview(item) {// 1 图片样板 2 三维样板 3 图纸样板 4 文档样板if (this.tab == 2) {this.$refs.modelPopRef.init(item.sampleId, item.modelName, false, true);} else if (this.tab == 3) {let base = location.protocol + "//" + location.hostname + ":8012";let url =(base.includes("192.168.2.89") ? "http://192.168.0.19:8012" : base) +"/onlinePreview?url=" +encodeURIComponent(Base64.encode(item.url));window.open(url, "_blank");} else {console.log(item.docType);window.open((item.docType != "pdf"? "https://view.officeapps.live.com/op/view.aspx?src=": "") + item.url);}},},
};
</script> 

downloadZip.js

import axios from 'axios'
import { saveAs } from 'file-saver'
import { Loading, Message } from 'element-ui';
export default ({ store }, inject) => {const zip = (url, name) => {let loadingInstance = Loading.service({lock: true,text: '正在下载...',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'});const fullUrl = '/prod-api' + url;axios({method: 'get',url: fullUrl,responseType: 'blob',timeout: 600000,headers: { 'Authorization': store.state.token }}).then(async (res) => {const isLogin = await blobValidate(res.data);loadingInstance.close();if (isLogin) {const blob = new Blob([res.data], { type: 'application/zip' })saveAs(blob, name)} else {printErrMsg(res.data);}}).catch(() => {loadingInstance.close();});};// 验证是否为blob格式async function blobValidate(data) {try {const text = await data.text();JSON.parse(text);return false;} catch (error) {return true;}}let errorCode = {'401': '认证失败,无法访问系统资源','403': '当前操作没有权限','404': '访问资源不存在','default': '系统未知错误,请反馈给管理员'}async function printErrMsg(data) {const resText = await data.text();const rspObj = JSON.parse(resText);const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']Message.error(errMsg);}// 注入到全局上下文中inject('downloadZip', {zip,});
}

相关文章:

vue实现文件预览和文件上传、下载、预览——多图、模型、dwg图纸、文档(word、excel、ppt、pdf)

整体思路&#xff08;模型特殊不考虑&#xff0c;别人封装不具备参考性&#xff09; 图片上传采用单独的组件&#xff0c;其他三种类型采用一个上传组件&#xff08;仅仅文件格式不同&#xff09;文件上传采用前端直接上传阿里云的方式图片预览使用elementUI自带的image预览dw…...

探讨人工智能领域所需学习的高等数学知识及其应用场景,涵盖了微积分、线性代数、概率论等多个数学分支。

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下本文主要探讨了人工智能领域所需学习的高等数学知识及其应用场景。文章详细列出了人工智能中涉及的数学公式&#xff0c;涵盖了微积分、线性代数、概率论等多个数学分支。同时&#xff0c;本文深入介绍了这些数学知…...

详解安卓和IOS的唤起APP的机制,包括第三方平台的唤起方法比如微信

网页唤起APP是一种常见的跨平台交互方式&#xff0c;它允许用户从网页直接跳转到移动应用程序。 这种技术广泛应用于各种场景&#xff0c;比如让用户在浏览器中点击链接后直接打开某个应用&#xff0c;或者从网页引导用户下载安装应用。实现这一功能主要依赖于URL Scheme、Univ…...

服务器数据恢复—raid5阵列中多块硬盘离线导致崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; 三台V7000存储&#xff0c;共有64块SAS硬盘&#xff08;其中有三块热备盘&#xff0c;其中一块已启用&#xff09;组建了数组raid5阵列。分配若干LUN&#xff0c;上层安装Windows server操作系统&#xff0c;数据分区格式化为NTFS文件系统。 服…...

《深度学习》OpenCV FisherFaces算法人脸识别 原理及案例解析

目录 一、FisherFaces算法 1、什么是FisherFaces算法 2、原理 3、特点 4、算法步骤 1&#xff09;数据预处理 2&#xff09;特征提取 3&#xff09;LDA降维 4&#xff09;特征投影 5&#xff09;人脸识别 二、案例解析 1、完整代码 运行结果&#xff1a; 一、Fish…...

基于Python+Flask的天气预报数据可视化分析系统(源码+文档)

简介&#xff1a; 本系统是一个集数据收集、处理、分析和可视化于一体的天气预报数据平台。通过Python和Flask框架的结合&#xff0c;我们能够高效地构建出一个用户友好的Web界面&#xff0c;让用户能够轻松访问并理解复杂的天气数据。系统不仅能够实时获取最新的天气信息&…...

深入解析 Flutter兼容鸿蒙next全体生态的横竖屏适配与多屏协作兼容架构

目录 写在前面 1. Flutter 的基本适配机制 1.1 响应式布局 1.2 逻辑像素 2. 横屏与竖屏的适配 2.1 方向感知 2.2 针对方向的布局优化 3. 多屏协作的实现 3.1 适配多屏显示 3.2 使用 StreamBuilder 和 Provider 3.3 多设备协作的挑战 4. 实践中的应用场景 4.1 移动办…...

【Spring】Spring实现加法计算器和用户登录

加法计算器 准备工作 创建 SpringBoot 项目&#xff1a;引入 Spring Web 依赖&#xff0c;把前端的页面放入项目中 **<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport"…...

电脑d盘不见了怎么恢复?

在使用电脑的时候&#xff0c;我们可能会遇到这样一个问题&#xff0c;电脑里的D盘突然不见了&#xff0c;在“此电脑”中看不到D盘了。这这个情况可能会让人感到非常困惑甚至是头疼&#xff0c;因为D盘里面可能存放着非常重要的文件。今天的内容要和大家分析一下D盘不见的原因…...

电子商务网站维护技巧:保持WordPress、主题和插件的更新

在这个快节奏的数字时代&#xff0c;维护一个电子商务网站的首要任务之一是保持WordPress、主题和插件的最新状态。过时的软件不仅可能导致功能故障&#xff0c;还可能带来安全风险。本文将深入探讨如何有效地更新和维护您的WordPress网站&#xff0c;以确保其安全性和性能。 …...

交叉编译--目标平台aarch64 ubuntu 22.04

开发宿主机&#xff1a; ubuntu22.04虚拟机&#xff08;PC&#xff09; 目标平台&#xff1a; 地平线x3派/x3 Module , ubuntu22.04&#xff0c; ros2 humble 基于地平线x3开发板 5核 4G的内存的有限的资源&#xff0c;直接在目标机上编译虽然也可以&#xff0c;但耗时太长&a…...

【pytorch】昇思大模型配置python的conda版本

首先&#xff0c;切换conda的源&#xff0c;可以参考这篇文章&#xff0c;如果python的版本比较老的话不推荐使用清华源。 比如算子开发文档中推荐的python版本是3.7.5&#xff0c;比较老&#xff0c;使用清华源无法安装。 之后就是比较重要的&#xff0c;修改~/.bashrc。 把…...

nodejs的卸载和nvm安装

由于项目需求&#xff0c;需要多版本控制的nodejs&#xff0c;所以要把原来的nodejs卸载干净&#xff0c;然后再装nvm 常见问题 1.在安装nvm的时候没有卸载node&#xff0c;导致使用nvm安装完之后&#xff0c;node和npm都不可用。 2.在第一次使用nvm安装node后&#xff0c;要…...

网络七层架构

目录标题 网络七层架构从正确认识网络七层架构开始 网络七层架构 简介&#xff1a; 网络七层架构是指ISO/OSI模型&#xff0c;它是国际标准化组织&#xff08;ISO&#xff09;制定的一种用于计算机网络体系结构的参考模型。该模型将计算机网络的功能划分为七个层次&#xff0c…...

2024年华为OD机试真题-敏感字段加密-Java-OD统一考试(E卷)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。 题目描述 给定一个由多个…...

图神经网络黑书笔记--术语

一、图的基本概念 图由节点集合和边集合组成。节点代表实体&#xff0c;边代表实体之间的关系。节点、边、整个图都可以与丰富的信息相关联&#xff0c;这些信息被表征为节点/边/图的特征。 中心度&#xff1a;是度量节点的重要性。如果许多其他重要的节点也连接到该节点&a…...

原型基于颜色的图像检索与MATLAB

原型基于颜色的图像检索与MATLAB 摘要 基于内容的检索数据库(图像)已经变得越来越受欢迎。为了达到这一目的&#xff0c;需要发展算法检测/模拟工具&#xff0c;但市场上没有合适的商业工具。 本文介绍了一个模拟环境&#xff0c;能够从数据库中检索图像直方图的相似之处。该…...

【C++笔试强训】如何成为算法糕手Day9

学习编程就得循环渐进&#xff0c;扎实基础&#xff0c;勿在浮沙筑高台 循环渐进Forward-CSDN博客 目录 循环渐进Forward-CSDN博客 添加逗号 思路&#xff1a; 代码实现&#xff1a; 跳台阶 思路&#xff1a; 代码实现&#xff1a; 扑克牌顺子 思路&#xf…...

初识算法 · 二分查找(1)

目录 前言&#xff1a; 二分查找 题目解析 算法原理 算法编写 搜索插入位置 题目解析 算法原理 算法编写 前言&#xff1a; 本文呢&#xff0c;我们从滑动窗口窗口算法移步到了二分查找算法&#xff0c;我们简单了解一下二分查找算法&#xff0c;二分查找算法是一个十…...

数据结构:数字统计

请统计某个给定范围[L, R]的所有整数中&#xff0c;数字2出现的次数。 比如给定范围[2, 22]&#xff0c;数字2在数2中出现了1次&#xff0c;在数12中出现1次&#xff0c;在数20中出现1次&#xff0c;在数21中出现1次&#xff0c;在数22中出现2次&#xff0c;所以数字2在该范围…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...