<?php namespace Api\Controller\User; use Com\Rpc; use Common\Common\User; use Common\Common\StudyMapRight; use Common\Model\AttrModel; use Common\Service\AttrService; use Common\Service\UserRecordService; use Common\Service\UserService; use Common\Common\Cache; class SaveController extends AbstractController { /** * 权限标识列表 */ const RIGHT_TYPE_LIST = [ 1 => 'dp_ids', 5 => 'job_ids', 6 => 'role_ids' ]; /** * 权限标识:人员 */ const RIGHT_TYPE_IS_USER = 3; /** * Save * @author tangxingguo * @desc 【通讯录】人员保存 * @param Array dp_ids:true 部门ID * @param String uid:true 人员ID * @param Int list[].type:true 字段类型(1=单行文本;2=多行文本;3=数字;4=日期;5=时间;6=日期时间;7=单选;8=多选;9=地址;10=图片;999=选人组件,前端不可选择) * @param String list[].field_name:true 属性对应的UC字段名称 * @param String list[].attr_name:true 属性名称 * @param String|Array list [].attr_value:true 属性的值(属性类型为图片、多选时,该值为数组类型;单选时,值为单选项Option中的value) * @param String|Array list [].option:true 单选选项(属性类型为单选时,必须以数组形式请求) * @param String|Array list [].is_required:true 是否必填(0=非必填;1=必填) * @param String|Array list [].is_system:true 是否为系统字段(0=自定义字段;1=系统字段) * @param String|Array list [].postion:true 前端布局 * @return bool */ public function Index_post() { $uid = I('post.uid', '', 'trim'); $list = I('post.list'); $dpIds = I('post.dp_ids'); // 权限检查 if (!$this->_checkRight()) { E('_ERR_NO_EDIT_USER_RIGHT'); } if (empty($uid)) { E('_ERR_UID_IS_NULL'); } if (empty($list) || empty($dpIds)) { E('_ERR_PARAM_IS_NULL'); } // 以架构接口参数字段为键,拼接用户信息 $attrServ = new AttrService(); $attrs = $attrServ->getAttrList(true, array(), true); $data = [ 'dpIdList' => $dpIds ]; $list = array_combine(array_column($list, 'field_name'), $list); foreach ($attrs as $attr) { $fieldName = $attr['field_name']; // 日期类型 为空时 跳过 if (($attr['type'] == AttrModel::ATTR_TYPE_DATE) && empty($list[$fieldName]['attr_value']) ) { continue; } // 防止前端未传参时,赋值为null,UC在保存自定义属性的值时,null会导致保存失败! $data[$fieldName] = $list[$fieldName]['attr_value'] !== null ? $list[$fieldName]['attr_value'] : ''; // 图片、多选项,序列化存储在架构 $serializeAttr = [ AttrModel::ATTR_TYPE_CHECKBOX, AttrModel::ATTR_TYPE_PICTURE, ]; if (in_array($list[$fieldName]['type'], $serializeAttr) && !empty($data[$fieldName])) { $data[$fieldName] = serialize($data[$fieldName]); } } // 调用验证接口,验证参数传值是否符合规范 $errors = $attrServ->checkValue($data); if (!empty($errors)) { E($errors[0]); } // 编辑前获取用户完整数据,用于编辑后对比组织、岗位、角色变化($userOld非地图逻辑) $userSdk = &User::instance(); $userOld = $user_old = $userSdk->getByUid($uid); // =========学习地图业务逻辑 Start========= // 未关注的用户不进行对比 if (isset($user_old['memSubscribeStatus']) && $user_old['memSubscribeStatus'] != User::SUBSCRIBE_STATUS_SUBSCRIBED) { $user_old = []; } // =========学习地图业务逻辑 End========= $userServ = new UserService(); $result = $userServ->saveUser($uid, $data); // 新增、修改用户成功时,UC返回该用户的完整信息 if (isset($result['memUid'])) { $uid = $result['memUid']; } // 保存后新的用户数据($userNew非地图逻辑) $userNew = $user_new = $userSdk->getByUid($uid); // =========学习地图业务逻辑 Start========= if (!empty($user_old)) { // 用户部门、岗位和角色数据有差异 if ($this->_contrastRight($user_old, $user_new)) { // 获取新的可参与学习的地图ID $studyMapRight = &StudyMapRight::instance(); $map_ids_old = $studyMapRight->listMapId($user_old); $map_ids_new = $studyMapRight->listMapId($user_new); $diff_ids = array_diff($map_ids_new, $map_ids_old); if (!empty($diff_ids)) { $url = rpcUrl('/Map/Rpc/User/SendNotice'); $parmas = ['uid' => $uid, 'map_ids' => array_values($diff_ids)]; Rpc::phprpc($url)->invoke('index', $parmas); } } } // =========学习地图业务逻辑 End========= // 人员信息被修改,保存变更记录 if ($this->_diffData($userOld, $userNew)) { $recordServ = new UserRecordService(); $recordServ->insert([ 'uid' => $this->uid, 'username' => $this->_login->user['memUsername'], 'edit_uid' => $userNew['memUid'], 'edit_username' => $userNew['memUsername'], 'old_form' => serialize($userOld), 'new_form' => serialize($userNew), ]); } $this->_result = [ 'uid' => $uid ]; } /** * 对比用户部门、岗位和角色数据,有差异则返回true * @param array $user_old 旧的用户数据 * @param array $user_new 新的用户数据 * @return bool */ private function _contrastRight($user_old, $user_new) { // 获取旧数据中部门、岗位和角色ID $old_ids = array_column($user_old['dpName'], 'dpId'); $old_ids[] = $user_old['job']['jobId']; $old_ids[] = $user_old['role']['roleId']; // 获取新数据中部门、岗位和角色ID $new_ids = array_column($user_new['dpName'], 'dpId'); $new_ids[] = $user_new['job']['jobId']; $new_ids[] = $user_new['role']['roleId']; return !empty(array_diff($old_ids, $new_ids)) || !empty(array_diff($new_ids, $old_ids)); } /** * 检查当前用户是否有人员编辑权限 * @author tangxingguo * @return bool */ private function _checkRight() { // 当前员工是否有编辑权限(flag:1=部门;3=人员;5=岗位;6=角色) clear_cache(); // 权限类型 $rightType = self::RIGHT_TYPE_LIST; // 权限数据 $rights = []; // 权限内的人员 $uids = []; $settings = Cache::instance()->get('Common.AppSetting'); if (!empty($settings['manageAuths']['value']['selectedList'])) { foreach ($settings['manageAuths']['value']['selectedList'] as $v) { // 权限代表人员 if ($v['flag'] == self::RIGHT_TYPE_IS_USER) { $uids[] = $v['id']; continue; } // 其他 if (isset($rightType[$v['flag']])) { $rights[$rightType[$v['flag']]][] = $v['id']; } } } $rightUids = $this->_getUids($rights); $uids = array_values(array_unique(array_merge($uids, $rightUids))); return in_array($this->uid, $uids) ? true : false; } /** * 通过组织、岗位、角色获取人员UID * @author tangxingguo * @param $data * @return array */ private function _getUids($data) { $uids = []; $userServ = &User::instance(); // 组织 if (isset($data['dp_ids'])) { $conds = [ 'dpIdList' => $data['dp_ids'], 'departmentChildrenFlag' => 1 ]; $list = $userServ->listAll($conds); if (!empty($list)) { $uids = array_column($list, 'memUid'); } } // 岗位 if (isset($data['job_ids'])) { $conds = [ 'jobIdList' => $data['job_ids'] ]; $list = $userServ->listAll($conds); if (!empty($list)) { $uids = array_merge($uids, array_column($list, 'memUid')); } } // 角色 if (isset($data['role_ids'])) { $conds = ['roleIdList' => $data['role_ids']]; $list = $userServ->listAll($conds); if (!empty($list)) { $uids = array_merge($uids, array_column($list, 'memUid')); } } return $uids; } /** * 对比数据 * @author tangxingguo * @param $oldData * @param $newData * @return bool */ private function _diffData($oldData, $newData) { // 对比用户部门、岗位和角色数据,有差异则返回true if ($this->_contrastRight($oldData, $newData)) { return true; } // 对比属性 $keys = ['memEmail', 'memUsername', 'memGender', 'memTelephone', 'custom1', 'custom2', 'custom3', 'custom4', 'custom5', 'custom6', 'custom7', 'custom8', 'custom9', 'custom10']; $oldData = array_intersect_key_reserved($oldData, $keys, true); $newData = array_intersect_key_reserved($newData, $keys, true); foreach ($newData as $k => $v) { if ($v == $oldData[$k]) { continue; } if ($v != $oldData[$k]) { // 非序列化数据 if (!is_serialized($v)) { return true; } // 序列化信息判断 if (!is_serialized($oldData[$k])) { // 老数据非序列化数据 return true; } $newAttr = unserialize($v); $oldAttr = unserialize($oldData[$k]); if ($newAttr[0]['name'] != $oldAttr[0]['name'] || $newAttr[0]['value'] != $oldAttr[0]['value']) { return true; } } } return false; } }