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

uniapp 微信小程序webview 和 h5数据通信

项目是uniapp编写,因为是先开发了h5和app,小程序是突然要用的,做兼容开发已经来不及,由于微信小程序webview载入h5 因为通信必须要特殊限制(网页向小程序 postMessage 时,会在以下特定时机触发并收到消息:小程序后退、组件销毁、分享、复制链接(2.31.1)。e.detail = { data },data是多次 postMessage 的参数组成的数组。),不能满足使用,所以搞了一套特别low的通信机制,缺点是通信时候会有一个loading的过渡页面

业务逻辑大致为:
1、微信小程序webview访问h5带参数的url,获取初始的参数,可以携带页面参数或者登录token等,通过reciver接受h5返回的参数。
2、h5通过一个中间html页面存储小程序的通信逻辑,然后在h5页面通过定时器一直获取缓存本地的数据,根据数据信息执行不同的业务逻辑

1、微信小程序项目
(1)微信小程序项目
index.vue

<template><web-view v-if="src" :src="src" bindload="bindload" binderror="binderror"></web-view>
</template><script lang="ts">
import { cfg } from '@/cfg'
import Base64 from '@/utils/Base64'export default {data() {return {src: '',}},onLoad(e: any) {let loginA = parseInt(e.loginA)console.log(e.loginA)if (loginA) {let self = thiswx.login({success(res: any) {// 自动登录成功self.msg(Base64.encode64('loginA,' + JSON.stringify([loginA, cfg.mpApp, res.code])))},fail(res: any) {// 自动登录失败self.msg(Base64.encode64('loginAFail,' + JSON.stringify([loginA, res.errMsg])))},})return}this.msg(e.msg)},methods: {msg(msg: any) {if (msg) {this.src = cfg.mpUrl + 'static/mpMsg.html?uid=' + cfg.mpid + '&msg=' + msg// this.src = 'http://www.baidu.com/#/'console.log(this.src)// 超时自动关闭// @ts-ignorethis['$timer'] = setTimeout(() => {this.navBack()}, 3000)return}this.navBack()},bindload() {console.log('bindload')this.navBack()},binderror() {console.log('binderror')this.navBack()},navBack() {let pages = getCurrentPages()if (pages[pages.length - 1].$vm == this) {uni.navigateBack()}// @ts-ignorelet timer = this['$timer']if (timer) {// @ts-ignoredelete this['$timer']clearTimeout(timer)}},},
}
</script><style></style>

(2)reciver.vue

<template><view id="preloader"></view>
</template><script lang="ts">
import { App } from '@/store/app'
import Base64 from '@/utils/Base64'export default {data() {return {src: '',}},onLoad(e: any) {try {let msg = e.msgif (msg) {msg = Base64.decode64(msg)let i = msg.indexOf(',')let key = msglet val = ''if (i > 0) {key = msg.substring(0, i)val = msg.substring(i + 1)}// 如果是pc小程序bridge支付,则直接跳转到支付页面// const info = uni.getSystemInfoSync()// if ((info?.deviceType == 'pc' || info?.deviceType == 'PC') && key == 'pay') {//   uni.redirectTo({//     url: `/pages/index/pay?pay=${Base64.encode64(val)}`,//   })// } else {//   uni.navigateBack({//     complete() {//       // setTimeout(() => {//       App.mpRecieverMsg(key, val)//       // }, 100)//     },//   })// }uni.navigateBack({complete() {// setTimeout(() => {App.mpRecieverMsg(key, val)// }, 100)},})return}} catch (e) {console.error(e)}uni.navigateBack()},methods: {},
}
</script><style scoped>
#preloader {position: absolute;width: 30px;height: 30px;background: rgba(253, 87, 17, 1);border-radius: 50px;left: 0;right: 0;top: 0;bottom: 0;margin: auto;-webkit-animation: preloader_1 1.5s infinite linear;-moz-animation: preloader_1 1.5s infinite linear;-ms-animation: preloader_1 1.5s infinite linear;animation: preloader_1 1.5s infinite linear;
}
#preloader:after {position: absolute;width: 50px;height: 50px;border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);border-left: 10px solid transparent;border-right: 10px solid transparent;border-radius: 50px;content: '';top: -20px;left: -20px;-webkit-animation: preloader_1_after 1.5s infinite linear;-moz-animation: preloader_1_after 1.5s infinite linear;-ms-animation: preloader_1_after 1.5s infinite linear;animation: preloader_1_after 1.5s infinite linear;
}@-webkit-keyframes preloader_1 {0% {-webkit-transform: rotate(0deg);}50% {-webkit-transform: rotate(180deg);background: #ff4f11;}100% {-webkit-transform: rotate(360deg);}
}
@-webkit-keyframes preloader_1_after {0% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}@-moz-keyframes preloader_1 {0% {-moz-transform: rotate(0deg);}50% {-moz-transform: rotate(180deg);background: #ff4f11;}100% {-moz-transform: rotate(360deg);}
}
@-moz-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}@-ms-keyframes preloader_1 {0% {-ms-transform: rotate(0deg);}50% {-ms-transform: rotate(180deg);background: #ff4f11;}100% {-ms-transform: rotate(360deg);}
}
@-ms-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}@keyframes preloader_1 {0% {transform: rotate(0deg);}50% {transform: rotate(180deg);background: #ff4f11;}100% {transform: rotate(360deg);}
}
@keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}
}
</style>

(3)app.ts

import cfg from '@/cfg'
import Base64 from '@/utils/Base64'export const App = {shareData: {},mpPostMsg(key: string, val?: string, redirect: boolean = true) {const msg = val ? key + ',' + val : keyif (redirect) {uni.redirectTo({ url: '/pages/msg/post?msg=' + Base64.encode64(msg) })} else {uni.navigateTo({ url: '/pages/msg/post?msg=' + Base64.encode64(msg) })}},mpRecievers: {userStorageCert(cert: string) {console.log('userCert', cert)if (cert) {uni.setStorageSync(cfg.mpApp + 'userStorageCert', cert)}},shareAppMessage(v: string) {let sharetry {share = JSON.parse(v)if (share.path) {// 使用正则表达式匹配 _i= 后面的字符串const match1 = share.path.match(/_i=([^&]+)/)// 如果匹配成功,获取匹配到的字符串if (match1) {const extractedString = match1[1]share.path = '/pages/index/index?i=' + extractedStringconsole.log(' share.path', share.path)}}} catch (error) {}try {if (share.imageUrl) {share.imageUrl = share.imageUrl.replace(/(w_\d+)|(h_\d+)/g, (match: string) => {if (match.startsWith('w_')) {return 'w_300'} else if (match.startsWith('h_')) {return 'h_300'}})}} catch (error) {}if (share) {App.shareData = share}},pay(v: string) {const pay = JSON.parse(v)pay.success = function () {// 需要通知App.mpPostMsg('pay,1', undefined, false)}// pay.complete = function () {//   // 需要通知//   App.mpPostMsg('pay,1', undefined, false)// }pay.fail = function (e: any) {console.log('pay fail ' + JSON.stringify(e))uni.showToast({title: '支付失败',icon: 'none',duration: 2000,})}// 支付参数console.log(JSON.stringify(pay))const info = uni.getSystemInfoSync()// 如果是pc小程序bridge支付,则延迟掉起,防止不显示支付弹窗if (info?.deviceType == 'pc' || info?.deviceType == 'PC') {uni.showLoading()setTimeout(() => {uni.hideLoading()wx.requestPayment(pay)}, 1000)} else {wx.requestPayment(pay)}},bindWx() {wx.login({success: function (res: any) {let data = ''if (res) {let appid = ''if (cfg.mpApp) {appid = cfg.mpApp}data = JSON.stringify([appid, res.code])}App.mpPostMsg('bindWx', data, false)},fail: function (err: any) {console.log('bindWx fail', err)App.mpPostMsg('bindWx', '', false)},})},openLocation(adress: string) {const data = JSON.parse(adress)wx.openLocation({latitude: Number(data.latitude),longitude: Number(data.longitude),name: data.name,scale: 18,complete: e => {console.log('openLocation complete', e)},})console.log('openLocation data', data)},downloadAndSave(res: string) {const data = JSON.parse(res)const $delay = data['$delay']if ($delay > 0) {setTimeout(() => {wx.downloadFile({url: data.url,success: function (res) {wx.openDocument({filePath: res.tempFilePath,fileType: 'pdf',showMenu: true,})},})}, $delay)} else {wx.downloadFile({url: data.url,success: function (res) {wx.openDocument({filePath: res.tempFilePath,fileType: 'pdf',showMenu: true,})},})}},callFun(res: string) {const data = JSON.parse(res)// @ts-ignoreconst fun = wx[data['$fun']]if (fun) {delete data['$fun']const $delay = data['$delay']if ($delay > 0) {delete data['$delay']setTimeout(() => {fun.call(wx, data)}, $delay)} else {fun.call(wx, data)}}},},mpRecieverMsg(key: string, val?: string) {// @ts-ignoreconst fun = App.mpRecievers[key]if (fun) {fun(val)return}},
}

(3)Base64.ts

// private property
let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";// private method for UTF-8 encoding
let _utf8_encode = function (str: string) {str = str.replace(/\r\n/g, "\n");let utftext = "";for (let n = 0; n < str.length; n++) {let c = str.charCodeAt(n);if (c < 128) {utftext += String.fromCharCode(c);} else if ((c > 127) && (c < 2048)) {utftext += String.fromCharCode((c >> 6) | 192);utftext += String.fromCharCode((c & 63) | 128);} else {utftext += String.fromCharCode((c >> 12) | 224);utftext += String.fromCharCode(((c >> 6) & 63) | 128);utftext += String.fromCharCode((c & 63) | 128);}}return utftext;
}// private method for UTF-8 decoding
let _utf8_decode = function (utftext: string) {let string = "";let i = 0;let c, c1, c2, c3c = c1 = c2 = 0;while (i < utftext.length) {c = utftext.charCodeAt(i);if (c < 128) {string += String.fromCharCode(c);i++;} else if ((c > 191) && (c < 224)) {c2 = utftext.charCodeAt(i + 1);string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));i += 2;} else {c2 = utftext.charCodeAt(i + 1);c3 = utftext.charCodeAt(i + 2);string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));i += 3;}}return string;
}const Base64 = {// public method for encodingencode(input: string) {let output = "";let chr1, chr2, chr3, enc1, enc2, enc3, enc4;let i = 0;input = _utf8_encode(input);while (i < input.length) {chr1 = input.charCodeAt(i++);chr2 = input.charCodeAt(i++);chr3 = input.charCodeAt(i++);enc1 = chr1 >> 2;enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);enc4 = chr3 & 63;if (isNaN(chr2)) {enc3 = enc4 = 64;} else if (isNaN(chr3)) {enc4 = 64;}output = output +_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +_keyStr.charAt(enc3) + _keyStr.charAt(enc4);}return output;},// public method for decodingdecode(input: string) {let output = "";let chr1, chr2, chr3;let enc1, enc2, enc3, enc4;let i = 0;input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");while (i < input.length) {enc1 = _keyStr.indexOf(input.charAt(i++));enc2 = _keyStr.indexOf(input.charAt(i++));enc3 = _keyStr.indexOf(input.charAt(i++));enc4 = _keyStr.indexOf(input.charAt(i++));chr1 = (enc1 << 2) | (enc2 >> 4);chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);chr3 = ((enc3 & 3) << 6) | enc4;output = output + String.fromCharCode(chr1);if (enc3 != 64) {output = output + String.fromCharCode(chr2);}if (enc4 != 64) {output = output + String.fromCharCode(chr3);}}output = _utf8_decode(output);return output;},// 编码encode64(str: string, uri: boolean = true) {str = Base64.encode(str);if (uri) {str = str.replace(/[+|=|/]/g, function (word) {switch (word) {case "+":return "-";case "=":return "_";case "/":return ".";}return word;});}return str;},// 解码decode64(str: string, uri: boolean = true) {if (uri) {str = str.replace(/[-|_|.]/g, function (word) {switch (word) {case "-":return "+";case "_":return "=";case ".":return "/";}return word;});}str = Base64.decode(str);return str;},
}export default Base64

index.vue

<template><web-view :src="src" @message="receiveMessage"> </web-view>
</template><script lang="ts">
import { cfg } from '@/cfg'
import { App } from '@/store/app'
import Base64 from '@/utils/Base64'
export default {data() {return {src: '',srcP: '',shareData: {imageUrl:'https://yjy.yiyiny.com//static/images/20240122/' +cfg.mpApp +'.png?x-oss-process=image/auto-orient,1/resize,m_fixed,w_100,h_100',},shareI: '',}},onLoad(e: any) {// e.scene  生成小程序码必须是这个keythis.setSrc(cfg.entryUrl, e.i || e.scene)wx.showShareMenu({withShareTicket: true,menus: ['shareAppMessage'],success(res) {console.log('mixin share success', res ? JSON.stringify(res) : res)},fail(err) {console.log('mixin share fail', err ? JSON.stringify(err) : err)},})},onShow() {cfg.mpSrcP = this.srcPApp.shareData = {}},onShareAppMessage(res: any) {console.log(res)if (res.from === 'button') {return this.shareData}if (res.from === 'menu') {return this.shareData || {}}},onShareTimeline() {let data = {title: '一乙艺术山庄',query: 'id=1',// imageUrl: '',}return data// return axCc.vueSelf.shareData || {};},onHide() {},methods: {setSrc(src: string, shareI?: string) {let cert = uni.getStorageSync(cfg.mpApp + 'userStorageCert')console.log('setSrc src', src)console.log('setSrc shareI', shareI)let i = src.indexOf('#')let j = src.indexOf('?')let srcP = i > 0 && i < j ? src.substring(0, i) : j > 0 ? src.substring(0, j) : srcif (srcP && srcP[srcP.length - 1] != '/') {srcP = srcP + '/'}if (i > 0) {cfg.mpUrl = src.substring(0, i)} else {cfg.mpUrl = cfg.entryUrl}console.log('[  cfg.mpUrl ] >', cfg.mpUrl)this.srcP = srcPcfg.mpSrcP = this.srcPsrc = j > 0 ? src + '&_mpid_=' + cfg.mpid : src + '?_mpid_=' + cfg.mpidif (shareI) {src = src + '&_i=' + shareI// 分享地址拼接const startIndex = src.indexOf('#')const endIndex = src.indexOf('?')if (startIndex !== -1 && endIndex !== -1) {src = src.substring(0, startIndex) + src.substring(endIndex)console.log(src)}this.shareI = shareI}src = src + '&ver=' + cfg.versionif (cert) {src = src + '&_cert_=' + encodeURIComponent(cert)}this.src = srcconsole.log('setSrc this.src', this.src)},// 监听h5 消息// { merber 用户信息 imageUrl 默认分享图 path 分享地址 title:分享标题   desc }receiveMessage(e: any) {console.log('receiveMessage333', e)let arr = e?.detail?.datalet data = arr && arr.length > 0 ? arr[arr.length - 1] : nulllet urlif (data && data?.merber?.id) {url = data?.path? data.path: cfg.mpName == 'mp_wdysj'? 'pages/artisthome/artisthome': '/pagesShop/shop/wHome'let parms = this.gen(url, false, { mmId: data?.merber.id }, 13050, data?.merber?.id)console.log('data222', data)this.shareData = {path: '/pages/index/index?i=' + parms + '&fk=1',imageUrl: data?.imageUrl? data.imageUrl: 'https://yjy.yiyiny.com//static/images/20240122/' +cfg.mpApp +'.png?x-oss-process=image/auto-orient,1/resize,m_fixed,w_100,h_100',title: data?.title ? data.title : cfg.mpName,desc: data?.desc ? data.desc : '',query: parms,}} else {wx.hideShareMenu()}},// 地址加密gen(uri: string, bind: boolean, reg: any, eid?: number, memberId?: number): string {// 标准编码let ps = [memberId, '', false, uri || '', reg || '', eid]for (let i = ps.length - 1; i >= 0; i--) {if (ps[i]) {let del = ps.length - i - 1if (del > 0) {ps.splice(i + 1, del)}break}}let _ps: any = ps_ps[0] = _ps[0] || ''if (bind) {_ps[2] = uri_ps[3] = ''} else {_ps[2] = ''}return Base64.encode64(JSON.stringify(ps))},},
}
</script><style></style>

cfg.ts

export const cfg = {mpApp: 'mp_wdysj', //一乙艺术商城mpName: '一乙艺术商城',mpUrl: 'https://p.yiyiny.com/xxx/',mpid: '',mpSrcP: '',version: '1.0.8',entryUrl: 'https://p.yiyiny.com/xxx/#/pagesShop/shop/wHome',
}const info = uni.getSystemInfoSync()
if (!cfg.mpid) {const host = info.host// @ts-ignoreif (host && host.appid) {// @ts-ignorecfg.mpid = host.appid}if (!cfg.mpid) {cfg.mpid = cfg.mpApp}
}
export default cfg

2、h5端
(1)项目初始化时候h5载入微信sdk
Ainit.ts

 // #ifdef H5let _mpid_;try {let search = <any>((launcher.h5Search || ab_.route(false, false, false).search));_mpid_ = search['_mpid_'];let _cert_ = search['_cert_'];// 获取小程序传递的证书if (_cert_) {_cert_ = decodeURIComponent(_cert_)User.status.storage.cert = _cert_}let app = axConfig.webType || 'web'if (Weixin.isWeiXin()) {axCc.Loader().wait("weixinLogin");ab_.reqJs(axCc.https? "https://res.wx.qq.com/open/js/jweixin-1.6.0.js": "http://res.wx.qq.com/open/js/jweixin-1.6.0.js",null,function () {function wxH5() {if (search["code"]) {let parms: Array<string> = [axConfig.webType, search["code"]];User.loginProvBack("wx",function (logined) {console.log("微信登陆成功", logined);try {if (logined) {axCc.saveStorage("wxLogined", {token: App.client.plt.headers["atoken"],authPar: User.status.authPar,authParas: User.status.authParas,});} else {axCc.saveStorage("wxLogined", {});}} finally {axCc.Loader().done("weixinLogin");// 微信jsConfigWeixin.wxConfig();}},parms,true,true,true);} else {try {// 关闭自动登录// User.autoLogin = false;let wxLogined = axCc.getStorage("wxLogined");if (wxLogined && wxLogined.token && wxLogined.authParas && wxLogined.authParas[0] === app) {User.loginToken(wxLogined.token, (logined) => {if (logined) {User.status.authPar = wxLogined.authPar;User.status.authParas = wxLogined.authParas;axCc.Loader().done("weixinLogin");} else {//微信浏览器 吊起微信支付必须要获取openidconsole.log("掉起微信支付必须要获取openid");Weixin.snsapi_base();}});} else {//微信浏览器 吊起微信支付必须要获取openidconsole.log("掉起微信支付必须要获取openid");Weixin.snsapi_base();}} finally {// 微信jsConfigWeixin.wxConfig();}}}// @ts-ignoreif (window.wx) {User.autoLogin = false;try {// @ts-ignoreif (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {handleFontSize();} else {if (document.addEventListener) {document.addEventListener("WeixinJSBridgeReady", handleFontSize, false);// @ts-ignore} else if (document.attachEvent) {// @ts-ignoredocument.attachEvent("WeixinJSBridgeReady", handleFontSize);// @ts-ignoredocument.attachEvent("onWeixinJSBridgeReady", handleFontSize);}}function handleFontSize() {// 设置网页字体为默认大小// @ts-ignoreWeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize': 0 });// 重写设置网页字体大小的事件// @ts-ignoreWeixinJSBridge.on('menu:setfont', function () {// @ts-ignoreWeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize': 0 });});}// @ts-ignoreif (wx.miniProgram) {// @ts-ignorewx.miniProgram.getEnv((res) => {if (res.miniprogram) {User.status.info.cert = trueUser.autoLogin = true;// && search['_mpid_'] == "mp_wdysj_shop"if (_mpid_) {if ((_mpid_ == "mp_wdysj_shop" || _mpid_ == "mp_wdysj_yiyi_shop")) {axConfig.pltName = "商城"axConfig.home = "/pagesShop/shop/wHome"App.shopScoreName = '商城'App.client.storeHttp.head('platform', 'mp')axConfig.appProv = _mpid_axConfig.appEid = 13061}axConfig.pltApp = _mpid_User.status.info.app = _mpid_}// 小程序Weixin.initWxMpH5(_mpid_, search['ver'])axCc.Loader().done("weixinLogin");} else {wxH5()}})return}} catch (e) {console.error(e)}wxH5()} else {axCc.Loader().done("weixinLogin");}},undefined);} else {}} catch (e) {console.error(e);}// #endif

2、Weixin.ts

import ab_ from 'axj-ab_'; //npm install axj-ab_
import Base64 from '../util/Base64';interface ShareInfo {title: string,desc?: string,link: string,imageUrl?: string,logo?: string,//兼容老项目imgUrl?: string,//兼容老项目scene?: string
}let weixin = false;
let readyReg = false;
let wxConfigState = -1;
let wxMpH5 = false;
let wxMpApp = '';
// let wxMpToken = '';const Weixin = {initStepsArray: [1000, 2000, 4000, 8000, 16000, 32000, 64000],initI: 0,erred: false,readyed: false,shareInfo: <undefined | ShareInfo>undefined,// 如果wx授权失败,则定时再次获取授权wxConfigRe(e?: any) {console.log('wxConfig error ' + e)// alert('wxConfig error ' + JSON.stringify(e))Weixin.erred = true// @ts-ignoresetTimeout(Weixin.wxConfig, Weixin.initI < Weixin.initStepsArray.length ? Weixin.initStepsArray[Weixin.initI++] : Weixin.initStepsArray[Weixin.initStepsArray.length - 1])},// 通过config接口注入权限验证配置wxConfig() {let authUrl = location.hrefwxConfigState++switch (wxConfigState) {case 1:authUrl = Ainit.h5Hrefbreak// case 2://   authUrl = location.protocol + '//' + location.host + location.pathname + location.search + location.hash//   breakdefault:wxConfigState = 0break}//调接口授权的方法可以自己写App.client.plt.reqA(-1, 'C/wxConfig', [axConfig.webType, authUrl], function (err, rep) {console.log('pltClient C/wxConfig err,data:', err, rep)if (rep && rep.appId) {// rep.debug = truerep.jsApiList = ['updateAppMessageShareData','updateTimelineShareData','onMenuShareAppMessage','onMenuShareTimeline',"getLocation","scanQRCode",// 'wx-open-launch-weapp',// 'chooseWXPay']// rep.debug = trueconsole.log('wxready  wx.config')Weixin.erred = false// @ts-ignorewx.config(rep)// @ts-ignorewx.error(Weixin.wxConfigRe)let readyFun = function () {if (Weixin.erred) {return}Weixin.readyed = true}if (readyReg) {setTimeout(readyFun, 1000);} else {readyReg = true// @ts-ignorewx.ready(readyFun)}return;}Weixin.wxConfigRe()})},wxShare(v: ShareInfo) {console.log('h5  wxShare alert', v);if (weixin) {// @ts-ignorev = typeof (v) === 'object' ? v : JSON.parse(v)if (!Weixin.readyed) {Weixin.shareInfo = vreturn}delete Weixin.shareInfovar share = {title: v.title || 'xx', // 分享标题desc: v.desc || '', // 分享描述link: v.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl: v.imageUrl || v.logo || v.imgUrl, // 分享图标success: (e) => {console.log('wxShare success  ', e)// 显示微信分享// @ts-ignore// if (window.WeixinJSBridge) {//   // @ts-ignore//   window.WeixinJSBridge.call('showOptionMenu')// }if (window.wx && window.wx.showMenuItems) {// @ts-ignorewindow.wx.showMenuItems({menuList: ['menuItem:share:appMessage','menuItem:share:timeline','menuItem:favorite','menuItem:share:qq','menuItem:share:QZone',]})}},fail: function (e) {console.log('wxShare fail', e)}}console.log('updateWx', share)// @ts-ignorewx.updateAppMessageShareData(share)// @ts-ignorewx.updateTimelineShareData(share)// WeixinJSBridge.call("showOptionMenu");}},// 静默授权snsapi_base() {var backUri = Ainit.h5Href || location.hrefconsole.log(backUri)var redirectUri = axConfig.pltH5 + 'static/wx.html?u=' + Base64.encode64(backUri, true)redirectUri ='https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + (axConfig.webType == 'wdysjh5' ? 'wxab385cf8a7ec96d8' : 'wx59a0fb7a9bd076e5') + '&redirect_uri=' +encodeURIComponent(redirectUri) +'&response_type=code&scope=snsapi_userinfo&state=1'console.log(redirectUri)location.replace(redirectUri)// setTimeout(() => {//   location.replace(redirectUri)// }, 3000);},isWeiXin() {return weixin;},isWxMpH5() {return wxMpH5},getWxMpApp() {return wxMpApp},initWxMpH5(mpid: string, ver?: string) {console.log('initWxMpH5 ' + mpid)weixin = falsewxMpH5 = trueif (mpid) {wxMpApp = mpid} else {console.log('initWxMpH5 no mpid' + location.href)console.log(launcher.h5Href)console.log(launcher.h5Search)}Artist.getReviewVersion(`mp-${ver}`)// 消息通道setInterval(function () {let msg = localStorage.getItem('_mpmsg_')if (msg) {try {msg = JSON.parse(msg)if (!mpid || msg[0] === mpid) {// 是发给我的消息msg = msg[1]msg = Base64.decode64(msg)let i = msg.indexOf(',')if (i > 0) {Weixin.onWxMpMsg(msg.substring(0, i), msg.substring(i + 1))} else {Weixin.onWxMpMsg(msg, '')}localStorage.removeItem('_mpmsg_')}} catch (e) {console.error(e)localStorage.removeItem('_mpmsg_')}}}, 100)},onWxMpMsg(key: string, val?: string) {console.log('onWxMpMsg,' + key + ',' + val)if (key == 'pay') {console.log('updatePay,更新支付状态' + key)uni.$emit('updatePay', { msg: '更新支付状态' })}// @ts-ignorewx.miniProgram.navigateBack()let fun = Weixin.onWxMpCenter[key]if (fun) {fun(val)}},forWxMpToken(back: (err?: any) => void) {if (User.status.authPar) {back && back()return}// @ts-ignorelet nextT = ab_.nextT()// @ts-ignoreWeixin['forWxMpTokenBacks'] = [nextT, back]// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/msg/post?loginA=' + nextT })},onWxMpCenter: {loginA(val: string) {let paras = JSON.parse(val)let nextT = 0let back: anylet loginA = falseif (typeof (paras[0]) === 'number') {loginA = truenextT = paras[0]paras = ab_.args(paras, 1, paras.length)let backs = Weixin['forWxMpTokenBacks']if (backs) {delete Weixin['forWxMpTokenBacks']if (backs[0] === nextT) {back = backs[1]}}}let noRep = nextT && User.state.loginedUser.loginProvBack('wx', (succ, rep) => {console.log('loginA ', succ, rep)if (succ) {Page.loginSuccBack()if (loginA) {// @ts-ignorewx.miniProgram.navigateBack()}} else if (!User.state.authing && !nextT) {console.log('toLogin--------')Weixin.postWxMpMsg('toLogin')}// 回调back && back(User.status.authToken ? undefined : rep)}, paras, false, 2, false, noRep)},loginAFail(val: string) {let paras = JSON.parse(val)let nextT = paras[0]let backs = Weixin['forWxMpTokenBacks']if (backs) {delete Weixin['forWxMpTokenBacks']if (backs[0] === nextT) {backs[1] && backs[1](paras[1])}}},loginInfo(val: string) {//let loginInfo = JSON.parse(val)let paras = JSON.parse(val)if (User.status.authToken) {paras[1] = User.status.authToken}User.loginProvBack('wx', (succ) => {if (succ) {Page.loginSuccBack()} else if (!User.state.authing) {User.status.authToken = ''}}, paras, true, 2)},bindWx(val: string) {uni.$emit('updateBindWx', { msg: val })}},postWxMpMsg(key: string, val?: string) {console.log('postWxMpMsg,' + key + ',' + val)if (key === 'toLogin') {// ios 微信新用户第一次登录 会导致不执行此逻辑setTimeout(() => {// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/index/login?t=' + User.status.authToken })}, 400);return}// if (key === 'toLoginA') {//   // @ts-ignore//   wx.miniProgram.navigateTo({ url: '/pages/index/login' })//   return// }if (key === 'share') {// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/msg/share?s=' + val })return}let msg = val ? (key + ',' + val) : keysetTimeout(() => {// @ts-ignorewx.miniProgram.navigateTo({ url: '/pages/msg/reciver?msg=' + Base64.encode64(msg) })}, 400);console.log('postWxMpMsg.navigateTo');},
}// #ifdef H5
try {// 微信环境判断let userAgent: any = window.navigator.userAgent.toLowerCase();weixin =userAgent.match(/MicroMessenger/i) == "micromessenger" &&!(window.parent && window.parent !== window);//兼容 微信支付路径if (weixin) {let h5Uri = location.href;if (h5Uri.indexOf('/#/') < 0) {// axCc.Loader().wait("weixinHref");try {h5Uri = location.origin + location.pathname + "#/" + location.searchlocation.href = h5UrisetTimeout(() => {location.reload()}, 1000);axCc.Loader().wait("weixinHref");} catch (error) {}}}} catch (e) {console.error(e);
}
// #endifexport default Weixin;

3、公共h5跳转页

<html><head><meta charset="utf-8" /><metaname="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1,viewport-fit=cover"/><title>···</title><style>#loadingBg {width: 100vw;height: 100vh;position: fixed;z-index: 10000;top: 0;}body {margin: 0px;font-size: 12px;}#preloader {position: absolute;width: 30px;height: 30px;background: rgba(253, 87, 17, 1);border-radius: 50px;left: 0;right: 0;top: 0;bottom: 0;margin: auto;-webkit-animation: preloader_1 1.5s infinite linear;-moz-animation: preloader_1 1.5s infinite linear;-ms-animation: preloader_1 1.5s infinite linear;animation: preloader_1 1.5s infinite linear;}#preloader:after {position: absolute;width: 50px;height: 50px;border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);border-left: 10px solid transparent;border-right: 10px solid transparent;border-radius: 50px;content: "";top: -20px;left: -20px;-webkit-animation: preloader_1_after 1.5s infinite linear;-moz-animation: preloader_1_after 1.5s infinite linear;-ms-animation: preloader_1_after 1.5s infinite linear;animation: preloader_1_after 1.5s infinite linear;}@-webkit-keyframes preloader_1 {0% {-webkit-transform: rotate(0deg);}50% {-webkit-transform: rotate(180deg);background: #ff4f11;}100% {-webkit-transform: rotate(360deg);}}@-webkit-keyframes preloader_1_after {0% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}@-moz-keyframes preloader_1 {0% {-moz-transform: rotate(0deg);}50% {-moz-transform: rotate(180deg);background: #ff4f11;}100% {-moz-transform: rotate(360deg);}}@-moz-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}@-ms-keyframes preloader_1 {0% {-ms-transform: rotate(0deg);}50% {-ms-transform: rotate(180deg);background: #ff4f11;}100% {-ms-transform: rotate(360deg);}}@-ms-keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}@keyframes preloader_1 {0% {transform: rotate(0deg);}50% {transform: rotate(180deg);background: #ff4f11;}100% {transform: rotate(360deg);}}@keyframes preloader_1_after {0% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}50% {border-top: 10px solid rgba(253, 87, 17, 1);border-bottom: 10px solid rgba(253, 87, 17, 1);}100% {border-top: 10px solid rgba(255, 139, 9, 1);border-bottom: 10px solid rgba(255, 139, 9, 1);}}</style></head><script>function getPara(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");var r = window.location.search.substr(1).match(reg);if (r != null) {return unescape(r[2]);}return null;}let uid = getPara("uid");let msg = getPara("msg");if (msg) {localStorage.setItem("_mpmsg_", JSON.stringify([uid, msg]));}</script><body><div id="loadingBg"><div id="preloader"></div><!-- <div>加载中</div> --></div></body>
</html>

相关文章:

uniapp 微信小程序webview 和 h5数据通信

项目是uniapp编写&#xff0c;因为是先开发了h5和app&#xff0c;小程序是突然要用的&#xff0c;做兼容开发已经来不及&#xff0c;由于微信小程序webview载入h5 因为通信必须要特殊限制&#xff08;网页向小程序 postMessage 时&#xff0c;会在以下特定时机触发并收到消息&a…...

3D 生成重建021-LRM基于大模型的生成式3D生成模型

3D 生成重建021-LRM基于大模型的生成式3D生成模型 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 论文提出了一种名为大型重建模型 (LRM) 的新型模型&#xff0c;该模型可在短短 5 秒内根据单张输入图像预测物体的 3D 模型。与许多先前仅在 ShapeNet 等小型数据集上进行…...

12.6深度学习_模型优化和迁移_整体流程梳理

七、整体流程梳理 1. 引入使用的包 用到什么包&#xff0c;临时引入就可以&#xff0c;不用太担心。 import time import osimport numpy as np import pandas as pd import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvisio…...

CCF-GESP 编程能力认证 C++ 七级 2024年9月份判断题详细解析

链接&#xff1a;CCF-GESP 编程能力认证 C 七级 2024年9月份选择题详细解析-CSDN博客 目录 第 1 题 第 2 题 第 3 题 第 4 题 第 5 题 第 6 题 第 7 题 第 8 题 第 9 题 第 10 题 第 1 题 表达式 a << 1 的结果为 a&#xff08;错误&#xff09; 【a是字符常…...

ESP32-S3模组上跑通ES8388(20)

接前一篇文章:ESP32-S3模组上跑通ES8388(19) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析完了es8388_init函数中的第7段代码,本回继续往下解析。为了便于理解和回顾,再次贴出es8388_init函数源码,在components\audio_hal\driver\es8388\es8388.c中,如下: ​ …...

UE5.5 Geometry库平面切割原理分析

平面切割--FMeshPlaneCut 平面定义: 面上一个点 法线 算法流程如下 求几何体所有顶点和面的有向距离(Signs) Sign计算&#xff1a; float Sign (VertexPos - PlaneOrigin).Dot(PlaneNormal); 遍历所有几何体所有交叉边, 进行SplitEdge 对于位于切割面两侧的交叉边(Sign…...

JAVAWeb中的Servlet学习

一 Servlet简介 1.1动态资源和静态资源 静态资源 无需在程序运行时通过代码运行生成的资源,在程序运行之前就写好的资源.例如:html css js img ,音频文件和视频文件 动态资源 需要在程序运行时通过代码运行生成的资源,在程序运行之前无法确定的数据,运行时动态生成,例如Servle…...

【Linux】多线程

目录 线程 线程和进程的关系 虚拟地址与物理地址的映射&#xff08;三级映射&#xff09; ​编辑 线程的使用 线程安全 临界资源和临界区 互斥锁 同步与互斥 互斥锁的使用 锁的初始化 加锁与解锁 信号量 信号与信号量的区别 信号量的使用 Lock_guard与unique_lock …...

如何使用Python库连接Redis

1、redis-py 库封装一个 Redis 工具类可以帮助我们简化 Redis 的操作并提高代码的复用性和可维护性。 安装redis pip install redisimport redis import logginglogging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__)class RedisUtils:def __init__(s…...

mybatis一对多的查询怎么查?

1.问题描述 我有一个班级&#xff0c;班级里有很多学生&#xff0c;我需要一个查询把班级和学生信息查出来&#xff0c;怎么查&#xff1f; 这里有个问题&#xff0c;就是我班级的命名和学生的命名可能重了。 例如&#xff1a; class Gradle{ private String id; private …...

[C++]友元函数和友元类

1. 友元函数 1.1 友元函数的概念 友元函数是一个非成员函数&#xff0c;它被类声明为“友元”&#xff0c;从而能够访问类的私有成员和保护成员。正常情况下&#xff0c;类的外部函数是不能访问类的私有成员的&#xff0c;而友元函数打破了这一限制。 class MyClass { priva…...

实战:MyBatis适配多种数据库:MySQL、Oracle、PostGresql等

概叙 很多时候&#xff0c;一套代码要适配多种数据库&#xff0c;主流的三种库&#xff1a;MySQL、Oracle、PostGresql&#xff0c;刚好mybatis支持这种扩展&#xff0c;如下图所示&#xff0c;在一个“namespace”&#xff0c;判断唯一的标志是iddatabaseId&#xff0c;刚好写…...

2024年天津市职业院校技能大赛高职组 “信息安全管理与评估”样题第三阶段

&#xff08;四&#xff09;第三阶段竞小组&#xff08;赛项&#xff09;目&#xff08;300分&#xff09; 第三阶段竞赛内容是:网络安全渗透&#xff08;夺旗挑战赛CTF&#xff09; 本模块要求参赛者作为攻击方&#xff0c;运用所学的信息收集、漏洞发现、漏洞利用等渗透测试技…...

游戏引擎学习第36天

仓库 :https://gitee.com/mrxiao_com/2d_game 回顾之前的内容 在这个程序中&#xff0c;目标是通过手动编写代码来从头开始制作一个完整的游戏。整个过程不使用任何库或现成的游戏引擎&#xff0c;这样做的目的是为了能够全面了解游戏执行的每一个细节。开发过程中&#xff0…...

数仓技术hive与oracle对比(一)

准备 包括软硬件环境、数据、测试数据三方面的准备内容。 环境 虚拟机软件virtualbox7&#xff0c;同样的虚拟机配置&#xff1a;内存2G、cpu一核&#xff0c;物理主机同一台macbookpro&#xff08;13-2020款&#xff09;&#xff0c;所以硬盘IO读写速度一致。 综上&#x…...

LeetCode题集-5 - 最长回文子串(一)

题目&#xff1a;给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 这一题作为中等难度&#xff0c;常规解法对于大多数人应该都没有难度。但是其中也有超难的解决办法&#xff0c;下面我们就一起由易到难&#xff0c;循序渐进地来解这道题。 01、暴力破解法 对于大多…...

A3026 Java+jsp+servlet+mysql高校学生请假管理系统

高校学生请假管理系统 1.摘要2. 绪论3.功能结构4.界面展示5.源码获取 1.摘要 高校学生请假管理系统 摘要&#xff1a;随着计算机的发展与不断进步&#xff0c;各个领域都出现了新的技术&#xff0c;曾经各种规模之间的竞争已经发展成为技术之间的竞争&#xff0c;管理和人才之…...

LDO低压差线性稳压器

1. 简介 LDO 是 “Low Dropout Regulator” 的缩写&#xff0c;中文称为“低压差线性稳压器”。LDO 稳压器是一种用于电压调节的电子设备&#xff0c;它的主要特点是输出电压和输入电压之间的压差非常低。这种特性使得 LDO 在许多应用场景中非常有用&#xff0c;特别是在需要高…...

Angular由一个bug说起之十一:排序之后无法展开 Row

问题现象 在使用 Material Table 时&#xff0c;排序功能触发了一个奇怪的 Bug&#xff1a;表格的 Row 无法展开。最终排查发现&#xff0c;问题的根源在于 trackBy 的错误使用。trackBy 方法接受两个参数&#xff1a;index&#xff08;数据索引&#xff09;和 row&#xff08;…...

wlanapi.dll丢失怎么办?有没有什么靠谱的修复wlanapi.dll方法

在遇到各种系统文件错误当中&#xff0c;其中之一就是“wlanapi.dll文件丢失”的问题。这种问题通常发生在Windows操作系统上&#xff0c;特别是当系统试图执行与无线网络相关的任务时。wlanapi.dll是一个重要的系统文件&#xff0c;它负责处理Windows无线网络服务的许多功能。…...

redis安装和使用教程【保姆级】

1.下载 通过网盘分享的文件&#xff1a;redis 链接: https://pan.baidu.com/s/1Tu1KZkf33YJFdul8s6SzqQ?pwd8888 提取码: 8888 2.启动 进入根目录&#xff0c;使用redis-server redis.windows.conf命令启行启动Redis服务&#xff0c; 如下图所示为启动成功&#xff0c;默认…...

Github 2024-12-01 开源项目月报 Top20

根据Github Trendings的统计,本月(2024-12-01统计)共有20个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10TypeScript项目9Go项目2HTML项目1Shell项目1Jupyter Notebook项目1屏幕截图转代码应用 创建周期:114 天开发语言:TypeScript, Py…...

C总结(C语言知识点,深化重难点)

C语言 1.使用C语言的7个步骤2.ASCII码3.提高程序可读性的机巧4.如何使用多种整形5.打印多种整形6.课移植类型&#xff1a;stdint.h和inttypes.h7.浮点数常量8.浮点值的上溢和下溢9.使用数据类型11.常量和C预处理器12.转换说明的意义12.1转换不匹配13.副作用和序列点14.数组简介…...

[Collection与数据结构] 位图与布隆过滤器

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

Redis与缓存

目录 缓存 缓存优缺点 缓存更新策略 超时剔除 先删缓存再更新数据库 旁路缓存(先更新数据库&#xff0c;再删缓存&#xff09; 先更新数据库&#xff0c;再更新缓存 读写穿透 ​编辑 异步缓存写入模式 缓存常见问题 缓存穿透 缓存雪崩 缓存击穿 缓存 在业务开发…...

Ubuntu Linux 文件、目录权限问题(五)

本文为Ubuntu Linux操作系统- 第五弹 此文是在上期文件目录的内容操作基础上接着讲权限问题 上期回顾&#xff1a;Ubuntu Linux 目录和文件的内容操作 文件访问者身份与文件访问权限 Linux文件结构 所有者&#xff08;属主&#xff09;所属组&#xff08;属组&#xff09;其他…...

AI 名人堂:Jeff Dean

Jeff Dean&#xff0c;谷歌的高级研究员和人工智能领域的领军人物&#xff0c;以其在大规模分布式计算系统和人工智能系统的杰出贡献而闻名。 谷歌AI掌门人 TensorFlow项目负责人 美国工程院院士 2AGI.NET AI 名人堂 AI 名人堂&#xff1a;Jeff DeanAI 名人堂&#xff1a;Je…...

基础排序算法详解:冒泡排序、选择排序与插入排序

引言 上一章&#xff0c;我们聊到了排序的基本概念和常见算法的分类。这一次&#xff0c;我们从基础开始&#xff0c;深入剖析三种常见的O(n) 排序算法&#xff1a;冒泡排序、选择排序 和 插入排序。 它们是学习排序算法的入门神器&#xff0c;不仅实现简单&#xff0c;还能帮…...

Flink如何基于数据版本使用最新离线数据

业务场景 假设批量有一张商户表&#xff0c;表字段中有商户名称和商户分类两个字段。 批量需要将最新的商户名称和分类的映射关系推到hbase供实时使用。 原实现方案 a.原方案内容 为解决批量晚批问题&#xff0c;批量推送hbase表时一份数据产生两类rowkey&#xff1a;T-1和…...

什么是反向代理?作用、原理和实例详解

&#x1f680; 什么是反向代理&#xff1f;作用、原理和实例详解 在现代的网络架构中&#xff0c;反向代理&#xff08;Reverse Proxy&#xff09;无处不在。无论是负载均衡、加速缓存&#xff0c;还是WebSocket 支持&#xff0c;反向代理都是必不可少的工具。 这篇文章将带您…...

国产GPU中,VLLM0.5.0发布Qwen2.5-14B-Instruct-GPTQ-Int8模型,请求返回结果乱码

概述 国产GPU: DCU Z100 推理框架&#xff1a; vllm0.5.0 docker容器化部署 运行如下代码&#xff1a; python -m vllm.entrypoints.openai.api_server --model /app/models/Qwen2.5-14B-Instruct-GPTQ-Int8 --served-model-name qwen-gptq --trust-remote-code --enforce…...

Stable Diffusion本地部署:从零开始的完整指南

1、引言 Stable Diffusion是计算机视觉领域的一个生成式大模型&#xff0c;能够进行文生图&#xff08;txt2img&#xff09;和图生图&#xff08;img2img&#xff09;等图像生成任务。它利用深度学习技术&#xff0c;特别是RealisticVision v2.0模型&#xff0c;能够创造出接近…...

隐式神经网络实现低光照图像增强

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

Flutter动画(三)内建显式动画Widget

常见的内建显式动画Widget&#xff1a; ListenableBuilder&#xff1a; AnimatedBuilder AnimatedWidget AlignTransition DecoratedBoxTransition DefaultTextStyleTransition PositionedTransition RelativePositionedTransition RotationTransition ScaleTransiti…...

springSecurity自定义登陆接口和JWT认证过滤器

下面我会根据该流程图去自定义接口&#xff1a; 我们需要做的任务有&#xff1a; 登陆&#xff1a;1、通过ProviderManager的方法进行认证&#xff0c;生成jwt&#xff1b;2、把用户信息存入redis&#xff1b;3、自定义UserDetailsService实现到数据库查询数据的方法。 校验&a…...

Spring Boot日志:从Logger到@Slf4j的探秘

写在前面 Hello大家好&#xff0c;今日是2024年的第一天&#xff0c;祝大家元旦快乐?? 2024第一篇文章从SpringBoot日志开始 文章目录 一、前言二、日志有什么用&#xff1f;三、日志怎么用&#xff1f;四、自定义日志打印 ?? 常见日志框架说明4.1 在程序中得到?志对象【…...

使用 LabVIEW 与 PLC 通信的方式

要将 PLC 与 LabVIEW 或其他 NI 产品进行通信&#xff0c;首先需要明确 PLC 支持的通信协议和接口类型。NI 提供了多种方案&#xff0c;包括 OPC 服务器、Modbus、Ethernet/IP 和其他工业通信协议。下面将详细介绍这些方法&#xff0c;并进行比较分析&#xff0c;帮助你选择最适…...

python录制鼠标键盘操作循环播放

依赖 pip install pynput 程序: from pynput import mouse, keyboard import time import threading# 用于存储录制的鼠标和键盘事件 mouse_events [] keyboard_events []# 定义事件处理函数# 处理鼠标事件 def on_move(x, y):mouse_events.append((move, x, y))def on_cl…...

开发者如何使用GCC提升开发效率Opencv操作

看此篇前请先阅读 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144216351?spm=1001…...

异常与文件

目录 1.异常 1.1.概念 1.2.常见异常 1.3.异常处理方式 1.3.1.try except 1.3.2.try except else 1.3.3.try except else finally 2.文件 2.1.文件分类 ps&#xff1a;python 程序的数据保存在哪里? 2.2.常见的文件类型 2.3.python 操作文件的函数 2.3.1.读取文件…...

【C语言】完成程序设计填空

文章目录 1、请阅读下面的程序,在空白处填写正确的代码,要求各在一行从头开始输出m和n的值。2、求100~599之间的所有水仙花数,即各位数字的立方和恰好等于该数本身的数。3、以下程序的功能是:将值为三位正整数的变量x中的数值按照个位、十位、百位的顺序 拆分并输出。请填空…...

西湖大学:LLM零样本推理任务校准

&#x1f4d6;标题&#xff1a;Task Calibration: Calibrating Large Language Models on Inference Tasks &#x1f310;来源&#xff1a;arXiv, 2410.18764 &#x1f31f;摘要 &#x1f538;大型语言模型&#xff08;LLM&#xff09;在推理任务上表现出令人印象深刻的零样本…...

windows下Qt5自动编译配置QtMqtt环境(11)

文章目录 [toc]1、概述2、准备1.1 下载源码1.2 配置环境1.3 解释原理 3、编译4、验证5、参考6、视频 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt网络编程 &#x1f448; 1、概述 Qt默认是不包含mqtt库的&#xff0c;如果需要使用到mqtt库就只能自己编译配…...

每天五分钟深度学习:神经网络的前向传播的计算(多样本)

本文重点 前面我们学习了单样本的前向传播,本文我们学习多样本的前向传播,我们先来回忆一下,神经网络的单样本的前向传播的向量化的方式: m个样本依次进行前向传播 这里我们说明一下符号: 我们使用(m)表示第m个样本,用[m]表示神经网络的第m层 a[2](i) 表示第i个样本计…...

基于 NXP S32K312+FS23 的汽车通用评估板方案

S32K3 系列是 NXP 推出的面向汽车电子和工业应用的微控制器&#xff0c;基于 ARMCortex-M7 内核&#xff0c;支持单核、双核和锁步内核配置。S32K3 系列具有内核、内存和外设数量方面的可扩展性&#xff0c;符合 ISO26262 标准&#xff0c;能达到 ASIL B/D 安全等级&#xff0c…...

11进阶篇:专业课论文阅读方向指南(2025版)

文章目录 第一个检索式:图情档核心期刊(北大 + CSSCI)发文情况研究方法类关键词研究主题类关键词论文阅读建议第二个检索式:川大公共管理学院在核心期刊(北大 + CSSCI)的发文情况研究方法类关键词研究主题类关键词特点关键词与2024年972(现815)两道题目的映射情况815信…...

Qt之第三方库‌QXlsx使用(三)

Qt开发 系列文章 - QXlsx&#xff08;三&#xff09; 目录 前言 一、Qt开源库 二、QXlsx 1.QXlsx介绍 2.QXlsx下载 3.QXlsx移植 4.修改项目文件.pro 三、使用技巧 1.写入数据 2.读出数据 总结 前言 Qt第三方控件库是指非Qt官方提供的、用于扩展Qt应用程序功能的控件…...

第145场双周赛: 使数组的值全部为 K 的最少操作次数、破解锁的最少时间 Ⅰ、使两个整数相等的位数操作、统计最小公倍数图中的连通块数目

Q1、使数组的值全部为 K 的最少操作次数 1、题目描述 给你一个整数数组 nums 和一个整数 k 。 如果一个数组中所有 严格大于 h 的整数值都 相等 &#xff0c;那么我们称整数 h 是 合法的 。 比方说&#xff0c;如果 nums [10, 8, 10, 8] &#xff0c;那么 h 9 是一个 合法…...

AJAX三、XHR,基本使用,查询参数,数据提交,promise的三种状态,封装-简易axios-获取省份列表 / 获取地区列表 / 注册用户,天气预报

一、XMLHttpRequest基本使用 XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。 二、XMLHttpRequest-查询参数 语法: 用 & 符号分隔的键/值对列表 三、XMLHttpRequest-数据提交 核心步骤 : 1. 请求头 设置 Content-Type 2. 请求体 携带 符合要求 的数…...

Android期末复习题

1.如何搭建Android开发环境&#xff1f; 答案:搭建Android开发环境需要以下几个步骤&#xff1a; &#xff08;1&#xff09;下载和安装JDK &#xff08;2&#xff09;配置PATH环境变量 &#xff08;3&#xff09;下载和安装Android Studio &#xff08;4&#xff09;创建A…...