部门管理中非递归搜索部门以及所管辖下部门

部门管理中非递归搜索部门以及所管辖下部门,处理此种问题包括以下几种方法:

一、树形控件显示,当展开部门节点时,再去读取所管辖的子部门。

二、SQL SERVER后台写函数处理,利用游标处理。

三、使用父部门ID、层次级别实现部门搜索。

 

本文重点介绍,利用父部门ID、层次级别实现部门搜索。

搜索部门时,首先使用用户登录,获取到用户所属部门ID和LevelPath;

组合LevelPath+A部门IDA(简称组合串),再使用like %组合串% 搜索此部门的下属部门。

LevelPath级别路径:记录上级以上所有路径(包含上级,不含本级)。格式:A组ID1A-A组ID2A-A组ID3A,比如:A1A-A2A-A3A

  Department

  -------------------------------------------------------------------------------

  DepetID/GroupID   GroupName                   LevelPath       ParentGroupID

  -------------------------------------------------------------------------------

  1                 整个系统           

  2                 公司                                           A1A                     1

  3                 部门A                                     A1A-A2A                 2

  4                 部门B                                      A1A-A2A               2

  5                 部门A子部门a                    A1A-A2A-A3A             3

  6                 部门A子部门b                    A1A-A2A-A3A             3

  7                 部门A子部门a组              A1A-A2A-A3A-A5A        5

  -------------------------------------------------------------------------------

DepetID/GroupID:自动增长字段

 

部门级别路径类:

 LevelPath.h

/*
  部门级别路径类,方便非递归搜索部门以及管辖部门。
  搜索部门时,首先使用用户登录,获取到用户所属部门ID和LevelPath;
  组合LevelPath+A部门IDA(简称组合串),再使用like %组合串% 搜索此部门的下属部门。
  LevelPath级别路径:记录上级以上所有路径(包含上级,不含本级)。格式:A组ID1A-A组ID2A-A组ID3A,比如:A1A-A2A-A3A
 */

#pragma  once

class LevelPath
{
public:
	LevelPath();
	~LevelPath();

	//设置参数
	void   SetParams(char cPrev,char cNext,char cSplit);

	//组转换到单个级别路径
	char * GroupId2CellLevelPath(int nGroupId);
	//单个级别路径转换到组
	int    CellLevelPath2GroupId(char *pCellLevelPath);

	//组合级别路径
	bool   MergeLevelPath(char *pPrevLevelPath,char *pNextLevelPath,char *pCurrentLevelPath,char *pNewLevelPath);
	bool   MergeLevelPath(int arrayLevelPath[],int nLevelPathSize,char *pNewLevelPath);

	//解析级别路径
	int	   ParseLevelPath(char *pLevelPath,int arrayLevelPath[],int & nLevelPathSize);

protected:
	char m_cPrev;			//前字符
	char m_cNext;			//后字符
	char m_cSplit;			//分隔符

};

LevelPath.cpp

#include "LevelPath.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

LevelPath::LevelPath()
{
	m_cPrev = 'A';			//前字符
	m_cNext = 'A';			//后字符
	m_cSplit = '-';			//分隔符
}

LevelPath::~LevelPath()
{

}

//设置参数
void LevelPath::SetParams(char cPrev,char cNext,char cSplit)
{
	m_cPrev = cPrev;
	m_cNext = cNext;
	m_cSplit = cSplit;
}

//组转换到单个级别路径
char *  LevelPath::GroupId2CellLevelPath(int nGroupId)
{
	char szPath[256] = {0};
	sprintf(szPath,"%c%d%c",m_cPrev,nGroupId,m_cNext);

	return szPath;
}

//单个级别路径转换到组
int    LevelPath::CellLevelPath2GroupId(char *pCellLevelPath)
{
	if(NULL == pCellLevelPath)
		return 0;

	int nGroupId = 0;
	char szTmp[256] = {0};
	//查找最后字符
	char *p = strrchr(pCellLevelPath,m_cNext);
	if(p != NULL)
	{
		memcpy(szTmp,pCellLevelPath,p-pCellLevelPath);
	}
	else
	{
		strcpy(szTmp,pCellLevelPath);
	}
	//查找前字符
	p = strchr(szTmp,m_cPrev);
	if(p != NULL)
	{
		nGroupId = atoi(szTmp+1);
	}

	return nGroupId;

}

//组合级别路径
bool LevelPath::MergeLevelPath(char *pPrevLevelPath,char *pNextLevelPath,char *pCurrentLevelPath,char *pNewLevelPath)
{
	if(NULL == pNewLevelPath || NULL == pCurrentLevelPath)
		return false;

	if(NULL != pPrevLevelPath && strlen(pPrevLevelPath) > 0)
	{
		sprintf(pNewLevelPath,"%s%c%s",pPrevLevelPath,m_cSplit,pCurrentLevelPath);
		if(NULL != pNextLevelPath && strlen(pNextLevelPath) > 0)
		{
			char szTmp[32] = {0};
			sprintf(szTmp,"%c",m_cSplit);
			strcat(pNewLevelPath,szTmp);
			strcat(pNewLevelPath,pNextLevelPath);
		}
	}
	else
	{
		sprintf(pNewLevelPath,"%s",pCurrentLevelPath);
		if(NULL != pNextLevelPath && strlen(pNextLevelPath) > 0)
		{
			char szTmp[32] = {0};
			sprintf(szTmp,"%c",m_cSplit);
			strcat(pNewLevelPath,szTmp);
			strcat(pNewLevelPath,pNextLevelPath);
		}
	}

	return true;
}

bool LevelPath::MergeLevelPath(int arrayLevelPath[],int nLevelPathSize,char *pNewLevelPath)
{
	if(nLevelPathSize <= 0 || NULL == pNewLevelPath)
		return false;

	int m = 0;
	for(m=0; m<nLevelPathSize; m++)
	{
		strcat(pNewLevelPath,GroupId2CellLevelPath(arrayLevelPath[m]));
		if(m != nLevelPathSize-1)
		{
			//非最后一个levelpath时,增加分隔符
			sprintf(pNewLevelPath,"%s%c",pNewLevelPath,m_cSplit);
		}
	}

	return true;
}

/*
功能说明:解析级别路径
参数说明:pLevelPath,分组级别路径字符串;arrayLevelPath,表示组ID数组
返回值:int 0,表示成功,-1,表示参数错误;-2,表示nLevelPathSize太小
*/
int LevelPath::ParseLevelPath(char *pLevelPath,int arrayLevelPath[],int & nLevelPathSize)
{
	if(nLevelPathSize <= 0 || NULL == pLevelPath)
		return -1;


	char *p = NULL,*q = NULL;
	char szCell[128] = {0};
	int n = 0;
	q = pLevelPath;
	while(true)
	{
		memset(szCell,0,sizeof(szCell));
		p = strchr(q,m_cSplit);
		if(p != NULL)
		{
			memcpy(szCell,q,p-q);
			if(n >= nLevelPathSize)
			{
				return -2;
			}
			arrayLevelPath[n] = CellLevelPath2GroupId(szCell);
			n++;
			q = p + 1;
			continue;
		}
		else
		{
			strcpy(szCell,q);
			if(n >= nLevelPathSize)
			{
				return -2;
			}
			arrayLevelPath[n] = CellLevelPath2GroupId(szCell);
			n++;
			break;
		}

	}

	nLevelPathSize = n;

	return 0;
}


 

使用方法:

1、  插入部门

void insertDepartment(int nGroupID,char *pGroupLevelPath,char *pInsertGroupName)

{

LevelPath lpLevelPath;

char szParentLevelPath[256] = {0};

char szParentParentLevelPath[256] = {0};

char szNewLevelPath[256] = {0};

strcpy(szParentLevelPath, lpLevelPath.GroupId2CellLevelPath(nGroupID));

strcpy(szParentParentLevelPath,pGroupLevelPath);

lpLevelPath.MergeLevelPath(szParentParentLevelPath,NULL,szParentLevelPath,szNewLevelPath);

//插入sql语句

char szSql[1024] = {0};

sprintf(szSql, Insert into Department(GroupName,LevelPath,ParentGroupID) values(%s,%s,%d), pInsertGroupName, szNewLevelPath, nGroupID);

执行sql语句

}

2、  更新部门

参考插入部门代码。

 

3、  删除部门

void deleteDepartment(int nGroupID)

{

LevelPath lpLevelPath;

char szGroupLevelPath [256] = {0};

strcpy(szGroupLevelPath, lpLevelPath.GroupId2CellLevelPath(nGroupID));

//插入sql语句

char szSql[1024] = {0};

sprintf(szSql,"DELETE FROM Department WHERE GroupID=%d OR levelPath like '%%%s%%')",nGroupID,szGroupLevelPath);

执行sql语句

 

}

 

4、  搜索部门以及管辖部门

void queryDepartment(int nGroupID)

{

LevelPath lpLevelPath;

char szGroupLevelPath [256] = {0};

strcpy(szGroupLevelPath, lpLevelPath.GroupId2CellLevelPath(nGroupID));

//插入sql语句

char szSql[1024] = {0};

sprintf(szSql,"SELECT GroupID,GroupName ,ParentGroupID,LevelPath FROM Department WHERE GroupID=%d OR levelPath like '%%%s%%')",nGroupID,szGroupLevelPath);

执行sql语句

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byxdaz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值