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

QT聊天项目DAY13

1. 重置密码

重置密码label也要实现浮动和点击效果,所以将忘记密码这个标签提升为ClickedLabel

1.1 ClickedLabel的复用

由于样式表(.qss) 文件中可以写入多个控件的状态UI,所以为了ClickedLabel能够复用,将成员变量的初始化方式修改为函数声明

1.2 定义忘记密码标签的样式表

#ForgetLabel[state='normal'],#ForgetLabel[state='selected']
{color:black;
}#ForgetLabel[state='normal_hover'],#ForgetLabel[state='selected_hover']
{color:rgb(42,112,241);
}

样式表设置好以后,对忘记密码这个标签进行提升

在LoginWidget类中设置状态对应的字符串,方便UI的切换

生效

1.2 新建忘记密码界面类

1. 整体设置为垂直布局

2. 在垂直布局中拖进来水平布局

3. 以上面为模板,先拖进来6个水平布局,然后分别在水平布局中设置标签和文本编辑框,每个标签的最大高度和宽度写死,50 * 50

拖入弹簧就能够设置成上述的样子

4. 设置每个控件的名称如下

1.3 忘记密码对应的回调函数

在LoginWidget界面发射信号

在MainWindow界面绑定信号并切换界面

1.4 忘记密码界面类的错误标签刷新样式

1. 根据标签名称添加样式到样式表中

#Tip_Label[state='normal']
{color: green;
}#Tip_Label[state='error']
{color: red;
}

2. 创建标签用来刷新标签的样式

3. 添加错误记录容器,用于存储和刷新文本标签的错误提示

这一段的逻辑和注册窗口里的逻辑一样,代码都是一样的,并且后续的文本框检验的逻辑大致上也一样

这里完全可以继承一个基类,在基类中写,回调函数也可以在基类中写,就比如用户名文本检验 CheckUserValid 可以在基类中声明虚函数,在子类中进行重载即可,甚至可以一部分在基类中写,一部分在子类中写, 只需要在子类中 基类::CheckUserValid 即可

写虚幻C++真的可以提升自己的C++水平,在回头看QTC++有种初中生回忆自己小学上学的体验

1.5 检验密码的合法性

1. 首先绑定文本输入完成的信号槽

2. 实现具体的检验逻辑

2.1 检验用户名是否合理

/* 检验用户名是否合法 */
bool ForgetPwdWidget::CheckUserValid()
{if (ui.UserName_Edit->text().isEmpty()){AddTipErr(TipErr::TIP_USER_ERR, QString::fromLocal8Bit("用户名不能为空"));return false;}/* 一切正常则删除错误提示 */DelTipErr(TipErr::TIP_USER_ERR);return true;
}

2.2 检查邮箱是否合理

/* 检验邮箱是否合法 */
bool ForgetPwdWidget::CheckEmailValid()
{QString emailText = ui.Email_Edit->text();// 邮箱地址的正则表达式QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+)");bool match = regex.match(emailText).hasMatch();if (!match){AddTipErr(TipErr::TIP_EMAIL_ERR, QString::fromLocal8Bit("邮箱格式不正确"));return false;}/* 一切正常则删除错误提示 */DelTipErr(TipErr::TIP_EMAIL_ERR);return true;
}

2.3 检查密码的合理性

/* 检验密码是否合法 */
bool ForgetPwdWidget::CheckPwdValid()
{QString passText = ui.NewPassword_Edit->text();if (passText.length() < 6 || passText.length() > 15){AddTipErr(TipErr::TIP_PWD_ERR, QString::fromLocal8Bit("密码长度必须在6-15位之间"));return false;}/* 密码长度至少6位 可以是字母、数字、特定的特殊字符 */QRegularExpression regExp("^[a-zA-Z0-9!@#$%^&*]{6,15}$");bool match = regExp.match(passText).hasMatch();if (!match){AddTipErr(TipErr::TIP_PWD_ERR, QString::fromLocal8Bit("不能包含非法字符"));return false;}/* 一切正常则删除错误提示 */DelTipErr(TipErr::TIP_PWD_ERR);return true;
}

2.4 检查验证码的合理性

/* 检验验证码是否合法 */
bool ForgetPwdWidget::CheckVerifyCodeValid()
{QString verifyText = ui.VerifyCode_Edit->text();if (verifyText.isEmpty()){AddTipErr(TipErr::TIP_VERIFY_ERR, QString::fromLocal8Bit("验证码不能为空"));return false;}/* 一切正常则删除错误提示 */DelTipErr(TipErr::TIP_VERIFY_ERR);return true;
}

2. 创建基类窗口,派生出注册窗口和忘记密码窗口

基类窗口

#ifndef BASEWIGET_H
#define BASEWIGET_H#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <functional>
#include <QMap>
#include "ClickedLabel.h"
#include "Enum.h"
#include "Global.h"
#include "TimerBtn.h"
#include "ui_BaseWiget.h"class BaseWidget : public QDialog
{Q_OBJECTpublic:BaseWidget(QWidget *parent = nullptr);~BaseWidget();signals:void sigSwitchToLoginPage();																	// 切换到登录界面public slots:/* 检查输入是否合法 */virtual bool CheckUserValid();																	// 检查用户名是否合法virtual bool CheckPasswordValid();																// 检查密码是否合法virtual bool CheckEmailValid();																	// 检查Email是否合法virtual bool CheckVerifyValid();																// 检查验证码是否合法virtual bool CheckEnsureValid();																// 检查确认密码是否合法/* 获取验证码 */virtual void OnGetCodeButtonClicked();/* 确认按钮点击 */virtual void OnConfirmButtonClicked();/* 返回按钮点击 */virtual void OnReturnButtonClicked();/* 注册模块完成时的回调 */virtual void slot_reg_mod_finish(ReqID reqId, QString res, ErrorCodes errCode);public:void ShowTipLabel(const QString& tip, const QString& State);									// 刷新文本提示标签的样式void AddTipErr(TipErr err, const QString& tips);												// 添加错误提示void DelTipErr(TipErr err);																		// 清除错误提示void AnalyzingJsonData(ReqID reqId, QByteArray data);											// 解析Jsonvirtual void BindSlots();virtual void BindSlotsFromEdit();																// 绑定当文本输入完成的槽函数virtual void BindSlotsFromButton();																// 绑定按钮的槽函数virtual void BindSlotsFromClickedLabel();														// 绑定信号槽从ClickedLabel控件virtual void InitHttpHandlers();																// 设置网络回包的回调函数private:Ui::BaseWigetClass ui;public:QLabel* Tip_Label;ClickedLabel* PassWord_Visible;																	// 密码可见ClickedLabel* Ensure_Visible;																	// 确认密码可见QLineEdit* User_LineEdit;																		// 用户名QLineEdit* Password_LineEdit;																	// 密码QLineEdit* Email_LineEdit;																		// EmailQLineEdit* Verify_LineEdit;																		// 验证码QLineEdit* Ensure_LineEdit;																		// 确认密码TimerBtn* GetCode_Button;																	// 获取验证码按钮QPushButton* Confirm_Button;																	// 确认按钮QPushButton* Return_Button;																		// 返回按钮QMap<TipErr, QString> _TipErrs;																	// 错误提示记录QMap<ReqID, std::function<void(const QJsonObject&)>> _handlers;									// 不同类型的回调函数
};#endif // BASEWIGET_H

注册窗口

#ifndef REGISTERWIDGET_H
#define REGISTERWIDGET_H#include "BaseWidget.h"
#include "ui_RegisterWidget.h"class RegisterWidget : public BaseWidget
{Q_OBJECTpublic:RegisterWidget(QWidget *parent = nullptr);~RegisterWidget();public:/* 确认按钮点击 */virtual void OnConfirmButtonClicked() override;/* 返回按钮点击 */void OnReturnButtonClicked();/* 取消按钮点击 */void OnCancelButtonClicked();/* 注册成功跳转到注册提示界面 */void ChangeToTipPage();virtual void BindSlotsFromEdit() override;														// 绑定当文本输入完成的槽函数virtual void BindSlotsFromButton() override;													// 绑定按钮的槽函数virtual void BindSlotsFromClickedLabel() override;												// 绑定信号槽从ClickedLabel控件virtual void InitHttpHandlers() override;														// 设置网络回包的回调函数void InitCountDownTimer();																		// 初始化倒计时器void InitParentControl();																		// 初始化父控件private:Ui::RegisterWidgetClass ui;QTimer* _CountDownTimer;																		// 注册成功倒计时器int _CountDownTime;																				// 倒计时时间
};
#endif // REGISTERWIDGET_H

忘记密码窗口

#ifndef FORGETPWDWIDGET_H
#define FORGETPWDWIDGET_H#include "BaseWidget.h"
#include "ui_ForgetPwdWidget.h"class ForgetPwdWidget : public BaseWidget
{Q_OBJECTpublic:ForgetPwdWidget(QWidget *parent = nullptr);~ForgetPwdWidget();/* 初始化父类控件 */void InitParentControl();public:virtual void InitHttpHandlers() override;											// 设置网络回包的回调函数virtual void BindSlots() override;													// 绑定信号槽virtual void OnConfirmButtonClicked() override;										// 确认按钮点击事件
private:Ui::ForgetPwdWidgetClass ui;
};#endif // FORGETPWDWIDGET_H

2.1 创建忘记密码窗口的Post请求

重点区别在注册窗口的确认按钮发送的QUrl注册用户的Post请求,忘记密码窗口的确认按钮发送的QUrl是重置用户密码的Post请求

忘记密码窗口

注册用户窗口

注册用户窗口的处理服务器响应的回调函数

2.2 服务器处理重置密码请求

重温一遍逻辑

客户端发送请求

这个客户端为了跨平台没有用正常的TCP请求,而是采用Http请求,有一个HttpMannager管理类

而该请求的发送通常是由按钮点击事件触发的,重要的是当服务器处理完成客户端发来的请求回发给客户端的http响应

处理服务器发来的响应

sig_http_finished 绑定的是基类窗口的槽函数,该槽函数是可以重载的,重要的是这个this指针,子类创建对象时绑定的就是子类的,基类的构造函数是空白的

服务器处理请求

在CServer中监听是否有客户端发来Http请求,创建处理连接的对象,该对象从事件循环池中获取一个事件循环,然后向该事件循环中注册要坚挺的HTTP请求的读写事件

/* 实时的监听该端口是否有客户端发来新的HTTP请求 */
void CServer::Start()
{cout << "CServer Thread ID: " << this_thread::get_id() << "\n";auto& IOService = AsioIOServicePool::GetInstance()->GetIOService();HttpConnection* pConnection = new HttpConnection(IOService);								// 创建新的连接对象_acceptor.async_accept(pConnection->GetSocket(), [this, pConnection](boost::system::error_code ec){try {if (ec){Start();																	// 重新监听return;}pConnection->Start();															// 启动连接Start();																		// 继续监听}catch (const std::exception& e) {std::cerr << "CServer::Exception: " << e.what() << "\n";}});
}

注册Http的读事件监听

HttpConnection::HttpConnection(net::io_context& ioContext): _socket(ioContext)
{CheckDeadline();														// 绑定超时的回调
}http::async_read(_socket, _buffer, _request, [this](beast::error_code ec, std::size_t bytes_transferred)

监听到读事件,就处理客户端发来的数据,对Get请求和Post请求区分处理

先看post请求,将数据转发给专门处理登录请求的类去处理,这里不应该用单例了,因为多线程情况下可能会触发使用同一个单例的情况,并且这个类也没有什么特殊的,就是调用function,更应该用静态成员函数吧,或者使用登录对象池以及成员变量的方式

登录逻辑类中处理客户端发来的Post请求,根据url来执行相应的处理函数,其实和直接用if,if的效果一样

bool LogicSystem::HandlePost(std::string url, HttpConnection* connection)
{if (_postHandlers.find(url) == _postHandlers.end())return false;_postHandlers[url](connection);return true;
}

重要的是这个url,和客户端发来的url都对应上了

只需要在添加一个服务器处理客户端重置用户密码的请求即可

增加Mysql的API 分别为检查邮箱以及更新密码

bool MySqlDAO::CheckEmail(const string& username, const string& email)
{auto conn = _pool->getConnection();if (!conn){cout << "Get connection failed" << endl;return false;}// 查询用户邮箱sql::PreparedStatement* stmt = conn->_con->prepareStatement("SELECT email FROM user WHERE name = ?");if (!stmt){cout << "Prepare statement failed" << endl;_pool->retunConnection(conn);return false;}// 传入参数stmt->setString(1, username);// 执行查询sql::ResultSet* res = stmt->executeQuery();// 循环查询结果while (res->next()){cout << "Email: " << res->getString("email") << endl;_pool->retunConnection(conn);if (email != res->getString("email")){cout << "Email not match" << endl;return false;}cout << "Email match" << endl;return true;}cout << "res->next() is Null" << endl;_pool->retunConnection(conn);return false;
}
bool MySqlDAO::UpdataPassword(const string& username, const string& email, const string& password)
{auto conn = _pool->getConnection();if (!conn){cout << "Get connection failed" << endl;return false;}// 更新用户密码sql::PreparedStatement* stmt = conn->_con->prepareStatement("UPDATE user SET pwd = ? WHERE name = ? AND email = ?");if (!stmt){_pool->retunConnection(conn);return false;}// 传入参数stmt->setString(1, password);stmt->setString(2, username);stmt->setString(3, email);// 执行更新int result = stmt->executeUpdate();if (result > 0){cout << "Update password success" << endl;_pool->retunConnection(conn);return true;}cout << "Update password failed" << endl;_pool->retunConnection(conn);return false;
}

再一次封装

添加验证码不匹配的枚举

enum ErrorCodes
{SUCCESS = 0,ERROR_JSON = 1001,																		// Json错误RPC_FAILED = 1002,																		// RPC通信失败ERROR_JSON_KEY_EMAIL_LACK = 1003,														// Json中缺少email字段Verify_Expired = 1004,																	// 验证码过期Verify_Not_Match = 1005,																// 验证码不匹配User_Exists = 1006,																		// 用户已存在Email_Not_Match = 1007,																	// 邮箱不匹配Update_Password_Failed = 1008,															// 更新密码失败
};

完整的重置密码请求代码

/* 用户重置密码 */
RegisterPost("/ResetUserPassword", [](HttpConnection* connection){if (connection){auto bodyStr = boost::beast::buffers_to_string(connection->_request.body().data());	// 获取 Http请求体中的内容cout << "receive body is \n" << bodyStr << endl;connection->_response.set(http::field::content_type, "text/json");					// 设置 Http响应头中的 content-typeJson::Value jsonResonse;															// 响应用的JsonJson::Value jsonResult;																// 请求体解析出来的JsonJson::Reader reader;																// Json解析器bool parseSuccess = reader.parse(bodyStr, jsonResult);								// 将请求体解析为Jsonif (!parseSuccess){cout << "parse json failed" << endl;jsonResonse["error"] = ErrorCodes::ERROR_JSON;									// 设置响应的错误码string jsonStr = jsonResonse.toStyledString();beast::ostream(connection->_response.body()) << jsonStr;						// 向 Http响应体中写入错误码内容return;}/* 查找redis中存储的email对应的验证码是否合理 */string verifyCode = "";bool bGetVerifyCode = RedisManage::GetInstance()->Get(CODE_PREFIX + jsonResult["email"].asString(), verifyCode);if (!bGetVerifyCode){cout << "get verify code Expired " << endl;jsonResonse["error"] = ErrorCodes::Verify_Expired;string jsonStr = jsonResonse.toStyledString();beast::ostream(connection->_response.body()) << jsonStr;return;}/* 判断验证码是否正确 */if (verifyCode != jsonResult["verifyCode"].asString()){cout << "verify code not match" << endl;jsonResonse["error"] = ErrorCodes::Verify_Not_Match;string jsonStr = jsonResonse.toStyledString();beast::ostream(connection->_response.body()) << jsonStr;return;}/* 访问Mysql检查用户名和邮箱是否匹配 */bool bEmailMatch = MySqlManage::GetInstance()->CheckEmail(jsonResult["email"].asString(), jsonResult["user"].asString());if (!bEmailMatch){cout << "user or email not match\n";jsonResonse["error"] = ErrorCodes::Email_Not_Match;string jsonStr = jsonResonse.toStyledString();beast::ostream(connection->_response.body()) << jsonStr;return;}/* 访问Mysql更新用户密码 */bool bUpdatePassword = MySqlManage::GetInstance()->UpdataPassword(jsonResult["email"].asString(), jsonResult["password"].asString());if (!bUpdatePassword){cout << "update password failed\n";jsonResonse["error"] = ErrorCodes::Update_Password_Failed;string jsonStr = jsonResonse.toStyledString();beast::ostream(connection->_response.body()) << jsonStr;return;}/* 返回响应报文给客户端 */jsonResonse["error"] = 0;jsonResonse["email"] = jsonResult["email"];jsonResonse["user"] = jsonResult["user"];jsonResonse["password"] = jsonResult["password"];jsonResonse["verifyCode"] = jsonResult["verifyCode"];string jsonStr = jsonResonse.toStyledString();beast::ostream(connection->_response.body()) << jsonStr;							// 向 Http响应体中写入Json内容return;}else{std::cout << "connection is null" << std::endl;}});

3. 配置新电脑环境

由于在家里学习效率低下的缘故,现在改成在公司学习,重新配置该程序的环境

Boost库没有问题

Json库没有问题

GRPC库没有问题

Mysql连接库没有问题

GRPC-JS库没有问题

使用npm 安装东西出问题了

更换镜像源,已经能够正常安装

// 1. 清空缓存
npm cache clean --force
// 2. 切换新源
npm config set registry https://registry.npmmirror.com
// 3. 查看源是否设置成功
npm config get registry
// 4. 可以正常安装需要的工具了
npm insatll xxx
)

使用npm安装各种库

npm install @grpc/grpc-js
npm install @grpc/proto-loader
npm install nodemailer
npm install redis
npm install ioredis

启动redis服务测试一下

.\redis-server.exe .\redis.windows.conf

连接到redis服务,查看配置文件

监听端口号

监听IP地址,添加一个本机IP地址即可

密码

连接成功

安装MySql

安装地址

在服务中右键Mysql为手动

配置Mysql环境

配置成功

安装Mysql图形化界面

新建数据库

新建user表

新建user_id表

配置完毕,测试注册功能

注册成功

测试忘记密码

返回结果是空的,应该是哪里出问题了,传参出问题了

再次测试

原密码

邮箱匹配但是更新密码失败

修改重置密码逻辑,重置成功

相关文章:

QT聊天项目DAY13

1. 重置密码 重置密码label也要实现浮动和点击效果&#xff0c;所以将忘记密码这个标签提升为ClickedLabel 1.1 ClickedLabel的复用 由于样式表(.qss) 文件中可以写入多个控件的状态UI&#xff0c;所以为了ClickedLabel能够复用&#xff0c;将成员变量的初始化方式修改为函数…...

Web3如何重塑数据隐私的未来

在这个信息爆炸的时代&#xff0c;数据隐私已成为我们不得不面对的严峻问题。Web3&#xff0c;作为下一代互联网的代表&#xff0c;以其去中心化、用户主权和数据安全等特点&#xff0c;正在重塑数据隐私的未来。它不仅仅是技术的革新&#xff0c;更是对个人隐私保护理念的一次…...

【鸿蒙】HarmonyOS NEXT之如何正常加载地图组件

1、不支持模拟器&#xff0c;需要真机&#xff01; 2、Map地图需要在AGC上申请权限&#xff0c;需要在AGC上创建对应的项目 地址&#xff1a; AppGallery Connect 2.1 AGC中项目创建 2.1.1 添加项目 2.1.2 起个名字 2.1.3 添加应用&#xff1a; 2.1.4 选择HarmonyOS APP&…...

前端框架进化史

本内容是对 You’ll Never Manually Update the DOM Again // Here’s Why 内容的翻译与整理。 你再也不需要手工更新DOM, 以下是原因 现代 JavaScript 框架&#xff0c;如 React、Vue、Svelte、Solid、Quick&#xff0c;以及本周推出的其他 786 个框架&#xff0c;都试图做一些…...

“轻量应用服务器” vs. “云服务器CVM”:小白入门腾讯云,哪款“云机”更适合你?(场景、配置、价格对比解析)

更多云服务器知识&#xff0c;尽在hostol.com 当你第一次踏入腾讯云这个“数字百货大楼”&#xff0c;面对琳琅满目的“云产品”&#xff0c;是不是有点眼花缭乱&#xff0c;特别是看到“轻量应用服务器”和“云服务器CVM”这两位都号称能帮你“安家落户”的“云主机”时&…...

day63—回溯—全排列(LeetCode-46)

题目描述 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#xff1a; 输入&#x…...

(二)stm32使用4g模块(移远ec800k)连接mqtt

下面代码是随手写的&#xff0c;没有严谨测试仅供参考测试 uint8_t msgBuf[200]{"msg from mcu"}; uint8_t txBuf[250]{0}; uint16_t msgid0; uint16_t mqttTaskState0; uint16_t t100msCount0; uint8_t sendFlag10; uint8_t sendFlag20; void t100msTask1(void) { …...

防火墙iptables项目实战

目录 一、网络规划 三、环境准备与检测 1、firewall &#xff08;1&#xff09;配置防火墙各大网卡ip并禁用firewalld和selinux &#xff08;2&#xff09;打开firewall路由转发 2、PC1&#xff08;内网&#xff09; &#xff08;1&#xff09;配置ip并禁用firewalld和s…...

webpack继续学习

认识PostCSS工具 PostCSS是一个通过JS来转换样式的工具&#xff0c;这个工具可以帮助我们进行一些CSS的转换和适配&#xff0c;比如自动添加浏览器前缀&#xff0c;css样式的重置 实现这些功能需要借助于PostCSS对应的插件 自动添加浏览器前缀需要&#xff1a; npm install…...

Scrapy爬虫框架Spiders爬虫脚本使用技巧

我们都知道Scrapy是一个用于爬取网站数据、提取结构化数据的Python框架。在Scrapy中&#xff0c;Spiders是用户自定义的类&#xff0c;用于定义如何爬取某个&#xff08;或某些&#xff09;网站&#xff0c;包括如何执行爬取&#xff08;即跟踪链接&#xff09;以及如何从页面中…...

PowerBI企业运营分析—全动态盈亏平衡分析

PowerBI企业运营分析—全动态盈亏平衡分析 欢迎来到Powerbi小课堂&#xff0c;在竞争激烈的市场环境中&#xff0c;企业运营分析平台成为提升竞争力的核心工具。 该平台通过整合多源数据&#xff0c;实现关键指标的实时监控&#xff0c;从而迅速洞察业务动态&#xff0c;精准…...

docker的基本命令

容器的三大组成 镜像image 一个静态文件&#xff0c;特点&#xff1a;分层结构&#xff0c;不可更改 容器container 镜像运行的结果&#xff0c;容器可以修改&#xff0c;运行完后直接停止 仓库registry 用来存放镜像文件的地方 容器的常用命令介绍 关于镜像的命令 docker …...

【运维实战】Rsync将一台主Web服务器上的文件和目录同步到另一台备份服务器!

在管理 Web 服务器时&#xff0c;确保数据安全且在发生故障时能够快速恢复至关重要&#xff0c;备份和镜像 Web 服务器数据最可靠的方法之一是使用 rsync。 Rsync 工具可以帮助在两台服务器之间同步文件和目录&#xff0c;非常适合用于创建 Web 服务器数据的备份和镜像。 下面…...

实时通信RTC与传统直播的异同

实时通信&#xff08;RTC&#xff09;与直播虽然在音视频传输领域密切相关&#xff0c;但设计目标和实现原理是存在显著差异的。 一、核心联系 共同目标&#xff1a;均需实现音视频数据的采集、编码、传输与播放。技术重叠&#xff1a;使用相似的编码标准&#xff08;如H.264/…...

Python-正则表达式(re 模块)

目录 一、re 模块的使用过程二、正则表达式的字符匹配1. 匹配开头结尾2. 匹配单个字符3. 匹配多个字符4. 匹配分组5. Python 代码示例 三、re 模块的函数1. 函数一览表2. Python 代码示例1&#xff09;search 与 finditer2&#xff09;findall3&#xff09;sub4&#xff09;spl…...

AgenticSeek 本地部署教程(Windows 系统)

#工作记录 Fosowl/agenticSeek&#xff1a;完全本地的 Manus AI。 部署排错参考资料在文末 或查找往期笔记。 AgenticSeek 本地部署教程&#xff08;Windows 系统&#xff09; 一、环境准备 1. 安装必备工具 Docker Desktop 下载地址&#xff1a;Docker Desktop 官网 安装后启…...

基于 qiankun + vite + vue3 构建微前端应用实践

核心内容摘要​​ ​​技术栈组合​​ 采用 Vite Vue3 Qiankun 构建微前端架构主应用和子应用独立开发部署&#xff0c;通过 Qiankun 集成 ​​2. 主应用关键配置​​通过 registerMicroApps 注册子应用&#xff0c;配置路由匹配规则&#xff08;activeRule&#xff09;使用…...

VR教育:开启教育新时代的钥匙

VR 教育&#xff0c;即虚拟现实教育&#xff0c;是将虚拟现实技术(Virtual Reality&#xff0c;简称 VR)应用于教育领域的一种创新教育模式。它借助计算机技术、图形图像技术、传感器技术等&#xff0c;创建出高度逼真的虚拟学习环境&#xff0c;让学生通过头戴式显示设备、手柄…...

机器学习:逻辑回归与混淆矩阵

本文目录&#xff1a; 一、逻辑回归Logistic Regression二、混淆矩阵&#xff08;一&#xff09;精确率precision&#xff08;二&#xff09;召回率recall&#xff08;三&#xff09;F1-score&#xff1a;了解评估方向的综合预测能力&#xff08;四&#xff09;Roc曲线&#xf…...

20250602在荣品的PRO-RK3566开发板的Android13下打开HDMI显示

20250602在荣品的PRO-RK3566开发板的Android13下打开HDMI显示 2025/6/2 16:20 缘起&#xff1a;貌似荣品的PRO-RK3566开发板的Android13默认关闭了HDMI显示。 据说&#xff1a;荣品确认RK3566的GPU比较弱&#xff0c;同时开【MIPI接口的】LCD屏显示和HDMI显示容易出现异常。 更…...

【学习记录】快速上手 PyQt6:设置 Qt Designer、PyUIC 和 PyRCC 在 PyCharm中的应用

文章目录 &#x1f4cc; 前言✅ 第一步&#xff1a;安装 PyQt6 及其工具包&#x1f527; 第二步&#xff1a;找到相关工具路径&#x1f9f0; 第三步&#xff1a;在 PyCharm 中配置外部工具打开设置&#x1f6e0;️ 配置 Qt Designer&#x1f6e0;️ 配置 PyUIC6&#xff08;UI转…...

AI在网络安全领域的应用现状和实践

当前&#xff0c;人工智能技术已深度融入网络安全产品&#xff0c;推动传统防御模式向智能化、自适应方向加速演进。各安全厂商通过机器学习、深度学习与知识图谱等技术的融合应用&#xff0c;提高安全产品在威胁检测、攻击溯源、风险评估等场景的能力跃迁&#xff0c;突破传统…...

DrissionPage 异常处理实战指南:构建稳健的网页自动化防线

在网页自动化领域&#xff0c;异常处理能力直接决定了系统的健壮性。作为融合Selenium与Requests特性的创新工具&#xff0c;DrissionPage提供了多层次的异常处理机制。本文将深入剖析其异常体系&#xff0c;结合真实场景案例&#xff0c;为您构建一套完善的自动化容错方案。 …...

鸿蒙任务项设置案例实战

目录 案例效果 资源文件与初始化 string.json color.json CommonConstant 添加任务 首页组件 任务列表初始化 任务列表视图 任务编辑页 添加跳转 任务目标设置模型&#xff08;formatParams&#xff09; 编辑页面 详情页 任务编辑列表项 目标设置展示 引入目标…...

TDengine 的 AI 应用实战——运维异常检测

作者&#xff1a; derekchen Demo数据集准备 我们使用公开的 NAB数据集 里亚马逊 AWS 东海岸数据中心一次 API 网关故障中&#xff0c;某个服务器上的 CPU 使用率数据。数据的频率为 5min&#xff0c;单位为占用率。由于 API 网关的故障&#xff0c;会导致服务器上的相关应用…...

DHCP与DNS的配置

在网络管理中&#xff0c;DHCP&#xff08;动态主机配置协议&#xff09;和DNS&#xff08;域名系统&#xff09;是两个关键组件。DHCP用于自动分配IP地址&#xff0c;而DNS用于将域名解析为IP地址。本文将详细介绍如何在Linux环境下配置DHCP和DNS服务。 一、DHCP配置 1. 安装…...

使用Plop.js高效生成模板文件

前情 开发是个创造型的职业&#xff0c;也是枯燥的职业&#xff0c;因为开发绝大多数都是每天在业务的代码中无法自拨&#xff0c;说到开发工作&#xff0c;就永远都逃不开新建文件的步骤&#xff0c;特别现在组件化开发胜行&#xff0c;每天都是在新建新建组件的道路上一去不…...

Vue框架2(vue搭建方式2:利用脚手架,ElementUI)

一.引入vue第二种搭建方式 在以前的前端项目中,一个项目需要多个html文件实现页面之前的切换,如果页面中需要依赖js或者css文件,那么我们就需要在多个html文件中都需要导入vue.js文件,太过繁琐. 现在前端开发都采用单页面结果,一个项目中只有一个html文件 其他不同的内容都写…...

mac 设置cursor (像PyCharm一样展示效果)

一、注册 Cursor - The AI Code Editor 二、配置Python环境 我之前使用pycharm创建的python项目&#xff0c;以及创建了虚拟环境&#xff0c;现在要使用cursor继续开发。 2.1 选择Python 虚拟环境 PyCharm 通常将虚拟环境存储在项目目录下的 venv 或 .venv 文件夹中&#xf…...

SpringCloudAlibaba微服务架构

技术架构图 SpringCloudAlibaba微服务架构 说明&#xff1a; 1.1、采用SpringCloudAlibaba分布式微服务架构&#xff0c;使用Nginx做代理&#xff0c;服务治理使用Nacos组件&#xff0c;Gateway网关做权限验证、路由、过滤。 1.2、Redis做消息缓存&#xff0c;包括数据大屏、数…...