扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
做过一个E应用,使用lumen框架,和你的思路是一样的,新用户点进去就自动授权注册应用,数据存到我们自己的数据库中,不依赖钉钉,我们还同步了部门信息,如果粘贴复制和下面的那个同学一样,看上去你也会觉得懵,方法都是封装好了的。
创新互联公司是网站建设专家,致力于互联网品牌建设与网络营销,专业领域包括成都网站设计、成都做网站、电商网站制作开发、微信小程序开发、微信营销、系统平台开发,与其他网站设计及系统开发公司不同,我们的整合解决方案结合了恒基网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,且不断评估并优化我们的方案,为客户提供全方位的互联网品牌整合方案!
建议你这样试试看:
获取AccessToken:
后端通过corpid,corpsecret请求接口gettoken?corpid=idcorpsecret=secrect获取AccessToken
获取钉钉用户userid:
前端需要相应的处理,携带authCode请求,加上AccessToken这两个参数请求接口/user/getuserinfo?access_token=access_tokencode=authCode这个
获取钉钉用户详情:
使用access_token和上一步的钉钉userid 请求接口 /user/get?access_token=ACCESS_TOKENuserid=
插入钉钉用户的数据到你的 数据库中
我们这样做的:
/**
* 钉钉免登陆获获取用信息
* @param $authCode
* @param $url
* @return array
*/
static function outhLogin($authCode, $url)
{
if (empty($authCode) || empty($url)) {
return self::returnError('1101', self::$errorArray['1101']);
}
$accessToken = ComponentDingtalk::getPcAccessToken();
if ($accessToken['code']) {
self::logError(__CLASS__ . '-' . __FUNCTION__, '获取access_token失败');
return self::returnError('1102', self::$errorArray['1102']);
}
$dingUserId = ComponentDingtalk::getDingUserid($accessToken['data'], $authCode);
if ($dingUserId['code']) {
self::logError(__CLASS__ . '-' . __FUNCTION__, '用户userid获取失败(调用钉钉API)');
return self::returnError('1103', self::$errorArray['1103']);
}
$dinguserInfo = ComponentDingtalk::getDingUserInfo($accessToken['data'], $dingUserId['data']);
if ($dinguserInfo['code']) {
self::logError(__CLASS__ . '-' . __FUNCTION__, '用户信息获取失败(调用钉钉API)');
return self::returnError('1104', self::$errorArray['1004']);
}
$userInfo = $dinguserInfo['data'];
return self::transaction(function () use ($accessToken, $userInfo, $url) {
if (\count($userInfo['department']) 1) {
$departIdArr = [];
$departNameArr = [];
for ($i = 0, $iMax = \count($userInfo['department']); $i $iMax; $i++) {
$departInfo[$i] = ServerDepartment::getByDdDepartid($userInfo['department'][$i]);
$departIdArr[] = $departInfo[$i]['id'];
$departNameArr[] = $departInfo[$i]['name'];
}
$depart['id'] = implode(',', $departIdArr);
$depart['name'] = implode(',', $departNameArr);
} else {
$ddDepartmentId = implode(',', $userInfo['department']);
$depart = ServerDepartment::getByDdDepartid($ddDepartmentId);
}
//插入用户
$user = ServerEmployee::getByDdUserid($userInfo['userid']);
if ($user $user['status'] == 2) {
return self::returnError('1105', self::$errorArray['1105']);
}
if (empty($user)) {
$roleId = 0;
$departId = $depart['id'];
$name = $userInfo['name'];
$mobile = $userInfo['mobile'];
$departName = $depart['name'];
$position = $userInfo['position'];
$ddUserid = $userInfo['userid'];
$ddStatus = $userInfo['active'] ? 1 : 2;
$ddInfo = json_encode($userInfo, JSON_UNESCAPED_UNICODE);
$tokenOverAt = (int)(time() + $_ENV['PROJECT_apiAppTokenOverTime']);
$token = self::_createToken($userInfo['userid'], $tokenOverAt);
$status = 1;
$userId = ServerEmployee::insert($roleId, $departId, $name, $mobile, $departName, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status);
if (!$userId) {
self::logError(__CLASS__ . '-' . __FUNCTION__, '用户初始化创建失败');
return self::returnError('1106', self::$errorArray['1106']);
}
}
$userId = $userId ?? $user['id'];
// 更新Token
$id = $userId;
$roleId = $user['roleId'];
$departId = $depart['id'];
$name = $userInfo['name'];
$mobile = $userInfo['mobile'];
$departName = $depart['name'];
$position = $userInfo['position'];
$ddUserid = $userInfo['userid'];
$ddStatus = $userInfo['active'] ? 1 : 2;
$ddInfo = json_encode($userInfo, JSON_UNESCAPED_UNICODE);
$tokenOverAt = (int)(time() + $_ENV['PROJECT_apiAppTokenOverTime']);
$token = self::_createToken($userInfo['userid'], $tokenOverAt);
$status = 1;
$updateParams = ServerEmployee::update($id, $roleId, $departId, $name, $mobile, $departName, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status);
if (!$updateParams) {
self::logError(__CLASS__ . '-' . __FUNCTION__, '用户信息更新失败' . json_encode($updateParams, JSON_UNESCAPED_UNICODE) . '/' . json_encode([$id, $roleId, $departId, $name, $mobile, $depart, $position, $ddUserid, $ddStatus, $ddInfo, $token, $tokenOverAt, $status]));
return self::returnError('1107', self::$errorArray['1107']);
}
// 前端的配置信息
// 获取jsTicket
$jsTicket = ComponentDingtalk::getPcJsTicket($accessToken['data']);
if ($jsTicket['code']) {
self::logError(__CLASS__ . '-' . __FUNCTION__, '获取jsTicket失败(调用钉钉API)');
return self::returnError('1111', self::$errorArray['1111']);
}
// 组装签名数据
$curUrl = $url;;
$nonceStr = uniqid('', true);
$agentId = $_ENV['PROJECT_ddInterfaceAgentID'];
$timeStamp = time();
$corpId = $_ENV['PROJECT_ddInterfaceCorpId'];
$signature = ComponentDingtalk::getSign($jsTicket['data'], $nonceStr, $timeStamp, $curUrl);
$config = array(
'url' = urldecode($curUrl),
'nonceStr' = $nonceStr,
'agentId' = $agentId,
'timeStamp' = $timeStamp,
'corpId' = $corpId,
'signature' = $signature
);
// 获取当前角色的权限
$roleInfo = ServerRole::getById($roleId);
// 当前用户的顶级部门(不含根部门)
$departInfo = ServerDepartment::getById($departId);
if ($departInfo['parentid'] == 1) { // 二级部门(总经办)
$departRootId = $departId;
$departRootName = $departName;
} else {
$sonDepart = ServerDepartment::getById($departInfo['parentid']);//分组
if ($sonDepart['parentid'] == 1) {
$departRootId = $sonDepart['id'];
$departRootName = $sonDepart['name'];
} else {
$grandsonDepart = ServerDepartment::getById($sonDepart['parentid']);//部门
if ($grandsonDepart['parentid'] == 1) {
$departRootId = $grandsonDepart['id'];
$departRootName = $grandsonDepart['name'];
} else {
$grandchildDepart = ServerDepartment::getById($grandsonDepart['parentid']);//分公司
$departRootId = $grandchildDepart['id'];
$departRootName = $grandchildDepart['name'];
}
}
}
$company = ServerDepartment::get(['parentid' = 0, 'dd_departid' = 1]);
return self::returnSuccess(array(
'id' = $userId,
'name' = $name,
'token' = $token,
'tokenOverAt' = $tokenOverAt,
'config' = $config,
'power' = $roleInfo['power'] ?? '',
'departId' = $departId,
'departName' = $departName,
'departRootId' = $departRootId,
'departRootName' = $departRootName,
'company' = $company['name'],
));
}, function (\Exception $e) {
echo $e-getMessage();
self::logError(__CLASS__ . '-' . __FUNCTION__, $e-getMessage());
return self::returnError('1108', self::$errorArray['1108']);
});
}
若想查看日志,根据不同的角色可查看的范围不同哦:
1、其他人(包括管理员)在手机端/PC端只能查看/导出跟自己相关(我发出的/我收到的)的日志。
路径:【手机/电脑钉钉】-【工作】-【日志】-【看日志】 或者【手机/电脑钉钉】-【工作】-【日志】-【统计】/【日志报表】
2、主管理员可在管理后台导出全成员的数据进行查看。
3、有日志管理权限的子管理员仅支持查询和导出管理范围内的日志内容
4、日志导出记录不支持删除
5、无法批量阅读日志
可以,在你所发往的群(好友)可以看到,或者点 工作-日志-我发出的。
一、销售管道管理,钉钉表格协同处理
记得自己在创业公司还没有上CRM系统的时候,我们会把销售渠道通过excel表格的方式来进行管理,让所有销售主管,必须每周都对所有的销售员工的客户信息进行复盘,并将复盘总结整理汇总给销售运营专员,再由销售运营专员汇总到我这里,这样层层汇总信息经常出错误。
我做销售管理对数据非常敏感,汇总到我这里,哪个数据信息有问题我一眼就能看出,每当我看出来哪里有问题去review我下属的时候,他们都会非常紧张,经常会全盘检查。有时候涉及到一些我特别想知道的重要信息但又发现异常的时候,难免会把着急的情绪传染给了下属,直到我发现了钉钉在线文档,真的是高效又及时的解决了我这个问题。
我会把我想要的信息制定成模板,同步给销售运营组和销售管理者,所有人都在这一张表格上进行录入,销售运营可以在线整理。这样做的好处有以下几点:
1、有效处理信息:销售管理者可以在线复盘销售员工的客户信息并及时给出解决方案,而销售运营的同事们也可以在线进行汇总整理,无论是销售管理者还是销售运营都能直接在表格中@某位伙伴,被@到的伙伴能够及时得到需要整改、补录的要求;
2、实时查看数据:因为大家都是在线编辑和录入,我每次打开钉钉文档看到的都是最新消息,如果有我需要知道的紧迫信息,我会直接在文档中@相应的伙伴,快速沟通;
3、方便跟进状态:因为能实时看到信息,大家也可以实时在线处理,因此在遇到问题落实某项方案时,能做到实时且进度能够让所有的管理者实时跟进。
通过钉钉表格,相较于传统本地的Excel,它最大的优势就是可以实现协同编辑,适合多人、多地、多部门的协同填表场景,多人在表格里共同编辑数据,无需本地文件的多次传输汇总,提高数据收集效率的同时,很好地避免版本混乱可能造成的数据错误。
二、千人大会信息汇总,钉钉表格帮了我大忙
之前在一家互联网公司做营销管理,我们每个季度都要举办一次千人大会,由于是邀请制,不少参会人员会临时变更相关信息,且经常出现需要调整的情况。比如变更住宿情况、参会人员请假、和其他信息调整等。
有了钉钉表格之后,我们二十几位人员同时在线编辑一张表格,并将信息进行在线备注,最后我们整理表格的时候既保证了准确性,又高效。
好啦,以上就是我的分享啦,通过我的两个工作场景案例,想必大家已经发现钉钉在线文档能够帮助我们做很好的信息收集和处理,又准确,又高效,不止如此,钉钉在线文档是可以设置权限的,可以设置编辑与查看权限,我们可以根据所需对其进行设置。
发布于 9 月前著作权归作者所有
我网上搜了一下,有以下的方法
(来源于正解网)考勤打卡数据提供两种方式导出:
手机客户端:主管理员、子管理员、企业负责人、考勤组负责人,都可以导出数据 操作路径:进入工作—考勤打卡—统计—导出考勤报表—选择时间以及人员进行导出,会通过企业消息会话框推送过去,下载打开即可;
企业管理后台:只有主管理员和子管理员才可以登陆 操作路径:需要进入企业管理后台——右上角的微应用—找到考勤打卡—点击进入后台——选择左边的考勤报表—在右边选择需要导出的时间 导出即可。
温馨提示:只能管理员(包含子管理员)操作导出。
如果你的公司在用考勤系统的话,而它又与钉钉对接的话,可以实时获取钉钉的考勤数据,直接在考勤系统中导出数据。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流