UNIapp实现局域网内在线升级

news2024/12/23 4:02:55

首先是UNIapp 生成apk

用Hbuilder 进行打包云打包
可以从网站https://www.yunedit.com/reg?goto=cert 使用自有证书,目测比直接使用云证书要快一些。

发布apk 网站

发布内容用IIS发布即可
注意事项中记录如下内容

第一、需要在 iis 的MiMe 中添加apk 的格式,否则无法下载apk 文件到手持机中。 添加方式 打开MIME 点击添加
分别输入 apk application/vnd.android.package-archive 点击保存即可

第二、发布新的apk 的时候,需要修改应用版本号(往大了修改),同时版本号.json 文件中
newVersionCode对应的值,也要和新的应用版本号相同(方便检测更新) newVersionName 中保存的是当前PDA的版本名称
versionDesc 中可以添加修改的内容 appName 需要添加新发布的apk 名称(用于下载对应的文件)

第三、将对应的文件夹发布在iis中,同时要修改uniapp 中的http.js文件
uni.setStorageSync(‘loadVersion’, ‘http://127.0.0.1:8032/’); 修改内部的url

要在IIS中添加.apk文件的MIME类型,可以按照以下步骤操作:

打开IIS管理器,找到服务器,右键选择“属性”。
在打开的属性窗口中,选择“MIME类型”选项卡。
点击“MIME类型”按钮,打开MIME类型设置窗口。
选择“新建”来添加一个新的MIME类型。
在“扩展名”中填写“.apk”,在“MIME类型”中填写“.apk”的MIME类型“application/vnd.android.package-archive”。
点击“确定”保存设置。
重启IIS服务,以使更改生效。
完成以上步骤后,IIS就能够正确识别和处理.apk文件了

版本号.json中的内容为

{"newVersionCode":223,"newVersionName":"V1.2.0","versionDesc":"升级了部分功能","appName":"android_debug.apk"}

uniapp相关代码

结构
upgrade.vue中存在

<template>
	<view class="upgrade-popup">
		
		<view class="main">
			<view class="version">发现新版本{{versionName}}</view>
			<view class="content">
				<text class="title">更新内容</text>
				<view class="desc" v-html="versionDesc"></view>
			</view>
			<!--下载状态-进度条显示 -->
			<view class="footer" v-if="isStartDownload">
				<view class="progress-view" :class="{'active':!hasProgress}" @click="handleInstallApp">
					<!-- 进度条 -->
					<view v-if="hasProgress" style="height: 100%;">
						<view class="txt">{{percentText}}</view>
						<view class="progress" :style="setProStyle"></view>
					</view>
					<view v-else>
						<view class="btn upgrade force">{{ isDownloadFinish  ? '立即安装' :'下载中...'}}</view>
					</view>
				</view>
			</view>
			<!-- 强制更新 -->
			<view class="footer" v-else-if="isForceUpdate">
				<view class="btn upgrade force" @click="handleUpgrade">立即更新</view>
			</view>
			<!-- 可选择更新 -->
			<view class="footer" v-else>
				<view class="btn close" @click="handleClose">以后再说</view>
				<view class="btn upgrade" @click="handleUpgrade">立即更新</view>
			</view>
		</view>
	</view>
</template>
 
<script>
	import {
		downloadApp,
		installApp
	} from './upgrade.js'
	export default {
		data() {
			return {
				isForceUpdate: false, //是否强制更新
				versionName: '', //版本名称
				versionDesc: '', //更新说明
				downloadUrl: '', //APP下载链接
				isDownloadFinish: false, //是否下载完成
				hasProgress: false, //是否能显示进度条
				currentPercent: 0, //当前下载百分比
				isStartDownload: false, //是否开始下载
				fileName: '', //下载后app本地路径名称
			}
		},
		computed: {
			//设置进度条样式,实时更新进度位置
			setProStyle() {
				return {
					width: (510 * this.currentPercent / 100) + 'rpx' //510:按钮进度条宽度
				}
			},
			//百分比文字
			percentText() {
				let percent = this.currentPercent;
				if (typeof percent !== 'number' || isNaN(percent)) return '下载中...'
				if (percent < 100) return `下载中${percent}%`
				return '立即安装'
 
			}
		},
		onLoad(options) {
			this.init(options)
		},
		onBackPress(options) {
			// 禁用返回
			if (options.from == 'backbutton') {
				return true;
			}
 
		},
		methods: {
			//初始化获取最新APP版本信息
			init(options) {
				let randomNum = Math.random();
				//模拟接口获取最新版本号,版本号固定为整数
				const baseurl = uni.getStorageSync('loadVersion')+options.appName+'?V='+randomNum;;
				console.log('结果为')
				console.log((baseurl))
				//模拟接口获取
				setTimeout(() => {
                   //演示数据请根据实际修改
					this.versionName = options.versionName; //版本名称
					this.versionDesc = options.versionDesc; //更新说明
					this.downloadUrl = baseurl; //下载链接
					this.isForceUpdate = false; //是否强制更新
				}, 200)
			},
			//更新
			handleUpgrade() {
				console.log('Hello UniApp!-----------------------------------------------')
				uni.getStorage({
					key: 'loadVersion',
					success: function (res) {
						console.log(res.data);
					}
				});
			   //requestTask.abort();
				if (this.downloadUrl) {
					this.isStartDownload = true
					//开始下载App
					downloadApp(this.downloadUrl, current => {
						//下载进度监听
						this.hasProgress = true
						this.currentPercent = current
 
					}).then(fileName => {
						//下载完成
						this.isDownloadFinish = true
						this.fileName = fileName
						if (fileName) {
							//自动安装App
							this.handleInstallApp()
						}
					}).catch(e => {
						console.log(e, 'e')
					})
				} else {
					uni.showToast({
						title: '下载链接不存在',
						icon: 'none'
					})
				}
 
			},
			//安装app
			handleInstallApp() {
				//下载完成才能安装,防止下载过程中点击
				if (this.isDownloadFinish && this.fileName) {
					installApp(this.fileName, () => {
						//安装成功,关闭升级弹窗
						uni.navigateBack()
					})
				}
			},
			//关闭返回
			handleClose() {
				uni.navigateBack()
			},
		}
	}
</script>
 
<style>
	page {
		background: rgba(0, 0, 0, 0.5);/**设置窗口背景半透明*/
	}
</style>
<style lang="scss" scoped>
	.upgrade-popup {
		width: 580rpx;
		height: auto;
		position: fixed;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		background: #fff;
		border-radius: 20rpx;
		box-sizing: border-box;
		border: 1px solid #eee;
	}
 
	.header-bg {
		width: 100%;
		margin-top: -112rpx;
	}
 
	.main {
		padding: 10rpx 30rpx 30rpx;
		box-sizing: border-box;
		.version {
			font-size: 36rpx;
			color: #026DF7;
			font-weight: 700;
			width: 100%;
			text-align: center;
			overflow: hidden;
			text-overflow: ellipsis;
			white-space: nowrap;
			letter-spacing: 1px;
		}
 
		.content {
			margin-top: 60rpx;
 
			.title {
				font-size: 28rpx;
				font-weight: 700;
				color: #000000;
			}
 
			.desc {
				box-sizing: border-box;
				margin-top: 20rpx;
				font-size: 28rpx;
				color: #6A6A6A;
				max-height: 80vh;
				overflow-y: auto;
			}
		}
 
		.footer {
			width: 100%;
			display: flex;
			justify-content: center;
			align-items: center;
			position: relative;
			flex-shrink: 0;
			margin-top: 100rpx;
 
			.btn {
				width: 246rpx;
				display: flex;
				justify-content: center;
				align-items: center;
				position: relative;
				z-index: 999;
				height: 96rpx;
				box-sizing: border-box;
				font-size: 32rpx;
				border-radius: 10rpx;
				letter-spacing: 2rpx;
 
				&.force {
					width: 500rpx;
				}
 
				&.close {
					border: 1px solid #E0E0E0;
					margin-right: 25rpx;
					color: #000;
				}
 
				&.upgrade {
					background-color: #026DF7;
					color: white;
				}
			}
 
			.progress-view {
				width: 510rpx;
				height: 90rpx;
				display: flex;
				position: relative;
				align-items: center;
				border-radius: 6rpx;
				background-color: #dcdcdc;
				display: flex;
				justify-content: flex-start;
				padding: 0px;
				box-sizing: border-box;
				border: none;
				overflow: hidden;
 
				&.active {
					background-color: #026DF7;
				}
 
				.progress {
					height: 100%;
					background-color: #026DF7;
					padding: 0px;
					box-sizing: border-box;
					border: none;
					border-top-left-radius: 10rpx;
					border-bottom-left-radius: 10rpx;
 
				}
 
				.txt {
					font-size: 28rpx;
					position: absolute;
					top: 50%;
					left: 50%;
					transform: translate(-50%, -50%);
					color: #fff;
				}
			}
		}
	}
</style>

upgrade.js

/**
 * @description H5+下载App
 * @param downloadUrl:App下载链接
 * @param progressCallBack:下载进度回调
 */
export const downloadApp = (downloadUrl, progressCallBack = () => {}, ) => {
	return new Promise((resolve, reject) => {
		//创建下载任务
		const downloadTask = plus.downloader.createDownload(downloadUrl, {
			method: "GET"
		}, (task, status) => {
			console.log(status,'status')
			if (status == 200) { //下载成功
				resolve(task.filename)
 
			} else {
				reject('fail')
				uni.showToast({
					title: '下载失败',
					duration: 1500,
					icon: "none"
				});
			}
		})
		//监听下载过程
		downloadTask.addEventListener("statechanged", (task, status) => {
			switch (task.state) {
				case 1: // 开始  
					break;
				case 2: //已连接到服务器  
					break;
				case 3: // 已接收到数据  
					let hasProgress = task.totalSize && task.totalSize > 0 //是否能获取到App大小
					if (hasProgress) {
						let current = parseInt(100 * task.downloadedSize / task.totalSize); //获取下载进度百分比
						progressCallBack(current)
					}
					break;
				case 4: // 下载完成       
					break;
			}
		});
		//开始执行下载
		downloadTask.start();
	})
 
 
}
/**
 * @description H5+安装APP
 * @param fileName:app文件名
 * @param callBack:安装成功回调
 */
export const installApp = (fileName, callBack = () => {}) => {
	//注册广播监听app安装情况
	onInstallListening(callBack);
	//开始安装
	plus.runtime.install(plus.io.convertLocalFileSystemURL(fileName), {}, () => {
		//成功跳转到安装界面
	}, function(error) {
		uni.showToast({
			title: '安装失败',
			duration: 1500,
			icon: "none"
		});
	})
 
}
/**
 * @description 注册广播监听APP是否安装成功
 * @param callBack:安装成功回调函数
 */
const onInstallListening = (callBack = () => {}) => {
 
	let mainActivity = plus.android.runtimeMainActivity(); //获取activity
	//生成广播接收器
	let receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
		onReceive: (context, intent) => { //接收广播回调  
			plus.android.importClass(intent);
			mainActivity.unregisterReceiver(receiver); //取消监听
			callBack()
		}
	});
	let IntentFilter = plus.android.importClass('android.content.IntentFilter');
	let Intent = plus.android.importClass('android.content.Intent');
	let filter = new IntentFilter();
	filter.addAction(Intent.ACTION_PACKAGE_ADDED); //监听APP安装     
	filter.addDataScheme("package");
	mainActivity.registerReceiver(receiver, filter); //注册广播
 
}

home.vue

<template>
	<view>
		<image style="width: 100%;" mode="widthFix" src="/static/swiper1.png"></image>
		<!-- 	<u-swiper height="360rpx" :list="swiperList" :radius="0"></u-swiper> -->
		<view class="home-content">
			<view class="app-name">WMS手持机系统</view>
			<view class="card-container">
				<view class="fn-title">基础功能</view>
				<u-grid :border="false" @click="gridClick" col="4">
					<u-grid-item v-for="(item,index) in fn" :key="index">
						<view :class="['grid-item-bg','grid-item-bg-'+(index+1)]">
							<u-icon :name='item.icon' :color="item.color" size="28"></u-icon>
						</view>

						<view class="grid-text">{{item.name}}</view>
					</u-grid-item>
				</u-grid>
			</view>
			<view style="padding:30rpx;padding-top:0;">
				<vol-alert type="primary">

				</vol-alert>
			</view>

		</view>


	</view>
</template>

<script>
	export default {
		data() {
			return {
				height: 0,
				swiperList: [
					'/static/swiper1.png',
					'/static/swiper2.png',
					'/static/swiper3.png'
				],
				fn: [{
						name: "有单据组盘1",
						icon: '/static/fc.png',
						path: "/pages/basics/T_In_ReceiptNoticeDetail/T_In_ReceiptNoticeDetail",
						color: '#EE0000',
						subPage: true //二级页面
					}, {
						name: "手动入库",
						icon: '/static/fc.png',
						path: "",
						color: '#EE0000',
						subPage: true //二级页面
					}, {
						name: "无单据组盘",
						icon: 'edit-pen-fill',
						color: '#8B8989',
						path: "/pages/createbyus/HaveOrderGroup/HaveOrderGroup",
						subPage: true //二级页面
					}, {
						name: "入库计划",
						icon: '/static/fc.png',
						path: "/pages/basics/T_In_ReceiptNotice/T_In_ReceiptNotice",
						color: '#EE0000',
						subPage: true //二级页面
					}, {
						name: "确认出库",
						icon: '/static/fc.png',
						path: "/pages/reportvshow/V_OutboundDetail/V_OutboundDetail",
						color: '#EE0000',
						subPage: true //二级页面
					}, {
						name: "托盘处理",
						icon: '/static/fc.png',
						path: "/pages/strategy/DealTrayCURD/DealTrayCURD",
						color: '#EE0000',
						subPage: true //二级页面
					}, {
						name: "盘点处理",
						icon: '/static/fc.png',
						path: "/pages/strategy/T_InventoryCheckDetail/T_InventoryCheckDetail",
						color: '#EE0000',
						subPage: true //二级页面
					}, {
						name: "出库计划",
						icon: '/static/flow.png',
						color: '#EE0000',
						path: "/pages/basics/T_Out_DeliveryNotice/T_Out_DeliveryNotice",
						subPage: true //二级页面
					},
					{
						name: "审批流程",
						icon: '/static/flow.png',
						color: '#EE0000',
						path: "/pages/flow/flow",
						subPage: false //二级页面
					}, {
						name: "表单示例",
						icon: '/static/form.png',
						color: '#EE0000',
						path: "/pages/form/form",
						subPage: true //二级页面
					},
					{
						name: "Table组件",
						icon: '/static/fc.png',
						color: '#EE0000',
						path: "/pages/form/form",
						subPage: true //二级页面
					},
					{
						name: "菜单列表",
						icon: '/static/table.png',
						color: '#EE0000',
						path: "/pages/menu/menu",
						subPage: false //二级页面
					},

					// {
					// 	name: "地图导航",
					// 	icon: '/static/fc.png',
					// 	color:'#EE0000',
					// 	path: "/pages/map/map",
					// 	subPage: true //二级页面
					// },
					// //待开发功能
					// {
					// 	name: "敬请期待",
					// 	icon: '/static/fc.png',
					// 	path: "pages/basics/T_In_ReceiptNotice/T_In_ReceiptNotice",
					// 	color:'#EE0000',
					// 	subPage: true //二级页面
					// },

					// {
					// 	name: "敬请期待",
					// 	icon: '/static/fc.png',
					// 	color:'#EE0000',
					// 	path: "",
					// }
				],
			}
		},
		onLoad() {

			var _this = this;
			// 获取手机状态栏高度
			uni.getSystemInfo({
				success: function(data) {
					// 将其赋值给this
					_this.height = data.statusBarHeight;
				}
			});
			
			_this.init();
		},
		onReady(){
			this.checkVersion(1)
		},
		onShow() {
			
		},
		methods: {
			//初始化
			init() {

				

			},
			//检查版本更新情况
			checkVersion(indexValue) {

	var _this = this;
				let index=0;
				setTimeout(() => {
					let randomNum = Math.random();
					//模拟接口获取最新版本号,版本号固定为整数
					const baseurl = uni.getStorageSync('loadVersion')+'版本号.json?V='+randomNum;
					console.log(baseurl)
					var requestTask = uni.request({
						url: baseurl, //仅为示例,并非真实接口地址。
						method:'GET',
						success: function(res) {
							index++;
								console.log(res.data);	
								const newVersionName =res.data.newVersionName //线上最新版本名
								const newVersionCode =res.data.newVersionCode; //线上最新版本号
								const selfVersionCode = Number(uni.getSystemInfoSync().appVersionCode) //当前App版本号
								console.log(index+'../index/upgrade?versionName='+newVersionName+'&versionDesc='+res.data.versionDesc)
								console.log(selfVersionCode)
								console.log(newVersionCode)
								//线上版本号高于当前,进行在线升级
								if (selfVersionCode < newVersionCode) {
									let platform = uni.getSystemInfoSync().platform //手机平台
								
									uni.navigateTo({
										url: '../index/upgrade?versionName='+newVersionName+'&versionDesc='+res.data.versionDesc+'&appName='+res.data.appName
									})
								}
								else
								{
									_this.clickUseInfo(indexValue);
								}
								
							},
							fail :function(res)
							{
								console.log(res);
							},
							complete: ()=> {}
					});
				
				}, 200)
				
			},

			getStyle(item) {
				return {
					paddingTop: 20 + 'rpx',
					background: item.color,
					padding: '50%',
					color: "#ffff",
					'border-radius': '50%',
					left: '-24rpx'
				}
			},
			gridClick(index) {
				
				this.checkVersion(index)
				
				
			
			
			},
			clickUseInfo(index)
			{
				const item = this.fn[index];
				console.log(index)
				if (!item.path) {
					this.$toast('开发中')
					return;
				}
				
			//注意下面的跳转方式,一级页面指pages.json中tabBar配置path
			//具体见uni页面跳转文档
			if (item.subPage) {
				//二级页面用navigateTo跳转
				uni.navigateTo({
					url: this.fn[index].path
				})
				return;
			}
			//一级页面
			uni.switchTab({
				url: this.fn[index].path
			})
			},
			swiperClick(index) {

			}
		}
	}
</script>
<style lang="less" scoped>
	.home-content {
		z-index: 999;
		position: relative;
		margin-top: -220rpx;
	}

	.app-name {
		text-align: center;
		color: #ffff;
		font-weight: bolder;
		font-size: 60rpx;
		top: -40rpx;
		position: relative;
	}

	.card-container {

		box-shadow: 1px 1px 9px #b9b6b629;
		margin: 30rpx 30rpx 30rpx 30rpx;
		border: 1px solid #f1f1f1;
		border-radius: 10rpx;
		padding: 26rpx 10rpx 14rpx 10rpx;
		background: #ffff;


		.fn-title {
			font-family: 黑体;
			font-size: 30rpx;
			font-weight: bold;
			//color: #8f9ca2;
			padding: 4rpx 20rpx 30rpx 20rpx;
		}

		.grid-text {
			padding-top: 8rpx;
			font-size: 26rpx;
			color: #626262;
			padding-bottom: 20rpx;
		}

	}

	.grid-item-bg {
		border-radius: 50%;
		width: 86rpx;
		height: 86rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		box-shadow: 5px 3px 6px #e0ddddb0;
	}

	.grid-item-bg-1 {
		background-image: linear-gradient(to bottom right, #97caff, #47a1fe);
	}

	.grid-item-bg-2 {
		background-image: linear-gradient(to bottom right, #f8bcbc, #f07e7e);

	}

	.grid-item-bg-3 {
		background-image: linear-gradient(to bottom right, #afb5e6, #808cf0);
	}

	.grid-item-bg-4 {

		background-image: linear-gradient(to bottom right, #98e4e2, #56c3bf);
	}

	.grid-item-bg-5 {
		background-image: linear-gradient(to bottom right, #d1d1d1, #c878e7);
	}

	.grid-item-bg-6 {
		background-image: linear-gradient(to bottom right, #97caff, #47a1fe);
	}

	.grid-item-bg-7 {
		background-image: linear-gradient(to bottom right, #98e4e2, #56c3bf);

	}

	.grid-item-bg-8 {
		background-image: linear-gradient(to bottom right, #afb5e6, #808cf0);

	}
</style>

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

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

相关文章

Java架构之路-架构应全面了解的技术栈和工作域

有时候我在想这么简单简单的东西&#xff0c;怎么那么难以贯通。比如作为一个架构师可能涉及的不单单是技术架构&#xff0c;还包含了项目管理&#xff0c;一套完整的技术架构也就那么几个技术栈&#xff0c;只要花点心思&#xff0c;不断的往里面憨实&#xff0c;总会学的会&a…

UE4升级UE5 蓝图节点变更汇总(4.26/27-5.2/5.3)

一、删除部分 Ploygon Editing删除 Polygon Editing这个在4.26、4.27中的插件&#xff0c;在5.1后彻底失效。 相关的蓝图&#xff0c;如编辑器蓝图 Generate mapping UVs等&#xff0c;均失效。 如需相关功能&#xff0c;请改成Dynamic Mesh下的方法。 GetSupportedClass删…

在K8S集群中部署SkyWalking

1. 环境准备 K8S 集群kubectlhelm 2. 为什么要部署SkyWalking&#xff1f; 我也不道啊&#xff0c;老板说要咱就得上啊。咦&#xff0c;好像可以看到服务的各项指标&#xff0c;像SLA&#xff0c;Apdex这些&#xff0c;主要是能够进行请求的链路追踪&#xff0c;bug排查的利…

C向C++的一个过渡

思维导图 输入输出&#xff0c;以及基础头文件 在c语言中我们常用scanf("%d",&n);和printf("%d\n",n);来输出一些变量和常量&#xff0c;在C中我们可以用cin;和cout;来表示输入输出。 在C语言中输入输出有头文件&#xff0c;在C也有头文件&#xff0…

解放人力,提升品质:码垛输送机的工业应用与价值

在现代工业生产中&#xff0c;码垛输送机已成为许多企业自动化生产线上的关键设备。它不仅可以提高生产效率&#xff0c;降低人力成本&#xff0c;还能确保产品质量&#xff0c;并为企业带来许多其他方面的实际好处。 1. 提高生产效率&#xff1a; 快速码垛&#xff1a;码垛输…

蓝桥杯练习题——dp

五部曲&#xff08;代码随想录&#xff09; 1.确定 dp 数组以及下标含义 2.确定递推公式 3.确定 dp 数组初始化 4.确定遍历顺序 5.debug 入门题 1.斐波那契数 思路 1.f[i]&#xff1a;第 i 个数的值 2.f[i] f[i - 1] f[i - 2] 3.f[0] 0, f[1] 1 4.顺序遍历 5.记得特判 …

基于springboot+vue的医院药品管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

STM32CubeIDE基础学习-新建STM32CubeIDE基础工程

STM32CubeIDE基础学习-新建STM32CubeIDE基础工程 前言 有开发过程序的朋友都清楚&#xff0c;后面开发是不需要再新建工程的&#xff0c;一般都是在初学时或者有特殊需要的时候才需要新建项目工程的。 后面开发都是可以在这种已有的工程上添加相关功能就行&#xff0c;只要前…

Linux系统部署Discuz论坛并发布至公网随时随地可远程访问

目录 ​编辑 前言 1.安装基础环境 2.一键部署Discuz 3.安装cpolar工具 4.配置域名访问Discuz 5.固定域名公网地址 6.配置Discuz论坛 结语 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊Linux系统部署Discuz论坛并发布至公网随时随地…

Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍

1.简介 学习音视频开发&#xff0c;首先从做一款播放器开始是比较合理的&#xff0c;每一章节&#xff0c;我都会将源码贴在最后&#xff0c;此专栏你将学习到以下内容&#xff1a; 1&#xff09;音视频的解封装、解码&#xff1b; 2&#xff09;Qtopengl如何渲染视频&#…

matlab 提取分割位于多边形区域边缘内部或边缘上的点

[in,on] = inpolygon(xq,yq,xv,yv) xv 和 yv 为定义的多边形区域的,如xv = [1 4 4 1 1 ];yv = [1 1 4 4 1 ];注意最后一个数字与第一个重复,保证多边形闭合; xq 和 yq 为待查询的点in:在多边形内部和边缘的点序号on:仅在多边形边缘的点序号 提取分割方法: matrix=[xq yq…

Hystrix的一些了解

Hystrix如何实现容错 Hystrix是一个延迟和容错库&#xff0c;旨在隔离远程系统&#xff0c;服务和第三方库的访问点&#xff0c;当出现故障是不可避 免的故障时&#xff0c;停止级联故障并在复杂的分布式系统中实现弹性。 通常对于使用微服务架构开发的系统&#xff0c;涉及到…

12. Nginx进阶-Location

简介 Nginx的三大区块 在Nginx中主要配置包括三个区块&#xff0c;结构如下&#xff1a; http { #协议级别include /etc/nginx/mime.types;default_type application/octet-stream;log_format main $remote_addr - $remote_user [$time_local] "$r…

13-Java代理模式 ( Proxy Pattern )

Java代理模式 摘要实现范例 代理模式&#xff08;Proxy Pattern&#xff09;使用一个类代表另一个类的功能 代理模式创建具有现有对象的对象&#xff0c;以便向外界提供功能接口 代理模式属于结构型模式 摘要 1. 意图 为其他对象提供一种代理以控制对这个对象的访问2. 主…

游戏引擎用什么语言开发上层应用

现在主流的游戏引擎包括&#xff1a; 1、Unity3D&#xff0c;C#语言&#xff0c;优点在于支持几乎所有平台 丹麦创立的一家公司&#xff0c;现已被微软收购。在中国市场占有率最高&#xff0c;也是社群很强大&#xff0c;一般解决方案也能在网上找到&#xff0c;教程丰富。物理…

springboot项目单纯使用nacos注册中心功能

Spring Boot 项目完全可以单独使用 Nacos 作为注册中心。Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它支持服务的注册与发现&#xff0c;能够与 Spring Boot 应用无缝集成&#xff0c;为微服务架构提供了强大的支持。 在使用 Nacos 作为注册中…

eclipse搭建java web项目

准备条件 eclipsejdk1.8 &#xff08;配置jdk环境&#xff09;apache-tomcat-8.5.97&#xff08;记住安装位置&#xff09; 一 点击完成 开始创建javaweb项目 import java.io.IOException; import java.io.PrintWriter;import javax.servlet.ServletException; import javax.s…

java VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城 小程序商城搭建

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

3.1_2024ctf青少年比赛部分web题

php后门 根据x-powered-by知道php的版本 该版本存在漏洞&#xff1a; PHP 8.1.0-dev 开发版本后门 根据报错信息&#xff0c;进行提示&#xff0c;前 GET / HTTP/1.1 Host: challenge.qsnctf.com:31639 User-Agentt:12345678system(cat /flag);var_dump(2*3);zerodium12345678…

二维码门楼牌管理系统技术服务:安装要求详解

文章目录 前言一、安装要求二、系统功能与应用三、总结与展望 前言 在信息化时代的浪潮下&#xff0c;二维码技术的应用已经深入到了我们生活的方方面面。其中&#xff0c;二维码门楼牌管理系统的出现&#xff0c;不仅提高了社区管理的效率&#xff0c;还为居民带来了极大的便…