<?php /** * 考勤签到表Service * * @author: houyingcai * @email: 594609175@qq.com * @date : 2017-08-29 16:35:26 * */ namespace Common\Service; use Common\Common\ExportDownload; use Common\Model\EducationModel; use Common\Model\PlanModel; use Common\Model\RightUsersModel; use Common\Model\SignModel; use Com\PythonExcel; class SignService extends AbstractService { // 未默认状态 const SIGN_DEFAULT = 3; // 已签到 const SIGN_DO = 1; // 缺勤 const SIGN_NOT_DO = 2; // 审核通过 const CHECK_PASS = 1; /** @var PlanModel */ protected $plan_d; /** @var EducationModel */ protected $education_d; /** @var RightUsersModel */ protected $right_user_d; public function __construct() { $this->_d = new SignModel(); $this->plan_d = new PlanModel(); $this->education_d = new EducationModel(); $this->right_user_d = new RightUsersModel(); parent::__construct(); } /** * 考勤列表接口 * * @author 蔡建华 * @param array $params 搜索参数 * @param array $page_option 分页参数 * * @return array */ public function sign_search_list($params = [], $page_option = null) { // 默认值 $page = !empty($params['page']) ? intval($params['page']) : self::PAGE_DEFAULT; $limit = !empty($params['limit']) ? intval($params['limit']) : self::PAGE_LIMIT_DEFAULT; if (empty($params['plan_id'])) { E('_EMPTY_PLAN_ID'); } $plan = $this->plan_d->get($params['plan_id']); $education = $this->education_d->get($plan['ed_id']); // 判断计划信息是否存在 if (empty($plan)) { E('_EMPTY_PLAN_LIST'); } $uids = []; // 部门,角色,岗位,用户名查询 if (!empty($params['dpIDs']) || !empty($params['jobID']) || !empty($params['roleID']) || !empty($params['memUsername'])) { // 根据搜索条件获取用户ID集合(此处为各条件获取的用户uid的交集) $uids = $this->list_uids_by_dp_job_role($params['dpIDs'], $params['roleID'], $params['jobID'], $params['memUsername']); if (empty($uids)) { return [ 'total' => 0, 'limit' => intval($limit), 'page' => intval($page), 'list' => [], ]; } } $sign_list = []; // 根据签到状态搜索签到人员 $sign_status = intval($params['sign_status']); // 搜索已签到和缺勤 if (self::SIGN_DO == $sign_status) { // 已签到 // 按照签到时间进行倒序排列 $order_option = ['sign_on_time' => 'DESC']; $conds = [ 'plan_id' => $params['plan_id'], 'article_id' => $params['article_id'], ]; // 按照部门,角色,岗位,用户名称查询 if ($uids) { $conds['sign_uid'] = $uids; } // 列表总数 $total = $this->_d->list_by_conds($conds); if ($total > 0) { $fields = 'sign_id,sign_uid,sign_on_time,ed_id,plan_id'; $data = $this->_d->list_by_conds($conds, $page_option, $order_option, $fields); // 提取用户 $ru_uids = array_column($data, 'sign_uid'); // 签到列表 $sign_list = array_combine_by_key($data, 'sign_uid'); } } elseif (self::SIGN_NOT_DO == $sign_status) { // 缺勤 // 按照签到时间进行倒序排列 $order_option = ['ru_id' => 'asc']; // 按照部门,角色,岗位,用户名称查询 if ($uids) { $conds['ru_uid'] = $uids; } // 报名成功 $conds['ru_sign_status'] = RightUsersService::SIGN_SUCCESS; $conds['ed_id'] = $plan['ed_id']; // 开启审核 if (EducationService::EDUCATION_CHECK == $education['ed_is_check']) { $conds['ru_check_status'] = self::CHECK_PASS; } // 查询班级表 $fields = 'ru_uid'; $user_list = $this->right_user_d->list_by_conds($conds, null, $order_option, $fields); $user_list = array_combine_by_key($user_list, 'ru_uid'); $ru_uids = array_column($user_list, 'ru_uid'); $fields = 'sign_id,sign_uid,sign_on_time,ed_id,plan_id'; $where = [ 'plan_id' => $params['plan_id'], ]; // 查询签到表 $sign_list = $this->_d->list_by_conds($where, null, null, $fields); $sign_list_uids = array_column($sign_list, 'sign_uid'); // 没有签到的用户uid集合 $diff_uids = array_diff($ru_uids, $sign_list_uids); $total = count($diff_uids); // 初始化未签到的用户列表 $sign_list = []; if ($total) { // 获取未签到用户的班级表信息 foreach ($diff_uids as $no_sing_uid) { $sign_list[] = $user_list[$no_sing_uid]; } if ($page_option != null) { // 数组分页 $sign_list = array_slice($sign_list, $page_option[0], $limit); } // 分页后的用户UID $ru_uids = array_column($sign_list, 'ru_uid'); } } else { // 全部 // 按照签到时间进行倒序排列 $order_option = ['ru_id' => 'asc']; // 按照部门,角色,岗位,用户名称查询 if ($uids) { $conds['ru_uid'] = $uids; } // 报名成功 $conds['ru_sign_status'] = RightUsersService::SIGN_SUCCESS; $conds['ed_id'] = $plan['ed_id']; // 开启审核 if (EducationService::EDUCATION_CHECK == $education['ed_is_check']) { $conds['ru_check_status'] = self::CHECK_PASS; } $total = $this->right_user_d->count_by_conds($conds); if ($total > 0) { // 查询班级表 $fields = 'ru_uid'; $user_list = $this->right_user_d->list_by_conds($conds, $page_option, $order_option, $fields); $ru_uids = array_column($user_list, 'ru_uid'); $fields = 'sign_id,sign_uid,sign_on_time,ed_id,plan_id'; $where = [ 'plan_id' => $params['plan_id'], ]; // 查询签到表 $sign_list = $this->_d->list_by_conds($where, null, null, $fields); // 转换键值 $sign_list = array_combine_by_key($sign_list, 'sign_uid'); } } $list = $this->format_sign_list($ru_uids, $sign_list, $page, $limit); // 组装返回数 return [ 'total' => intval($total), 'limit' => intval($limit), 'page' => intval($page), 'list' => $list, ]; } /** * 签到列表数据格式化 * * @author 蔡建华 * * @param $uids array 用户UID * @param $sign_list array 签到数据 * @param $page int 页码 * @param $limit int 每页条数 * * @return array */ protected function format_sign_list($uids, $sign_list, $page, $limit) { if (empty($uids)) { return []; } $result = []; $user_list = $this->get_all_user_by_cache($uids); // 开始条数 $start = ($page - 1) * $limit; foreach ($uids as $key => $val) { $value = []; // 排序序号 $value['order_num'] = $start + $key + 1; $_user = $user_list[$val]; $value['memUsername'] = $_user['memUsername']; // 部门去重 $dpName = array_column($_user['dpName'], 'dpName'); array_unique($dpName); $value['dpName'] = implode(',', $dpName); $value['jobName'] = $_user['memJob']; $value['roleName'] = $_user['memRole']; $value['sign_id'] = intval($sign_list[$val]['sign_id']); // 已经签到 if ($sign_list[$val]['sign_on_time']) { $value['sign_on_time'] = $sign_list[$val]['sign_on_time']; $value['sign_status'] = self::SIGN_DO; } else { // 缺勤 $value['sign_status'] = self::SIGN_NOT_DO; $value['sign_on_time'] = ''; } $result[] = $value; } return $result; } /** * 考勤下载列表接口 * * @author 蔡建华 * @param $params array 请求参数 * @param $user array 后台用户详情 * * @return bool */ public function sign_download_list($params = [], $user = []) { if (empty($params['ed_id'])) { return false; } // 判断计划信息是否存在 $planlist = $this->plan_d->list_by_conds( [ 'ed_id' => $params['ed_id'], 'plan_type' => self::SIGN_DO ], null, ['plan_order' => 'ASC', 'plan_id' => 'DESC'] ); // 判断签到计划是否存在 if (empty($planlist)) { return false; } // 培训详情 $education = $this->education_d->get($params['ed_id']); if (empty($education)) { return false; } // 员工班级ID正序排列 $order_option = ['ru_id' => 'ASC']; // 查询已报名状态 $conds['ru_sign_status'] = RightUsersService::SIGN_SUCCESS; // 开启审核 if (EducationService::EDUCATION_CHECK == $education['ed_is_check']) { $conds['ru_check_status'] = self::CHECK_PASS; } // 培训ID $conds['ed_id'] = $params['ed_id']; $ru_uids = []; $total = $this->right_user_d->count_by_conds($conds); $sign_list = []; if ($total > 0) { // 查询班级表 $fields = 'ru_uid'; $user_list = $this->right_user_d->list_by_conds($conds, null, $order_option, $fields); $ru_uids = array_column($user_list, 'ru_uid'); // 查询签到表字段 $fields = 'sign_id,sign_uid,sign_on_time,ed_id,plan_id'; // 签到计划条件 $where = [ 'ed_id' => $params['ed_id'], 'article_id' => 0 // 过滤线下课程签到 ]; // 查询签到表 $sign_list = $this->_d->list_by_conds($where, null, null, $fields); // 转换键值 $sign_list = array_combine_by_key($sign_list, 'sign_uid'); } // 格式化数据 $data = $this->format_down_list($ru_uids, $sign_list, $planlist); // 下载 $this->_download($data, $education['ed_name'], $user); return true; } /** * 考勤下载数据格式化 * * @author 蔡建华 * @param $uids array 用户UID(所有已报名的班级人员UID) * @param $sign_list array 签到数据(在任一签到场次签到的人员列表) * @param $planlist array 签到场次(所有的签到场次列表) * * @return array */ protected function format_down_list($uids, $sign_list, $planlist) { // 初始化签到信息列表 $list = []; if (!empty($uids)) { // 查询用户缓存 $user_list = $this->get_all_user_by_cache($uids); // 任一场次签到的所有人员UID列表 $sign_uids = array_column($sign_list, 'sign_uid'); // 所有场次均未签到的人员UID列表 $unsign_uids = array_diff($uids, $sign_uids); // 获取所有场次均未签到的人员信息 $unsign_user_list = []; foreach ($unsign_uids as $val) { $unsign_user_list[] = [ $user_list[$val]['memUsername'], implode(',', array_unique(array_column($user_list[$val]['dpName'], 'dpName'))), $user_list[$val]['memJob'], $user_list[$val]['memRole'], '', '缺勤', ]; } foreach ($planlist as $plan) { // 初始化对应场次未签到的人员信息列表 $plan_unsign_user_list = []; // 将所有签到的人员分发到对应的签到场次中 foreach ($sign_list as $v) { if ($v['plan_id'] == $plan['plan_id']) { // 对应场次签到的人员信息列表 $list[$plan['plan_id']][] = [ $user_list[$v['sign_uid']]['memUsername'], implode(',', array_unique(array_column($user_list[$v['sign_uid']]['dpName'], 'dpName'))), $user_list[$v['sign_uid']]['memJob'], $user_list[$v['sign_uid']]['memRole'], empty($v['sign_on_time']) ? '' : rgmdate(strval($v['sign_on_time']), "Y-m-d H:i:s"), empty($v['sign_on_time']) ? '' : '已签到' ]; } else { // 对应场次未签到的人员信息列表 $plan_unsign_user_list[] = [ $user_list[$v['sign_uid']]['memUsername'], implode(',', array_unique(array_column($user_list[$v['sign_uid']]['dpName'], 'dpName'))), $user_list[$v['sign_uid']]['memJob'], $user_list[$v['sign_uid']]['memRole'], '', '缺勤', ]; } } // 对应场次所有未签到的人员信息合并 if (empty($unsign_user_list)) { $all_unsign_user_list = $plan_unsign_user_list; } else { $all_unsign_user_list = array_merge($unsign_user_list, $plan_unsign_user_list); } // 对应场次所有已签到和未签到人员信息合并 if (empty($list[$plan['plan_id']])) { $list[$plan['plan_id']] = $all_unsign_user_list; } else { $list[$plan['plan_id']] = array_merge($list[$plan['plan_id']], $all_unsign_user_list); } } } return [ 'list' => $list, 'planlist' => $planlist ]; } /** * 导出模板 * * @author 蔡建华 * @param array $list 列表数据 * @param string $name 培训名称 * @param $user array 后台用户详情 * @return bool */ private function _download($list = [], $name = '', $user = []) { // 初始化导出数据 $row_data = []; $file_name = $name . '-签到-' . rgmdate((string)NOW_TIME, 'Ymd'); $title = [ '员工姓名', '组织', '岗位', '角色', '签到时间', '签到状态' ]; $temp = $list['list']; // 按照签到场次组装 $sheets = []; foreach ($list['planlist'] as $k => $v) { if (in_array($v['plan_name'], $sheets)) { // 如果sheet名字重复自定加一 $sheets[] = $v['plan_name'] . '_' . $k; } else { // sheet名字组合 $sheets[] = $v['plan_name']; } $value = [ 'columns' => $title, 'rows' => isset($temp[$v['plan_id']]) ? $temp[$v['plan_id']] : [] ]; $row_data[] = $value; } // 生成Excel $realpath = ExportDownload::get_down_dir($user['eaId'] . microtime(true)) . NOW_TIME . ".xls"; $ret = PythonExcel::instance()->writeSheet($realpath, $sheets, $row_data); if ($ret) { $conditon = [ 'title' => $file_name, 'ea_id' => $user['eaId'], 'username' => $user['eaRealname'], 'type' => ExportDownload::EXCEL_TYPE, 'url' => $realpath ]; ExportDownload::insert_down_load($conditon); } return true; } /** * 导出线下课程签到数据 * @author zhonglei * @param array $article 线下课程数据 * @param array $data 线下课程签到数据 * @param array $user 管理员数据 * @return void */ public function exportArticleSignData($article, $data, $user) { $titles = [ '员工姓名', '组织', '岗位', '角色', '签到时间', '签到状态' ]; $realpath = ExportDownload::get_down_dir($user['eaId'] . microtime(true)) . MILLI_TIME . '.xls'; $ret = PythonExcel::instance()->write($realpath, $titles, $data); if ($ret) { $conditon = [ 'title' => "{$article['article_title']}-签到-" . rgmdate(MILLI_TIME), 'ea_id' => $user['eaId'], 'username' => $user['eaRealname'], 'type' => ExportDownload::EXCEL_TYPE, 'url' => $realpath ]; ExportDownload::insert_down_load($conditon); } } }