Ant Design Vue和VUE3下的upload组件使用以及文件预览

news2024/9/20 1:24:51

在这里插入图片描述

Ant Design Vue和VUE3下的upload组件使用以及文件预览

用到技术:Ant Design Vue、VUE3、xlsx的文件预览功能(也可预览txt,csv)

一、多文件上传

需求

  1. 可以多文件上传
  2. 文件先上传到本地,点击开始上传再通过后端接口继续上传
  3. 上传后显示全部、正确和错误的数据信息
  4. 上传后可以下载

注意细节:

  1. 最开始文件上传到本地时,右边页面不加载,当点击上传后,在右边未获取数据之前,
    a.上传组件无法再次上传;
    b:右边数据均处于加载中状态;
    c.文件下载处于不可编辑状态
  2. 加载出数据后,
    a.上传组件可再次上传;
    b.文件预览中的全部、正确和错误数据均需显示出对应的数据序号
    c.正确和错误的数据,均不显示‘比对结果’,仅全部数据显示
  3. 文件下载接口注意文件类型为‘blob’

样例

在这里插入图片描述

代码

<template>
	<a-row :gutter="8">
		<a-col :span="8">
			<a-card title="文件上传">
				<a-upload-dragger
					v-model:fileList="fileList"
					name="files"
					accept=".txt"
					:multiple="true"
					:action="action"
					:before-upload="beforeUpload"
					:disabled="upLoadDisabled"
					@remove="handleRemove"
					:showUploadList="{
						showRemoveIcon: true
					}"
				>
					<p class="ant-upload-drag-icon">
						<inbox-outlined></inbox-outlined>
					</p>
					<p class="ant-upload-text">点击或将文件拖拽到这里上传, 支持扩展名:.txt</p>
				</a-upload-dragger>
				<div style="text-align: right">
					<a-button
						type="primary"
						:disabled="fileList.length === 0"
						:loading="uploading"
						style="margin-top: 16px"
						@click="handleUpload"
					>
						{{ uploading ? '上传中' : '开始上传' }}
					</a-button>
				</div>
			</a-card>
		</a-col>
		<a-col :span="16">
			<a-card>
				<a-spin :spinning="upLoadSpinning" tip="数据加载中...">
					<a-row :gutter="16">
						<a-col :span="12">
							<a-statistic title="正确/错误(个)" :value="trueNum" class="demo-class">
								<template #suffix>
									<span>/{{ falseNum }}</span>
								</template>
							</a-statistic>
						</a-col>
						<a-col :span="12">
							<a-statistic title="完善度" :value="wcdPercent" style="margin-right: 50px" />
						</a-col>
					</a-row>
				</a-spin>
			</a-card>
			<a-card title="文件预览" style="margin-top: 5px">
				<a-spin :spinning="upLoadSpinning" tip="数据加载中...">
					<a-tabs v-model:activeKey="activeKey" type="card" @change="tabChange">
						<a-tab-pane key="0">
							<template #tab>
								<div>全部</div>
							</template>
							<div style="padding-bottom: 20px; padding-top: 20px">
								<div v-if="tableData0.length > 0">
									<a-table :columns="columns" :data-source="tableData0" bordered> </a-table>
								</div>
								<div v-else>
									<div class="emptyStyle"></div>
								</div>
							</div>
						</a-tab-pane>
						<a-tab-pane key="1">
							<template #tab>
								<div>正确</div>
							</template>
							<div style="padding-bottom: 20px; padding-top: 20px">
								<div v-if="tableData1.length > 0">
									<a-table :columns="columns1" :data-source="tableData1" bordered> </a-table>
								</div>
								<div v-else>
									<div class="emptyStyle"></div>
								</div>
							</div>
						</a-tab-pane>
						<a-tab-pane key="2">
							<template #tab>
								<div>错误</div>
							</template>
							<div style="padding-bottom: 20px; padding-top: 20px">
								<div v-if="tableData2.length > 0">
									<a-table :columns="columns1" :data-source="tableData2" bordered> </a-table>
								</div>
								<div v-else>
									<div class="emptyStyle"></div>
								</div>
							</div>
						</a-tab-pane>
						<template #rightExtra>
							<a-button @click="fileDownloadBtn" type="primary" :disabled="fileDownload">文件下载</a-button>
						</template>
					</a-tabs>
				</a-spin>
			</a-card>
		</a-col>
	</a-row>
</template>

<script setup>
	import { message } from 'ant-design-vue'
	import sysConfig from '@/config'
	import uploadApi from '@/api/auth/uploadApi'
	import * as XLSX from 'xlsx'
	import { clone } from 'lodash-es'
	import fileApi from '@/api/dev/fileApi'
	const props = defineProps({
		action: {
			type: String,
			default: '/biz/file/upload',
			required: false
		}
	})
	const action = sysConfig.API_URL + props.action
	const fileList = ref([])
	const beforeUpload = (file) => {
		fileList.value = [...(fileList.value || []), file]
		return false
	}
	const handleRemove = (file) => {
		const index = fileList.value.indexOf(file)
		const newFileList = fileList.value.slice()
		newFileList.splice(index, 1)
		fileList.value = newFileList
	}
	const handleUpload = () => {
		// 可预览
		upLoadSpinning.value = true
		upLoadDisabled.value = true
		fileDownload.value = true
		uploading.value = true
		const fileData = new FormData()
		fileList.value.forEach((item) => {
			fileData.append('files', item.originFileObj)
		})
		uploadApi
			.upload(fileData)
			.then((res) => {
				message.success(`文件上传成功`)
				previewFile()
				trueNum.value = res.trueNum
				falseNum.value = res.falseNum
				wcdPercent.value = res.wcdPercent
			})
			.catch(() => {
				message.error(`文件上传失败`)
			})
			.finally(() => {
				//开始上传按钮
				uploading.value = false
				//文件上传禁选择
				upLoadDisabled.value = false
				//可预览
				upLoadSpinning.value = false
				//可下载
				fileDownload.value = false
			})
	}
	const activeKey = ref('0')
	const uploading = ref(false)
	const upLoadSpinning = ref(true)
	const upLoadDisabled = ref(true)
	const tableData = ref([])
	const tableData0 = ref([])
	const tableData1 = ref([])
	const tableData2 = ref([])
	const columns = ref({})
	const columns1 = ref({})
	const previewFile = () => {
		uploadApi
			.download()
			.then((res) => {
				const reader = new FileReader()
				reader.readAsBinaryString(res.data)
				reader.onload = (ev) => {
					try {
						const data = ev.target.result
						const wb = XLSX.read(data, {
							type: 'binary',
							cellText: false,
							cellDates: true
						})
						const outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])
						let tableheader = outdata[0]
						columns.value = [
							{
								title: '序号',
								dataIndex: '序号',
								key: '序号'
							}
						]
						columns1.value = [
							{
								title: '序号',
								dataIndex: '序号',
								key: '序号'
							}
						]
						for (let val in tableheader) {
							if (val !== '__EMPTY') {
								columns.value.push({
									title: val,
									dataIndex: val,
									key: val
								})
								if (val !== '比对结果') {
									columns1.value.push({
										title: val,
										dataIndex: val,
										key: val
									})
								}
							}
						}
						tableData.value = clone(outdata)
						tabChange(activeKey.value)
					} catch (e) {
						return false
					}
				}
				fileDownload.value = false
			})
			.catch((error) => {
				console.log(error)
			})
	}
	const tabChange = (key) => {
		if (key === '0') {
			const tableAll = tableData.value
			tableAll.forEach((v, i) => {
				v['序号'] = v.__EMPTY + 1
				v = { ...v, key: i + 1 }
			})
			tableData0.value = tableAll
		} else if (key === '1') {
			const tableTrue = tableData.value.filter((item) => item['比对结果'] === 1)
			tableTrue.forEach((v, i) => {
				v['序号'] = i + 1
			})
			tableData1.value = tableTrue
		} else if (key === '2') {
			const tableFalse = tableData.value.filter((item) => item['比对结果'] === 0)
			tableFalse.forEach((v, i) => {
				v['序号'] = i + 1
			})
			tableData2.value = tableFalse
		}
	}
	const fileDownload = ref(true)
	const trueNum = ref(0)
	const falseNum = ref(0)
	const wcdPercent = ref(0)
	const fileDownloadBtn = () => {
		upLoadSpinning.value = true
		upLoadDisabled.value = true
		fileDownload.value = true
		uploadApi
			.download()
			.then((res) => {
				message.success('文件下载成功')
				const blob = new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' })
				const $link = document.createElement('a')
				$link.href = URL.createObjectURL(blob)
				// $link.download = 'xxx.xlsx'
				$link.download = 'xxx.csv'
				$link.click()
				document.body.appendChild($link)
				document.body.removeChild($link) // 下载完成移除元素
				window.URL.revokeObjectURL($link.href) // 释放掉blob对象
				//文件上传禁选择
				upLoadDisabled.value = false
				//可预览
				upLoadSpinning.value = false
				//可下载
				fileDownload.value = false
			})
			.catch((error) => {
				console.log(error)
			})
	}
	onMounted(() => {
		//文件上传禁选择
		upLoadDisabled.value = false
		//可预览
		upLoadSpinning.value = false
	})
</script>

<style scoped>
	.emptyStyle {
		height: 200px;
		background-image: url(../../assets/images/empty1.png);
		background-position: center;
		background-repeat: no-repeat;
		background-size: 200px 200px;
		cursor: default;
	}
</style>

二、单文件上传

需求

  1. 单个文件上传
  2. 文件直接上传,直接调用后端接口
  3. 上传后显示全部、正确和错误的数据信息
  4. 上传后可以下载

注意细节:

  1. 文件上传未完成时,不可以再次上传,不可以下载,右边需要处于加载状态
  2. 文件再次上传后,原文件被覆盖,需要清除之前的fileList
  3. 文件下载接口注意类型为blob

样例

在这里插入图片描述

代码

<template>
	<a-row :gutter="8">
		<a-col :span="8">
			<a-card title="文件上传">
				<a-upload-dragger
					v-model:fileList="fileList"
					name="files"
					accept=".txt"
					:multiple="false"
					:action="action"
					@change="handleChange"
					:disabled="upLoadDisabled"
					:showUploadList="{
						showRemoveIcon: false
					}"
				>
					<p class="ant-upload-drag-icon">
						<inbox-outlined></inbox-outlined>
					</p>
					<p class="ant-upload-text">点击或将文件拖拽到这里上传, 支持扩展名:.txt</p>
					<p class="ant-upload-hint">仅支持单个文件上传</p>
					<template #removeIcon><StarOutlined></StarOutlined></template>
				</a-upload-dragger>
			</a-card>
		</a-col>
		<a-col :span="16">
			<a-card>
				<a-spin :spinning="upLoadSpinning" tip="文件加载中...">
					<a-row :gutter="16">
						<a-col :span="12">
							<a-statistic title="正确/错误(个)" :value="trueNum" class="demo-class">
								<template #suffix>
									<span>/{{ falseNum }}</span>
								</template>
							</a-statistic>
						</a-col>
						<a-col :span="12">
							<a-statistic title="完善度" :value="wcdPercent" style="margin-right: 50px" />
						</a-col>
					</a-row>
				</a-spin>
			</a-card>
			<a-card title="文件预览" style="margin-top: 5px">
				<a-spin :spinning="upLoadSpinning" tip="文件加载中...">
					<a-tabs v-model:activeKey="activeKey" type="card" @change="tabChange">
						<a-tab-pane key="0">
							<template #tab>
								<div>全部</div>
							</template>
							<div style="padding-bottom: 20px; padding-top: 20px">
									<div v-if="tableData0.length > 0">
										<a-table :columns="columns" :data-source="tableData0" bordered> </a-table>
									</div>
									<div v-else>
										<div class="emptyStyle"></div>
									</div>
							</div>
						</a-tab-pane>
						<a-tab-pane key="1">
							<template #tab>
								<div>正确</div>
							</template>
							<div style="padding-bottom: 20px; padding-top: 20px">
									<div v-if="tableData1.length > 0">
										<a-table :columns="columns1" :data-source="tableData1" bordered> </a-table>
									</div>
									<div v-else>
										<div class="emptyStyle"></div>
									</div>
							</div>
						</a-tab-pane>
						<a-tab-pane key="2">
							<template #tab>
								<div>错误</div>
							</template>
							<div style="padding-bottom: 20px; padding-top: 20px">
									<div v-if="tableData2.length > 0">
										<a-table :columns="columns1" :data-source="tableData2" bordered> </a-table>
									</div>
									<div v-else>
										<div class="emptyStyle"></div>
									</div>
							</div>
						</a-tab-pane>
						<template #rightExtra>
							<a-button @click="fileDownloadBtn" type="primary" :disabled="fileDownload">文件下载</a-button>
						</template>
					</a-tabs>
				</a-spin>
			</a-card>
		</a-col>
	</a-row>
</template>

<script setup>
	import { message } from 'ant-design-vue'
	import sysConfig from '@/config'
	import uploadApi from '@/api/auth/uploadApi'
	import * as XLSX from 'xlsx'
	import { clone } from 'lodash-es'
	const props = defineProps({
		action: {
			type: String,
			default: '/biz/file/upload',
			required: false
		}
	})
	const action = sysConfig.API_URL + props.action
	const fileList = ref([])
	const handleChange = (info) => {
		if (fileList.value.length > 1) {
			fileList.value.shift()
		}
		upLoadSpinning.value = true
		upLoadDisabled.value = true
		fileDownload.value = true
		const status = info.file.status
		if (status === 'done') {
			if (info.file.response.code === 200) {
				message.success(`${info.file.name}上传成功`)
				trueNum.value = info.file.response.data.trueNum
				falseNum.value = info.file.response.data.falseNum
				wcdPercent.value = info.file.response.data.wcdPercent
				//文件上传禁选择
				upLoadDisabled.value = false
			}
			//可预览
			upLoadSpinning.value = false
			//可下载
			fileDownload.value = false
			previewFile(1)
		} else if (status === 'error') {
			message.error(`${info.file.name}上传失败`)
			//文件上传禁选择
			upLoadDisabled.value = false
			//可预览
			upLoadSpinning.value = false
			//可下载
			fileDownload.value = false
		} else if (status === 'removed') {
			//文件上传禁选择
			upLoadDisabled.value = false
			//可预览
			upLoadSpinning.value = false
			//可下载
			fileDownload.value = false
		}
	}
	const activeKey = ref('0')
	const upLoadSpinning = ref(true)
	const upLoadDisabled = ref(true)
	const tableData = ref([])
	const tableData0 = ref([])
	const tableData1 = ref([])
	const tableData2 = ref([])
	const columns = ref({})
	const columns1 = ref({})
	const previewFile = () => {
		uploadApi
			.download()
			.then((res) => {
				const reader = new FileReader()
				reader.readAsBinaryString(res.data)
				reader.onload = (ev) => {
					try {
						const data = ev.target.result
						const wb = XLSX.read(data, {
							type: 'binary',
							cellText: false,
							cellDates: true
						})
						const outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])
						let tableheader = outdata[0]
						columns.value = [
							{
								title: '序号',
								dataIndex: '序号',
								key: '序号'
							}
						]
						columns1.value = [
							{
								title: '序号',
								dataIndex: '序号',
								key: '序号'
							}
						]
						for (let val in tableheader) {
							if (val !== '__EMPTY') {
								columns.value.push({
									title: val,
									dataIndex: val,
									key: val
								})
								if (val !== '比对结果') {
									columns1.value.push({
										title: val,
										dataIndex: val,
										key: val
									})
								}
							}
						}
						tableData.value = clone(outdata)
						tabChange(activeKey.value)
					} catch (e) {
						return false
					}
				}
				fileDownload.value = false
				upLoadDisabled.value = false
				//可预览
				upLoadSpinning.value = false
			})
			.catch((error) => {
				console.log(error)
			})
	}
	const tabChange = (key) => {
		console.log(key, 'key')
		if (key === '0') {
			const tableAll = tableData.value
			tableAll.forEach((v, i) => {
				v['序号'] = v.__EMPTY + 1
				v = { ...v, key: i + 1 }
			})
			tableData0.value = tableAll
		} else if (key === '1') {
			const tableTrue = tableData.value.filter((item) => item['比对结果'] === 1)
			tableTrue.forEach((v, i) => {
				v['序号'] = i + 1
			})
			tableData1.value = tableTrue
		} else if (key === '2') {
			const tableFalse = tableData.value.filter((item) => item['比对结果'] === 0)
			tableFalse.forEach((v, i) => {
				v['序号'] = i + 1
			})
			tableData2.value = tableFalse
		}
	}
	const fileDownload = ref(true)
	const trueNum = ref(0)
	const falseNum = ref(0)
	const wcdPercent = ref(0)
	const fileDownloadBtn = () => {
		upLoadSpinning.value = true
		upLoadDisabled.value = true
		fileDownload.value = true
		uploadApi
			.download()
			.then((res) => {
				message.success('文件下载成功')
				const blob = new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' })
				const $link = document.createElement('a')
				$link.href = URL.createObjectURL(blob)
				// $link.download = 'xxx.xlsx'
				$link.download = 'xxx.csv'
				$link.click()
				document.body.appendChild($link)
				document.body.removeChild($link) // 下载完成移除元素
				window.URL.revokeObjectURL($link.href) // 释放掉blob对象
				//文件上传禁选择
				upLoadDisabled.value = false
				//可预览
				upLoadSpinning.value = false
				//可下载
				fileDownload.value = false
			})
			.catch((error) => {
				console.log(error)
			})
	}
	onMounted(() => {
		//文件上传禁选择
		upLoadDisabled.value = false
		//可预览
		upLoadSpinning.value = false
	})
</script>

<style scoped>
	.emptyStyle {
		height: 200px;
		background-image: url(../../assets/images/empty1.png);
		background-position: center;
		background-repeat: no-repeat;
		background-size: 200px 200px;
		cursor: default;
	}
</style>

二、多文件上传产生的时间超时问题

当上传文件太多时,需要延长请求时间,以减少报错情况

文件路径:src/config/index.js
修改该文件中的TIMEOUT以延长请求时间
在这里插入图片描述

三、文件系统名称更改

  1. 修改文件index.html
    文件路径:index.html,修改这两处,即可修改刷新系统时候,浏览器显示的系统名称
    在这里插入图片描述
  2. 修改文件index.js
    文件路径:src/config/index.js,修改此处即可修改登陆页面系统名称
    在这里插入图片描述

四、系统登陆后的首页更改

原始首页为个人首页,若想修改为自己想要的页面,并且面包屑也不显示已去除的个人首页时,需修改文件util.js
文件路径:src/views/auth/login/util.js
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT信号和槽机制connect用法

信号与槽机制是绝对不可或缺且常用的&#xff0c;其中的参数一般都会比较简单&#xff0c;bool、int、QString之类的&#xff0c;但当我们想要传递相对比较复杂的参数&#xff0c;例如QVector<int>、QList<QString>&#xff0c;以及一些我们自定义的结构体时&#…

【timm笔记1】

1. 安装timm pip install timm2. 打印模型 import timm# 获取并打印所有可用的预训练模型名称 available_models = timm.list_models() # 打印出所有的模型 print(available_models)# 打印所有包含"resnet"字符的模型名称 resnet_models = timm.list_models(*resne…

C# 数组(Array)

C# 数组&#xff08;Array&#xff09; 初始化数组 声明一个数组不会在内存中初始化数组。当初始化数组变量时&#xff0c;您可以赋值给数组。 数组是一个引用类型&#xff0c;所以您需要使用 new 关键字来创建数组的实例。 例如&#xff1a; double[] b new double[10];…

排序算法:归并排序(递归)

文章目录 一、归并排序的思路二、代码编写 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的支持就是我坚持下去的动力。点赞后不要忘了关注我哦&#xff01; 所属专栏:排序算法 一、归并排序的思路 单…

C++基础基础基础杂谈,面试理解,看看就行,有不对欢迎指出

20240321 面试 今天面了一家公司&#xff0c;遇到几个之前没有遇到的问题&#xff0c;回答得不是特别好&#xff0c;对此进行归纳整理&#xff0c;顺道吐槽一下&#xff0c;最近西安的公司是真的一言难尽啊&#xff0c;有好的公司推荐下小弟我。 联系方式 &#xff11;&#…

LeetCode-60题:排列序列解法二(原创)

【题目描述】 给出集合 [1,2,3,...,n]&#xff0c;其所有元素共有 n! 种排列。按大小顺序列出所有排列情况&#xff0c;并一一标记&#xff0c;当 n 3 时, 所有排列如下&#xff1a;"123" 、"132" 、"213" 、"231"、"312"、…

element-ui实现证件照上传预览下载组件封装

element-ui实现证件照上传预览下载组件封装 效果&#xff1a; 参数说明 我只写了两个参数&#xff0c;后续有需求再对其组件进行丰富~ 参数说明fileListProp用来存储上传后后端返回的图片UR了uploadUrl图片上传反悔的URL后端接口地址 父组件调用&#xff1a; <au-upload…

OSPF-1类Router LSA学习

前面我们又复习了一遍OSPF概述&#xff0c;在OSPF建立关系后有几种交互报文&#xff0c;通过LSU类型报文包含LSA信息实现路由信息传递&#xff0c;常见了1、2、3、4、5、7类LSA&#xff0c;分别对应不同功能使用。这里先看下1类LSA-Router LSA。 一、LSA概述 LSA&#xff0c;全…

vscode中断无法识别npm的命令解决方案

在cmd中可以正常执行npm -v等指令,但是在vs code终端中,无法执行npm -v,node -v等指令 出现报错&#xff1a; 解决办法&#xff1a; 方法一&#xff1a;【右键单击Vscode】以【管理员身份运行】&#xff0c;【重启Vscode】&#xff08;这种办法每次打开都用管理员身份比较麻烦…

【实例】React 组件传值方法: Props、回调函数、Context、路由传参

React原始传值方法 借用状态管理库的传值见下篇文&#xff1a;MobX 和 Redux 【实例】React 状态管理库 MobX Redux 入门及对比 文章目录 React原始传值方法父组件->子组件 props子组件->父组件 回调函数Context路由传值 父组件->子组件 props 父组件可以通过属性&a…

字符串筛选排序 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 输入一个由n个大小写字母组成的字符串, 按照 ASCII 码值从小到大的排序规则,查找字符串中第 k 个最小ASCII 码值的字母(k>=1) , 输出该字母所在字符串的位置索引(字符串的第一个字符位置索引为0) 。…

电源配小了,是不是容易烧?是的!

电源小的话会不会容易烧毁&#xff1f; 是的。 功率电压*电流。 随着功率增大&#xff0c;电压不变&#xff0c;电流增大&#xff0c;发热量增大&#xff0c;可能会烧毁。 今天给大家推荐一款650w的电脑电源&#xff0c;不过在推荐之前&#xff0c;首先要确认自己的电脑功耗…

OpenCV4.9.0在Android 开发简介

查看&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;使用 Clojure 进行 OpenCV 开发简介 下一篇&#xff1a;暂无 引言&#xff1a; OpenCV是一个跨平台计算机视觉库&#xff0c;广泛用于图像处理、计算机视觉和机器学习等领域…

【翻译】Attentive Pooling Networks

摘要&#xff1a; 在这项工作中&#xff0c;我们提出了注意力池化&#xff08;AP&#xff09;&#xff0c;一种用于判别模型训练的双向注意力机制。在使用神经网络进行成对排序或分类的背景下&#xff0c;AP使得池化层能够意识到当前的输入对&#xff0c;使得两个输入项的信息…

AI系统性学习03—ChatGPT开发教程

文章目录 1、OpenAI关键概念⭐️2、OpenAI SDK介绍3、OpenAI API KEY&API 认证3.1 REST API安全认证 4、OpenAI模型⭐️4.1 模型分类4.2 GPT44.3 GPT-3.54.4 Embeddings 5、OpenAI快速入门6、Function calling(函数调用)⭐️⭐️⭐️6.1 应用场景6.2 支持function calling的…

稀碎从零算法笔记Day23-LeetCode:相同的树

题型&#xff1a;二叉树的遍历、链表 链接&#xff1a;100. 相同的树 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;…

ERP系统在企业管理中的重要作用

效率和盈利能力是企业在商业领域取得成功的两大关键要素。企业希望以尽可能高效的方式执行必要的、有利可图的业务流程&#xff0c;但又需要在保持最低运营成本的同时最大化企业的底线利润。要实现这种高效和高盈利的水平&#xff0c;企业需要扩展其业务流程管理策略&#xff0…

python网络爬虫实战教学——urllib的使用(3)

文章目录 专栏导读1、urlsplit2、urlunsplit3、urljoin4、urlencode 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对大学生、…

三级数据库技术考点(详解!!)

1、 答疑:【解析】分布式数据库系统按不同层次提供的分布透明性有:分片透明性;②位置透明性;③局部映像透明性&#xff0c;位置透明性是指数据分片的分配位置对用户是透明的&#xff0c;用户编写程序时只需 要考虑数据分片情况&#xff0c;不需要了解各分片在各个场地的分配情…

CMake学习(上)

1. CMake概述 CMake 是一个项目构建工具&#xff0c;并且是跨平台的。关于项目构建我们所熟知的还有Makefile&#xff08;通过 make 命令进行项目的构建&#xff09;&#xff0c;大多是IDE软件都集成了make&#xff0c;比如&#xff1a;VS 的 nmake、linux 下的 GNU make、Qt …