AJAX项目——数据管理平台

黑马程序员视频地址:

黑马程序员——数据管理平台

前言 

功能:

1.登录和权限判断

2.查看文章内容列表(筛选,分页)

3.编辑文章(数据回显)

4.删除文章

5.发布文章(图片上传,富文本编辑器)

技术:

1.基于Bootstrap 搭建网站标签和样式

2.集成wangEditor 插件实现富文本编辑器

3.使用原生JS 完成增删改查等业务

4.基于axios 与黑马头条线上接口交互

5.使用axios 拦截器进行权限判断

项目准备:

准备配套的素材代码
包含:html,css,js,静态图片,第三方插件等等

数据管理平台模板代码.zip文件大小:13.5 M|https://user-a001.lanzouv.com/ijtSu2mp9i9ghttps://user-a001.lanzouv.com/ijtSu2mp9i9ghttps://user-a001.lanzouv.com/ijtSu2mp9i9ghttps://user-a001.lanzouv.com/ijtSu2mp9i9ghttps://user-a001.lanzouv.com/ijtSu2mp9i9ghttps://user-a001.lanzouv.com/ijtSu2mp9i9ghttps://user-a001.lanzouv.com/ijtSu2mp9i9g

接口文档:

欢迎使用 - B站-AJAX和黑马头条-数据管理平台 

目录管理:
• assets:资源文件夹(图片,字体等)
• lib:资料文件夹(第三方插件,例如:form-serialize)
• page:页面文件夹
• utils:实用程序文件夹(工具插件)


验证码登录

1.在utils/request.js中配置基地址

// axios 公共配置
// 基地址
axios.defaults.baseURL = "http://geek.itheima.net" 

2.登录按钮代码

document.querySelector(".btn").addEventListener("click", () => {const form = document.querySelector(".login-form")const data = serialize(form, {hash: true, empty: true})axios({url: "/v1_0/authorizations",method: "POST",data}).then(result => {myAlert(true, "登录成功!")}).catch(error => {myAlert(false, error.response.data.message)})
})

token

token 的介绍


token 的使用

1. 在utils/auth.js 中判断无 token 令牌字符串,则强制跳转到登录页(手动修改地址栏测试)

/*** 目标1:访问权限控制* 1.1 判断无 token 令牌字符串,则强制跳转到登录页* 1.2 登录成功后,保存 token 令牌字符串到本地,并跳转到内容列表页面*/
const token = localStorage.getItem("token")
if(!token)
{alert("请先登录!")setTimeout(() => {location.href = "../login/index.html"}, 1500)
}

2. 在登录成功后,保存token 令牌字符串到本地,再跳转到首页(手动修改地址栏测试)

then(result => {//存入tokenlocalStorage.setItem("token", result.data.data.token)//提示框myAlert(true, "登录成功!")//1.5s后跳转新页面setTimeout(() => {location.href = "../content/index.html"}, 1500)})

axios 请求拦截器和个人信息设置

1. 什么是axios 请求拦截器?

✓ 发起请求之前,调用的一个函数,对请求参数进行设置

2. axios 请求拦截器,什么时候使用?

✓ 有公共配置和设置时,统一设置在请求拦截器中

官方文档:

拦截器 | Axios中文文档 | Axios中文网https://www.axios-http.cn/docs/interceptorshttps://www.axios-http.cn/docs/interceptorshttps://www.axios-http.cn/docs/interceptorshttps://www.axios-http.cn/docs/interceptorshttps://www.axios-http.cn/docs/interceptorshttps://www.axios-http.cn/docs/interceptorshttps://www.axios-http.cn/docs/interceptors

1.在utils/request.js文件中配置

// 添加请求拦截器
axios.interceptors.request.use(function (config) {// 在发送请求之前做些什么const token = localStorage.getItem("token")token && (config.headers.Authorization = `Bearer ${token}`)return config
}, function (error) {// 对请求错误做些什么return Promise.reject(error);
})

2.在utils/auth.js 中请求个人信息并设置到页面

/*** 目标2:设置个人信息* 2.1 在 utils/request.js 设置请求拦截器,统一携带 token* 2.2 请求个人信息并设置到页面*/
axios({url: "/v1_0/user/profile"
}).then(result => {const username = result.data.data.namedocument.querySelector(".nick-name").innerText = username
}).catch(error => {console.log(error)
})

axios 响应拦截器和身份验证失败

1. 什么是axios 响应拦截器?
✓ 响应回到then/catch 之前,触发的拦截函数,对响应结果统一处理
2. axios 响应拦截器,什么时候触发成功/失败的回调函数?
✓ 状态为2xx触发成功回调,其他则触发失败的回调函数

// 添加响应拦截器
axios.interceptors.response.use(function (response) {// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么response = response.data    //⭐️数据优化,得到的response是服务器数据+axios修饰后的代码,//而response.data是服务器返回的数据,将服务器返回的数据直接返回给then中//如上文代码中的result.data.data.name,如果此处返回response,则调用result.data.data.name//如果此处返回response.data,则调用result.data.namereturn response    //⭐️response会传进.then(result => {})中,由result接收
}, function (error) {// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么⭐️if(error?.response?.status === 401){alert("身份验证过期,请重新登录!")localStorage.clear()location.href = "../login/index.html"}return Promise.reject(error)    //⭐️error会传进.catch(error => {})中,由error接收
})

发布文章

富文本编辑器

官方手册:

wangEditor 5https://www.wangeditor.com/v5/getting-started.htmlhttps://www.wangeditor.com/v5/getting-started.htmlhttps://www.wangeditor.com/v5/getting-started.htmlhttps://www.wangeditor.com/v5/getting-started.htmlhttps://www.wangeditor.com/v5/getting-started.htmlhttps://www.wangeditor.com/v5/getting-started.htmlhttps://www.wangeditor.com/v5/getting-started.html手册中有完整步骤

1.引入CSS:在相应页面(publish/index.css)引入CSS

/* 富文本编辑器 */ 
#editor—wrapper {border: 1px solid #ccc;z-index: 100; /* 按需定义 */}#toolbar-container {border-bottom: 1px solid #ccc;}#editor-container {height: 500px;}

2.定义HTML:在需要部署的页面(publish/index.html)放置HTML代码

<!-- 富文本编辑器位置 -->
<div id="editor—wrapper"><div id="toolbar-container"><!-- 工具栏 --></div><div id="editor-container"><!-- 编辑器 --></div>
</div>
<!-- 记录富文本内容-用于表单收集 -->
<textarea name="content" class="publish-content" hidden></textarea>

3.引入 JS 创建编辑器:在utils/editor.js中放入代码

// 富文本编辑器
// 创建编辑器函数,创建工具栏函数
const { createEditor, createToolbar } = window.wangEditor// 编辑器配置对象
const editorConfig = {// 占位提示文字placeholder: '发布文章内容...',// 编辑器变化时回调函数onChange(editor) {// 获取富文本内容const html = editor.getHtml()// 也可以同步到 <textarea>// 为了后续快速收集整个表单内容做铺垫document.querySelector('.publish-content').value = html}
}// 创建编辑器
const editor = createEditor({// 创建位置selector: '#editor-container',// 默认内容html: '<p><br></p>',// 配置项config: editorConfig,// 配置集成模式(default 全部)(simple 简洁)mode: 'default', // or 'simple'
})// 工具栏配置对象
const toolbarConfig = {}// 创建工具栏
const toolbar = createToolbar({// 为指定编辑器创建工具栏editor,// 工具栏创建的位置selector: '#toolbar-container',// 工具栏配置对象config: toolbarConfig,// 配置集成模式mode: 'default', // or 'simple'
})

4.引入文件:在publish/index.html中引入script(黑马程序员已经帮我们引入过了)

<!--引入 CSS 定义样式-->
<linkhref="https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css"rel="stylesheet"
/><!--引入 JS 创建编辑器-->
<script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script>

频道列表

目标1:设置频道下拉菜单
1.1 获取频道列表数据
1.2 展示到下拉菜单中 

//publish/index.jsasync function getChannels()
{//请求数据const channelsData  = await axios({url: "/v1_0/channels"})//拼接数据const channelsHTML = `<option value="" selected="">请选择文章频道</option>` + channelsData.data.data.channels.map(item => `<option value="${item.id}" >${item.name}</option>`).join("")//渲染数据document.querySelector(".form-select").innerHTML = channelsHTML
}
getChannels()

封面设置

目标2:文章封面设置
2.1 准备标签结构和样式
2.2 选择文件并保存在 FormData
2.3 单独上传图片并得到图片 URL 网址
2.4 回显并切换 img 标签展示(隐藏 + 号上传标签) 

document.querySelector(".img-file").addEventListener("change", async e => {//获取本地上传照片数据const file = e.target.files[0]//实例化表单对象const fd = new FormData()//添加image属性,并放入图片数据fd.append("image", file)//上传数据,返回照片地址const res = await axios({url: "/v1_0/upload",method: "POST",data: fd})const imgUrl = res.data.data.url//渲染到本地document.querySelector(".rounded").src = imgUrl  //照片回显document.querySelector(".rounded").classList.add("show") //显示照片盒子document.querySelector(".place").classList.add("hide")  //隐藏加号盒子
})//⭐️点击图片,模拟点击上传图片按钮,从而再次调用代码
document.querySelector(".rounded").addEventListener("click", () => {document.querySelector(".img-file").click()
})

收集并保存

目标3:发布文章保存
3.1 基于 form-serialize 插件收集表单数据对象
3.2 基于 axios 提交到服务器保存
3.3 调用 Alert 警告框反馈结果给用户
3.4 重置表单并跳转到列表页 

document.querySelector(".send").addEventListener("click", async e => {//⭐️编辑功能留空1//获取表单const form = document.querySelector(".art-form")//获取表单数据const data = serialize(form, {hash: true, empty: true})//⭐️删除id字段数据delete data.id//获取图片数据data.cover = {type: 1, images: [document.querySelector(".rounded").src]}//上传数据try{const result = await axios({url: "/v1_0/mp/articles",method: "POST", data})//调用 Alert 警告框反馈结果给用户myAlert(true, "发布成功!")//清除表单form.reset()//清除图片document.querySelector(".rounded").src = ``  //清除图片数据document.querySelector(".rounded").classList.remove("show") //隐藏照片盒子document.querySelector(".place").classList.remove("hide")  //显示加号盒子//⭐️清除富文本框内容editor.setHtml('')//跳转文章列表页面setTimeout(() => {location.href = "../content/index.html"}, 1500)}catch(error){//调用 Alert 警告框反馈结果给用户myAlert(false, error.response.data.message)}})

内容管理

文章列表展示

目标1:获取文章列表并展示
1.1 准备查询参数对象
1.2 获取文章列表数据
1.3 展示到指定的标签结构中 

标⭐️为代码留空区域,在对应功能模块编写时会添加 

// 1.准备查询参数对象
const queryObj = {status: '', // 文章状态(1-待审核,2-审核通过)空字符串-全部channel_id: '', // 文章频道 id,空字符串-全部page: 1, // 当前页码per_page: 10 // 当前页面条数
}//⭐️分页功能留空1async function getArtileList() {//2.获取文章列表数据const res = await axios({url: '/v1_0/mp/articles',params: queryObj})//3.展示到指定的标签结构中const htmlStr = res.data.data.results.map(item => `<tr><td><img src="${item.cover.type === 0 ? `https://img2.baidu.com/it/u=2640406343,1419332367&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=708&amp;h=500`: item.cover.images[0]}" alt=""></td><td>${item.title}</td><td>${item.status === 1 ? `<span class="badge text-bg-primary">待审核</span>` : `<span class="badge text-bg-success">审核通过</span>`}</td><td><span>${item.pubdate}</span></td><td><span>${item.read_count}</span></td><td><span>${item.comment_count}</span></td><td><span>${item.like_count}</span></td><td "⭐️删除功能留空1"><i class="bi bi-pencil-square edit"></i><i class="bi bi-trash3 del"></i></td>
</tr>`).join('')document.querySelector('.art-list').innerHTML = htmlStr//⭐️分页功能留空2}
getArtileList()

筛选功能

目标2:筛选文章列表
2.1 设置频道列表数据
2.2 监听筛选条件改变,保存查询信息到查询参数对象
2.3 点击筛选时,传递查询参数对象到服务器
2.4 获取匹配数据,覆盖到页面展示 

//1.设置频道列表数据
async function getChannels()
{//请求数据const channelsData  = await axios({url: "/v1_0/channels"})//拼接数据const channelsHTML = `<option value="" selected="">请选择文章频道</option>` + channelsData.data.data.channels.map(item => `<option value="${item.id}" >${item.name}</option>`).join("")//渲染数据document.querySelector(".form-select").innerHTML = channelsHTML
}
getChannels()//2.监听筛选条件改变,保存查询信息到查询参数对象
//状态
document.querySelectorAll(".form-check").forEach(item => {item.addEventListener("change", e => {queryObj.status = e.target.value})
})//频道
document.querySelector(".form-select").addEventListener("change", e => {queryObj.channel_id = e.target.value
})
//3.点击筛选时,传递查询参数对象到服务器,并获取匹配数据,覆盖到页面展示
document.querySelector(".sel-btn").addEventListener("click", () => {getArtileList()
})

分页功能

目标3:分页功能
3.1 保存并设置文章总条数
3.2 点击下一页,做临界值判断,并切换页码参数并请求最新数据
3.3 点击上一页,做临界值判断,并切换页码参数并请求最新数据 

//————————————————————————1.代码写在文章列表展示中——————————————————————————————//1.1保存文章总条数(对应留空1)let totalCount = 0 //1.2获取文章总条数(对应留空2)totalCount = res.data.total_countdocument.querySelector('.total-count').innerHTML = `共 ${totalCount} 条`
//————————————————————————————————————————————————————————————————————————————//2.点击下一页
document.querySelector(".next").addEventListener("click", () => {//判断是否可以进行下一页:当前页码小于总页码(总页码=(总条数/每一页最大条数)向上取整)if(queryObj.page < Math.ceil(totalCount / queryObj.per_page)){      //页码自增queryObj.page++ //页面显示当前页码document.querySelector(".page-now").innerHTML = `第 ${queryObj.page} 页`  //更新数据getArtileList() }
})//3.点击上一页
document.querySelector('.last').addEventListener('click', e => {// 大于 1 的时候,才能翻到上一页if (queryObj.page > 1) {//页码自减queryObj.page--//页面显示当前页码document.querySelector('.page-now').innerHTML = `第 ${queryObj.page} 页`//更新数据getArtileList()}
})

删除功能

目标4:删除功能
4.1 关联文章 id 到删除图标
4.2 点击删除时,获取文章 id
4.3 调用删除接口,传递文章 id 到服务器
4.4 删除最后一页的最后一条,需要自动向前翻页 
4.5 重新获取文章列表,并覆盖展示

//————————————————————————1.关联文章 id————————————————————————//留空1补自定义属性data-id="${item.id}"//——————————————————————————————————————————————————————————————————————
//2.点击删除时,获取文章 id
document.querySelector(".art-list").addEventListener("click", async e => {if(e.target.classList.contains("del")){//2.获取idconst delId = e.target.parentNode.dataset.id//3.调用删除接口,传递文章 id 到服务器const res = await axios({url: `/v1_0/mp/articles/${delId}`,method: "DELETE"})//4.删除最后一页的最后一条,需要自动向前翻页//获取子元素数组const children = document.querySelector(".art-list").children//判断子元素数组长度等于1并且当前页码数不等于1if(children.length === 1 && queryObj.page !== 1){//页码自减queryObj.page--//页面显示当前页码document.querySelector('.page-now').innerHTML = `第 ${queryObj.page} 页`}//5.重新获取并渲染数据getArtileList()}
})

编辑功能

回显文章 

目标4:编辑-回显文章

4.1 页面跳转传参(URL 查询参数方式)

4.2 发布文章页面接收参数判断(共用同一套表单)

4.3 修改标题和按钮文字

4.4 获取文章详情数据并回显表单

//content/index.js//1.点击编辑时,获取文章 id,跳转到发布文章页面传递文章 id 过去
document.querySelector(".art-list").addEventListener("click", e => {//判断是否点击编辑按钮if(e.target.classList.contains("edit")){//获取idconst editId = e.target.parentNode.dataset.id//跳转到发布页面,并传递idlocation.href = `../publish/index.html?id=${editId}`}})
//publish/index.js
//使用立即执行函数(IIFE)创建一个独立的作用域,避免变量污染全局作用域
;(function(){//⭐️获取网页中携带的参数const paramsStr = location.search//⭐️实例化内置对象(用来处理?后面内容的对象)const params = new URLSearchParams(paramsStr)params.forEach(async (value, key) => {//判断是否含有id参数if(key === "id"){//修改页面文字document.querySelector(".title span").innerHTML = "修改文章"document.querySelector(".send").innerHTML = "修改"//获取文章详情const res = await axios({url: `/v1_0/mp/articles/${value}`})//整理需要用的值//方法一:解构// const {channel_id, title, cover:{images:[image]}, content, id} = res.data.data//方法二:创立新对象挨个赋值(本篇选择此方法)const dataObj = {channel_id: res.data.data.channel_id,title: res.data.data.title,image: res.data.data.cover.images[0],content: res.data.data.content,id: res.data.data.id}console.log(dataObj)//数据渲染Object.keys(dataObj).forEach(key => {if(key === "image"){document.querySelector(".rounded").src = dataObj[key]  //照片回显document.querySelector(".rounded").classList.add("show") //显示照片盒子document.querySelector(".place").classList.add("hide")  //隐藏加号盒子}else if(key === "content"){//设置富文本编辑框内容editor.setHtml(dataObj[key])}else{//利用name选择器赋值document.querySelector(`[name=${key}]`).value = dataObj[key]}}) }})
})();

保存文章 

目标5:编辑-保存文章

5.1 判断按钮文字,区分业务(因为共用一套表单)

5.2 调用编辑文章接口,保存信息到服务器

5.3 基于 Alert 反馈结果消息给用户

//区分发布按钮与修改按钮
//——————————————————————发布文章/收集并保存中的留空1代码————————————————————————————//判断是否为发布按钮if(e.target.innerHTML != "发布") return
//————————————————————————————————————————————————————————————————————————————————
document.querySelector(".send").addEventListener("click", async e => {//判断是否为修改按钮if(e.target.innerHTML !== "修改") return//获取表单对象const form = document.querySelector(".art-form")//使用serialize插件获取表单数据const data = serialize(form, {hash: true, empty: true})//提交数据try{const res = await axios({url: `/v1_0/mp/articles/${data.id}`,method: "PUT",data:{...data,cover:{type: document.querySelector(".rounded").src ? 1 : 0,images: [document.querySelector(".rounded").src]}}})//成功弹窗myAlert(true, "修改成功!")//返回内容管理页面setTimeout(() =>{location.href = "../content/index.html"}, 1500)}catch(error){//异常弹窗myAlert(false, error.response.data.message)}
})

退出登录 

目标3:退出登录

3.1 绑定点击事件

3.2 清空本地缓存,跳转到登录页面

//utils/auth.js//绑定事件
document.querySelector(".quit").addEventListener("click", () => {//清空本地缓存localStorage.clear()//提示框myAlert(true, "退出成功!即将返回登陆页面!")//跳转登录页面setTimeout(() => {location.href ="../login/index.html"}, 1500)
})

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

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

相关文章

html转PDF文件最完美的方案(wkhtmltopdf)

目录 需求 一、方案调研 二、wkhtmltopdf使用 如何使用 文档简要说明 三、后端服务 四、前端服务 往期回顾 需求 最近在做报表类的统计项目&#xff0c;其中有很多指标需要汇总&#xff0c;网页内容有大量的echart图表&#xff0c;做成一个网页去浏览&#xff0c;同时…

示例:JAVA调用deepseek

近日&#xff0c;国产AI DeepSeek在中国、美国的科技圈受到广泛关注&#xff0c;甚至被认为是大模型行业的最大“黑马”。在外网&#xff0c;DeepSeek被不少人称为“神秘的东方力量”。1月27日&#xff0c;DeepSeek应用登顶苹果美国地区应用商店免费APP下载排行榜&#xff0c;在…

.NET周刊【2月第1期 2025-02-02】

国内文章 dotnet 9 已知问题 默认开启 CET 导致进程崩溃 https://www.cnblogs.com/lindexi/p/18700406 本文记录 dotnet 9 的一个已知且当前已修问题。默认开启 CET 导致一些模块执行时触发崩溃。 dotnet 使用 ColorCode 做代码着色器 https://www.cnblogs.com/lindexi/p/…

AES200物理机部署DeepSeek-R1蒸馏模型

AES200物理机部署DeepSeek-R1模型 华为官方官宣自己的NPU支持DeepSeek-R1模型部署&#xff0c;华为的大模型推理部署依托于其大模型推理引擎&#xff1a;MindIE&#xff0c;但是根据MindIE的文档&#xff0c;其只支持以下硬件&#xff1a; 表1 MindIE支持的硬件列表 类型配置…

【后端开发】系统设计101——Devops,Git与CICD,云服务与云原生,Linux,安全性,案例研究(30张图详解)

【后端开发】系统设计101——Devops&#xff0c;Git与CICD&#xff0c;云服务与云原生&#xff0c;Linux&#xff0c;安全性&#xff0c;案例研究&#xff08;30张图详解&#xff09; 文章目录 1、DevopsDevOps与SRE与平台工程的区别是什么&#xff1f;什么是k8s&#xff08;Ku…

正泰中间电磁继电器【8脚10A】DC24V 待机功率

需求&#xff1a;继电器能耗测试。 1.连接24V2A的电源&#xff0c; 2. 稳定功率为 1.4W 3. 正泰中间电磁继电器【8脚10A】直流DC24V 注&#xff1a;联通时电磁继电器会轻微发热 4.电磁继电器的工作原理基于电流的磁效应 电磁激励&#xff1a;电磁继电器主要由线圈、铁芯、衔…

npm无法加载文件 因为此系统禁止运行脚本

安装nodejs后遇到问题&#xff1a; 在项目里【node -v】可以打印出来&#xff0c;【npm -v】打印不出来&#xff0c;显示npm无法加载文件 因为此系统禁止运行脚本。 但是在winr&#xff0c;cmd里【node -v】,【npm -v】都也可打印出来。 解决方法&#xff1a; cmd里可以打印出…

JVM春招快速学习指南

1.说在前面 在Java相关岗位的春/秋招面试过程中&#xff0c;JVM的学习是必不可少的。本文主要是通过《深入理解Java虚拟机》第三版来介绍JVM的学习路线和方法&#xff0c;并对没有过JVM基础的给出阅读和学习建议&#xff0c;尽可能更加快速高效的进行JVM的学习与秋招面试的备战…

认识Electron 开启新的探索世界一

一、Electron轻松入门 1.搭建开发环境&#xff1a; 一般情况下开发者会使用node.js来创建electron项目&#xff0c;node.js是一个基于Chrome V8引擎的javascript运行环境&#xff0c;所以首先需要到官网去下载安装node.js 下载链接&#xff1a;https://nodejs.org/enhttps://no…

MySQL下载过程

MySQL Enterprise Edition Downloads | Oracle mysql官方下载网址&#xff08;9.2版本&#xff09; 下面的示例是5.7的包&#xff0c;过程是一样的 port&#xff1a;3308&#xff08;默认的是3306&#xff0c;笔者下了一个占用了该端口&#xff09; root&#xff1a;123456 问题…

【学术投稿】第五届计算机网络安全与软件工程(CNSSE 2025)

重要信息 官网&#xff1a;www.cnsse.org 时间&#xff1a;2025年2月21-23日 地点&#xff1a;中国-青岛 简介 第五届计算机网络安全与软件工程&#xff08;CNSSE 2025&#xff09;将于2025年2月21-23日在中国-青岛举行。CNSSE 2025专注于计算机网络安全、软件工程、信号处…

Qt:QWidget核心属性

目录 QWidget核心属性 enab geometry WindowFrame的影响 windowTitle windowIcon qrc文件管理资源 windowOpacity cursor font toolTip focusPolicy styleSheet QWidget核心属性 在Qt中使用QWidget类表示"控件"&#xff0c;如按钮、视图、输入框、滚动…

Linux TCP 编程详解与实例

一、引言 在网络编程的领域中&#xff0c;TCP&#xff08;Transmission Control Protocol&#xff09;协议因其可靠的数据传输特性而被广泛应用。在 Linux 环境下&#xff0c;使用 C 或 C 进行 TCP 编程可以实现各种强大的网络应用。本文将深入探讨 Linux TCP 编程的各个方面&…

论文笔记:Rethinking Graph Neural Networks for Anomaly Detection

目录 摘要 “右移”现象 beta分布及其小波 实验 《Rethinking Graph Neural Networks for Anomaly Detection》&#xff0c;这是一篇关于图&#xff08;graph&#xff09;上异常节点诊断的论文。 论文出处&#xff1a;ICML 2022 论文地址&#xff1a;Rethinking Graph Ne…

神经网络常见激活函数 6-RReLU函数

文章目录 RReLU函数导函数函数和导函数图像优缺点pytorch中的RReLU函数tensorflow 中的RReLU函数 RReLU 随机修正线性单元&#xff1a;Randomized Leaky ReLU 函数导函数 RReLU函数 R R e L U { x x ≥ 0 a x x < 0 \rm RReLU \left\{ \begin{array}{} x \quad x \ge 0…

Vue(6)

一.路由板块封装 &#xff08;1&#xff09;路由的封装抽离 目标&#xff1a;将路由板块抽离出来 好处&#xff1a;拆分板块&#xff0c;利于维护 // 路由的使用步骤 5 2 // 5个基础步骤 // 1. 下载 v3.6.5 // 2. 引入 // 3. 安装注册 Vue.use(Vue插件) // 4. 创建路由对象…

【python】matplotlib(animation)

文章目录 1、matplotlib.animation1.1、FuncAnimation1.2、修改 matplotlib 背景 2、matplotlib imageio2.1、折线图2.2、条形图2.3、散点图 3、参考 1、matplotlib.animation 1.1、FuncAnimation matplotlib.animation.FuncAnimation 是 Matplotlib 库中用于创建动画的一个…

【东莞常平】戴尔R710服务器不开机维修分享

1&#xff1a;2025-02-06一位老客户的朋友刚开工公司ERP服务器一台戴尔老服务器故障无法开机&#xff0c;于是经老客户介绍找到我们。 2&#xff1a;服务器型号是DELL PowerEdge R710 这个服务器至少也有15年以上的使用年限了。 3&#xff1a;客户反馈的故障问题为&#xff1a;…

Spring AI -使用Spring快速开发ChatGPT应用

前言 Spring在Java生态中一直占据大半江山。最近我发现Spring社区推出了一个Spring AI项目&#xff0c;目前该项目还属于Spring实验性项目&#xff0c;但是我们可以通过该项目&#xff0c;可以非常快速的开发出GPT对话应用。 本篇文章将会对SpringAI进行简单的介绍和使用&#…

经典排序算法复习----C语言

经典排序算法复习 分类 交换类 冒泡快排 分配类 计数排序基数排序 选择类 选择排序 堆排序 归并类 归并排序 插入类 直接插入排序 希尔排序 折半插入排序 冒泡排序 基于交换。每一轮找最大值放到数组尾部 //冒泡排序 void bubSort(int* arr,int size){bool sorte…