大华ICC平台对接组织设备通道

sdk版本:ICC_DPSDK_C_Chn_Win32_IS_V5.0.5.20230418

lib:DPSDK.lib

头文件:

#include "./DH_NET/include/DPSDK_Error.h"
#include "./DH_NET/include/DPSDK.h"

1.初始化SDK

DPSDK_INT32 iRet = DPSDK_Init();
if (iRet == DPSDK_SUCCESS)
{
	//系统初始化成功
	bIniSDK = true;
}
else
{
	LOG_E("初始化SDK失败!。。。。");
	return false;
}

2.登录大华平台

	if (!bLogin && bIniSDK)
	{
		DPSDK_SetHttpsMode(1);
		DPSDK_LOGIN_PARAM struLoginParam;
		memset(&struLoginParam, 0, sizeof(struLoginParam));
		struLoginParam.bDomainUser = true;//域登录
		struLoginParam.uiClientType = CLIENT_PC; //PC客服端
		strcpy(struLoginParam.szUserName, m_device->user.c_str());
		strcpy(struLoginParam.szPWD, m_device->pass.c_str());
		strcpy(struLoginParam.struIP.szIP, m_device->addr.c_str());
		struLoginParam.uiPort = m_device->port;
		DPSDK_INT32 iSessionID = -1;
		DPSDK_INT32 iRet = DPSDK_Login(&struLoginParam, &iSessionID);
		if (iRet == DPSDK_SUCCESS)
		{
			m_login_id = iSessionID;
			LOG_E("登录成功!");
			bIniSDK = true;
			//成功,用户登录可在此处设置回调函数,参见设置事件回调函数DPSDK_SetEventCallBack 
			return true;
		}
		else
		{
			LOG_E("大华设备登录失败 -  错误码: %d ,设备类型:%s, 设备IP: %s,端口:%d, 用户名:%s, 密码:%s \n", iRet, m_device->dev_type.c_str(), m_device->addr.c_str(), m_device->port, m_device->user.c_str(), m_device->pass.c_str());
			return false;
		}
	}

3.获取设备树

	m_struDevInfoAll.vecDevInfo.clear();
	int iRet = DPSDK_GetDevice(m_login_id, NULL, 0, &DataCallback, &m_struDevInfoAll);
	if (iRet == DPSDK_SUCCESS)
	{
		LOGE("获取通道信息成功!");
	}
	else
	{
		LOGE("获取通道信息失败,错误码:" << iRet);
	}

3.1设置数据同步回调函数

DPSDK_VOID  CDHdevice::DataCallback(DPSDK_INT32 iDataType, DPSDK_VOID* pDataBuf, DPSDK_UINT32 uiBufSize, DPSDK_VOID* pUserData)
{
	if (iDataType == DPSDK_DATA_ORG_INFO)
	{
		DPSDK_ORG_INFO* pOrgInfo = (DPSDK_ORG_INFO*)pDataBuf;
		Dep_Info_All_t* pDepInfo = (Dep_Info_All_t*)pUserData;
	}
	else if (iDataType == DPSDK_DATA_DEVICE_INFO)
	{
		DPSDK_DEV_ALL_INFO_LIST* pDevInfo = (DPSDK_DEV_ALL_INFO_LIST*)pDataBuf;
		Dev_Info_All_t* pUserDevInfo = (Dev_Info_All_t*)pUserData;
		CopyDevData(pDevInfo, pUserDevInfo);
	}
}

3.2获取到的设备数据放入对应结构体

void CDHdevice::CopyDevData(DPSDK_DEV_ALL_INFO_LIST* pDevInfo, Dev_Info_All_t* pUserDevInfo)
{
	for (int i = 0; i < pDevInfo->iDevNum; i++)
	{
		Dev_Info_t devInfo;
		memset(&devInfo.struDevInfo, 0, sizeof(devInfo.struDevInfo));
		memcpy(&devInfo.struDevInfo, &pDevInfo->pDevAllInfoList[i].struDevInfo, sizeof(devInfo.struDevInfo));

		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iEncChnlNum; j++)
		{
			DPSDK_ENC_CHANNEL_INFO encChnlInfo;
			memset(&encChnlInfo, 0, sizeof(encChnlInfo));
			memcpy(&encChnlInfo, &pDevInfo->pDevAllInfoList[i].pEncChnlInfoList[j], sizeof(encChnlInfo));
			devInfo.vecEncChnlInfo.push_back(encChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iDecChnlNum; j++)
		{
			DPSDK_DEC_CHANNEL_INFO decChnlInfo;
			memset(&decChnlInfo, 0, sizeof(decChnlInfo));
			memcpy(&decChnlInfo, &pDevInfo->pDevAllInfoList[i].pDecChnlInfoList[j], sizeof(decChnlInfo));
			devInfo.vecDecChnlInfo.push_back(decChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iAlarmInChnlNum; j++)
		{
			DPSDK_ALARMIN_CHANNEL_INFO alarmInChnlInfo;
			memset(&alarmInChnlInfo, 0, sizeof(alarmInChnlInfo));
			memcpy(&alarmInChnlInfo, &pDevInfo->pDevAllInfoList[i].pAlarmInChnlInfoList[j], sizeof(alarmInChnlInfo));
			devInfo.vecAlarmInChnlInfo.push_back(alarmInChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iAlarmOutChnlNum; j++)
		{
			DPSDK_ALARMOUT_CHANNEL_INFO alarmOutChnlInfo;
			memset(&alarmOutChnlInfo, 0, sizeof(alarmOutChnlInfo));
			memcpy(&alarmOutChnlInfo, &pDevInfo->pDevAllInfoList[i].pAlarmOutChnlInfoList[j], sizeof(alarmOutChnlInfo));
			devInfo.vecAlarmOutChnlInfo.push_back(alarmOutChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iTvWallInChnlNum; j++)
		{
			DPSDK_TVWALLIN_CHANNEL_INFO tvWallInChnlInfo;
			memset(&tvWallInChnlInfo, 0, sizeof(tvWallInChnlInfo));
			memcpy(&tvWallInChnlInfo, &pDevInfo->pDevAllInfoList[i].pTvWallInChnlInfoList[j], sizeof(tvWallInChnlInfo));
			devInfo.vecTvWallInChnlInfo.push_back(tvWallInChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iTvWallOutChnlNum; j++)
		{
			DPSDK_TVWALLOUT_CHANNEL_INFO tvWallOutChnlInfo;
			memset(&tvWallOutChnlInfo, 0, sizeof(tvWallOutChnlInfo));
			memcpy(&tvWallOutChnlInfo, &pDevInfo->pDevAllInfoList[i].pTvWallOutChnlInfoList[j], sizeof(tvWallOutChnlInfo));
			devInfo.vecTvWallOutChnlInfo.push_back(tvWallOutChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iDoorChnlNum; j++)
		{
			DPSDK_DOOR_CHANNEL_INFO doorChnlInfo;
			memset(&doorChnlInfo, 0, sizeof(doorChnlInfo));
			memcpy(&doorChnlInfo, &pDevInfo->pDevAllInfoList[i].pDoorChnlInfoList[j], sizeof(doorChnlInfo));
			devInfo.vecDoorChnlInfo.push_back(doorChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iVoiceChnlNum; j++)
		{
			DPSDK_VOICE_CHANNEL_INFO voiceChnlInfo;
			memset(&voiceChnlInfo, 0, sizeof(voiceChnlInfo));
			memcpy(&voiceChnlInfo, &pDevInfo->pDevAllInfoList[i].pVoiceChnlInfoList[j], sizeof(voiceChnlInfo));
			devInfo.vecVoiceChnlInfo.push_back(voiceChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iRoadGateChnlNum; j++)
		{
			DPSDK_ROADGATE_CHANNEL_INFO roadChnlInfo;
			memset(&roadChnlInfo, 0, sizeof(roadChnlInfo));
			memcpy(&roadChnlInfo, &pDevInfo->pDevAllInfoList[i].pRoadGateChnlInfoList[j], sizeof(roadChnlInfo));
			devInfo.vecRoadGateChnlInfo.push_back(roadChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iLEDChnlNum; j++)
		{
			DPSDK_LED_CHANNEL_INFO ledChnlInfo;
			memset(&ledChnlInfo, 0, sizeof(ledChnlInfo));
			memcpy(&ledChnlInfo, &pDevInfo->pDevAllInfoList[i].pLEDChnlInfoList[j], sizeof(ledChnlInfo));
			devInfo.vecLEDChnlInfo.push_back(ledChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iDispatcherChnlNum; j++)
		{
			DPSDK_DISPATCHER_CHANNEL_INFO dispatcherChnlInfo;
			memset(&dispatcherChnlInfo, 0, sizeof(dispatcherChnlInfo));
			memcpy(&dispatcherChnlInfo, &pDevInfo->pDevAllInfoList[i].pDispatcherChnlInfoList[j], sizeof(dispatcherChnlInfo));
			devInfo.vecDispatcherChnlInfo.push_back(dispatcherChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iPosChnlNum; j++)
		{
			DPSDK_POS_CHANNEL_INFO posChnlInfo;
			memset(&posChnlInfo, 0, sizeof(posChnlInfo));
			memcpy(&posChnlInfo, &pDevInfo->pDevAllInfoList[i].pPosChnlInfoList[j], sizeof(posChnlInfo));
			devInfo.vecPosChnlInfo.push_back(posChnlInfo);
		}
		for (int j = 0; j < pDevInfo->pDevAllInfoList[i].iVirtualChnlNum; j++)
		{
			DPSDK_VIRTUAL_CHANNEL_INFO virChnlInfo;
			memset(&virChnlInfo, 0, sizeof(virChnlInfo));
			memcpy(&virChnlInfo, &pDevInfo->pDevAllInfoList[i].pVirtualChnlInfoList[j], sizeof(virChnlInfo));
			devInfo.vecVirtualChnlInfo.push_back(virChnlInfo);
		}
		for (int j = 0; j < 4; j++)
		{
			for (int k = 0; k < pDevInfo->pDevAllInfoList[i].pAlarmBoxUnit[j].iChannelNum; k++)
			{
				DPSDK_ALARMBOX_CHANNEL_INFO alarmBoxChnlInfo;
				memset(&alarmBoxChnlInfo, 0, sizeof(alarmBoxChnlInfo));
				memcpy(&alarmBoxChnlInfo, &pDevInfo->pDevAllInfoList[i].pAlarmBoxUnit[j].pAlarmBoxChnList[k], sizeof(alarmBoxChnlInfo));
				devInfo.vecAlarmBoxChnlInfo.push_back(alarmBoxChnlInfo);
			}
		}

		pUserDevInfo->vecDevInfo.push_back(devInfo);
	}
}

目录

1.初始化SDK

2.登录大华平台

3.获取设备树

3.1设置数据同步回调函数

3.2获取到的设备数据放入对应结构体


bool CDHdevice::GetChannelInfo(Json::Value &root)
{
	if (m_struDevInfoAll.vecDevInfo.size() == 0)
	{
		return false;
	}
	int nNum = 0;
	for (std::vector<Dev_Info>::iterator i = m_struDevInfoAll.vecDevInfo.begin(); i < m_struDevInfoAll.vecDevInfo.end(); i++)
	{
		Dev_Info_t& struDevAllInfo = *(i);

		//Encode channel
		for (std::vector<DPSDK_ENC_CHANNEL_INFO>::iterator j = struDevAllInfo.vecEncChnlInfo.begin(); j != struDevAllInfo.vecEncChnlInfo.end(); j++)
		{
			DPSDK_ENC_CHANNEL_INFO& struEncChnlInfo = *(j);
			std::string strUtf8 = struEncChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_no"] = nNum + 1;
			jChan["chan_id"] = struEncChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struEncChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			nNum++;
			root.append(jChan);
		}
		//Decode channel
		for (std::vector<DPSDK_DEC_CHANNEL_INFO>::iterator j = struDevAllInfo.vecDecChnlInfo.begin(); j != struDevAllInfo.vecDecChnlInfo.end(); j++)
		{
			DPSDK_DEC_CHANNEL_INFO& struDecChnlInfo = *(j);
			std::string strUtf8 = struDecChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struDecChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struDecChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Alarm input channel
		for (std::vector<DPSDK_ALARMIN_CHANNEL_INFO>::iterator j = struDevAllInfo.vecAlarmInChnlInfo.begin(); j != struDevAllInfo.vecAlarmInChnlInfo.end(); j++)
		{
			DPSDK_ALARMIN_CHANNEL_INFO& struAlarmInChnlInfo = *(j);
			std::string strUtf8 = struAlarmInChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struAlarmInChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struAlarmInChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Alarm output channel
		for (std::vector<DPSDK_ALARMOUT_CHANNEL_INFO>::iterator j = struDevAllInfo.vecAlarmOutChnlInfo.begin(); j != struDevAllInfo.vecAlarmOutChnlInfo.end(); j++)
		{
			DPSDK_ALARMOUT_CHANNEL_INFO& struAlarmOutChnlInfo = *(j);
			std::string strUtf8 = GBKToUTF8(struAlarmOutChnlInfo.struChannelInfo.szChannelName);
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struAlarmOutChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struAlarmOutChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Big screen input channel
		for (std::vector<DPSDK_TVWALLIN_CHANNEL_INFO>::iterator j = struDevAllInfo.vecTvWallInChnlInfo.begin(); j != struDevAllInfo.vecTvWallInChnlInfo.end(); j++)
		{
			DPSDK_TVWALLIN_CHANNEL_INFO& struTvWallInChnlInfo = *(j);

			std::string strUtf8 = struTvWallInChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struTvWallInChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struTvWallInChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Big screen output channel
		for (std::vector<DPSDK_TVWALLOUT_CHANNEL_INFO>::iterator j = struDevAllInfo.vecTvWallOutChnlInfo.begin(); j != struDevAllInfo.vecTvWallOutChnlInfo.end(); j++)
		{
			DPSDK_TVWALLOUT_CHANNEL_INFO& struTvWallOutChnlInfo = *(j);

			std::string strUtf8 = struTvWallOutChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struTvWallOutChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struTvWallOutChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Acess channel
		for (std::vector<DPSDK_DOOR_CHANNEL_INFO>::iterator j = struDevAllInfo.vecDoorChnlInfo.begin(); j != struDevAllInfo.vecDoorChnlInfo.end(); j++)
		{
			DPSDK_DOOR_CHANNEL_INFO& struDoorChnlInfo = *(j);

			std::string strUtf8 = struDoorChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struDoorChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struDoorChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Audio channel
		for (std::vector<DPSDK_VOICE_CHANNEL_INFO>::iterator j = struDevAllInfo.vecVoiceChnlInfo.begin(); j != struDevAllInfo.vecVoiceChnlInfo.end(); j++)
		{
			DPSDK_VOICE_CHANNEL_INFO& struVoiceChnlInfo = *(j);

			std::string strUtf8 = struVoiceChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struVoiceChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struVoiceChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Road gate channel
		for (std::vector<DPSDK_ROADGATE_CHANNEL_INFO>::iterator j = struDevAllInfo.vecRoadGateChnlInfo.begin(); j != struDevAllInfo.vecRoadGateChnlInfo.end(); j++)
		{
			DPSDK_ROADGATE_CHANNEL_INFO& struRoadChnlInfo = *(j);

			std::string strUtf8 = struRoadChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struRoadChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struRoadChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//LED channel
		for (std::vector<DPSDK_LED_CHANNEL_INFO>::iterator j = struDevAllInfo.vecLEDChnlInfo.begin(); j != struDevAllInfo.vecLEDChnlInfo.end(); j++)
		{
			DPSDK_LED_CHANNEL_INFO& struLEDChnlInfo = *(j);

			std::string strUtf8 = struLEDChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struLEDChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struLEDChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Dispatcher channel
		for (std::vector<DPSDK_DISPATCHER_CHANNEL_INFO>::iterator j = struDevAllInfo.vecDispatcherChnlInfo.begin(); j != struDevAllInfo.vecDispatcherChnlInfo.end(); j++)
		{
			DPSDK_DISPATCHER_CHANNEL_INFO& struDisChnlInfo = *(j);

			std::string strUtf8 = struDisChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struDisChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struDisChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//POS channel
		for (std::vector<DPSDK_POS_CHANNEL_INFO>::iterator j = struDevAllInfo.vecPosChnlInfo.begin(); j != struDevAllInfo.vecPosChnlInfo.end(); j++)
		{
			DPSDK_POS_CHANNEL_INFO& struPosChnlInfo = *(j);

			std::string strUtf8 = struPosChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struPosChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struPosChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
		//Virtual channel
		for (std::vector<DPSDK_VIRTUAL_CHANNEL_INFO>::iterator j = struDevAllInfo.vecVirtualChnlInfo.begin(); j != struDevAllInfo.vecVirtualChnlInfo.end(); j++)
		{
			DPSDK_VIRTUAL_CHANNEL_INFO& struVirChnlInfo = *(j);

			std::string strUtf8 = struVirChnlInfo.struChannelInfo.szChannelName;
			Json::Value jChan;
			jChan["title"] = strUtf8;
			jChan["chan_id"] = struVirChnlInfo.struChannelInfo.szChannelID;
			LOGI("通道ID:" << struVirChnlInfo.struChannelInfo.szChannelID << ", 通道名称:" << UTF8ToGBK(strUtf8));
			jChan["chan_no"] = nNum + 1;
			nNum++;
			root.append(jChan);
		}
	}
	return true;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ICC大华物联网管理平台客户端是一款为大华物联网管理平台设计的移动应用程序。该应用程序提供了一系列功能,便于用户通过移动设备大华物联网管理平台进行管理和监控。 首先,大华物联网管理平台客户端具有实时监控的功能。用户可以通过客户端实时查看物联网设备的状态和数据。例如,用户可以查看和监控摄像头、传感器等设备的运行状态,以及获取实时图像或数据流。 其次,客户端还具有设备管理功能。用户可以通过客户端添加、编辑和删除物联网设备,并对设备进行配置和管理。例如,用户可以设置设备的参数、查看设备的报警信息、远程控制设备等。 此外,客户端还支持数据分析和报表功能。用户可以通过客户端对采集到的物联网数据进行分析和统计,生成报表和图表,并进行数据可视化展示。这样,用户可以更好地了解设备运行情况、监测趋势并进行决策分析。 此外,ICC大华物联网管理平台客户端还提供了安全保护措施。客户端采用了加密技术和身份验证机制,确保用户只能访问其权限范围内的设备和数据,并提供端到端的安全通信。 综上所述,ICC大华物联网管理平台客户端是一款功能全面、易于使用且安全可靠的应用程序。它帮助用户方便地管理和监控物联网设备,并实现数据的分析和报表生成。这对于企业和个人来说,都是一个强大的工具,可以提升管理效率和决策能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值