Vue+Notification 自定义消息通知组件 支持数据分页 实时更新
效果图:
message.vue 消息组件 子组件
<template><div class="custom-notification"><div class="content"><span @click="gotoMessageList(currentMessage.split('=')[1])">{{ currentMessage.split('=')[0] }}</span></div><div class="footer"><div class="left-buttons"><el-button size="mini" type="text" @click="handleIgnoreAll">忽略全部</el-button></div><div class="pagination"><el-paginationsmall:key="paginationKey":current-page.sync="currentPage":page-size="1":total="localNoticeList.length"layout="prev,slot, next"prev-text="<"next-text=">"@prev-click="currentPage--"@next-click="currentPage++"><span class="pagination-text">{{ currentPage }} / {{ totalPages }}</span></el-pagination></div><div class="right-button"><el-button type="primary" size="mini" @click="handleAccept(currentMessage.split('=')[1])">接受</el-button></div></div></div>
</template><script>export default {props: {messages: {type: Array,default: () => []},total:{type:Number,default:0},noticeList:{type:Array,default:()=>[]}},data() {return {localNoticeList: [], // 新增本地副本currentPage: 1,totalPage: 5,paginationKey: 0 // 分页组件独立key}},watch: {noticeList: {deep:true,immediate: true,handler(newVal) {this.localNoticeList = JSON.parse(JSON.stringify(newVal))// 当消息更新时自动重置页码this.currentPage = Math.min(this.currentPage, newVal.length)this.paginationKey++ // 强制分页组件重置// this.updateList(this.localNoticeList)}}},computed: {totalPages() {return this.localNoticeList.length || 1},currentMessage() {return this.localNoticeList[this.currentPage - 1]?.messageTitle +'='+this.localNoticeList[this.currentPage - 1]?.messageId || ''}},methods: {handleLater() {// 稍后提醒逻辑this.$emit('later')},handleIgnoreAll() {// 忽略全部 将消息全部设为已读this.$emit('ignore-all',this.localNoticeList) // 触发父级关闭事件},handleAccept(msgId) {//接收this.$emit('gotoMessageList',msgId)},gotoMessageList(msgId){this.$emit('gotoMessageList',msgId)},// 通过事件通知父组件updateList(newList) {this.$emit('update-list', newList)}}}
</script><style scoped>.custom-notification {padding: 15px 0px 15px 0px;width: 270px;}.header {display: flex;align-items: center;margin-bottom: 12px;}.content{cursor: pointer;font-weight: bold;font-size: 13px;}.header i {margin-right: 8px;font-size: 16px;}.footer {display: flex;justify-content: space-between;align-items: center;margin-top: 15px;}.pagination {display: flex;align-items: center;gap: 8px;}.pagination i {cursor: pointer;color: #606266;}.left-buttons .el-button--text {color: #909399;}.pagination-text{text-align: center;}
</style>
消息父组件:
<template><div><el-badge :value="total" class="item" style="line-height: 40px; position: relative;"><span @click="bellClick"><el-iconclass="el-icon-bell"style="font-size: 20px; cursor: pointer; transform: translateY(1.1px)"></el-icon></span></el-badge><!-- 添加或修改我的消息对话框 --><el-dialog title="我的消息" :visible.sync="open" width="500px" append-to-body><el-form ref="form" :model="form" :rules="rules" label-width="80px"><el-form-item label="消息标题" prop="messageTitle"><el-input disabled v-model="form.messageTitle" placeholder="请输入消息标题" /></el-form-item><el-form-item label="消息内容"><editor :readOnly="true" v-model="form.messageContent" :min-height="192" /></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="cancel">关闭</el-button></div></el-dialog><!-- word预览弹窗 --><el-dialog fullscreen title="word预览" :visible.sync="dialogVisibleWord" append-to-body><vue-office-docx :src="previewWordOffice" @rendered="renderedHandler" @error="errorHandler" /></el-dialog><!-- doc预览 --><el-dialog fullscreen title="word预览" :visible.sync="DocSync" append-to-body><VueOfficePdf :src="docSrc" /></el-dialog><el-dialog:title="msg.messageTitle":visible.sync="messageVisible"width="800px"append-to-bodyclass="my-message__dialog"@close="closeMsgModel"><div><span class="contentImg" v-html="msg.messageContent"></span></div><div class="my-message__filebox" v-if="fileList.length > 0"><div>附件:</div><ul class="my-message__ul"><li class="my-message__li" v-for="(item, index) in fileList" :key="index"><div class="my-message__li--title">{{ item.name }}</div><div class="my-message__li--opt"><el-buttonstyle="color: green"@click.stop="handleShow(index, item)"type="text"icon="el-icon-view"size="mini"v-if="getFileExtension(item.name) !== 'zip' && getFileExtension(item.name) !== 'rar'">查看</el-button></div></li></ul></div><div slot="footer" class="dialog-footer"><el-button @click.stop="closeMsgModel">关闭</el-button></div></el-dialog>
<!-- <custom-notification></custom-notification>--></div>
</template><script>
import Vue from 'vue'
import { mapGetters } from 'vuex';//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx';
import { listMyUnreadNotice, getSysmessage, listSysmessage } from '@/api/system/sysmessage';
import { fileDownload, previewDocumentAPI } from '@/api/files/files';
import XLSX from 'xlsx';
import events from '@/utils/events';
import VueOfficePdf from '@vue-office/pdf';
import Notification from 'element-ui/lib/notification'
import CustomNotification from '@/components/Bell/component/message'
export default {name: 'index',components: { VueOfficePdf, VueOfficeDocx,CustomNotification },data() {return {DocSync:false,docSrc:'',baseUrl: 'http://' + window.location.host + process.env.VUE_APP_BASE_API,dialogVisibleWord: false,previewWordOffice: '',noticeList: [],noticeListNew:[],//pollInterval: null,// 轮询定时器lastCheckTime: null,// 最后检查时间notificationKey:0,isFirstCheck: true,// 首次检查标志templateVisible: false,messageVisible:false,showAllBtn: false,msg:{},form: {},rules: {},open: false,queryParams: {id: null,status: '0'},fileList: [],total: 0,totalNew:0,notificationInstance:null //通知示例};},computed: {...mapGetters(['isDot', 'id'])},created() {// on接收 emit发送this.clearPolling()this.getUnRead(); //查询是否有未读消息通知this.getUnReadNew(); //初始化调用获取未读消息events.$on('noticePush', this.getUnRead);events.$on('noticePushByMsg', this.getUnRead);this.$nextTick(() => {events.$on('noticeCheckByMsg', this.getUnRead);// events.$on('noticeCancel',this.cancel);});events.$on('noticePush',this.getUnReadNew)},mounted() {},beforeDestroy() {// this.clearPolling()},// 关闭定时器deactivated(){// this.clearPolling()},methods: {// 跳转链接clickSpan() {// 点击跳转我的消息页this.$router.push('/task/myMessage');},/**word预览组件回调函数 */renderedHandler() {console.log('渲染完成');},errorHandler() {console.log('渲染失败');},/** 查询是否存在未读消息 根据当前用户匹配消息表中得ID */getUnRead() {this.queryParams.id = this.id;// 查询未读消息listSysmessage(this.queryParams).then((res) => {if (res.code == 200) {if (res.rows.length > 0) {// 这里的total 要请求我的代办的接口 然后加起来this.total = res.total;this.noticeList = res.rows;this.$store.dispatch('app/setIsDot', true);} else {this.total = null;this.noticeList = [];this.$store.dispatch('app/setIsDot', false);}this.$emit('getUnRead', this.noticeList);}});},//查询未读消息重构 添加定时任务 每隔20分钟调用一次/** 核心查询方法 */async getUnReadNew() {try {const params = {id: this.id, // 用户IDstatus:0,}const { code, rows, total } = await listSysmessage(params)if (code === 200) {this.handleNewMessages(rows, total)this.lastCheckTime = new Date()}} catch (error) {console.error('消息检查失败:', error)}},/** 处理新消息逻辑 */handleNewMessages(rows, total) {// 数据同步this.noticeListNew = rowsthis.totalNew = rows.length//total// 仅当有新消息时触发通知if (rows.length > 0) {if (this.notificationInstance) {// 手动创建组件实例// 通过 key 变化强制更新组件this.notificationKey = Date.now()// const NotificationComponent = new Vue({// render: h => h(CustomNotification, {// props: {// noticeList: [...this.noticeListNew],// total: this.noticeListNew.length// },// on: {// // 事件监听...// }// })// }).$mount()// // 保存组件实例引用// this.customNotificationInstance = NotificationComponent.$children[0]// this.customNotificationInstance = this.notificationInstance.$children[0]//已有弹窗时仅更新数据this.customNotificationInstance.$set(this.customNotificationInstance,'noticeList',[...rows])this.customNotificationInstance.$forceUpdate()} else {this.showNotification()}}this.$emit('update:noticeList', rows)window.clearInterval(this.pollInterval)this.setupPolling()// 启动轮询 后台发送消息时 自动触发},/** 判断是否有新消息 */hasNewMessages(newRows) {return newRows.some(item =>!this.noticeListNew.find(old => old.messageId === item.messageId))},/** 轮询控制 */setupPolling() {// 5分钟调用一次 60000 * 5 300000this.clearPolling() // 清除已有定时器this.pollInterval = window.setInterval(() => {this.getUnReadNew()},300000)},/** 销毁定时器*/clearPolling() {if (this.pollInterval) {window.clearInterval(this.pollInterval)this.pollInterval = null}},bellClick() {this.getUnRead();},cancel() {this.open = false;this.getUnRead();},cancelTempDialog() {this.templateVisible = false;this.getUnRead();},// 查看更多showAll() {this.$router.push({ path: '/monitor/myMessage' });},//查看消息 弹窗显示handleRead(data) {const messageId = data.messageId;getSysmessage(messageId).then((response) => {this.form = response.data;// this.form.messageTitle = data.messageTitle// this.form.messageContent = data.messageContentif (this.form.fileJSON && JSON.parse(this.form.fileJSON)) {this.fileList = JSON.parse(this.form.fileJSON);} else {this.fileList = [];}if (this.form.messageType === '3') {this.templateVisible = true;} else {this.open = true;this.title = '查看我的消息';}});},toLink(url) {if (url) {if (url.indexOf('http://') > -1 || url.indexOf('https://') > -1) {window.open(url);} else {this.$router.push({ path: url });}}this.cancelTempDialog();},handleDownLoad(index, file) {const param = {code: file.code,fileName: file.name};fileDownload(param).then((response) => {if (response) {const url = window.URL.createObjectURL(new Blob([response]));const link = document.createElement('a');link.href = url;link.setAttribute('download', file.name); // 设置下载的文件名document.body.appendChild(link);link.click();document.body.removeChild(link);}}).catch((error) => {});},// 预览async handleShow(index, file) {const param = {code: file.code,fileName: file.name};const type = file.name.split('.')[file.name.split('.').length - 1];await fileDownload(param).then(async (response) => {if (type === 'pdf' || type === 'PDF') {//pdf预览let blob = new Blob([response], {type: 'application/pdf'});let fileURL = window.URL.createObjectURL(blob);window.open(fileURL, '_blank'); //这里是直接打开新窗口} else if (type === 'txt' || type === 'TXT') {//txt预览// 将文件流转换为文本const text = await response.text();// 在新窗口中打开文本内容const newWindow = window.open();newWindow.document.write(`<pre>${text}</pre>`);} else if (type === 'xls' || type === 'xlsx') {//excel预览// 将文件流转换为ArrayBufferconst arrayBuffer = await response.arrayBuffer();// 使用xlsx插件解析ArrayBuffer为Workbook对象const workbook = XLSX.read(arrayBuffer, { type: 'array' });// 获取第一个Sheetconst sheetName = workbook.SheetNames[0];const sheet = workbook.Sheets[sheetName];// 将Sheet转换为HTML表格const html = XLSX.utils.sheet_to_html(sheet);// 添加表格线样式const styledHtml = `<style>table {border-collapse: collapse;}td, th {border: 1px solid black;padding: 8px;}</style>${html}`;// 在新窗口中打开HTML内容const newWindow = window.open();setTimeout(() => {newWindow.document.title = sheetName;}, 0);newWindow.document.write(styledHtml);} else if (type === 'doc' || type === 'docx') {if (type === 'doc') {// doc预览 需要转码 定时任务this.handleMany(file.code,type)}else{// docx预览const fileUrl = window.URL.createObjectURL(response);this.previewWordOffice = fileUrl;this.dialogVisibleWord = true;}}else if (type === 'png' || type === 'jpg') {const fileURL = window.URL.createObjectURL(response);this.qrCode = fileURL;this.dialogVisible = true;console.log(fileURL, 'fileURL的值为-----------');this.saveFile = file;}}).catch((error) => {});},// doc 预览handleMany(code,type) {previewDocumentAPI({code: code}).then(response => {let fileURLfileURL = this.baseUrl + response.msgif (type === 'doc' || type === 'docx') {this.docSrc = fileURLthis.DocSync = true}})},showNotification() {// 如果已有通知实例且未关闭,先关闭if (this.notificationInstance) {this.$notify.closeAll()}const h = this.$createElementconst notificationNode = h(CustomNotification, {key: this.notificationKey, // 添加唯一keyprops: {noticeList: [...this.noticeListNew], // 传递消息列表total:this.noticeListNew.length},on: {// 添加事件监听'update-list': this.handleListUpdate,'close-notification': () => this.$notify.closeAll(),'later': () => {this.$notify.closeAll()},'ignore-all': (localNoticeList) => {const msgList = localNoticeListmsgList & msgList.forEach((item)=>{this.readMessageAll(item.messageId)})this.$notify.closeAll()this.getUnRead()},'accept': () => {console.log('接受处理逻辑')},close: () => {this.notificationInstance = null},'gotoMessageList': (msgId) => {this.readMessage(msgId)this.getUnRead()//阅读了那一条 根据ID匹配然后进行过滤this.noticeListNew = this.noticeListNew.filter(item=> item.messageId !== Number(msgId))if(this.noticeListNew.length > 0){this.customNotificationInstance.$set(this.customNotificationInstance,'noticeList',[...this.noticeListNew])this.customNotificationInstance.$forceUpdate()}else{this.$notify.closeAll()}}}})this.notificationInstance = this.$notify.info({title: '消息通知',message: notificationNode,customClass:'bellClass',position: 'bottom-right',duration:60000,onClose: () => {this.notificationInstance = null}});// 获取组件实例this.customNotificationInstance = notificationNode.componentInstance},// 处理列表更新事件handleListUpdate(newList) {this.noticeListNew = newList},//查看消息 弹窗显示readMessage(msgId) {const messageId = msgId;getSysmessage(messageId).then((response) => {this.messageVisible = truethis.msg = response.data;// this.form.messageTitle = data.messageTitle// this.form.messageContent = data.messageContentif (this.msg.fileJSON && JSON.parse(this.msg.fileJSON)) {this.fileList = JSON.parse(this.msg.fileJSON);} else {this.fileList = [];}});},//批量已读readMessageAll(msgId) {const messageId = msgId;getSysmessage(messageId).then((response) => {});},getFileExtension(filename) {// 获取最后一个点的位置const lastDotIndex = filename.lastIndexOf('.')// 如果没有点或者点在第一个位置,返回空字符串if (lastDotIndex === -1 || lastDotIndex === 0) {return ''}// 截取点后的字符串作为后缀return filename.substring(lastDotIndex + 1)},closeMsgModel(){this.messageVisible = false}}
};
</script><style rel="stylesheet/scss" lang="scss" scoped>
.my-message {::v-deep .el-checkbox__label {vertical-align: middle;}&__editor {::v-deep .ql-toolbar {display: none;}::v-deep .ql-container {// border-top: 1px solid #ccc !important;border: none !important;}::v-deep .ql-editor {max-height: 500px;}}&__ul {list-style-type: none;// border: 1px solid #ccc;// border-radius: 5px;}&__filebox {margin-top: 10px;padding-left: 20px;padding-right: 20px;background: #e6f7ff;border-radius: 5px;}&__dialog {::v-deep .el-dialog__body {padding-bottom: 0px !important;}}&__li {width: 100%;display: flex;justify-content: space-between;margin-bottom: 5px;&--opt {padding-right: 10px;}}
}::v-deep .el-badge__content.is-fixed {transform: translateY(-22%) translateX(100%);
}::v-deep .el-badge__content {font-size: 11px;padding: 0 5px;
}
::v-deep .is-fullscreen {.el-dialog__body {/* padding: 15px 20px !important; */color: #606266;font-size: 14px;word-break: break-all;height: calc(100vh - 40px);overflow: auto;}
}</style>
<style>.bellClass .el-notification__icon::before {content: '\e7ba'; /* 需要更换的图标编码 */color: #8BC34A; /* 图标颜色 */}.bellClass {/*border: 1px solid #8bc34a57; !* 修改边框样式 f55e00 *!*/box-shadow: 0 2px 10px 0 rgb(0 0 0 / 48%) !important;}.el-notification__title {color: #000; /* 修改标题字体颜色 */font-size:12px;font-weight: 100;}.bellClass .el-notification__icon {height: 20px;width: 20px;font-size: 18px;transform: translateY(-2px);}.bellClass .el-notification__group {margin-left: 8px;margin-right: 8px;}
</style>
核心代码:
这个显示通知的核心方法, 自定义消息组件 通过$createElement创建Vnode挂载到message中,
数据传递的话通过props传递,通过on自定义事件
showNotification() {// 如果已有通知实例且未关闭,先关闭if (this.notificationInstance) {this.$notify.closeAll()}const h = this.$createElementconst notificationNode = h(CustomNotification, {key: this.notificationKey, // 添加唯一keyprops: {noticeList: [...this.noticeListNew], // 传递消息列表total:this.noticeListNew.length},on: {// 添加事件监听'update-list': this.handleListUpdate,'close-notification': () => this.$notify.closeAll(),'later': () => {this.$notify.closeAll()},'ignore-all': (localNoticeList) => {const msgList = localNoticeListmsgList & msgList.forEach((item)=>{this.readMessageAll(item.messageId)})this.$notify.closeAll()this.getUnRead()},'accept': () => {console.log('接受处理逻辑')},close: () => {this.notificationInstance = null},'gotoMessageList': (msgId) => {this.readMessage(msgId)this.getUnRead()//阅读了那一条 根据ID匹配然后进行过滤this.noticeListNew = this.noticeListNew.filter(item=> item.messageId !== Number(msgId))if(this.noticeListNew.length > 0){this.customNotificationInstance.$set(this.customNotificationInstance,'noticeList',[...this.noticeListNew])this.customNotificationInstance.$forceUpdate()}else{this.$notify.closeAll()}}}})this.notificationInstance = this.$notify.info({title: '消息通知',message: notificationNode,customClass:'bellClass',position: 'bottom-right',duration:60000,onClose: () => {this.notificationInstance = null}});// 获取组件实例this.customNotificationInstance = notificationNode.componentInstance},
获取当前弹窗的实例时数据通信的关键!
/** 处理新消息逻辑 */handleNewMessages(rows, total) {// 数据同步this.noticeListNew = rowsthis.totalNew = rows.length//total// 仅当有新消息时触发通知if (rows.length > 0) {if (this.notificationInstance) {// 手动创建组件实例// 通过 key 变化强制更新组件this.notificationKey = Date.now()// const NotificationComponent = new Vue({// render: h => h(CustomNotification, {// props: {// noticeList: [...this.noticeListNew],// total: this.noticeListNew.length// },// on: {// // 事件监听...// }// })// }).$mount()// // 保存组件实例引用// this.customNotificationInstance = NotificationComponent.$children[0]// this.customNotificationInstance = this.notificationInstance.$children[0]//已有弹窗时仅更新数据this.customNotificationInstance.$set(this.customNotificationInstance,'noticeList',[...rows])this.customNotificationInstance.$forceUpdate()} else {this.showNotification()}}this.$emit('update:noticeList', rows)window.clearInterval(this.pollInterval)this.setupPolling()// 启动轮询 后台发送消息时 自动触发},
已有弹窗只更新数据 不弹窗
相关文章:
Vue+Notification 自定义消息通知组件 支持数据分页 实时更新
效果图: message.vue 消息组件 子组件 <template><div class"custom-notification"><div class"content"><span click"gotoMessageList(currentMessage.split()[1])">{{ currentMessage.split()[0] }}</…...
机械设计【】技术要求(实际使用)
目录 台板技术要求加工件技术要求钣金件技术要求工装型腔技术要求铝型材框架技术要求装配体技术要求焊接件技术要求1(外形尺寸≥1500mm)焊接件技术要求2(外形尺寸<1500mm)焊接件技术要求3(不锈钢)其他要求台板技术要求 1.台板下表面周边不倒角,其余未注倒角C0.5; 2.去…...
遨游科普:防爆平板是指什么?有哪些应用场景?
在石油开采平台的炽热甲板、化工园区的反应釜旁、矿井巷道的瓦斯弥漫区,总能看到一群手持特殊设备的作业人员。他们手中的平板并非寻常消费电子产品,而是专门应对极端环境的防爆平板。防爆平板承载着工业安全的核心诉求,其技术演进与应用拓展…...
【GCC】gcc编译学习
文章目录 1. 过程2. 常用命令选项3. 多个源文件编译参考内容 1. 过程 step1 : 预处理,生成.i文件(预处理器cpp) gcc -E [源文件] -o [生成的.i文件] gcc -E test.c -o test.istep2 : 汇编,将预处理后的文件转换为汇编语言生成.s…...
不确定与非单调推理的可信度方法
可信度方法是肖特里菲(E.H.Shortliffe)等人在确定性理论(Theoryof Comfirmation)的基础上,结合概率论等提出的一种不确定性推理方法,首先在专家系统MYCIN中得到了成功的应用。由于该方法比较直观、简单,而且效果也比较好,因而受到人们的重视。目前,许多专家系统都是基于…...
个人自用-导入安装Hexo
因为本人原来就有备份好的资料,所以重新安装起来会很方便,这个教程也只适合我自己用 但是所有的命令行都要在Git的命令行里面使用(因为我就是这样操作的) 1 安装Git Git的官网 Git git --version 这个是查看Git的版本 git --…...
2025年最新版 Git和Github的绑定方法,以及通过Git提交文件至Github的具体流程(详细版)
文章目录 Git和Github的绑定方法与如何上传至代码仓库一. 注册 GitHub 账号二.如何创建自己的代码仓库:1.登入Github账号,完成登入后会进入如下界面:2.点击下图中红色框选的按钮中的下拉列表3.选择New repostitory4.进入创建界面后࿰…...
Java 动态代理实现
Java 动态代理实现 一、JDK动态代理二、CGLIB动态代理三、动态代理的应用场景四、JDK代理与CGLIB代理比较 动态代理是Java中一种强大的技术,它允许在运行时创建代理对象,用于拦截对目标对象的方法调用。 一、JDK动态代理 JDK动态代理是Java标准库提供的代…...
从零开始搭建CLIP模型实现基于文本的图像检索
目录 CLIP原理简介代码实现参考链接 CLIP原理简介 论文链接,源码链接 CLIP模型由OpenAI在2021年提出,利用双Decoder(Dual Encoder)的架构来学习图像和文本之间的对应关系,是多模态大模型的开创之作,为后续许…...
健康养生之道
在快节奏的现代生活中,健康养生不再是中老年人的专属话题,越来越多的人开始意识到,合理的养生方式是保持良好身体状态和生活质量的关键。 饮食养生是健康的基石。遵循 “食物多样、谷类为主” 的原则,保证每天摄入足够的蔬菜、…...
基于autoware.1.14与gazebo联合仿真进行Hybrid A* 算法规划控制代价地图版
1.首先安装autoware ,大家可以以下一下博客进行安装,如果缺少库什么的直接问ai安装对应的库就行。ubuntu18.04安装Autoware1.14---GPU版 最全环境配置说明_autoware1.14安装教程-CSDN博客 安装成功后运行: source install/setup.bash roslau…...
5G基站设计难题:尺寸、重量、功耗和散热
设计5G基站的工程师们必须应对能源消耗、重量、尺寸和散热等问题,这些因素会影响到设计决策。 5G新空口(NR)采用了多用户大规模多输入多输出(MU-MIMO)技术、集成接入与回传(IAB)技术࿰…...
【leetcode100】分割等和子集
1、题目描述 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11…...
sed命令笔记250419
sed命令笔记250419 sed(Stream Editor)是 Linux/Unix 系统中强大的流编辑器,主要用于对文本进行过滤和转换(按行处理)。它支持正则表达式,适合处理文本替换、删除、插入等操作。以下是 sed 的详细解析&…...
LinearLayout 线性布局
目录 Android LinearLayout(线性布局)简单介绍与使用示例 一、效果介绍 二、布局文件(XML) 三、Java 代码 四、程序运行效果 五、总结 在 Android 移动应用开发中,LinearLayout(线性布局)…...
System.in 详解
System.in 详解 System.in 是 Java 提供的标准输入流(InputStream 类型),默认关联键盘输入,通常用于从控制台读取用户输入。由于它是字节流(InputStream),直接使用较麻烦,一般会配合…...
JAVA IO、BIO、NIO、AIO及零拷贝
概述 IO,常写作 I/O,是 Input/Output 的简称,是 Input/Output 的简称,即输入/输出。通常指数据在内部存储器(内存)和外部存储器(硬盘、优盘等)或其他周边设备之间的输入和输出。 目前有三种 IO 共存。分别是 BIO、NIO 和 AIO。 BIO 全称 Block-IO 是一种同步且阻塞的…...
AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年4月19日第57弹
从今天开始,咱们还是暂时基于旧的模型进行预测,好了,废话不多说,按照老办法,重点8-9码定位,配合三胆下1或下2,杀1-2个和尾,再杀6-8个和值,可以做到100-300注左右。 (1)定…...
REST 架构详解:从概念到应用的全面剖析
REST(Representational State Transfer)即表述性状态转移,是一种用于构建网络应用程序的架构风格和设计理念,由计算机科学家罗伊・菲尔丁(Roy Fielding)在 2000 年提出。以下是关于它的详细介绍:…...
SICAR程序标准功能块 FB1512 “Robot_kuka_FB“
1、FB1512功能块截图 2、FB1512 功能块引脚功能定义 一、输入引脚 EN:使能输入,决定功能块是否执行。IDENTIFIER(WSTRING#"FW010_R01"):设备标识,指定关联的机器人设备。OPMODE_USER_INTERFACE_OUT:操作模式输入,定义机器人工作模式(如手动、自动),数据源…...
win安装软件
win安装软件 jdk安装 jdk安装 首先去官网下载适合系统版本的JDK,下载地址: http://www.oracle.com/technetwork/java/javase/downloads/index.html进入下载页面,如下图: 首先选择:Accept License Agreement单选按钮&…...
文本生成与采样策略 (Text Generation Sampling)
我们已经学习了如何构建和训练一个基于 Transformer Decoder-only 的语言模型。模型训练的目标是学习预测给定前缀下下一个 token 的概率分布。但是,训练完成后,我们如何利用这个模型来生成全新的、连贯的文本呢? 这就涉及到推理过程和采样策略。推理是模型投入实际使用、生…...
为什么 waitress 不支持 WebSocket?
waitress 是一个纯 Python 实现的 WSGI 服务器,主要用于生产环境部署 Python Web 应用。但它不支持 WebSocket 协议,因为它只实现了 WSGI 规范,而 WebSocket 协议需要 ASGI(Asynchronous Server Gateway Interface)支持…...
[C++] 高精度加法(作用 + 模板 + 例题)
高精度加法-目录 高精度加法用途高精度加法模板string转数位数组int 转数位数组(附加型知识点)高精度输出高精度加法函数大合集!!! 高精度加法用途 高精度加法通常用于加很大的数(真的很大, 超unsigned long long的那种). 高精度加法模板 注: 本篇数组下标0(x[0])存储的是该…...
python程序的流程
三大基本流程: 顺序结构、分支结构(又称为选择结构)、循环结构 分支结构又分为单分支、双分支、多分支 从键盘上输入一个数字,并输出奇数或偶数 #从键盘上输入一个数字,并输出奇数或偶数 nint(input("n ")…...
基于大模型的下肢静脉曲张全流程预测与诊疗方案研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 1.3 研究方法与数据来源 二、下肢静脉曲张概述 2.1 定义与病理生理 2.2 风险因素与临床表现 2.3 诊断方法与现有治疗手段 三、大模型预测原理与构建 3.1 大模型技术简介 3.2 预测模型的数据收集与预处理 3.…...
Android 应用wifi direct连接通信实现
一. 打开Wi-Fi direct 1.必须启用Wi-Fi功能:在设备设置中开启Wi-Fi主开关(即使未连接路由器) 关闭冲突功能:若已开启「热点共享」或连接到其他Wi-Fi网络,需先关闭相关功能以避免硬件占. <!-- Wi-Fi Direct 核心权限…...
AI写代码工具分享:Cursor 高效使用攻略与实战秘籍
写在前面 在软件开发领域,效率和生产力是永恒的追求。集成开发环境(IDE)作为开发者的核心工具,其能力直接影响着开发速度和质量。近年来,人工智能(AI)的浪潮席卷了各个行业,编程领域也不例外。Cursor IDE 正是这股浪潮中的佼佼者,它以 AI-First 的理念,在广受欢迎的…...
关于viewpager常见的泄漏
在一个页面中 如果有用到tab,有需要进行fragment的切换,经常就看到了private var fragments arrayListOf<Fragment>()private fun initFragment() {arguments?.let {hopeToPosition it.getInt(IntentConstant.MAIN_PAGE_GO, 0)workoutType it.…...
vue3专题1------父组件中更改子组件的属性
理解 Vue 3 中父组件如何引用子组件的属性是一个很重要的概念。 这里涉及到 defineExpose 和 ref 这两个关键点。 方法:使用 defineExpose 在子组件中暴露属性,然后在父组件中使用 ref 获取子组件实例并访问暴露的属性。 下面我将详细解释这个过程&…...
代谢组数据分析(二十四):基于tidymass包从质谱原始数据到代谢物注释结果的实践指南
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据准备原始数据处理导入massDataset数据对象交互图数据探索更新样本表格信息峰分布情况缺失值情况数据清洗数据质量评估去除噪声代谢特征过滤立群样本填补缺失值数据标准化…...
Java使用javacv实现的多种音视频格式播放器
一、前言 最近写了一款图形界面版的音视频播放器,可以支持多种音视频格式的播放,比如MP4、avi、mkv、flv、MP3、ogg、wav等多种格式,非常好用,可以本地打开多种格式音视频。 二、实现 1.通过引入javacv相关依赖实现,如…...
csdn教程
hello,大家好,我是黑名单小羊,今天给大家分享一下csdn怎么换背景喵~ 成品: 首先,点击管理博文喵~ 然后,把任务栏往下翻喵~ 你就会看见博客设置,点击喵~ 再点击等级,如果你开通了 vip࿰…...
React 第三十三节 ReactRouter 中 useSearchParams 使用详解及注意事项
一、useSearchParams 定义 基本用法 定义:用于返回当前 URL 的 URLSearchParams 的元组和用于更新它们的函数。设置 search params 会导致导航。 import { useSearchParams } from react-router-dom export default function orderCenter() {const [searchParams,…...
@EnableAsync+@Async源码学习笔记之四
接上一篇,我们进入 AsyncAnnotationAdvisor 的分析,源码如下: package org.springframework.scheduling.annotation;import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.LinkedHashSet; import java.util…...
【java实现+4种变体完整例子】排序算法中【快速排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
以下是快速排序的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格: 一、快速排序基础实现 原理 通过分治法选择一个基准元素(pivot),将数组分为两部分: 左边元素均小于…...
MAUI项目iOS应用以进 App Store 分发
目录 一.通过Visual Studio分发应用1. 登录Apple 开发者帐户到 Visual Studio2.创建分发证书和配置文件3. 分发应用4. 在App Store Connect 中创建应用程序记录5. 如果你想使用mac发布应用 一.通过Visual Studio分发应用 1. 登录Apple 开发者帐户到 Visual Studio 首先我们要…...
Linux——firewalld防火墙(笔记)
目录 一:Firewalld防火墙的概述 (1)firewalld简介 (2)firewalld&iptables的关系 (3)firewalld与iptables service的区别 1. 规则管理方式 2. 默认策略与设计逻辑 3. 配置文…...
SICAR标准功能块 FB1514 “Robot_request_FB”
1、功能块截图 2、引脚功能描述 输入引脚: EN:使能输入,控制功能块运行。PLANT_IDENTIFIER:工厂或设备标识符(如 #FWO10_RO1_SEGM_201),用于标识操作对象。OPMODE_USER:操作模式输入(用户模式)。INTERFACE_OUT:连接系统数据库的操作模式接口(SYSTEM_DB.OPmode[2].U…...
vue3 watch和watchEffect 的用法和区别
在 Vue 3 里,watch 和 watchEffect 都是用于响应式数据变化的 API,但它们在使用方法和应用场景上存在差异。下面详细介绍它们的用法和区别。 用法 watch watch 用于监听特定的响应式数据源,当数据源发生变化时,会执行相应的回调…...
Linux | I.MX6ULL 使用 Yocto 文件系统开发 QT
01 Yocto 文件系统默认支持了 QT,那么我们要怎么在 Yocto 文件系统来运行我们的 QT 程序呢?本章节我们就来学习上在 yocto 文件系统+Ubuntu 环境来开发 QT 程序。 注意,开发环境是基于“qtcreator-3.5.1”(Ubuntu16.04.6),库文件是Qt5.5.1 02 QT 安装 (1)首先我们…...
论文阅读:2024 ICLR Workshop. A STRONGREJECT for Empty Jailbreaks
总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 A STRONGREJECT for Empty Jailbreaks https://arxiv.org/pdf/2402.10260 https://github.com/dsbowen/strong_reject https://strong-reject.readthedocs.io/en/latest/ …...
数据结构实验7.2:二叉树的基本运算
文章目录 一,实验目的二,问题描述三,基本要求四,实验操作五,示例代码六,运行效果 一,实验目的 深入理解树与二叉树的基本概念,包括节点、度、层次、深度等,清晰区分二叉…...
关于一对多关系(即E-R图中1:n)中的界面展示优化和数据库设计
前言 一对多,是常见的数据库关系。在界面设计时,有时为了方便,就展示成逗号分割的字符串。例如:学生和爱好的界面。 存储 如果是简单存储,建立数据库:爱好,课程,存在一张表中。 但…...
Jenkins设置中文显示
1 安装插件 依次进入菜单: Jenkins -> Manage Jenkins -> Plugin Manager -> Avaliable 1.1 安装插件Locale plugin 1.2 安装插件Localization: Chinese(Simplified) 2 修改配置 点击菜单Manage Jenkins进入系统管理 点击菜单C…...
【MATLAB海洋专题】历史汇总
【MATLAB海洋专题】历史汇总 目录 01:海洋专题进阶教学 02:海洋数据处理 03:海洋数据下载 04:海洋配色 05:海洋专题基础教学 06: 其他基础画图 07:python 画海图专题 08:模式相关文件制作 01…...
【java实现+4种变体完整例子】排序算法中【归并排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
以下是归并排序的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格: 一、归并排序基础实现 原理 通过分治法将数组分为两半,递归排序子数组,最后合并有序子数组。 代码示例 public class Mer…...
深入理解前端安全:CSRF与XSS攻击详解
引言 在Web开发的世界里,安全性就像是房子的门锁。你可能觉得它不显眼,但一旦没了它,麻烦可就大了!本文将深入探讨两大前端安全威胁:CSRF(跨站请求伪造)和XSS(跨站脚本攻击…...
spring-batch批处理框架(2)
文章目录 八、作业控制8.1 作业启动8.1.1 SpringBoot 启动8.1.2 Spring 单元测试启动8.1.3 RESTful API 启动 8.2 作业停止方案1:Step 步骤监听器方式方案2:StepExecution停止标记 8.3 作业重启8.3.1 禁止重启8.3.2 限制重启次数8.3.3 无限重启 九、Item…...
[Java · 初窥门径] Java 注释符
🌟 想系统化学习 Java 编程?看看这个:[编程基础] Java 学习手册 0x01:Java 注释符简介 在编写程序时,为了使代码易于理解,通常会为代码加一些注释。Java 注释就是用通俗易懂的语言对代码进行描述或解释&a…...