Skip to content
Merged

Fix2 #87

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
8 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ set(SHARED_SOURCES
view/RegisterCenter/changepasswordadmin.cpp
view/RegisterCenter/changepasswordadmin.h
view/RegisterCenter/changepasswordadmin.ui
module/scanner/DbCaculator.cpp
module/scanner/DbCaculator.h
)
list(REMOVE_DUPLICATES SHARED_SOURCES)

Expand Down
2 changes: 2 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
#include "view/RegisterCenter/checknewuser.h"
#include "view/SplashScreen/nativesplash.h"
//#include "view/SplashScreen/splashscreen.h"
#include "module/scanner/DbCaculator.h"
#include "module/scanner/WorkAlert.h"

void setup_tasks() {
// 后台定时每1分钟扫描库存告警
service::taskManager::getTimer().scheduleTask(60000, []() {
bot::InventoryAlert::sendAlert();
bot::WorkAlert::sendAdminCheckNewUserAlert();
bot::DbCaculator::reCaculate();
});
}

Expand Down
38 changes: 36 additions & 2 deletions module/data/data_EquipmentManage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,9 @@ namespace data::Equipment {
QString queryString = "SELECT id, class_id FROM equipment_instance WHERE name = ?";
QVariantList params = {devName};

// 使用你已有的 executePreparedQueryAndFetchAll 函数
auto queryResult = db.executePreparedQueryAndFetchAll(queryString, params);

if (!queryResult.isEmpty()) {
// 假设设备名称是唯一的,我们只取第一个结果
QVariantMap row = queryResult.first();
result.id = row["id"].toInt();
result.class_id = row["equipment_class_id"].toInt();
Expand Down Expand Up @@ -353,6 +351,42 @@ namespace data::Equipment {

return newId;
}

QList<EquipmentClassRecord> searchEquClassList(QString keyword) {
service::DatabaseManager db(service::Path::equipment());
QString queryString = R"(
SELECT
id,
name,
description,
created_at,
total_amount,
usable_amount,
alarm_amount
FROM
equipment_class
WHERE status != 'deleted' AND (name LIKE ? OR description LIKE ?)
)";

auto results = db.executePreparedQueryAndFetchAll(queryString, {
"%" + keyword + "%", "%" + keyword + "%"
});

QList<EquipmentClassRecord> records;
for (const auto &row: results) {
EquipmentClassRecord rec;
rec.id = row["id"].toInt();
rec.name = row["name"].toString();
rec.description = row["description"].toString();
rec.created_at = row["created_at"].toDateTime();
rec.total_amount = row["total_amount"].toInt();
rec.usable_amount = row["usable_amount"].toInt();
rec.alarm_amount = row["alarm_amount"].toInt();
records.append(rec);
}
return records;
}

// 新增:删除设备类别(软删除,设置status为deleted)
bool deleteEquipmentClass(int classId) {
service::DatabaseManager db(service::Path::equipment());
Expand Down
3 changes: 3 additions & 0 deletions module/data/data_EquipmentManage.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ namespace data::Equipment {
* @return 如果创建成功,返回新记录的ID;如果失败,返回 -1。
*/
int addEquipmentClass(const EquipmentClassRecord &record);

QList<EquipmentClassRecord> searchEquClassList(QString keyword);

}

namespace EquipmentInstnace {
Expand Down
41 changes: 41 additions & 0 deletions module/data/data_UserControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,18 @@ namespace data::UserControl {
return results.first()["id"].toInt();
}

std::expected<int, UserInfoError> getIdNumberById(int Id) {
service::DatabaseManager db(service::Path::user());
QString query = "SELECT id_number FROM users WHERE id = ? AND status != 'Deleted'";
auto results = db.executePreparedQueryAndFetchAll(query, {Id});

if (results.isEmpty()) {
return std::unexpected(UserInfoError::UserNotFound);
}

return results.first()["id_number"].toInt();
}

void changeUserName(int userId, const QString &newName) {
service::DatabaseManager db(service::Path::user());
QString updateQuery = R"(
Expand Down Expand Up @@ -847,6 +859,17 @@ namespace data::UserControl {
return true;
}

bool deleteUser(int userId) {
service::DatabaseManager db(service::Path::user());
QString query = R"(
UPDATE users SET status = 'Deleted' WHERE id = ? AND status = 'AllRight'
)";
if (!db.executePreparedNonQuery(query, {userId})) {
return false;
}
return true;
}

bool rejectUserRegister(int userId) {
service::DatabaseManager db(service::Path::user());
QString query = R"(
Expand All @@ -869,5 +892,23 @@ namespace data::UserControl {
}
return results.first()["status"].toString();
}

QList<int> searchUserIdByNameOrIdNumber(QString keyword) {
service::DatabaseManager db(service::Path::user());
QString query = R"(
SELECT id FROM users
WHERE status != 'Deleted'
AND (username LIKE ? OR id_number LIKE ?)
)";
auto results = db.executePreparedQueryAndFetchAll(query, {
{"%" + keyword + "%","%" + keyword + "%"}
});

QList<int> userIds;
for (const auto &row: results) {
userIds.append(row["id"].toInt());
}
return userIds;
}
}
}
7 changes: 7 additions & 0 deletions module/data/data_UserControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ namespace data::UserControl {

std::expected<int, UserInfoError> getIdByIdNumber(QString IdNumber);

std::expected<int, UserInfoError> getIdNumberById(int Id);

/**
* @brief 更改指定用户的用户名。
*
Expand Down Expand Up @@ -313,9 +315,14 @@ namespace data::UserControl {
bool banUser(int userId);

bool unbanUser(int userId);

bool deleteUser(int userId);

bool rejectUserRegister(int userId);

QString getUserStatus(int userId);

QList<int> searchUserIdByNameOrIdNumber(QString keyword);
}
}

Expand Down
16 changes: 16 additions & 0 deletions module/scanner/DbCaculator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Created by gouzuang on 25-7-14.
//

#include "DbCaculator.h"

#include "module/data/data_EquipmentManage.h"

namespace bot::DbCaculator {
void reCaculate() {
auto equipmentClasses = data::Equipment::EquipmentClass::getEquClassList();
for (const auto &classItem : equipmentClasses) {
int classId = classItem.id;
data::Equipment::EquipmentClass::recalculateClassCounts(classId);
}}
}
10 changes: 10 additions & 0 deletions module/scanner/DbCaculator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// Created by gouzuang on 25-7-14.
//

#ifndef DBCACULATOR_H
#define DBCACULATOR_H
namespace bot::DbCaculator {
void reCaculate();
}
#endif //DBCACULATOR_H
5 changes: 0 additions & 5 deletions tests/test_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ private slots:
QVERIFY2(dbManager.isConnected(), "数据库管理器在构造后应该处于连接状态");
QVERIFY2(QFile::exists(testDbPath), "数据库文件应该被创建");
} // dbManager 在这里被销毁,析构函数被调用

// Assert (after destruction)
// 验证连接是否已被清理。一个简单的验证方法是再次尝试使用相同的连接名(内部实现),
// 如果清理成功,则不会有问题。或者,我们可以假设析构函数工作正常。
// 对于这个测试,我们主要信任 isConnected 的准确性。
}

void testNonQueryExecution() {
Expand Down
2 changes: 2 additions & 0 deletions view/EquipmentClass/equipmentclassdetail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace view::EquipmentClass {
ui->UsableNum->setText("0");
ui->listWidget->clear();

data::Equipment::EquipmentClass::recalculateClassCounts(m_classId);


// 连接信号,当用户输入名称时,检查是否可以创建
connect(ui->EquName, &QLineEdit::textChanged, this, &EquipmentClassDetail::check_can_create);
Expand Down
41 changes: 40 additions & 1 deletion view/EquipmentClass/equipmentclassmanagehomepage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,49 @@ void EquipmentClassManageHomepage::on_addButton_clicked() {
}

void EquipmentClassManageHomepage::on_refreshButton_clicked() {
m_totalPages = data::UserControl::check::getAllUserCount() / m_itemsPerPage + 1;
m_totalPages = (data::Equipment::EquipmentClass::getEquClassCount() / m_itemsPerPage) + 1;
m_currentPage = 1;
loadEquipmentClasses();
}

void EquipmentClassManageHomepage::on_lineEdit_returnPressed() {
auto keyword = ui->lineEdit->text().trimmed();
auto records = data::Equipment::EquipmentClass::searchEquClassList(keyword);

ui->scrollAreaWidgetContents->setUpdatesEnabled(false);

auto *layout = qobject_cast<QVBoxLayout *>(ui->scrollAreaWidgetContents->layout());
if (!layout) {
layout = new QVBoxLayout(ui->scrollAreaWidgetContents);
layout->setSpacing(5);
layout->setAlignment(Qt::AlignTop);
layout = qobject_cast<QVBoxLayout *>(ui->scrollAreaWidgetContents->layout());
if (!layout) {
log(LogLevel::ERR) << "错误:布局创建后仍然为空!";
return; // 提前退出以避免崩溃
}
}

// 清除现有的消息块
QLayoutItem *child;
while ((child = layout->takeAt(0)) != nullptr) {
delete child->widget();
delete child;
}

// 为每个设备分类记录创建信息块
for (const auto &record: records) {
auto *block = new EquipmentClassBlock(record); // 创建信息块实例
layout->addWidget(block);
}

m_totalPages = 1;
m_currentPage = 1;
updatePaginationControls();
// 加载完数据后更新分页控件
ui->scrollAreaWidgetContents->setUpdatesEnabled(true);
}

void EquipmentClassManageHomepage::updatePaginationControls() {
if (m_totalPages == 0) {
ui->pageLabel->setText("0 / 0");
Expand Down
2 changes: 2 additions & 0 deletions view/EquipmentClass/equipmentclassmanagehomepage.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace view::EquipmentClass {
void on_addButton_clicked();
void on_refreshButton_clicked();

void on_lineEdit_returnPressed();

private:
Ui::EquipmentClassManageHomepage *ui;

Expand Down
38 changes: 36 additions & 2 deletions view/EquipmentClass/equipmentclassmanagehomepage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="addButton">
<property name="styleSheet">
Expand Down Expand Up @@ -301,6 +301,40 @@ QPushButton {
<string>刷新</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="styleSheet">
<string notr="true">QLineEdit {
/* 基础样式:几乎透明的背景,细微的浅色边框 */
background-color: rgba(255, 255, 255, 10); /* 几乎全透明的白色背景,数值越低越透明 */
color: black; /* 文字颜色保持黑色,确保可见性 */
border: 1px solid rgba(192, 192, 192, 50); /* 极淡的边框,几乎不可见但有存在感 */
border-radius: 4px; /* 圆角与之前风格统一 */
padding: 5px 8px; /* 内边距 */
font-size: 10pt;
min-height: 24px; /* 高度 */
}

QLineEdit:hover {
/* 鼠标悬停时:边框稍微明显一点 */
border: 1px solid rgba(160, 160, 160, 100); /* 边框略微显现 */
}

QLineEdit:focus {
/* 聚焦时:背景变为白色,边框高亮为蓝色 */
background-color: white; /* 聚焦时背景变为不透明白色 */
border: 1px solid #0078D4; /* 边框高亮为熟悉的蓝色 */
outline: none; /* 移除默认的焦点虚线框 */
}

/* 占位符文本样式 */
QLineEdit::placeholder {
color: rgba(0, 0, 0, 120); /* 占位符文本略带透明度的黑色,确保可见 */
}
</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
Expand Down Expand Up @@ -353,7 +387,7 @@ QPushButton {
<x>0</x>
<y>0</y>
<width>539</width>
<height>445</height>
<height>442</height>
</rect>
</property>
</widget>
Expand Down
Loading