vue+springboot实验个人信息,修改密码,忘记密码功能实现

前端部分

新增Person(个人页面),Password(修改密码页面),还需要对Manager,login页面进行修改

router文件夹下的index.js:

 

import Vue from 'vue'
import VueRouter from 'vue-router'
import Manager from '../views/Manager.vue'
// 解决导航栏或者底部导航tabBar中的vue-router在3.0版本以上频繁点击菜单报错的问题。
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (location) {return originalPush.call(this, location).catch(err => err)
}
Vue.use(VueRouter)const routes = [{path: '/',name: 'manager',component: Manager,children:[{path:'home',name:'Home',meta:{ name:'系统首页' },component:()=>import('../views/manager/Home.vue')},{path:'user',name:'User',meta:{ name:'用户信息' },component:()=>import('../views/manager/User.vue')},{path:'403',name:'Auth',meta:{ name:'无权限' },component:()=>import('../views/Auth.vue')},{path:'Person',name:'person',meta:{ name:'个人信息' },component:()=>import('../views/manager/Person.vue')},{path:'Password',name:'password',meta:{ name:'修改密码' },component:()=>import('../views/manager/Password.vue')}],redirect:'/home'},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')},{path:'/login',name:'login',meta:{ name:'登录' },component: ()=>import('../views/login.vue')},{path:'/register',name:'register',meta:{ name:'注册' },component: ()=>import('../views/register.vue')},{path:'*',name:'404',meta:{ name:'无法访问' },component: ()=>import('../views/404.vue')}
]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})
router.beforeEach((to,from,next)=>{let adminPaths=['/user']let user=JSON.parse(localStorage.getItem('honey-user')||'{}')if(user.role !== '管理员' && adminPaths.includes(to.path)){next('/403')}else{next()}
})
export default router

Person.vue

<template><div><el-card style="width: 50%"><el-form :model="user" label-width="80px" style="padding-right: 20px"><div style="margin: 15px;text-align: center"><el-uploadclass="avatar-uploader"action="http://localhost:9090/file/upload":headers="{ token: user.token }":show-file-list="false":on-success="handleAvatarSuccess"><img v-if="user.avatar" :src="user.avatar" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon"></i></el-upload></div><el-form-item label="用户名" prop="username"><el-input v-model="user.username" disabled></el-input></el-form-item><el-form-item label="姓名" prop="name"><el-input v-model="user.name"></el-input></el-form-item><el-form-item label="电话" prop="phone"><el-input v-model="user.phone"></el-input></el-form-item><el-form-item label="邮箱" prop="email"><el-input v-model="user.email"></el-input></el-form-item><el-form-item label="地址" prop="address"><el-input type="textarea" v-model="user.address"></el-input></el-form-item></el-form><div style="text-align: center;margin-bottom: 20px"><el-button type="primary" @click="update">保存</el-button></div></el-card></div>
</template><script>
export default {data(){return{user:JSON.parse(localStorage.getItem('honey-user'||'{}'))}},methods:{update(){this.$request.put('/user/update',this.user).then(res=>{if(res.code==='200'){this.$message.success('保存成功')localStorage.setItem('honey-user',JSON.stringify(this.user))this.$emit('update:user',this.user)}else{this.$message.error(res.msg)}})},handleAvatarSuccess(response,file,fileList){console.log(response)this.user.avatar=response.data}}
}
</script><style scoped>
/deep/.el-form-item__label{font-weight: bold;
}
/deep/.el-upload{border-radius: 50%;
}
/deep/.avatar-uploader .el-upload {border: 1px dashed #d9d9d9;cursor: pointer;position: relative;overflow: hidden;border-radius: 50%;
}
/deep/.avatar-uploader .el-upload:hover {border-color: #409EFF;
}
.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;border-radius: 50%;
}
.avatar {width: 178px;height: 178px;display: block;border-radius: 50%;
}
</style>

Password.vue:

<template><div><el-card style="width: 50%"><el-form ref="fromRef" :model="user" label-width="80px" style="padding-right: 20px" :rules="rules"><el-form-item label="原始密码" prop="password"><el-input v-model="user.password" show-password></el-input></el-form-item><el-form-item label="新密码" prop="newPassword"><el-input v-model="user.newPassword"></el-input></el-form-item><el-form-item label="确认密码" prop="confirmPassword"><el-input v-model="user.confirmPassword"></el-input></el-form-item><div style="text-align: center;margin-bottom: 20px"><el-button type="primary" @click="update">确认修改</el-button></div></el-form></el-card></div>
</template><script>
export default {data(){const validatePassword = (rule, value, callback) => {if (value === '') {callback(new Error('请输入确认密码'));} else if(value !== this.user.newPassword){callback(new Error('两次密码不一致'));} else {callback();}};return{user:JSON.parse(localStorage.getItem('honey-user'||'{}')),rules:{password:[{required:true,message:'请输入原始密码',trigger:'blur'}],newPassword:[{required:true,message:'请输入新密码',trigger:'blur'}],confirmPassword:[{validator:validatePassword,required:true,trigger:'blur',}]}}},methods:{update(){this.$refs.fromRef.validate((valid)=>{if(valid){this.user.password=this.user.newPasswordthis.$request.put('/user/update',this.user).then(res=>{if(res.code==='200'){this.$message.success('保存成功')this.$router.push('/login')}else{this.$message.error(res.msg)}})}})},}
}
</script><style scoped>
/deep/.el-form-item__label{font-weight: bold;
}
</style>

 Manager.vue:

<template><div><el-container><!--    侧边栏  --><el-aside :width="asideWidth" style="min-height: 100vh; background-color: #001529"><div style="height: 60px; color: white; display: flex; align-items: center; justify-content: center"><img src="@/assets/logo1.png" alt="" style="width: 40px; height: 40px"><span class="logo-title" v-show="!isCollapse">honey2024</span></div><el-menu :collapse="isCollapse" :collapse-transition="false" router background-color="#001529" text-color="rgba(255, 255, 255, 0.65)" active-text-color="#fff" style="border: none" :default-active="$route.path"><el-menu-item index="/home"><i class="el-icon-s-home"></i><span slot="title">系统首页</span></el-menu-item><el-submenu index="info" v-if="user.role === '管理员'"><template slot="title"><i class="el-icon-menu"></i><span>信息管理</span></template><el-menu-item index="/user">用户信息</el-menu-item></el-submenu></el-menu></el-aside><el-container><!--        头部区域--><el-header><i :class="collapseIcon" style="font-size: 26px" @click="handleCollapse"></i><el-breadcrumb separator-class="el-icon-arrow-right" style="margin-left: 20px"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item :to="{ path: $route.path }">{{ $route.meta.name }}</el-breadcrumb-item></el-breadcrumb><div style="flex: 1; width: 0; display: flex; align-items: center; justify-content: flex-end"><i class="el-icon-quanping" style="font-size: 26px" @click="handleFull"></i><el-dropdown placement="bottom"><div style="display: flex; align-items: center; cursor: default"><img :src="user.avatar||'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'" alt="" style="width: 40px; height: 40px; margin: 0 5px;border-radius: 50%"><span>{{user.name}}</span></div><el-dropdown-menu slot="dropdown"><el-dropdown-item @click.native="$router.push('/person')">个人信息</el-dropdown-item><el-dropdown-item @click.native="$router.push('/password')">修改密码</el-dropdown-item><el-dropdown-item @click.native="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></div></el-header><!--        主体区域--><el-main><router-view @update:user="updateUser"></router-view></el-main></el-container></el-container></div>
</template><script>
import axios from "axios";
import request from '@/utils/request'export default {name: 'HomeView',data() {return {isCollapse: false,  // 不收缩asideWidth: '200px',collapseIcon: 'el-icon-s-fold',user:JSON.parse(localStorage.getItem('honey-user')||'{}'),}},mounted() {// axios.get('http://localhost:9090/user/selectall').then(res=>{//   console.log(res.data);//   this.users=res.data.data// })// request.get('/user/selectall').then(res => {//   this.users = res.data// })},methods: {updateUser(user){this.user=JSON.parse(JSON.stringify(user))},handleFileUpload(response,file,fileList){this.fileList=fileListconsole.log(response,file,fileList)},logout() {localStorage.removeItem("honey-user")this.$router.push('/login')},handleFull() {document.documentElement.requestFullscreen()},handleCollapse() {this.isCollapse = !this.isCollapsethis.asideWidth = this.isCollapse ? '64px' : '200px'this.collapseIcon = this.isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'}}
}
</script><style>
.el-menu--inline {background-color: #000c17 !important;
}.el-menu--inline .el-menu-item {background-color: #000c17 !important;padding-left: 49px !important;
}.el-menu-item:hover, .el-submenu__title:hover {color: #fff !important;
}.el-submenu__title:hover i {color: #fff !important;
}.el-menu-item:hover i {color: #fff !important;
}.el-menu-item.is-active {background-color: #1890ff !important;border-radius: 5px !important;width: calc(100% - 8px);margin-left: 4px;
}.el-menu-item.is-active i, .el-menu-item.is-active .el-tooltip {margin-left: -4px;
}.el-menu-item {height: 40px !important;line-height: 40px !important;
}.el-submenu__title {height: 40px !important;line-height: 40px !important;
}.el-submenu .el-menu-item {min-width: 0 !important;
}.el-menu--inline .el-menu-item.is-active {padding-left: 45px !important;
}/*.el-submenu__icon-arrow {*/
/*  margin-top: -5px;*/
/*}*/.el-aside {transition: width .3s;box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
}.logo-title {margin-left: 5px;font-size: 20px;transition: all .3s; /* 0.3s */
}.el-header {box-shadow: 2px 0 6px rgba(0, 21, 41, .35);display: flex;align-items: center;
}
</style>

login.vue:

<template><div style="display: flex;align-items: center;justify-content: center;background-color: aquamarine;height: 100vh;"><div style="display: flex;width: 50%;background-color: white;border-radius: 5px;overflow: hidden;"><div style="flex: 1;"><img src="@/assets/login.png" alt="" style="width: 100%;"></div><div style="flex: 1;display: flex;align-items: center;justify-content: center;"><el-form :model="user" style="width: 80%;" :rules="rules" ref="loginRef"><div style="font-weight: bold; font-size: 20px;margin-bottom: 20px;text-align: center;">欢迎登陆后台管理系统</div><el-form-item prop="username"><el-input placeholder="请输入用户名" v-model="user.username" prefix-icon="el-icon-user"></el-input></el-form-item><el-form-item prop="password"><el-input placeholder="请输入密码" v-model="user.password" show-password prefix-icon="el-icon-lock"></el-input></el-form-item><el-form-item prop="code"><div style="display: flex;"><el-input prefix-icon="el-icon-circle-check" v-model="user.code"></el-input><div style="flex: 1;height: 32px"><valid-code @update:value="getCode"></valid-code></div></div></el-form-item><el-form-item><el-button type="primary" style="width: 100%;" @click="login">登录</el-button></el-form-item><div style="display: flex;"><div style="flex: 1;">还没有账号?去<span style="color:aquamarine;cursor: pointer;" @click="$router.push('/register')">注册</span></div><div style="flex: 1;text-align: right;cursor: pointer;color: aquamarine;" @click="handleForgetPass">忘记密码</div></div></el-form></div></div><el-dialog title="忘记密码" :visible.sync="forgetPassDialogVis" width="30%"><el-form :model="forgetUserForm" label-width="80px" style="padding-right: 20px"><el-form-item label="用户名"><el-input v-model="forgetUserForm.username" autocomplete="off"></el-input></el-form-item><el-form-item label="手机号"><el-input v-model="forgetUserForm.phone" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="forgetPassDialogVis = false">取 消</el-button><el-button type="primary" @click="resetPassword">确 定</el-button></div></el-dialog></div>
</template><script>
import ValidCode from "@/components/ValidCode.vue";
export default {name:'login',components:{ValidCode},data() {const validateCode = (rule, value, callback) => {if (value === '') {callback(new Error('请输入验证码'));} else if(value.toLowerCase() !== this.code){callback(new Error('验证码错误'));} else {callback();}};return {forgetUserForm:{},forgetPassDialogVis:false,code:'',user: {code:'',username: '',password: ''},rules:{username:[{required:'true',message:'请输入账号',trigger:'blur'}],password:[{required:'true',message:'请输入密码',trigger:'blur'}],code:[{validator:validateCode,trigger:'blur'}]},}},methods:{handleForgetPass(){this.forgetUserForm={}this.forgetPassDialogVis=true},getCode(code){this.code=code.toLowerCase()},resetPassword(){this.$request.put('/password',this.forgetUserForm).then(res=>{if(res.code==='200'){this.$message.success('密码重置成功')this.forgetPassDialogVis=false}else{this.$message.error(res.msg)}})},login(){this.$refs['loginRef'].validate((valid=>{if(valid){this.$request.post("/login",this.user).then(res=>{if(res.code === '200'){this.$router.push('/')this.$message.success('登录成功')localStorage.setItem('honey-user',JSON.stringify(res.data))}else{this.$message.error(res.msg)}console.log(res);})}}))}}
}
</script><style scoped></style>

后端部分 

只需要为忘记密码编写一个新接口即可:

 WebController:

package com.example.springboot.controller;import cn.hutool.core.util.StrUtil;
import com.example.springboot.common.AuthAccess;
import com.example.springboot.common.Result;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.service.UserService;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController
public class WebController {@ResourceUserService userService;@AuthAccess@GetMapping("/")public Result hello(){return Result.success("success");}@PostMapping("/login")public Result login(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPassword())){return Result.error("数据输入错误");}user=userService.login(user);return Result.success(user);}@AuthAccess@PostMapping("/register")public Result register(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPassword())){throw new ServiceException("输入不合法");}if(user.getUsername().length()>10||user.getPassword().length()>20){throw new ServiceException("长度过长");}user=userService.register(user);return Result.success(user);}@AuthAccess@PutMapping("/password")public Result password(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPhone())){throw new ServiceException("输入不合法");}userService.resetPassword(user);return Result.success();}
}

 UserService:

package com.example.springboot.service;import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.UserMapper;
import com.example.springboot.utils.TokenUtils;
import jdk.nashorn.internal.parser.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;import java.util.List;@Service
public class UserService {@AutowiredUserMapper userMapper;public void insertUser(User user){userMapper.insert(user);}public void updateUser(User user) {userMapper.updateUser(user);}public void deleteUser(Integer id) {userMapper.deleteUser(id);}public void batchdeleteUser(List<Integer> ids) {for(Integer id : ids){userMapper.deleteUser(id);}}public List<User> selectall() {return userMapper.selectall();}public User selectbyid(Integer id) {return userMapper.selectbyid(id);}public List<User> selectbyname(String name) {return userMapper.selectbyname(name);}public List<User> selectbymore(String username, String name) {return userMapper.selectbymore(username,name);}public List<User> selectbymo(String username, String name) {return userMapper.selectbymo(username,name);}public User login(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser == null){throw new ServiceException("账号不存在");}if(!user.getPassword().equals(dbuser.getPassword())){throw new ServiceException("账号或者密码错误");}String token=TokenUtils.createToken(dbuser.getId().toString(),dbuser.getPassword());dbuser.setToken(token);return dbuser;}public User register(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser != null){throw new ServiceException("用户名已存在");}userMapper.insert(user);return user;}public void resetPassword(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser==null){throw new ServiceException("用户不存在");}if(!user.getPhone().equals(dbuser.getPhone())){throw new ServiceException("验证错误");}dbuser.setPassword("123");userMapper.updateUser(dbuser);}
}

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

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

相关文章

视频下载为什么需要大带宽服务器?

视频直播已经成为人们日常生活中的常见形式之一。而在视频直播过程中&#xff0c;为什么需要大带宽呢&#xff1f;本文将深入探讨视频直播中为什么需要大带宽的原因。 视频直播的特点 视频直播是通过互联网进行实时视频传输的方式&#xff0c;与传统的视频点播相比&#xff0c;…

在 vue3 中使用高德地图

前言&#xff1a;定位地图位置所需要的经纬度&#xff0c;可以通过 拾取坐标 获取。 一&#xff1a;快速上手 1. 安装依赖 npm install amap/amap-jsapi-loader # or pnpm add amap/amap-jsapi-loader # or yarn add amap/amap-jsapi-loader 2. 创建组件 src/components/Ma…

飞书小技巧:markdown导出

文章目录 下载Feishu2Md飞书应用配置配置feishu2md工具绑定应用导出markdown 下载Feishu2Md Feishu2Md 飞书应用配置 进入飞书开发者后台 https://open.feishu.cn/app。 点击“创建企业自建应用”&#xff0c;并填写应用名称等信息。而后点击创建。 PS: 此处作者创建应用名…

C++ | Leetcode C++题解之第42题接雨水

题目&#xff1a; 题解&#xff1a; class Solution { public:int trap(vector<int>& height) {int n height.size();if (n 0) {return 0;}vector<int> leftMax(n);leftMax[0] height[0];for (int i 1; i < n; i) {leftMax[i] max(leftMax[i - 1], he…

网络安全之数据库基础篇(基础入门)

目录 一&#xff0c;操作数据库 1&#xff0c;查询所有数据库 2&#xff0c;创建数据库 3&#xff0c;查看数据库是否被创建 4&#xff0c;查看数据库的字符集 5&#xff0c;修改数据库的字符集 6&#xff0c;删除数据库 7&#xff0c;使用数据库 8&#xff0c;查看当前…

【Linux系统编程】

Linux系统编程 一.文件编程1.常用API1.1 打开&#xff1a;open1.2 读写&#xff1a;write/read1.3 光标定位: lseek1.4 创建&#xff1a;creat1.4 关闭&#xff1a;close 2.文件的打开及创建3.文件的写入4.文件的读取5.文件描述符5.代码实现cp指令6.编程实现修改文件配置7.写一…

计算机视觉与深度学习 | 基于特征的图像配准技术(全景图像拼接)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 基于特征的图像配准技术(全景图像拼接) 图像加载特征提取与图像配准初…

学习JavaEE的日子 Day40 反射案例

Day40 1.反射案例 之 万能数组扩容 public class Test01 {public static void main(String[] args) {String[] ss {"小希","小空","小丽","小光","小爱"};String[] newSS MyArrays.copyOf(ss, 8);System.out.println(My…

实现Node.js安装与配置。

一 、Node.js简介 Node.js是一个基于Chrome V8引擎的JavaScript运行时环境&#xff0c;用于构建高性能、可扩展的网络应用程序。它发布于2009年5月&#xff0c;由Ryan Dahl开发&#xff0c;允许使用JavaScript进行服务器端编程&#xff0c;使开发者能够在前后端都使用同一种编程…

Unity 新版输入系统(Input System)

前言 官方教程 注意 新的输入系统需要 Unity 2019.4 和 .NET 4 运行时。它不适用于 .NET 3.5 的项目。 教程版本&#xff1a;Unity 2021.3.26 1. 安装 1.1 打开 Package Manager 导航栏 -> Window -> Package Manager 1.2 安装 Input System 选择 Unity Registry 在列…

RabbitMQ, DelayQueue, Redis的介绍以及IDEA的实现

RabbitMQ RabbitMQ是一个开源的消息队列中间件&#xff0c;它实现了高效、可靠的消息传递机制。它支持多种消息传递模式&#xff0c;如发布/订阅、点对点、请求/回应等。RabbitMQ以其可靠性、灵活性和易用性受到广泛的关注和应用。 RabbitMQ基于AMQP&#xff08;Advanced Mess…

字符串刷题(day1)题解

文章目录 字符串刷题一、Erase First or Second Letter二、Swap and Reverse三、Largest Subsequence四、XOR Palindromes五、Strong Password六、Row Major七、Game with Reversing八、Tear It Apart 字符串刷题 vjudge题单 一、Erase First or Second Letter [Erase First…

孙中亮:北斗三十周年,看北斗芯片高质量发展历程和方向

1994年1月10日&#xff0c;北斗一号建设正式启动&#xff0c;党中央决策建设独立自主的北斗卫星导航系统。2020年7月31日&#xff0c;北斗三号全球卫星导航系统正式开通&#xff0c;标志着北斗系统进入全球化发展新阶段。随着2024年的到来&#xff0c;北斗系统建设已走过栉风沐…

汇智知了堂走进宜宾学院,共话国产化信创未来!

在春意盎然的四月&#xff0c;汇智知了堂以其深厚的品牌底蕴和卓越的教育品质&#xff0c;再次展现了其在教育领域的领先地位。4月18日&#xff0c;汇智知了堂走进宜宾学院&#xff0c;为广大学子带来了一场关于国产化信创时代的技术变革与专业学习建议的讲座。 汇智知了堂作…

前端 -- if-else嵌套地狱

要解决 if-else 嵌套地狱问题&#xff0c;可以考虑以下几种方法&#xff1a; 1. 使用早返回&#xff08;Early Return&#xff09;&#xff1a; 尽早返回函数&#xff0c;避免深层嵌套。 将条件判断简化为多个独立的 if 语句&#xff0c;每个 if 语句处理一种情况。 2. 使用…

2024深圳杯(东三省)数学建模挑战赛D题:音板的振动模态分析与参数识别思路代码成品论文分析

​ 更新完整代码和成品完整论文 《2024深圳杯&东三省数学建模思路代码成品论文》↓↓↓ https://www.yuque.com/u42168770/qv6z0d/zx70edxvbv7rheu7?singleDoc# 问题重述 深圳杯&#xff08;东三省&#xff09;数学建模挑战赛2024D题&#xff1a;音板的振动模态分析与…

YoloV9改进策略:注意力改进、Neck层改进_自研全新的Mamba注意力_即插即用,简单易懂_附结构图_检测、分割、关键点均适用(独家原创,全世界首发)

摘要 无Mamba不狂欢,本文打造基于Mamba的注意力机制。全世界首发基于Mamba的注意力啊!对Mamba感兴趣的朋友一定不要错过啊! 基于Mamba的高效注意力代码和结构图 import torch import torch.nn as nn # 导入自定义的Mamba模块 from mamba_ssm import Mamba class Eff…

vue做导入导出excel文档

系统中经常会遇到要实现批量导入/导出数据的功能&#xff0c;导入就需要先下载一个模板&#xff0c;然后在模板文件中填写内容&#xff0c;最后导入模板&#xff0c;导出就可能是下载一个excel文件。 1、导出 新建一个export.js文件如下&#xff1a; import {MessageBox,Mes…

赋能数据检索:构建用于www.sohu.com的新闻下载器

引言 在信息爆炸的时代&#xff0c;随着新闻数据的数量不断增长&#xff0c;获取和分析这些数据变得尤为关键。本文将介绍如何构建一个高效的新闻下载器&#xff0c;专门用于从搜狐网&#xff08;www.sohu.com&#xff09;检索和下载新闻内容。 背景介绍 搜狐网作为中国领先…

区块链和IPFS安全测试工具;ECC+AES混合加密机制:秘钥管理

目录 区块链和IPFS安全测试工具 区块链测试工具:Caliper,BlockEmulator IPFS测试工具:Testgrou