2024-08-31 01:03:37 +08:00

536 lines
18 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/*
* @link http://kodcloud.com/
* @author warlee | e-mail:kodcloud@qq.com
* @copyright warlee 2014.(Shanghai)Co.,Ltd
* @license http://kodcloud.com/tools/license/license.txt
*/
//用户管理【管理员配置用户or用户空间大小变更】
class adminMember extends Controller{
private $model;
function __construct() {
parent::__construct();
$this->model = Model('User');
$this->authCheck();
}
public function authCheck(){
if(KodUser::isRoot()) return;
if(MOD == 'install') return;
$data = Input::getArray(array(
"userID" => array("default"=>null),
"roleID" => array("default"=>2),
));
if(isset($data['userID']) && $data['userID'] == '1') {
show_json(LNG('admin.member.editNoAuth'), false);
}
$roleInfo = Model('SystemRole')->listData($data['roleID']);
if(!in_array(ACTION, array('admin.member.add', 'admin.member.edit'))) return;
if($roleInfo['administrator'] != 1) return; // 1为系统管理员
show_json(LNG('admin.member.editNoAuth'), false);
}
/**
* 根据所在部门获取用户列表
*/
public function get() {
$data = Input::getArray(array(
"groupID" => array("check"=>"require",'default'=>0),
"fields" => array("check"=>"require",'default'=>''),
"status" => array("default"=>null)
));
if(!$data['groupID']){show_json(array(),true);}
if($data['groupID'] == 1) $data['groupID'] = 0; // 根部门id=1获取全部用户
$result = $this->model->listByGroup($data['groupID'], $data);
$this->showUserfilterAllow($result['list']);
show_json($result,true);
}
/**
* 根据用户id获取信息
*/
public function getByID() {
$id = Input::get('id','[\d,]*');
$result = $this->model->listByID(explode(',',$id));
$this->showUserfilterAllow($result);
show_json($result,true);
}
/**
* 搜索用户
*/
public function search() {
$data = Input::getArray(array(
"words" => array("check"=>"require"),
"status" => array("default"=>null),
"parentGroup" => array("check"=>"require",'default'=>false),// 支持多个父部门,多个逗号隔开;
));
if(!$data['parentGroup']){
$result = $this->model->listSearch($data);
}else{
$groupArr = explode(',',$data['parentGroup']);$result = false;
foreach ($groupArr as $groupID) {
$data['parentGroup'] = intval($groupID);
$listSearch = $this->model->listSearch($data);
if(!$result){$result = $listSearch;continue;}
$result['list'] = array_merge($result['list'],$listSearch['list']);
}
if(is_array($result) && is_array($result['list'])){
$result = array_page_split(array_unique($result['list']),$result['pageInfo']['page'],$result['pageInfo']['pageNum']);
}
}
$this->showUserfilterAllow($result['list']);
show_json($result,true);
}
// 过滤不允许的用户信息(根据当前用户可见部门筛选)
private function showUserfilterAllow($list){
$userGroupRootShow = Action("filter.userGroup")->userGroupRootShow(); // 用户所在跟部门;可见范围
$userGroupAdmin = Action("filter.userGroup")->userGroupAdmin();// 用户所在部门为管理员的部门;
if(!$userGroupRootShow || !$list){return $list;}
// 获取完整用户信息, 有部门管理权限且该参数为full才返回用户完整信息,否则精简用户信息(去除邮箱,手机号等敏感信息)
$userAllow = array();
$requestAdmin = isset($this->in['requestFromType']) && $this->in['requestFromType'] == 'admin'; // 后端用户列表;
foreach ($list as $user){
$groupParentAll = array();
foreach ($user['groupInfo'] as $groupInfo){
$parents = Model('Group')->parentLevelArray($groupInfo['parentLevel']);
$groupParentAll = array_merge($parents,$groupParentAll,array($groupInfo['groupID']));
}
$groupParentAll = array_unique($groupParentAll);
$allowShow = array_intersect($groupParentAll,$userGroupRootShow) ? true : false; //是否有交集
$allowFull = array_intersect($groupParentAll,$userGroupAdmin) ? true : false;
if(KodUser::isRoot()){$allowFull = true;$allowShow = true;}//超级管理员(不受权限限制)
if(!$allowShow){continue;}
if($allowFull && $requestAdmin){$userAllow[] = $user;continue;}
$userItem = array();
$allowField = explode(',','userID,avatar,name,nickName,groupInfo');
foreach ($allowField as $key) {
$userItem[$key] = $user[$key];
}
$userAllow[] = $userItem;
}
// pr($userAllow,$list,$userGroupRootShow,$userGroupAdmin);exit;
return $userAllow;
}
/**
* 添加用户
*/
public function add() {
$this->import();
$data = Input::getArray(array(
"userID" => array("default"=>null),
"name" => array("check"=>"require"),
"sizeMax" => array("check"=>"float","default"=>1024*1024*100),
"roleID" => array("check"=>"int"),
"password" => array("check"=>"require"),
"email" => array("check"=>"email", "default"=>""),
"phone" => array("check"=>"phone", "default"=>""),
"nickName" => array("check"=>"require","default"=>""),
"avatar" => array("check"=>"require","default"=>""),
"sex" => array("check"=>"require","default"=>1),//0女1男
"status" => array("default"=>1),
));
if( !ActionCall('filter.userCheck.password',$data['password']) ){
return ActionCall('filter.userCheck.passwordTips');
}
// 1.添加用户
$res = $userID = $this->model->userAdd($data);
if($res <= 0) return show_json($this->model->errorLang($res),false);
// 初始化数据,不记录操作日志;
Model('SourceEvent')->recodeStop();
$groupInfo = json_decode($this->in['groupInfo'],true);
if(is_array($groupInfo)){
$this->model->userGroupSet($userID,$groupInfo,true);
}
// 2.添加用户默认配置
$userInfo = $this->model->getInfo($userID);
$this->settingDefault($userID);
// 3.添加用户默认目录
$sourceID = $userInfo['sourceInfo']['sourceID'];
$this->folderDefault($sourceID);
// 4.添加用户默认轻应用
$desktopID = $userInfo['sourceInfo']['desktop'];
$this->lightAppDefault($desktopID);
Model('SourceEvent')->recodeStart();
return show_json(LNG('explorer.success'), true, $userID);
}
/**
* 用户默认设置——主题、壁纸、界面样式选择等
*/
public function settingDefault($userID){
$default = $this->config['settingDefault'];
$insert = array();
foreach($default as $key => $value){
$insert[] = array(
'type' => '',
'userID' => $userID,
'key' => $key,
'value' => $value
);
}
Model('user_option')->addAll($insert);
}
/**
* 用户默认目录
*/
public function folderDefault($parentID){
$folderDefault = Model('SystemOption')->get('newUserFolder');
$folderList = explode(',', $folderDefault);
foreach($folderList as $name){
$path = "{source:{$parentID}}/" . $name;
IO::mkdir($path);
}
}
/**
* 添加用户轻应用
*/
public function lightAppDefault($desktop){
$list = Model('SystemLightApp')->listData();
$appList = array_to_keyvalue($list, 'name');
$appListID = array_to_keyvalue($list, 'id');
$defaultApp = Model('SystemOption')->get('newUserApp');
$defAppList = explode(',', $defaultApp);
foreach($defAppList as $name){
$app = _get($appListID,$name,_get($appList,$name));
if(!$app) continue;
// [user]/desktop/appName.oexe
$path = "{source:{$desktop}}/" . $app['name'] . '.oexe';
IO::mkfile($path, json_encode_force($app['content']));
}
}
/**
* 编辑
*/
public function edit() {
$data = Input::getArray(array(
"userID" => array("check"=>"int"), // userID=1可以编辑
"name" => array("check"=>"require","default"=>null),
"sizeMax" => array("check"=>"float", "default"=>null),
"roleID" => array("check"=>"int", "default"=>null),
"password" => array("check"=>"require","default"=>''),
"email" => array("check"=>"email", "default"=>null),
"phone" => array("check"=>"phone", "default"=>null),
"nickName" => array("check"=>"require","default"=>null),
"avatar" => array("check"=>"require","default"=>null),
"sex" => array("check"=>"require","default"=>null),//0女1男
"status" => array("check"=>"require","default"=>null),//0-未启用 1-启用
));
// 后台删除这些字段值时为空default=null时data不包含导致没有更新
foreach (array('email','phone','nickName') as $key) {
if (!isset($data[$key]) && isset($this->in[$key])) {
$data[$key] = '';
}
}
if( $data['password'] &&
!ActionCall('filter.userCheck.password',$data['password']) ){
return ActionCall('filter.userCheck.passwordTips');
}
// 不支持修改自己的权限角色;避免误操作;
if($data['userID'] == USER_ID && isset($data['roleID'])){
$user = Session::get('kodUser');
if($user['roleID'] != $data['roleID']){
return show_json(LNG('admin.member.errEditSelfRole'),false);
}
}
// 禁止修改超管角色
$userInfo = $this->model->getInfo($data['userID']);
if ($data['userID'] == '1' && $data['userID'] != USER_ID) {
if(isset($data['roleID']) && $data['roleID'] != $userInfo['roleID']){
return show_json(LNG('admin.member.errEditSelfRole'),false);
}
}
$dataSave = array();$groupSave = false; // 仅处理变化的内容;
foreach($data as $key => $value) {
if($key == 'userID') continue;
if($value == $userInfo[$key]) continue;
$dataSave[$key] = $value;
}
if($dataSave){$res = $this->model->userEdit($data['userID'],$dataSave);}
$groupInfo = json_decode($this->in['groupInfo'],true);
if(isset($this->in['groupInfo'])){
// 编辑用户,必须有至少一个默认部门; 即便是没有权限;
$groupInfo = is_array($groupInfo) ? $groupInfo : array();
$userGroup = array_to_keyvalue($userInfo['groupInfo'],'groupID','auth.id',true);
// 添加到指定部门时;保持原来所在部门权限不变;
$isGroupAppend = isset($this->in['groupInfoAppend']) && $this->in['groupInfoAppend'] == '1';
// 仅添加时,用户所在部门不在设置范围内则自动加入;
foreach ($userGroup as $groupID => $auth){
if($isGroupAppend && !isset($groupInfo[$groupID])){$groupInfo[$groupID] = $auth;}
}
if($userGroup != $groupInfo){
$groupSave = true;$res = 1;
$this->model->userGroupSet($data['userID'],$groupInfo,true);
}
}
$this->in['_change'] = $dataSave;
if($groupSave){$this->in['_change']['groupInfo'] = $_REQUEST['groupInfo'];}
if(!$dataSave && !$groupSave){$res = 1;}
$msg = $res > 0 ? LNG('explorer.success') : $this->model->errorLang($res);
return show_json($msg,($res>0),$data['userID']);
}
/**
* 添加到部门
*/
public function addGroup() {
$data = Input::getArray(array(
"userID" => array("check"=>"int"),
"groupInfo" => array("check"=>"json"),
));
$res = $this->model->userGroupAdd($data['userID'],$data['groupInfo']);
$msg = $res ? LNG('explorer.success') : LNG('explorer.error');
show_json($msg,!!$res);
}
/**
* 从部门删除
*/
public function removeGroup() {
$data = Input::getArray(array(
"userID" => array("check"=>"int"),
"groupID" => array("check"=>"int"),
));
$res = $this->model->userGroupRemove($data['userID'],$data['groupID']);
$msg = $res ? LNG('explorer.success') : LNG('explorer.error');
show_json($msg,!!$res);
}
/**
* 部门迁移
*/
public function switchGroup(){
$data = Input::getArray(array(
"userID" => array("check"=>"int"),
"from" => array("check"=>"int"),
"to" => array("check"=>"int"),
));
$userInfo = $this->model->getInfo($data['userID']);
if(!$userInfo) show_json(LNG('ERROR_USER_NOT_EXISTS'), false);
$authID = 0;
// 删除来源部门,新增到新部门
$groupInfo = !empty($userInfo['groupInfo']) ? $userInfo['groupInfo'] : array();
foreach($groupInfo as $item) {
if($item['groupID'] != $data['from']) continue;
if(isset($item['auth']['id'])) {
$authID = $item['auth']['id'];
}
$this->model->userGroupRemove($data['userID'],$item['groupID']);
break;
}
// 权限无效(无来源部门)时,取权限列表中第一个显示项
if (!$authID) {
$list = Model('Auth')->listData();
foreach ($list as $item) {
if ($item['display'] != '0') {
$authID = $item['id'];
break;
}
}
}
$groupInfo = array($data['to'] => $authID);
$res = $this->model->userGroupAdd($data['userID'],$groupInfo);
$msg = $res ? LNG('explorer.success') : LNG('explorer.error');
show_json($msg,!!$res);
}
/**
* 更新用户状态
*/
public function status(){
$data = Input::getArray(array(
"userID" => array("check"=>"int"),
"status" => array("check"=>"in", "param" => array(0, 1)),
));
$res = $this->model->userStatus($data['userID'], $data['status']);
$msg = $res ? LNG('explorer.success') : LNG('explorer.error');
show_json($msg,!!$res);
}
/**
* 删除
*/
public function remove() {
$id = Input::get('userID','bigger',null,1);
$res = $this->model->userRemove($id);
$msg = $res ? LNG('explorer.success') : LNG('explorer.error');
show_json($msg,!!$res);
}
/**
* 批量导入用户
* @return void
*/
private function import(){
if(!isset($this->in['isImport'])) return;
// 1.上传
if(empty($this->in['filePath'])) {
// 1.1 上传文件——返回前端:>100kb上传分多次请求无法直接获取结果
if (empty($this->in['path'])) {
$path = IO::mkdir(TEMP_FILES . 'import_' . time());
$this->in['path'] = $path;
Action('explorer.upload')->fileUpload();
}
// 1.2 获取上传文件内容
$file = $this->in['path'];
$data = $this->getImport($file);
del_file($file);
if(empty($data['list'])) show_json(LNG('admin.member.uploadInvalid'), false);
$filename = get_path_this($file);
Cache::set(md5('memberImport'.$filename), $data);
show_json('success', true, $filename);
}
$filename = Input::get('filePath','require');
// 获取新增用户进度
$taskId = md5('import-user-'.$filename);
if (isset($this->in['process'])) {
$cache = Cache::get($taskId);
if ($cache) {
Cache::remove($taskId);
show_json($cache,true,1);
}
$data = Task::get($taskId);
show_json($data);
}
Cache::remove($taskId);
// 2.读取数据并新增
$fileData = Cache::get(md5('memberImport'.$filename));
Cache::remove(md5('memberImport'.$filename));
if(!$fileData || empty($fileData['list'])) show_json(LNG('admin.member.uploadDataInvalid'), false);
$data = Input::getArray(array(
'sizeMax' => array('check' => 'require'),
'roleID' => array('check' => 'require'),
'groupInfo' => array('check' => 'require'),
));
$total = (int) $fileData['total'];
$task = new Task($taskId,'importUser',$total,LNG('admin.member.userImport'));
$error = array();
foreach($fileData['list'] as $value) {
$task->update(1);
if(!is_array($value)) continue;
$this->in = array_merge($value, $data);
$res = ActionCallHook('admin.member.add');
if (!$res['code']) $error[$this->in['name']] = $res['data'];
}
$task->task['error'] = $error;
Cache::set($taskId, $task->task);
$task->end();
$success = $total - count($error);
$info = array(
'total' => $total,
'success' => $success,
'error' => $error,
);
$code = (boolean) $success;
$data = $code ? LNG('admin.member.importSuccess') : LNG('admin.member.importFail');
show_json($data, $code, $info);
}
// 获取csv分隔符——编辑后的csv文件不一定是默认的','
private function getCsvSep($line) {
if (empty($line)) return ',';
$data = array();
$separators = array(',', ';', ':', "\t", '|');
foreach ($separators as $separator) {
$fields = explode($separator, $line);
$fields = array_filter($fields, 'trim');
$data[$separator] = count($fields);
}
// 找到字段数量最多的分隔符
$maxCnt = max($data);
return array_search($maxCnt, $data);
}
/**
* 获取导入文件数据
* @param [type] $file
* @return void
*/
private function getImport($file){
if (!$handle = fopen($file, 'r')) {
del_file($file);
show_json('read file error.', false);
}
$line = fgets($handle); // 获取分隔符
$separator = $this->getCsvSep(trim($line));
$dataList = array();
while (($data = fgetcsv($handle,0,$separator)) !== false) {
$dataList[] = $data;
}
fclose($handle);
// 2.获取列表数据
unset($dataList[0]);
$dataList = array_filter($dataList);
$list = array();
$keys = array('name'=>'','nickName'=>'','password'=>'','sex'=>1,'phone'=>'','email'=>'');
foreach($dataList as $value) {
$tmp = array();
$i = 0;
foreach($keys as $key => $val) {
$val = trim($value[$i]);
$i++;
if($key == 'name' && empty($val)) break;
if($key == 'password' && empty($val)) break;
if (is_null($val)) $val = '';
switch($key) {
case 'name':
case 'nickName':
$val = $this->iconvValue($val);
break;
case 'sex':
$val = $val != '0' ? 1 : 0;
break;
case 'phone':
case 'email':
$val = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $val); // 删除不可见的特殊字符如null
if(!Input::check($val, $key)) $val = '';
break;
default: break;
}
$tmp[$key] = $val;
}
if(empty($tmp) || empty($tmp['name']) || empty($tmp['password'])) continue;
if(isset($list[$tmp['name']])) continue;
$list[$tmp['name']] = array_merge($keys,$tmp);
}
return array(
'list' => array_values($list),
'total' => count($list),
);
}
// 部分文件转换无效
private function iconvValue($value){
// $encoding = array('GB2312', 'GBK', 'GB18030', 'UTF-8', 'ASCII', 'BIG5');
// $charset = mb_detect_encoding($value,$encoding);
// $value = iconv_to($value,$charset,'utf-8');
$charset = get_charset($value);
if(!in_array($charset,array('utf-8','ascii'))){
$value = iconv_to($value, $charset, 'utf-8');
}
return $value;
}
}