uni-app自动升级功能

news2025/4/1 8:29:09

效果图

一、VUE 

login.vue

<template>
	<view>
		<view class="uni-common-mt">
			<view class="uni-flex uni-column">
				<view class="flex-item  flex-item-V">
					<view class="logo">
						<image src="/static/image/uniui-logo.png" style="height:90px;display: none;"></image>
					</view>
					<view class="logoHead">欢迎使用WMS</view>
				</view>
				<view class="flex-item flex-item-V">

				</view>
				<view class="flex-item flex-item-V form">
					<form>
						<view class="uni-form-item uni-column">
							<uni-easyinput v-model="formData.loginName" maxlength="50" name="loginName"
								placeholder="请输入账号" prefixIcon="person" value="">
							</uni-easyinput>
						</view>

						<view class="uni-form-item uni-column">
							<uni-easyinput v-model="formData.password2" maxlength="50" name="password" type="password"
								placeholder="请输入密码" prefixIcon="locked" @confirm="formSubmit">
							</uni-easyinput>
						</view>

						<view class="uni-btn-v loginBtn">
							<button form-type="submit" type="primary" :loading="loginLoading" @click="formSubmit">登
								录</button>

						</view>
					</form>
				</view>
			</view>
		</view>
	</view>
	<view class="register-section">
		Copyright © 2025 **科技 版本号:{{ThisVersion}}
	</view>
</template>

<script setup>
	import {
		nextTick,
		onMounted,
		ref
	} from 'vue';
	import {
		userApi
	} from "@/api/user";
	import graceChecker from "@/common/graceChecker.js";
	import CryptoJS from 'crypto-js';
	import G from '@/utils/global.js'
	const ThisVersion = G.ApkVersion;
	const loginLoading = ref(false);
	const myForm = ref();
	const formData = ref({
		loginName: "",
		password: "",
		password2: "",
		tenantId: "1867144130501541888",
		lang: "zh_cn",
		industry: null
	}); 
	//提交登录
	const formSubmit = (e) => {
		//定义表单规则
		var rule = [{
				name: "loginName",
				checkType: "string",
				checkRule: "1,20",
				errorMsg: "请输入1-20位的账号"
			},
			{
				name: "password2",
				checkType: "string",
				checkRule: "3,20",
				errorMsg: "请输入3-20密码"
			}
		];
		//进行表单检查 
		var checkRes = graceChecker.check(formData.value, rule);
		if (checkRes) {
			//登录信息 
			formData.value.password = CryptoJS.SHA256(formData.value.password2).toString(CryptoJS.enc.Hex);
			let thisObj = {
				"thisObj": formData.value
			};
			loginLoading.value = true;
			uni.setStorageSync('token', "login");

			//1.登录得到code
			userApi.LoginByOauth(thisObj).then(loginRes => {
				console.log('loginRes========', JSON.stringify(loginRes));
				if (loginRes.mfail != '0' || loginRes.data == null) {
					loginLoading.value = false;
					uni.showToast({
						icon: 'none',
						duration: G.ShowPopTime,
						title: `登录异常,code获取异常:${loginRes.msg}`
					});
					return;
				} else {
					//2.通过code获取Token
					let postData = {
						code: loginRes.data.code
					};
					//获取token
					userApi.GetTokenFromCode(postData).then(tokenRes => {
						console.log('Token========', JSON.stringify(tokenRes));
						if (tokenRes.mfail != '0' || tokenRes.data == null) {
							loginLoading.value = false;
							uni.showToast({
								icon: 'none',
								duration: G.ShowPopTime,
								title: `登录异常,token获取异常:${res.msg}`
							});
							return;
						}
						//登录成功后,将token写入全局变量
						uni.setStorageSync('token', tokenRes.data.token);
						//跳转到首页
						nextTick(() => {
							uni.reLaunch({
								animationType: 'zoom-out',
								animationDuration: 200,
								url: "/pages/index/index"
							});

						});
					}).catch(error => {
						uni.setStorageSync('token', null);
						loginLoading.value = false;
						uni.showToast({
							icon: 'none',
							duration: G.ShowPopTime,
							title: `访问失败,请联系管理员!:${res.msg}`
						});

					});

				}

			}).catch(error => {
				uni.setStorageSync('token', null);
				loginLoading.value = false;
				uni.showToast({
					icon: 'none',
					duration: G.ShowPopTime,
					title: `访问失败,请联系管理员!:${res.msg}`
				});
			});

		} else {
			loginLoading.value = false;
			uni.showToast({
				title: graceChecker.error,
				icon: "error",
				duration: G.ShowPopTime
			});
		}

	}
	//自动更新升级新版本
	const autoUpdate = () => { 
		var myVerson =ThisVersion; //Android当前版本
		var obj = {
			AppType: G.AppType, //1.Android(默认)  2.ISO 
			AppVersion: myVerson
		}		
		userApi.getVersion(obj).then(res => {
			console.log("查询服务器版本信息---------------- " + JSON.stringify(res));
			if (res == undefined) {
				console.log('连接服务器失败!');
			} else {
				if (res.IsUpdate == true) {
					console.log('需要更新版本!');  
					uni.showModal({
						title: "版本更新",
						content: '检测到程序有新版本,是否立即进行新版本下载?',
						confirmText: '立即更新',
						cancelText: '稍后进行',
						success: function(res) {
							if (res.confirm) {
								//设置 最新版本apk的下载 
								let downloadApkUrl = G.DownLoadUrl;
								//GLOBAL.DOMAIN_URL + "/apk/mzz2.apk";
								let dtask = plus.downloader.createDownload(downloadApkUrl, {},
									function(d, status) {
										// 下载完成 
										if (status == 200) {
											plus.runtime.install(plus.io
												.convertLocalFileSystemURL(d
													.filename), {}, {},
												function(error) {
													uni.showToast({
														title: '安装失败',
														duration: 1500
													});
												})
										} else {
											uni.showToast({
												title: '更新失败',
												duration: 1500
											});
										}
									});
								dtask.start();
								var prg = 0;
								var showLoading = plus.nativeUI.showWaiting("正在下载");
								 //创建一个showWaiting对象 
								dtask.addEventListener('statechanged', function(task, status) {
									// 给下载任务设置一个监听 并根据状态  做操作
									switch (task.state) {
										case 1:
											showLoading.setTitle("正在下载");
											break;
										case 2:
											//showLoading.setTitle("已连接到服务器");
											break;
										case 3:
											prg = parseInt(
												(parseFloat(task.downloadedSize) /
													parseFloat(task.totalSize)) *
												100
											);
											showLoading.setTitle("正在下载" + prg + "%  ");										
											break;
										case 4:
											plus.nativeUI.closeWaiting();
											//下载完成
											break;
									}
								});
							} else if (res.cancel) {
								console.log('稍后更新');
							}
						}
					});
				} else {
					console.log('不需要更新版本!');
				}
			}
		}).catch(error => {
			console.log('访问失败,请联系管理员!!');
		});
	}
	onMounted(() => {
		uni.setStorageSync('token', null);
		autoUpdate();
	});
</script>

<style scoped lang="scss">
	view {
		box-sizing: border-box;
	}

	.uni-common-mt {
		margin: 0;
	}

	.flex-item:nth-child(1) {
		display: flex;
		flex-flow: column;
		justify-content: center;
		align-content: center;
	}

	.flex-item:nth-child(2) {
		height: 120rpx;
		background: url("/static/login-style.png") round space;

	}

	.logo {
		min-height: 100rpx;
		padding-left: 10px;
		margin-top: 100rpx;
	}

	.logoHead {
		font-family: 'Microsoft YaHei', sans-serif;
		text-align: center;
		color: darkblue;
		font-size: 58rpx;
		font-weight: bold;
		text-shadow: 1px 1px rgba(0, 0, 0, .3);
		padding-bottom: 40rpx;
	}

	.loginBtn {
		padding-top: 40rpx;
	}

	.form {
		padding: 0px 40px;
	}

	.register-section {
		position: absolute;
		left: 0;
		bottom: 20px;
		width: 100%;
		font-size: $uni-font-size-sm;
		color: $uni-text-color;
		text-align: center;
	}
</style>

global.js

export default {
	CAPTCHA_TYPE: {
		COMMON: 'common'
	},
	ShowPopTime: 5000, //弹框持续时间
	AppType: 1, //1.Android(默认)  2.ISO
	ApkVersion: 'v5.3.25.2', //Android当前版本
	IsoVersion: 'v5.2.20.1', //Iso当前版本
	DownLoadUrl: 'http://192.168.6.1/APPDownLoad/TJWMSApp.apk', //正式下载App地址
	REQUEST_URL: 'http://192.168.6.3', //正式api地址 http://192.168.6.3,代理地址/base-api	
	// REQUEST_URL: 'http://localhost:80', //本地api地址/
	FileHandler: 'http://192.168.6.1/APPDownLoad/' //正式保存图片地址UAWebService/api/Test/SaveFile
};

API user.ts

import { request } from '@/utils/request.js';
//1.登录得到code
const LoginByOauth = (data) => {
	return request.post('/levault/usrsvr/Usr/LoginByOauth', data);
};
//2.通过code获取Token
const GetTokenFromCode = (data) => {
	return request.post('/levault/usrsvr/Usr/GetTokenFromCode', data);
};
// 获取版本号
 const getVersion=(data)=> {
	return request.post('http://192.168.6.1/api/GetVersion', data);  
};
export const userApi = {
	LoginByOauth,
	GetTokenFromCode,
	getVersion
};

request.js

import config from '@/utils/config';
// 统一 POST 请求方法示例
const post = async (url, data, options = {}) => {
	if (!String(url).startsWith('http://')) {
		url = config.url + url;
	}
	console.log("uni.getStorageSync('token')==========", uni.getStorageSync('token'));
	//判断是否登录
	if (uni.getStorageSync('token') == null || uni.getStorageSync('token') == '') {
		// uni.reLaunch({
		// 	animationType: 'zoom-out',
		// 	animationDuration: 200,
		// 	url: "/pages/login/index"
		// });
	}
	const defaultOptions = {
		method: 'POST',
		header: {
			'Content-Type': 'application/json'
			// ,'token': `${uni.getStorageSync('token')}`
		}
	};
	const finalOptions = { ...defaultOptions, ...options };
	// 如果服务器需要 token,可以在这里添加 Authorization 头部
	if (!finalOptions.header['token'] && uni.getStorageSync('token')) {
		finalOptions.header['token'] = `${uni.getStorageSync('token')}`;
	}

	// if (!finalOptions.header['Authorization'] && uni.getStorageSync('token')) {
	//   finalOptions.header['Authorization'] = `Bearer ${uni.getStorageSync('token')}`;
	// }
	console.log('POST 请求参数=====', JSON.stringify(data));
	console.log('POST 请求header=====', finalOptions);
	console.log('POST url=====', url);
	uni.showLoading({
		title: '加载中...'
	});
	return new Promise((resolve, reject) => {
		uni.request({
			...finalOptions,
			url: url,
			data: data,
			success: (res) => {
				console.log('请示结果=============', res);
				if (res.statusCode === 200) {
					resolve(res.data);
				} else {
					reject(new Error(`POST请求失败,状态码:${res.statusCode}`));
					uni.showToast({
						icon: 'none',
						title: `POST请求失败,状态码:${res.statusCode}`
					});
				}
			},
			fail: (err) => {
				reject(err);
				// 网络错误或其他请求失败的情况
				uni.showToast({
					icon: 'none',
					title: 'POST系统异常,请稍后再试'
				});
			},
			complete: () => {
				uni.hideLoading();
			}
		});
	});
};
// 统一 GET 请求方法示例
const get = async (url, data, options = {}) => {
	url = config.url + url;
	console.log("uni.getStorageSync('token')==========", uni.getStorageSync('token'));
	const defaultOptions = {
		method: 'GET',
		header: {
			'Content-Type': 'application/json'
			// ,'token': `${uni.getStorageSync('token')}`
		}
	};
	//判断是否登录
	if (uni.getStorageSync('token') == null || uni.getStorageSync('token') == '') {
		// uni.reLaunch({
		// 	animationType: 'zoom-out',
		// 	animationDuration: 200,
		// 	url: "/pages/login/index"
		// });
	}
	const finalOptions = { ...defaultOptions, ...options };
	// 如果服务器需要 token,可以在这里添加 Authorization 头部
	if (!finalOptions.header['token'] && uni.getStorageSync('token')) {
		finalOptions.header['token'] = `${uni.getStorageSync('token')}`;
	}

	// if (!finalOptions.header['Authorization'] && uni.getStorageSync('token')) {
	//   finalOptions.header['Authorization'] = `Bearer ${uni.getStorageSync('token')}`;
	// }

	console.log('GET 请求header=====', finalOptions);
	console.log('GET url=====', url);
	console.log('GET 请求参数=====', data);
	uni.showLoading({
		title: '加载中...'
	});
	return new Promise((resolve, reject) => {
		uni.request({
			...finalOptions,
			url: url,
			data: data,
			success: (res) => {
				console.log('GET请示结果=============', res);
				if (res.statusCode === 200) {
					resolve(res.data);
				} else {
					reject(new Error(`GET请求失败,状态码:${res.statusCode}`));
					uni.showToast({
						icon: 'none',
						title: `GET请求失败,状态码:${res.statusCode}`
					});
				}
			},
			fail: (err) => {
				reject(err);
				// 网络错误或其他请求失败的情况
				uni.showToast({
					icon: 'none',
					title: 'GET系统异常,请稍后再试'
				});
			},
			complete: () => {
				uni.hideLoading();
			}
		});
	});
};
const postAsync = async (url, data, options = {}) => {
	try {
		// 合并基础URL
		const fullUrl = config.url + url;

		// 构建请求头(动态添加token)
		const headers = {
			'Content-Type': 'application/json',
			...(uni.getStorageSync('token') && { token: uni.getStorageSync('token') })
		};

		// 合并自定义配置
		const finalOptions = {
			method: 'POST',
			header: { ...headers, ...options.header },
			...options
		};

		// 调试日志(开发环境保留)
		if (process.env.NODE_ENV === 'development') {
			console.log('[POST Request]', {
				url: fullUrl,
				data,
				headers: finalOptions.header
			});
		}

		// 发送请求
		const response = await new Promise((resolve, reject) => {
			uni.request({
				url: fullUrl,
				data,
				...finalOptions,
				success: (res) => resolve(res),
				fail: (err) => reject(err)
			});
		});

		// 处理响应状态码
		if (response.statusCode !== 200) {
			const errorMessage = `请求失败 (${response.statusCode})`;
			uni.showToast({ icon: 'none', title: errorMessage });
			throw new Error(errorMessage);
		}

		return response.data;
	} catch (error) {
		// 统一错误处理
		const errorMessage = error.errMsg || '系统异常,请稍后再试';
		uni.showToast({ icon: 'none', title: errorMessage });
		throw error; // 继续抛出错误供调用方捕获
	}
};
export const request = {
	post,
	postAsync,
	get
};

二、C# MVC接口代码

检测系统版本号,是否需要升级

using MAPP.WebApi.Models;
 
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Configuration;

namespace MAPP.WebApi.Controllers
{
    public class SystemController : ApiController
    {
        /// <summary>
        /// 校验系统版本号,返回是否需要更新
        /// </summary>
        /// <param name="jo"></param>
        /// <returns></returns> 
        [HttpPost, Route("api/GetVersion")]
        public HttpResponseMessage GetVersion(JObject jo)
        {
            var result = new AppSystemModel();
            result.IsSuccess = true;
            result.IsUpdate = false;
            int appType = 1;//默认安卓系统
            try
            {
                //判断是否启用自动更新
                if (WebConfigurationManager.AppSettings["OpenAppUpdateOnline"].ToString() != "1")
                {
                    result.IsUpdate = false;
                    result.NewVersion = "";
                    //result.returnMsg = "不需要更新!";
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }

                string appVersion = "";
                if (jo["AppVersion"] == null)
                {
                    result.IsSuccess = false;
                    result.IsUpdate = false;
                    result.Msg = "无法获取当前版本号!";
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }

                if (jo["AppType"] != null)
                {
                    if (jo["AppType"].ToString() == "2")
                    {
                        appType = 2;
                    }
                }

                if (appType == 1)
                {
                    appVersion = WebConfigurationManager.AppSettings["APKVersion"].ToString();
                }
                else
                {
                    appVersion = WebConfigurationManager.AppSettings["IOSVersion"].ToString();
                }
                //服务器端版本
                Version v1_server = new Version(appVersion.ToLower().Replace("v", ""));
                //手机端版本
                Version v2_pda = new Version(jo["AppVersion"].ToString().ToLower().Replace("v", ""));
                if (v1_server > v2_pda)
                {
                    result.IsUpdate = true;
                    result.Msg = "请更新系统!";
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }
                else
                {
                    result.IsUpdate = false;
                    result.Msg = "";
                    return Request.CreateResponse(HttpStatusCode.OK, result);
                }
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.IsUpdate = false;
                result.Msg = "获取版本号失败:" + ex.Message;
                return Request.CreateResponse(HttpStatusCode.OK, result);
            }
        }

    }
}

web.config

<?xml version="1.0" encoding="utf-8"?>
<!--
  有关如何配置 ASP.NET 应用程序的详细信息,请访问
  https://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
  <appSettings>
    <!--==========Android版本相关配置============-->
    <!--APP更新下载路径-->
    <add key="AppDownLoadUrl" value="http://192.168.6.1/UpLoad/APPDownLoad/"/>
    <!-- APP是否启用自动升级:1启用,2关闭 -->
    <add key="OpenAppUpdateOnline" value="1"/>
    <!-- ==========Android版本号============ -->
    <add key="APKVersion" value="v1.5.20.1"/>
    <!--==========IOS版本号============-->
    <add key="IOSVersion" value="v1.3.31.1"/>
    
    <add key="webpages:Version" value="3.0.0.0"/>
    <add key="webpages:Enabled" value="false"/>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.6.1"/>
    <httpRuntime targetFramework="4.6.1"/>
  </system.web>
  <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
      <remove name="OPTIONSVerbHandler"/>
      <remove name="TRACEVerbHandler"/>
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler"
        preCondition="integratedMode,runtimeVersionv4.0"/>
    </handlers>
    <staticContent>
      <mimeMap fileExtension=".apk" mimeType="application/vnd.android.package-archive" />
    </staticContent>
  </system.webServer> 
</configuration>

AppSystemModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MAPP.WebApi.Models
{
    public class AppSystemModel
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool IsSuccess { get; set; }

        /// <summary>
        /// 返回App版本是否需要更新
        /// </summary>
        public bool IsUpdate { get; set; }

        /// <summary>
        /// 最新版本号
        /// </summary>
        public string NewVersion { get; set; }

        /// <summary>
        /// 返回消息
        /// </summary>
        public string Msg { get; set; }
    }

    public class Payloaddata
    {
        public string token { get; set; }
        public string nickname { get; set; }
        public string profile { get; set; }
        public bool hasLogin { get; set; }
        public bool isGoogle { get; set; }
        public object result { get; set; }
    }

    public class LoginModel
    {
        public string UserId { get; set; }
        public string RoleCode { get; set; }
        public object DeptId { get; set; }
        public string UserName { get; set; }
    }

    public class UserInfo
    {
        public string UserCode { get; set; }
        public string UserName { get; set; }
        public object AppModelPageList { get; set; }
        public object AppModelList { get; set; }
    }
}

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

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

相关文章

使用AI一步一步实现若依(26)

功能26&#xff1a;新增一个新员工培训页面 功能25&#xff1a;角色管理 功能24&#xff1a;菜单管理 功能23&#xff1a;从后端获取路由/菜单数据 功能22&#xff1a;用户管理 功能21&#xff1a;使用axios发送请求 功能20&#xff1a;使用分页插件 功能19&#xff1a;集成My…

逻辑回归(Logistic Regression)模型的概率预测函数

以二分类问题为例&#xff0c;常见的损失函数有 负对数似然损失(neg log-likelihood loss)&#xff0c;交叉熵损失(cross entropy loss)&#xff0c;deviance loss指数损失(exponential loss)。 前三者虽然名字不同&#xff0c;但却具有相同的表达形式。此外&#xff0c;neg …

【零基础学python】python高级语法(四)

接续上面的系列文章&#xff1a; 【零基础学python】python基础语法&#xff08;一&#xff09;-CSDN博客 【零基础学python】python基础语法&#xff08;二&#xff09;-CSDN博客 【零基础学python】python高级语法&#xff08;三&#xff09;-CSDN博客 目录 2&#xff0c…

HarmonyOS 之 @Require 装饰器自学指南

在 HarmonyOS 应用开发工作中&#xff0c;我频繁碰到组件初始化传参校验的难题。在复杂的组件嵌套里&#xff0c;要是无法确保必要参数在构造时准确传入&#xff0c;就极易引发运行时错误&#xff0c;而且排查起来费时费力。一次偶然的机会&#xff0c;我接触到了 Require 装饰…

基于CNN的FashionMNIST数据集识别6——ResNet模型

前言 之前我们在cnn已经搞过VGG和GoogleNet模型了&#xff0c;这两种较深的模型出现了一些问题&#xff1a; 梯度传播问题 在反向传播过程中&#xff0c;梯度通过链式法则逐层传递。对于包含 L 层的网络&#xff0c;第 l 层的梯度计算为&#xff1a; 其中 a(k) 表示第 k层的…

0323-B树、B+树

多叉树---->B树&#xff08;磁盘&#xff09;、B树 磁盘由多个盘片组成&#xff0c;每个盘片分为多个磁道和扇区。数据存储在这些扇区中&#xff0c;扇区之间通过指针链接&#xff0c;形成链式结构。 内存由连续的存储单元组成&#xff0c;每个单元有唯一地址&#xff0c;数…

【工作记录】F12查看接口信息及postman中使用

可参考 详细教程&#xff1a;如何从前端查看调用接口、传参及返回结果&#xff08;附带图片案例&#xff09;_f12查看接口及参数-CSDN博客 1、接口信息 接口基础知识2&#xff1a;http通信的组成_接口请求信息包括-CSDN博客 HTTP类型接口之请求&响应详解 - 三叔测试笔记…

2024年认证杯SPSSPRO杯数学建模B题(第二阶段)神经外科手术的定位与导航全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 B题 神经外科手术的定位与导航 原题再现&#xff1a; 人的大脑结构非常复杂&#xff0c;内部交织密布着神经和血管&#xff0c;所以在大脑内做手术具有非常高的精细和复杂程度。例如神经外科的肿瘤切除手术或血肿清除手术&#xff0c;通常需要…

Android 12系统源码_系统启动(二)Zygote进程

前言 Zygote&#xff08;意为“受精卵”&#xff09;是 Android 系统中的一个核心进程&#xff0c;负责 孵化&#xff08;fork&#xff09;应用进程&#xff0c;以优化应用启动速度和内存占用。它是 Android 系统启动后第一个由 init 进程启动的 Java 进程&#xff0c;后续所有…

MOSN(Modular Open Smart Network)-05-MOSN 平滑升级原理解析

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFAStack-00-sofa 技术栈概览 MOSN&#xff08;Modular O…

Flink介绍与安装

Apache Flink是一个在有界数据流和无界数据流上进行有状态计算分布式处理引擎和框架。Flink 设计旨在所有常见的集群环境中运行&#xff0c;以任意规模和内存级速度执行计算。 一、主要特点和功能 1. 实时流处理: 低延迟: Flink 能够以亚秒级的延迟处理数据流&#xff0c;非常…

【gradio】从零搭建知识库问答系统-Gradio+Ollama+Qwen2.5实现全流程

从零搭建大模型问答系统-GradioOllamaQwen2.5实现全流程&#xff08;一&#xff09; 前言一、界面设计&#xff08;计划&#xff09;二、模块设计1.登录模块2.注册模块3. 主界面模块4. 历史记录模块 三、相应的接口&#xff08;前后端交互&#xff09;四、实现前端界面的设计co…

PowerBI,用度量值实现表格销售统计(含合计)的简单示例

假设我们有产品表 和销售表 我们想实现下面的效果 表格显示每个产品的信息&#xff0c;以及单个产品的总销量 有一个切片器能筛选各个门店的产品销量 还有一个卡片图显示所筛选条件下&#xff0c;所有产品的总销量 实现方法&#xff1a; 1.我们新建一个计算表&#xff0c;把…

26考研——查找_树形查找_二叉排序树(BST)(7)

408答疑 文章目录 三、树形查找二叉排序树&#xff08;BST&#xff09;二叉排序树中结点值之间的关系二叉树形查找二叉排序树的查找过程示例 向二叉排序树中插入结点插入过程示例 构造二叉排序树的过程构造示例 二叉排序树中删除结点的操作情况一&#xff1a;被删除结点是叶结点…

【行驶证识别】批量咕嘎OCR识别行驶证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,如物流管理、车辆租赁、保险理赔等,常常需要处理大量的行驶证照片复印件。手动录入行驶证上的文字信息,像车主姓名、车辆型号、车牌号码等,不仅效率低下,还容易出现人为错误。借助 OCR(光学字符识别)技术,能够自动识别行驶证图片中的文字信…

21.Excel自动化:如何使用 xlwings 进行编程

一 将Excel用作数据查看器 使用 xlwings 中的 view 函数。 1.导包 import datetime as dt import xlwings as xw import pandas as pd import numpy as np 2.view 函数 创建一个基于伪随机数的DataFrame&#xff0c;它有足够多的行&#xff0c;使得只有首尾几行会被显示。 df …

LabVIEW FPGA与Windows平台数据滤波处理对比

LabVIEW在FPGA和Windows平台均可实现数据滤波处理&#xff0c;但两者的底层架构、资源限制、实时性及应用场景差异显著。FPGA侧重硬件级并行处理&#xff0c;适用于高实时性场景&#xff1b;Windows依赖软件算法&#xff0c;适合复杂数据处理与可视化。本文结合具体案例&#x…

【NLP 48、大语言模型的神秘力量 —— ICL:in context learning】

目录 一、ICL的优势 1.传统做法 2.ICL做法 二、ICL的发展 三、ICL成因的两种看法 1.meta learning 2.Bayesian Inference 四、ICL要点 ① 语言模型的规模 ② 提示词prompt中提供的examples数量和顺序 ③ 提示词prompt的形式&#xff08;format&#xff09; 五、fine-tune VS I…

vue 中渲染 markdown 格式的文本

文章目录 需求分析第一步:安装依赖第二步:创建 Markdown 渲染组件第三步,使用实例扩展功能1. 代码高亮:2. 自定义渲染规则:需求 渲染 markdown 格式的文本 分析 在Vue 3中实现Markdown渲染的常见方法。通常有两种方式:使用现有的Markdown解析库,或者自己编写解析器…

工业4G路由器赋能智慧停车场高效管理

工业4G路由器作为智慧停车场管理系统通信核心&#xff0c;将停车场内的各个子系统连接起来&#xff0c;包括车牌识别系统、道闸控制系统、车位检测系统、收费系统以及监控系统等。通过4G网络&#xff0c;将这些系统采集到的数据传输到云端服务器或管理中心&#xff0c;实现信息…