uniapp在H5端实现PDF和视频的上传、预览、下载

上传

在这里插入图片描述

上传页面

		<u-form-item :label="(form.ququ3 == 1 ? '参培' : form.ququ3 == 2 ? '授课' : '') + '证明材料'" prop="ququ6" required>
          <u-button @click="upload" slot="right" type="primary" icon="arrow-upward" text="上传文件" size="small"></u-button>
        </u-form-item>
        <view class="red">只能上传视频和pdf文件(支持.pdf, .mp4, .avi, .ts)</view>
        <view v-for="(item, i) in form.ququ6" :key="i" class="mb-20 flex ">
          <view class="flex_l" @click="preview(item)">
            <image style="width: 46rpx;height: 46rpx;"
              :src="item.split('.')[item.split('.').length - 1] == 'pdf' ? '/static/pdf.png' : '/static/video.png'">
            </image>
            <view class="blue ml-20 u-line-1 flex-1 over-hidden">{{ item.split('-')[item.split('-').length - 1] }}</view>
          </view>
          <!-- <view class="blue" @click="preview(item)">预览</view> -->
        </view>


import { uploadFile } from '../../common/common'
upload() {
   uploadFile(6).then(res => {
      console.log(2222, res)
      this.form.ququ6 = this.form.ququ6.concat(res)
   })
},

上传方法

/**
 * 上传视频和pdf文件
 * @param {*} count 个数
 * @returns arr-- 最终结果   ['img','img']
 */
export let uploadFile = (count = 1) => {
	return new Promise((resolve, reject) => {
		uni.chooseFile({
			count: count,
			extension: ['.pdf', '.mp4', '.avi', '.ts'],
			success: function (res) {
				uni.showLoading({
					title: '上传中'
				})
				let imgarr = res.tempFilePaths
				let arr = []
				imgarr.forEach(item => {
					uni.uploadFile({
						url: '/prod-api' + '/file/upload',
						filePath: item,
						name: 'file',
						header: {
							Authorization: uni.getStorageSync('token') || ''
						},
						success: (res) => {
							console.log(JSON.parse(res.data))
							arr.push(JSON.parse(res.data).data.url)
							if (arr.length == imgarr.length) {
								uni.hideLoading()
								let arr1 = arr.filter(item => ['pdf', 'mp4', 'avi', 'ts'].includes(item.split('.')[item.split('.').length - 1]))
								if (arr1.length != arr.length) {
									uni.showToast({
										title: '只能上传视频和pdf文件',
										icon: 'none'
									})
								}
								resolve(arr1)
							}
						},
						fail: () => {
							uni.showToast({
								title: '上传失败',
								icon: 'none'
							})
						}
					});
				})
			}
		});
	})
}

整个页面静态

<template>
  <view class="ptb-20 plr-30 bg min100">
    <view class="bg-white radius-20 pd-30">
      <u--form labelPosition="left" :model="form" :rules="rules" ref="uForm" labelWidth="100">
        <u-form-item label="培训主题名" prop="ququ1" required>
          <u--input v-model="form.ququ1" disabledColor="#ffffff" placeholder="请输入主题名" border="none"></u--input>
        </u-form-item>
        <u-form-item label="培训分类" prop="ququ2" required @click="showPop(1)">
          <u--input class="disabled" v-model="form.ququ2" disabled disabledColor="#ffffff" placeholder="请选择培训分类"
            border="none"></u--input>
          <u-icon slot="right" name="arrow-right"></u-icon>
        </u-form-item>
        <u-form-item label="本人所属类别" prop="ququ3" required>
          <u-radio-group v-model="form.ququ3" placement="row">
            <u-radio class="mr-20" label="参培人" name='1'></u-radio>
            <u-radio label="授课人" name='2'></u-radio>
          </u-radio-group>
        </u-form-item>
        <u-form-item label="参与地点" prop="ququ4">
          <u--input v-model="form.ququ4" placeholder="请输入参与地点" border="none"></u--input>
        </u-form-item>
        <u-form-item label="起止日期" prop="ququ5" @click="showPop(2)" required>
          <u--input class="disabled" v-model="form.ququ5" disabled disabledColor="#ffffff" placeholder="请选择起止日期"
            border="none"></u--input>
          <u-icon slot="right" name="arrow-right"></u-icon>
        </u-form-item>
        <u-form-item :label="(form.ququ3 == 1 ? '参培' : form.ququ3 == 2 ? '授课' : '') + '证明材料'" prop="ququ6" required>
          <u-button @click="upload" slot="right" type="primary" icon="arrow-upward" text="上传文件" size="small"></u-button>
        </u-form-item>
        <view class="red">只能上传视频和pdf文件(支持.pdf, .mp4, .avi, .ts)</view>
        <view v-for="(item, i) in form.ququ6" :key="i" class="mb-20 flex ">
          <view class="flex_l" @click="preview(item)">
            <image style="width: 46rpx;height: 46rpx;"
              :src="item.split('.')[item.split('.').length - 1] == 'pdf' ? '/static/pdf.png' : '/static/video.png'">
            </image>
            <view class="blue ml-20 u-line-1 flex-1 over-hidden">{{ item.split('-')[item.split('-').length - 1] }}</view>
          </view>
          <!-- <view class="blue" @click="preview(item)">预览</view> -->
        </view>
        <u-form-item label="备注" prop="ququ7">
          <u--textarea v-model="form.ququ7" placeholder="请输入备注" maxlength="150" count autoHeight
            border="none"></u--textarea>
        </u-form-item>
      </u--form>
      <!-- 下拉选择框 -->
      <u-action-sheet :show="show" :actions="actions" title="请选择" @close="close" @select="confirmSelect">
      </u-action-sheet>
      <!-- 日历选择范围 -->
      <u-calendar :maxDate="maxDate" :minDate="minDate" monthNum="10" :show="showDate" mode="range" @confirm="confirmDate"
        @close="close"></u-calendar>
      <view class="flex mt-60">
        <u-button @click="reset">重置</u-button>
        <u-button type="primary" plain class="mlr-20" @click="save">保存草稿</u-button>
        <u-button type="primary" @click="submit">提交审核</u-button>
      </view>
    </view>
  </view>
</template>

<script>
import { uploadFile } from '../../common/common'
const d = new Date()
const year = d.getFullYear()
let month = d.getMonth() + 1
month = month < 10 ? `0${month}` : month
const date = d.getDate()
export default {
  data() {
    return {
      show: false,
      type: null,
      actions: [],

      showDate: false, // 日期选择
      maxDate: `${year}-${month + 1}-${date}`,
      minDate: `${year}-${month - 8}-${date}`,
      form: {
        ququ1: '',
        ququ2: '',
        ququ2Id: '',
        ququ3: '',
        ququ4: '',
        ququ5: '',
        ququ6: [],
        ququ7: '',
      },
      rules: {
        'ququ1': {
          required: true,
          message: '请输入主题名',
          trigger: ['blur']
        },
        'ququ2': {
          required: true,
          message: '请选择培训分类',
          trigger: ['blur', 'change']
        },
        'ququ3': {
          required: true,
          message: '请选择所属类别',
          trigger: ['blur', 'change']
        },
        'ququ5': {
          required: true,
          message: '请选择起止日期',
          trigger: ['blur', 'change']
        },
      },
    };
  },
  onLoad() {

  },
  methods: {
    showPop(type) {
      this.type = type
      if (type == 1) {
        this.show = true
        this.actions = [{
          name: '培训分类1',
          id: 1
        },
        {
          name: '培训分类2',
          id: 2
        },
        ]
      } else {
        this.showDate = true
      }
    },
    close() {
      this.show = false
      this.showDate = false
      this.type = null
    },
    confirmSelect(e) {
      this.form['ququ2'] = e.name
      this.form['ququ2Id'] = e.id
      this.$refs.uForm.validateField('ququ2')
    },
    confirmDate(e) {
      console.log(e);
      this.form['ququ5'] = e[0] + '~' + e[e.length - 1]
      this.showDate = false
    },
    upload() {
      uploadFile(6).then(res => {
        console.log(2222, res)
        this.form.ququ6 = this.form.ququ6.concat(res)
      })
    },
    preview(item) {
      if (item.split('.')[item.split('.').length - 1] == 'pdf') {
        uni.navigateTo({
          url: '/pages/course/pdf?url=' + item
        })
      } else {
        // uni.navigateTo({
        //   url: '/pages/course/video?url=' + item
        // })
        window.open(item)
      }
    },
    submit() {
      this.$refs.uForm.validate().then(res => {
        if (!this.form.ququ6.length) {
          uni.$u.toast('请上传证明材料')
          return
        }
        uni.$u.toast('校验通过')
        this.$http('/system/user/profile', {
          avatar: this.form
        }, "post").then(res => {
          uni.showToast({
            title: '提交成功',
          })
        })
      }).catch(errors => {
        uni.$u.toast('校验失败')
      })
    },
    save() {
      this.$http('/system/user/profile', {
        avatar: this.form
      }, "post").then(res => {
        uni.showToast({
          title: '保存成功',
        })
      })
    },
    reset() {
      this.$refs.uForm.resetFields()
    },
  },

};
</script>

<style scoped lang="scss"></style>

预览和下载

在这里插入图片描述

预览页面 PDF预览详见

 <view class="title-left bold mtb-20">附件记录</view>
    <view v-for="(item, i) in form.ququ6" :key="i" class="mb-20 ml-30 flex">
      <view class="flex_l" @click="preview(item)">
        <image style="width: 46rpx;height: 46rpx;"
          :src="item.split('.')[item.split('.').length - 1] == 'pdf' ? '/static/pdf.png' : '/static/video.png'">
        </image>
        <view class="blue ml-20 u-line-1 flex-1 over-hidden">{{ item.split('-')[item.split('-').length - 1] }}</view>
      </view>
      <view class="green" @click="downLoad(item)">下载</view>
    </view>


 data() {
    return {
      form: {
        ququ6: ["https://cscec83-learnplatform.oss-cn-shanghai.aliyuncs.com/test/2023-11-27/6a12b9ca-3ae9-435b-b023-0f9c119afad3-1.mp4", "https://cscec83-learnplatform.oss-cn-shanghai.aliyuncs.com/test/2023-11-27/53aa1f60-0735-4203-86b2-c2b8b019e8d9-我的哈哈.pdf"]
      }
    }
  },

 preview(item) {
      if (item.split('.')[item.split('.').length - 1] == 'pdf') {
        uni.navigateTo({
          url: '/pages/course/pdf?url=' + item
        })
      } else {
        // uni.navigateTo({
        //   url: '/pages/course/video?url=' + item
        // })
        window.open(item)
      }
    },
    downLoad(url) {
      if (url.split('.')[url.split('.').length - 1] == 'pdf') {
        window.open(url)
      } else {
        let xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.responseType = 'blob'; // 返回类型blob
        xhr.onload = function () {
          if (xhr.readyState === 4 && xhr.status === 200) {
            let blob = this.response;
            // 转换一个blob链接
            let u = window.URL.createObjectURL(new Blob([blob]));
            let a = document.createElement('a');
            a.download = url.split('-')[url.split('-').length - 1]; //下载后保存的名称
            a.href = u;
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
            a.remove();
            uni.hideLoading();
          }
        };
        xhr.send()
      }
    },

详情页面静态

<template>
  <view class="mlr-30 pt-20">
    <view class="title-left bold mb-20">培训详情</view>
    <u-cell-group :border="false">
      <u-cell :border="false" title="培训主题名" :value="userInfo.nickName"></u-cell>
      <u-cell :border="false" title="培训分类" :value="userInfo.sex"></u-cell>
      <u-cell :border="false" title="本人所属类别" :value="userInfo.sex == 1 ? '参培人' : '授课人'"></u-cell>
      <u-cell :border="false" title="起止日期" :value="userInfo.phonenumber"></u-cell>
      <u-cell :border="false" title="参与地点" :value="userInfo.nickName"></u-cell>
      <u-cell :border="false" title="提交时间" :value="userInfo.nickName"></u-cell>
    </u-cell-group>
    <view class="title-left bold mtb-20">附件记录</view>
    <view v-for="(item, i) in form.ququ6" :key="i" class="mb-20 ml-30 flex">
      <view class="flex_l" @click="preview(item)">
        <image style="width: 46rpx;height: 46rpx;"
          :src="item.split('.')[item.split('.').length - 1] == 'pdf' ? '/static/pdf.png' : '/static/video.png'">
        </image>
        <view class="blue ml-20 u-line-1 flex-1 over-hidden">{{ item.split('-')[item.split('-').length - 1] }}</view>
      </view>
      <view class="green" @click="downLoad(item)">下载</view>
    </view>
    <view class="title-left bold mb-20">审批详情</view>
    <u-cell-group :border="false">
      <u-cell :border="false" title="审批状态" :value="userInfo.nickName"></u-cell>
      <u-cell :border="false" title="当前审批人" :value="userInfo.sex"></u-cell>
    </u-cell-group>
    <view class="flex mt-60">
      <u-button @click="back">返回首页</u-button>
      <u-button type="primary" plain class="mlr-20" @click="edit">修改</u-button>
      <u-button type="primary" @click="revoke">撤回流程</u-button>
    </view>
  </view>
</template>

<script>
import {
  mapState
} from 'vuex'
export default {
  data() {
    return {
      form: {
        ququ6: ["https://cscec83-learnplatform.oss-cn-shanghai.aliyuncs.com/test/2023-11-27/6a12b9ca-3ae9-435b-b023-0f9c119afad3-1.mp4", "https://cscec83-learnplatform.oss-cn-shanghai.aliyuncs.com/test/2023-11-27/53aa1f60-0735-4203-86b2-c2b8b019e8d9-我的哈哈.pdf"]
      }
    }
  },
  computed: {
    ...mapState(['userInfo']),
  },
  onLoad() {
    // 刷新个人信息
    this.$store.dispatch('updateUserInfo')
    this.img = this.userInfo.avatar ? this.userInfo.avatar : '/static/user-default.png'
  },
  methods: {
    preview(item) {
      if (item.split('.')[item.split('.').length - 1] == 'pdf') {
        uni.navigateTo({
          url: '/pages/course/pdf?url=' + item
        })
      } else {
        // uni.navigateTo({
        //   url: '/pages/course/video?url=' + item
        // })
        window.open(item)
      }
    },
    downLoad(url) {
      if (url.split('.')[url.split('.').length - 1] == 'pdf') {
        window.open(url)
      } else {
        let xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.responseType = 'blob'; // 返回类型blob
        xhr.onload = function () {
          if (xhr.readyState === 4 && xhr.status === 200) {
            let blob = this.response;
            // 转换一个blob链接
            let u = window.URL.createObjectURL(new Blob([blob]));
            let a = document.createElement('a');
            a.download = url.split('-')[url.split('-').length - 1]; //下载后保存的名称
            a.href = u;
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
            a.remove();
            uni.hideLoading();
          }
        };
        xhr.send()
      }
    },
    revoke() {
      this.$http('/system/user/profile', {
        avatar: 1
      }, "put").then(res => {
        uni.showToast({
          title: '撤回成功',
        })
      })
    },
    edit() {
      uni.navigateTo({
        url: './add?id=1'
      })
    },
    back() {
      uni.navigateBack()
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .u-cell__body {
  padding: 5px 15px !important;
}
</style>

完整的上传视频、上传pdf、上传图片 方法封装(需要传递name、size、时长)

/**
 *  上传图片
 *  count-- 可选张数
 * 	arr-- 最终结果   ['img','img']
 */
export let upload = (count = 1) => {
	console.log(count);
	return new Promise((resolve, reject) => {
		uni.chooseImage({
			count: count,
			sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
			success: function (res) {
				uni.showLoading({
					title: '上传中'
				})
				let imgarr = res.tempFilePaths
				let arr = []
				imgarr.forEach(item => {
					uni.uploadFile({
						url: '/prod-api' + '/file/upload',
						filePath: item,
						name: 'file',
						header: {
							Authorization: uni.getStorageSync('token') || ''
						},
						success: (res) => {
							console.log(JSON.parse(res.data))
							uni.hideLoading()
							arr.push(JSON.parse(res.data).data.url)
							if (arr.length == imgarr.length) {
								resolve(arr)
							}
						},
						fail: () => {
							uni.showToast({
								title: '上传失败',
								icon: 'none'
							})
						}
					});
				})
			}
		});
	})
}
/**
 * 上传pdf文件
 * @param {*} count 个数
 * @returns arr-- 最终结果   ['img','img']
 */
export let uploadFile = (count = 1) => {
	return new Promise((resolve, reject) => {
		uni.chooseFile({
			count: count,
			extension: ['.pdf'],
			success: function (res) {
				console.log(888, res)
				uni.showLoading({
					title: '上传中'
				})
				let imgarr = res.tempFiles
				let arr = []
				imgarr.forEach(item => {
					uni.uploadFile({
						url: '/prod-api' + '/file/appUpload', //接口地址
						filePath: item.path, // 上传文件参数值
						name: 'file', // 上传文件参数名
						formData: {  // 额外参数
							fileName: item.name,
							size: (item.size / 1024 / 1024).toFixed(2),
							type: 'pdf',
						},
						header: { //请求头
							Authorization: uni.getStorageSync('token') || ''
						},
						success: (res) => {
							arr.push(JSON.parse(res.data).data)
							if (arr.length == imgarr.length) {
								uni.hideLoading()
								let arr1 = arr.filter(item => 'pdf' == item.fileName.split('.')[item.fileName.split('.').length - 1])
								if (arr1.length != arr.length) {
									uni.showToast({
										title: '只能上传pdf文件',
										icon: 'none'
									})
								}
								resolve(arr1)
							}
						},
						fail: () => {
							uni.showToast({
								title: '上传失败',
								icon: 'none'
							})
						}
					});
				})
			}
		});
	})
}
/** 上传视频
 * 	arr-- 最终结果   [{img1:'全路径',img2:'半路径'},{img1:'全路径',img2:'半路径'}]
 */
export let uploadVideo = () => {
	return new Promise((resolve, reject) => {
		uni.chooseVideo({
			count: 1,
			success: function (res) {
				uni.showLoading({
					title: '上传中'
				})
				console.log(111111111111, res)
				uni.uploadFile({
					url: '/prod-api' + '/file/appUpload', //接口地址
					filePath: res.tempFilePath, // 上传文件参数值
					name: 'file', // 上传文件参数名
					formData: {  // 额外参数,formData传参
						fileName: res.name,
						size: (res.size / 1024 / 1024).toFixed(2),
						duration: res.duration,
						type: 'video',
					},
					header: { //请求头
						Authorization: uni.getStorageSync('token') || ''
					},
					success: (res) => {
						uni.hideLoading()
						if (JSON.parse(res.data).code == '200') {
							resolve(JSON.parse(res.data).data)
						} else {
							uni.showToast({
								title: JSON.parse(res.data).msg,
								icon: 'none'
							})
						}
					},
					fail: () => {
						uni.showToast({
							title: '上传失败,请重试',
							icon: 'none'
						})
					}
				});
			}
		});
	})
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型新升级:亚马逊云科技2023芯片创新日

在这个充满活力的2023年芯片创新日&#xff0c;Amazon EC2 的副总裁 Dave Brown 与观众分享了他与 EC2 的15年漫长旅程。他的眼中闪烁着对技术的热情&#xff0c;他描述了自己如何与一个才华横溢的团队合作&#xff0c;在这大语言模型与生成式AI的元年中致力于为客户提供最佳的…

Linux:进程状态

目录 1.Linux内核关于进程状态的源代码 2. 运行状态 3. 阻塞状态 4. 挂起 5.Linux中的进程状态 5.1 睡眠状态 5.2 暂停状态 5.3 僵尸进程与孤儿进程 我们在学习进程状态时&#xff0c;老师只是简单的让我们记住下面这张图 1.教材中进程操作系统的进程状态 那么这些…

四、shell - 字符串

目录 1、单引号 2、双引号 3、拼接字符串 3.1 使用双引号拼接 3.2 使用单引号拼接 4、获取字符串长度 ​​​​​​​5、提取子字符串 ​​​​​​​6、查找子字符串 ​​​​​​​字符串是shell编程中最常用最有用的数据类型&#xff08;除了数字和字符串&#xff0…

大模型的RPA应用 | 代理流程自动化(APA),开启智能自动化新纪元

随着技术创新的持续推进&#xff0c;自动化技术已经变得至关重要&#xff0c;成为驱动企业和社会向前发展的核心动力。在自动化的里程碑中&#xff0c;机器人流程自动化&#xff08;RPA&#xff09;已经有效地将简单、重复且规则性的任务自动化。可是随着对处理更为复杂、多变且…

“最甜港姐”走的与众不同之路

网络图片 媒体最新报道&#xff0c;她被誉为“最甜港姐”&#xff0c;曾是TVB炙手可热的当红花旦&#xff0c;却在最当红的时候选择急流勇退。 她不是退圈去相夫教子&#xff0c;而是读书深造&#xff0c;成为一名专业律师。 前不久&#xff0c;又有消息传出&#xff0c;明年…

VUE2+THREE.JS辉光设定和解决辉光导致背景变暗的问题

THREE.JS辉光设定和解决辉光导致背景变暗的问题 THREE.JS 辉光设定THREE.JS 辉光导致背景变暗的问题1.设定背景图片2.初始化辉光3. animate 一直渲染辉光 THREE.JS 辉光设定 给我的设计好的fbx模型,已经设定好了模型发光材质,所以直接添加辉光效果,就可以自动发光 blender模型生…

Docker 安装部署 Sentinel Dashboard

1、下载 jar 包 官方 jar 包下载地址&#xff1a;https://github.com/alibaba/Sentinel/releases 或者点击 链接 直接跳转到下载页 进入链接下载你需要的版本 下载完毕&#xff08;我这里统一放在一个sentinel目录内&#xff09; 2、编写 Dockerfile 文件&#xff08;这里我不…

求臻医学满分通过EMQN室间质评,检测实力再获国际权威机构认可

近日&#xff0c;欧洲分子基因诊断质量联盟&#xff08;European Molecular Genetics Quality Network&#xff0c;EMQN&#xff09;公布了2023年Oncogene panel 项目能力验证考核结果&#xff0c;求臻医学旗下北京和杭州检验实验室&#xff0c;使用自主研发的ChosenOne大Panel…

Apache DolphinScheduler 开源之夏采访:苏国伟的开源之旅

个人介绍 大家好&#xff0c;我是苏国伟&#xff0c;来自西安电子科技大学软件工程专业。我在实验室中主要从事数据集成等方面的工作。除了编程&#xff0c;我还热衷于踢足球、观看球赛和健身&#xff0c;这些爱好让我的生活更加丰富多彩。 开源之路 我最初是在本科的分布式…

【Linux基础开发工具】yum生态vim的配置与使用

目录 前言 1. Linux 软件包管理器 yum 1.1 什么是yum 1.2 快速上手yum 1.3 yum生态 2. Linux编辑器vim 2.1 vim的模式 2.2 vim使用技巧 3. vim编辑器辅助功能配置 3.1 配置 3.2 用户sudo权限配置 总结 前言 Linux基础指令与权限之后&#xff0c;Linux系统开发工具的使用…

美林防火建材——朱林甫 坚韧与创新:美林传奇

在这个变幻莫测的时代&#xff0c;有一些创业者凭借着对行业的深刻理解和对未来的敏锐洞察&#xff0c;不仅在商海中乘风破浪&#xff0c;更是引领了整个行业的发展。今天&#xff0c;我们要讲述的&#xff0c;就是一位这样的创业者——来自浙江嘉善的朱总&#xff0c;他创立的…

初始Redis(入门篇)

目录 什么是Redis Redis特性 速度快 丰富的功能 客户端语言多 持久化 主从复制 Redis可以做什么 缓存 排行榜系统 计数器应用 消息队列系统 Redis安装 centos7安装 Redis重要文件 Redis的使用 Redis通用命令 set get keys exists del expire 什么是Redi…

生成式AI与预测式AI的主要区别与实际应用

近年来&#xff0c;预测式人工智能&#xff08;Predictive AI&#xff09;通过先进的推荐算法、风险评估模型、以及欺诈检测工具&#xff0c;一直在推高着该领域公司的投资回报率。然而&#xff0c;今年初突然杀出的生成式人工智能&#xff08;Generative AI&#xff09;突然成…

如何绕过某讯手游保护系统并从内存中获取Unity3D引擎的Dll文件

​ 某讯的手游保护系统用的都是一套&#xff0c;在其官宣的手游加固功能中有一项宣传是对比较热门的Unity3d引擎的手游保护方案&#xff0c;其中对Dll文件的保护介绍如下&#xff0c; “Dll加固混淆针对Unity游戏&#xff0c;对Dll模块的变量名、函数名、类名进行加密混淆处理&…

Android中添加C或C++代码

1、创建cpp目录&#xff0c;用于存放C和C代码。 2、创建CMake构建脚本CMakeLists.txt文件&#xff0c;将其放在cpp目录中。 # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.22.1)# Declares and names the pro…

单宁对葡萄酒可饮用性和陈酿潜力会有影响吗?

当在酿酒过程中葡萄酒中的单宁过量时&#xff0c;酿酒师可以使用白蛋白、酪蛋白和明胶等各种细化剂&#xff0c;这些药物可以与单宁分子结合&#xff0c;并将其作为沉淀物沉淀出来。随着葡萄酒的老化&#xff0c;单宁将形成长长的聚合链&#xff0c;氧气可以与单宁分子结合&…

数据挖掘实战-基于word2vec的短文本情感分析(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【PPT模板合集】关于自制内容的PPT模板合集,包括原创的PPT及改良内容的PPT,适合科研/比赛/工作

【PPT模板合集】关于自制内容的PPT模板合集&#xff0c;包括原创的PPT及改良内容的PPT&#xff0c;适合科研/比赛/工作 零、前言一、校园层面的PPT模板1.1 各种毕业答辩1.2 夏令营答辩1.3 奖学金答辩1.4 比赛/项目答辩 二、学术层面的PPT模板2.1 学术汇报2.2 会议海报类型 三、…

使用VScode通过内网穿透在公网环境下远程连接进行开发

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

网站监控有什么作用?

科技改变生活&#xff0c;科技的发展让我们的生活越来越精彩丰富&#xff0c;数据中心机房监控系统也可以称为“自我监控系统”&#xff0c;主要是针对机房所有的设备及环境进行集中监控和管理的&#xff0c;其监控对象构成机房的各个子系统&#xff1a;动力系统、环境系统、消…