一、封装类
我们将对部门的操作,封装成一个类
首先我们简单分析一下可以知道,部门的相关操作应当有三个:
- 获取该部门所有成员的信息
- 增加一个部门
- 删除一个部门
.cpp文件
#include "pch.h"
#include "DepartmentCtrl.h"
DepartmentCtrl::DepartmentCtrl()
{
m_sql = MysqlUtil::GetInstance();
}
DepartmentCtrl::~DepartmentCtrl()
{
}
bool DepartmentCtrl::GetDepartmentAllInfo(vector<DepartmentInfo> &department)
{
vector<vector<string>> temp;
if (!m_sql->SelectData(temp, "SELECT * FROM tb_department")) {
return false;
}
for (auto d:temp) {
DepartmentInfo value;
value.id = atoi(d.at(FIELD_DEPARTMENT_ID).c_str());
value.name = CString(d.at(FIELD_DEPARTMENT_NAME).c_str());
value.parentId = atoi(d.at(FIELD_DEPARTMENT_PARENTID).c_str());
if(d.size()==4) value.managerId = atoi(d.at(FIELD_DEPARTMENT_MANAGER_ID).c_str());
department.push_back(value);
}
return true;
}
bool DepartmentCtrl::AddDepartment(int id, string name)
{
return m_sql->OperateData("INSERT INTO `db_myqq`.`tb_department` (`department_name`, `parent_id`) VALUES ('" + name + "', '" + to_string(id) +"');");
}
bool DepartmentCtrl::DeleteDepartment(int id)
{
return m_sql->OperateData("DELETE FROM `db_myqq`.`tb_department` WHERE (`department_id` = '" + to_string(id) + "');");
}
.h文件
#pragma once
#include "MysqlUtil.h"
#include "Common.h"
class DepartmentCtrl
{
public:
DepartmentCtrl();
~DepartmentCtrl();
public:
bool GetDepartmentAllInfo(vector<DepartmentInfo> &department);
bool AddDepartment(int parent_id, string name);
bool DeleteDepartment(int id);
private:
MysqlUtil* m_sql;
};
二、界面响应
2.1 初始化tree
这个我们用一个递归来实现
- 先把第一个节点插入,也就是总经办
- 然后找到所有的父节点(上属部门)是总经办的子部门
- 第二步用递归来做,递归以没有子部门为结束标志
2.2 添加部门
双击添加按钮,在函数中加入以下代码
获取选中的部门的id,以此id为parentid创建新的部门信息
2.3 删除部门
双击删除按钮,在生成的函数中加入以下代码:
2.4 显示部门信息
双击tree控件
三、代码
部门设置的代码
.cpp文件
// CDlgDepartment.cpp: 实现文件
//
#include "pch.h"
#include "qqService.h"
#include "CDlgDepartment.h"
#include "afxdialogex.h"
// CDlgDepartment 对话框
IMPLEMENT_DYNAMIC(CDlgDepartment, CDialogEx)
CDlgDepartment::CDlgDepartment(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DLG_DEPARTMENT, pParent)
{
}
CDlgDepartment::~CDlgDepartment()
{
}
void CDlgDepartment::InitDpListCtrl()
{
vector<DepartmentInfo> info;
m_ctrl.GetDepartmentAllInfo(info);
m_dbInfo = info;
m_dpList.DeleteAllItems();
HTREEITEM hParent;
m_hRoot = m_dpList.InsertItem(info.at(0).name, 0, 0);
info.erase(info.begin());
for (auto d :info)
{
if (d.parentId == 0) {
hParent = m_dpList.InsertItem(d.name, 0, 0, m_hRoot);
FindSubNode(hParent, d.id, info);
}
}
m_dpList.Expand(m_hRoot, TVE_EXPAND);
}
void CDlgDepartment::FindSubNode(HTREEITEM node, int id, vector<DepartmentInfo> info)
{
HTREEITEM hParent;
for (auto d:info) {
if (d.parentId == id) {
hParent = m_dpList.InsertItem(d.name, 0, 0, node);
FindSubNode(hParent, d.id, info);
}
}
}
void CDlgDepartment::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TREE_DEPARTMENT, m_dpList);
}
BEGIN_MESSAGE_MAP(CDlgDepartment, CDialogEx)
ON_BN_CLICKED(IDC_BTN_ADD_DEP, &CDlgDepartment::OnBnClickedBtnAddDep)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_DEPARTMENT, &CDlgDepartment::OnTvnSelchangedTreeDepartment)
ON_BN_CLICKED(IDC_BTN_DEL_DEP, &CDlgDepartment::OnBnClickedBtnDelDep)
END_MESSAGE_MAP()
// CDlgDepartment 消息处理程序
BOOL CDlgDepartment::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
m_ImageList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 1, 0);
CBitmap bmp;
bmp.LoadBitmap(IDB_DEPARTMENT);
m_ImageList.Add(&bmp, RGB(0, 0, 0));
m_dpList.SetImageList(&m_ImageList, TVSIL_NORMAL);
InitDpListCtrl();
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void CDlgDepartment::OnBnClickedBtnAddDep()
{
// TODO: 在此添加控件通知处理程序代码
CString departmet_name;
GetDlgItemText(IDC_EDIT_DEPARTMENT_NAME, departmet_name);
if (departmet_name.IsEmpty()) {
AfxMessageBox("请输入部门名!");
return;
}
bool res = m_ctrl.AddDepartment(GetDlgItemInt(IDC_EDIT_NODE_NUM), departmet_name.GetBuffer(0));
departmet_name.ReleaseBuffer();
if (!res) {
AfxMessageBox("添加失败!");
return;
}
InitDpListCtrl();
}
void CDlgDepartment::OnTvnSelchangedTreeDepartment(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
m_hItem = m_dpList.GetSelectedItem();
if (m_hItem != nullptr) {
CString s = m_dpList.GetItemText(m_hItem);
SetDlgItemText(IDC_EDIT_NODE, s);
for (auto v : m_dbInfo) {
if (v.name.Compare(s)== 0) {
SetDlgItemText(IDC_EDIT_NODE_NUM, to_string(v.id).c_str());
}
}
}
*pResult = 0;
}
void CDlgDepartment::OnBnClickedBtnDelDep()
{
// TODO: 在此添加控件通知处理程序代码
bool res = m_ctrl.DeleteDepartment(GetDlgItemInt(IDC_EDIT_NODE_NUM));
if (!res) {
AfxMessageBox("删除失败!");
return;
}
InitDpListCtrl();
}
.h文件
#pragma once
#include "DepartmentCtrl.h"
// CDlgDepartment 对话框
class CDlgDepartment : public CDialogEx
{
DECLARE_DYNAMIC(CDlgDepartment)
public:
CDlgDepartment(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CDlgDepartment();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DLG_DEPARTMENT };
#endif
private:
DepartmentCtrl m_ctrl;
CImageList m_ImageList;
vector<DepartmentInfo> m_dbInfo;
CTreeCtrl m_dpList;
HTREEITEM m_hRoot;
HTREEITEM m_hItem;
void InitDpListCtrl();
void FindSubNode(HTREEITEM node,int id,vector<DepartmentInfo> info);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedBtnAddDep();
virtual BOOL OnInitDialog();
afx_msg void OnTvnSelchangedTreeDepartment(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnBnClickedBtnDelDep();
};