563 lines
21 KiB
PHP
563 lines
21 KiB
PHP
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
*
|
|
*
|
|
*
|
|
* Date: 2021/9/22
|
|
* Time: 13:37
|
|
*/
|
|
|
|
|
|
namespace business\common\services;
|
|
|
|
use business\common\models\Department;
|
|
use business\common\models\DepartmentStaff;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Exception;
|
|
|
|
class DepartmentService
|
|
{
|
|
|
|
|
|
/*
|
|
* 根据方法获取可操作的部门
|
|
*/
|
|
public static function checkDepartmentIdByMethod($method, $department_id)
|
|
{
|
|
|
|
$right = BusinessService::checkBusinessRight();
|
|
if ($right['identity'] > 1) {
|
|
return true;
|
|
}
|
|
|
|
if (empty($right['route_department_id'][$method])) {
|
|
return false;
|
|
}
|
|
|
|
if (in_array($department_id, $right['route_department_id'][$method])) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
/*
|
|
* 删除部门
|
|
*/
|
|
public static function deleteDepartment($department_id, $is_callback = 0)
|
|
{
|
|
|
|
DB::beginTransaction();
|
|
|
|
try {
|
|
|
|
if (!$department = Department::business()->find($department_id)) {
|
|
throw new Exception('部门不存在');
|
|
}
|
|
|
|
if ($department->level == 1) {
|
|
throw new Exception('一级部门不允许删除');
|
|
}
|
|
|
|
if ($delete_sub_department_id = Department::getAllDepartmentSubId([$department->id])) {
|
|
throw new Exception('请先删除下级部门');
|
|
}
|
|
|
|
if ($is_callback){
|
|
|
|
if (DepartmentStaff::where('department_id', $department->id)->delete()) {
|
|
throw new Exception('请先移除该部门的员工');
|
|
}
|
|
|
|
if (!$department->delete()) {
|
|
throw new Exception('部门删除失败');
|
|
}
|
|
}else{
|
|
if (DepartmentStaff::where('department_id', $department->id)->first()) {
|
|
throw new Exception('请先移除该部门的员工');
|
|
}
|
|
|
|
if (!$department->delete()) {
|
|
throw new Exception('部门删除失败');
|
|
}
|
|
|
|
if ($department->wechat_department_id && SettingService::EnabledQyWx()) {
|
|
$res = (new QyWechatRequestService())->request('deleteDepartment', ['id' => $department->wechat_department_id]);
|
|
if (!$res['result']) {
|
|
throw new Exception($res['msg']);
|
|
}
|
|
}
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
DB::rollBack();
|
|
return self::returnArr(0, $e->getMessage());
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
BusinessService::flush(SettingService::getBusinessId()); //清除企业缓存
|
|
|
|
return self::returnArr(1, '删除部门成功');
|
|
|
|
}
|
|
|
|
/*
|
|
* 创建/编辑部门
|
|
*/
|
|
public static function changeDepartment($name, $parent_id = 0, $id = 0, $order = 0, $enable = 1)
|
|
{
|
|
|
|
DB::beginTransaction();
|
|
|
|
try {
|
|
|
|
$business_id = SettingService::getBusinessId();
|
|
|
|
if ($parent_id) {
|
|
if (!$parent_department = Department::business()->find($parent_id)) {
|
|
throw new Exception('上级部门不存在');
|
|
}
|
|
|
|
if (SettingService::EnabledQyWx() && $parent_department->wechat_department_id == 0) {
|
|
throw new Exception('上级部门未与企业微信关联');
|
|
}
|
|
} else {
|
|
if (!$id && Department::business()->where('level', 1)->first()) {
|
|
throw new Exception('一级部门只允许存在一个');
|
|
}
|
|
}
|
|
|
|
|
|
$update_data = [
|
|
'name' => $name,
|
|
'parent_id' => $parent_id,
|
|
'level' => $parent_department ? $parent_department->level + 1 : 1,
|
|
];
|
|
|
|
if (!$id) {
|
|
|
|
if (Department::where($update_data)->first()) {
|
|
throw new Exception('同一部门下不能存在名称相同的部门');
|
|
}
|
|
|
|
$update_data['order'] = intval($order) ?: 10000;
|
|
if (!$department = Department::create(array_merge($update_data, [
|
|
'business_id' => $business_id,
|
|
'uniacid' => \YunShop::app()->uniacid,
|
|
'wechat_department_id' => 0
|
|
]))) {
|
|
throw new Exception('创建部门失败');
|
|
}
|
|
} else {
|
|
if (!$department = Department::business()->find($id)) {
|
|
throw new Exception('部门不存在');
|
|
}
|
|
if (intval($order)) $update_data['order'] = intval($order);
|
|
$department->fill($update_data);
|
|
$department->save();
|
|
}
|
|
|
|
if (SettingService::EnabledQyWx() && $enable) { //如果开启了企业微信设置,进行推送
|
|
$res = self::pushDepartment($department);
|
|
if (!$res['result']) {
|
|
throw new Exception($res['msg']);
|
|
}
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
DB::rollBack();
|
|
return self::returnArr(0, $e->getMessage());
|
|
}
|
|
|
|
DB::commit();
|
|
BusinessService::flush(SettingService::getBusinessId()); //清除企业缓存
|
|
|
|
return self::returnArr(1, '成功');
|
|
|
|
}
|
|
|
|
/*
|
|
* 推送部门到企业微信
|
|
*/
|
|
public static function pushDepartment(Department $department)
|
|
{
|
|
try {
|
|
|
|
if ($department->level == 1 && !$department->wechat_department_id) {
|
|
$first_department = (new QyWechatRequestService())->request('getDepartmentList');
|
|
foreach ($first_department['data']['department'] as $v) {
|
|
if ($v['parentid'] == 0 && $v['name'] == $department->name) {
|
|
$department->wechat_department_id = $v['id'];
|
|
$department->save();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$department->wechat_department_id) {
|
|
throw new Exception('一级部门未与企业微信关联');
|
|
}
|
|
}
|
|
|
|
if ($department->level != 1 && !$department->hasOneParentDepartment->wechat_department_id) {
|
|
throw new Exception($department->name . '的上级部门未与企业微信关联');
|
|
}
|
|
|
|
$request_data = [
|
|
'id' => $department->wechat_department_id ?: 0,
|
|
'name' => $department->name,
|
|
'parent_id' => $department->hasOneParentDepartment->wechat_department_id ?: 0,
|
|
'order' => $department->order,
|
|
];
|
|
|
|
//判断是创建同步 还是 编辑同步
|
|
$function = $request_data['id'] ? 'updateDepartment' : 'createDepartment';
|
|
$res = (new QyWechatRequestService())->request($function, $request_data);
|
|
|
|
if (!$res['result']) {
|
|
throw new Exception($res['msg']);
|
|
}
|
|
|
|
if ($function == 'createDepartment') {
|
|
$department->wechat_department_id = $res['data']['id'];
|
|
$department->save();
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
return self::returnArr(0, $e->getMessage());
|
|
}
|
|
|
|
return self::returnArr(1, '推送部门成功');
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* 给部门添加权限数据
|
|
*/
|
|
public static function addDepartmentPremission($data, &$right = [], $parent_name = '', &$count = [])
|
|
{
|
|
if (!$count) {
|
|
$count = DepartmentStaff::business()->select(DB::raw('COUNT(distinct staff_id) as count'), 'department_id')->groupBy('department_id')->get()->toArray();
|
|
$count = array_column($count, 'count', 'department_id');
|
|
}
|
|
$function_arr = ['createDepartment', 'updateDepartment', 'deleteDepartment', 'getStaffList', 'createStaff', 'updateStaff'];
|
|
if (!$right) {
|
|
$right = BusinessService::checkBusinessRight();
|
|
}
|
|
foreach ($data as &$v) {
|
|
$v['staff_count'] = $count[$v['id']] ?: 0;
|
|
$v['parent_name'] = $parent_name;
|
|
$v['premission']['setDepartmentLeader'] = $right['identity'] > 1 ? 1 : 0;
|
|
foreach ($function_arr as $vv) {
|
|
if ($right['identity'] > 1) {
|
|
$v['premission'][$vv] = 1;
|
|
} else {
|
|
$v['premission'][$vv] = in_array($v['id'], $right['route_department_id'][$vv]) ? 1 : 0;
|
|
}
|
|
}
|
|
$v['create_staff_disabled'] = $v['premission']['createStaff'] ? false : true;
|
|
$v['update_staff_disabled'] = $v['premission']['updateStaff'] ? false : true;
|
|
$v['create_department_disabled'] = $v['premission']['createDepartment'] ? false : true;
|
|
if ($v['has_one_sub_department']) {
|
|
$v['has_one_sub_department'] = self::addDepartmentPremission($v['has_one_sub_department'], $right, $v['name'], $count);
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
|
|
/*
|
|
* 获取部门列表
|
|
*/
|
|
public static function getDepartmentList($parent_id = 0)
|
|
{
|
|
if (!$business_id = SettingService::getBusinessId()) {
|
|
return self::returnArr(0, '请先选择要管理的企业');
|
|
}
|
|
|
|
$where = [['business_id', $business_id],];
|
|
|
|
if ($parent_id) {
|
|
if (!$parent_department = Department::uniacid()->where($where)->find($parent_id)) {
|
|
return self::returnArr(0, '部门不存在');
|
|
}
|
|
$where[] = ['level', '>', $parent_department->level];
|
|
}
|
|
|
|
$department_list = Department::uniacid()->where($where)->orderBy('order', 'DESC', 'id', 'ASC')
|
|
->select('id', 'business_id', 'name', 'level', 'parent_id', 'wechat_department_id', 'order')->get();
|
|
|
|
$return_data = [];
|
|
if ($parent_department) {
|
|
$return_data[] = $parent_department->toArray();
|
|
} elseif ($department_list->isNotEmpty()) {
|
|
$return_data = $department_list->where('level', 1)->values()->toArray();
|
|
}
|
|
|
|
$department_list = $department_list->toArray();
|
|
foreach ($return_data as $k => $v) {
|
|
$return_data[$k]['has_one_sub_department'] = self::foreachDepartment($department_list, $v['id']);
|
|
}
|
|
|
|
return self::returnArr(1, '成功', $return_data);
|
|
}
|
|
|
|
|
|
/*
|
|
* 递归获取部门列表下级(不使用集合,很慢)
|
|
*/
|
|
public static function foreachDepartment(&$department_list, $id)
|
|
{
|
|
$res = [];
|
|
foreach ($department_list as $k => $v) {
|
|
if ($v['parent_id'] == $id) {
|
|
unset($department_list[$k]);
|
|
$v['has_one_sub_department'] = static::foreachDepartment($department_list, $v['id']);
|
|
if (empty($v['has_one_sub_department'])) {
|
|
unset($v['has_one_sub_department']);
|
|
}
|
|
$res[] = $v;
|
|
}
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
/*
|
|
* 获取所有下级部门id(包括当前)
|
|
*/
|
|
public static function getDepartmentChildIds($department_ids,$business_id = 0)
|
|
{
|
|
$department_list = Department::business($business_id)->select('id', 'name', 'level', 'parent_id')->get();
|
|
$check_department_list = $department_list->whereIn('id', $department_ids);
|
|
$group_department_list = $department_list->groupBy('level');
|
|
|
|
static::$department_ids = array();
|
|
unset($department_list);
|
|
foreach ($check_department_list as $department) {
|
|
static::recursionDown($department, $group_department_list);
|
|
}
|
|
$ids = array_values(array_filter(array_unique(static::$department_ids)));
|
|
static::$department_ids = array();
|
|
|
|
return $ids;
|
|
}
|
|
|
|
static $department_ids = array();
|
|
|
|
public static function recursionDown(Department $department, Collection $groupList)
|
|
{
|
|
if (in_array($department->id, static::$department_ids)) {
|
|
return static::$department_ids;
|
|
}
|
|
static::$department_ids[] = $department->id;
|
|
if (!$group = $groupList[$department->level + 1]) {
|
|
return static::$department_ids;
|
|
}
|
|
|
|
foreach ($group as $key => $item) {
|
|
if ($item->id == $department->parent_id) {
|
|
unset($group[$key]);
|
|
static::recursionDown($item, $groupList);
|
|
}
|
|
}
|
|
|
|
return static::$department_ids;
|
|
}
|
|
|
|
|
|
/*
|
|
* 从企业微信同步部门列表
|
|
*/
|
|
public static function refreshDepartment($business_id = 0)
|
|
{
|
|
|
|
try {
|
|
if (!$business_id = $business_id ?: SettingService::getBusinessId()) {
|
|
throw new Exception('请先选择要管理的企业');
|
|
}
|
|
$class = new QyWechatRequestService();
|
|
$res = $class->request('getDepartmentList');
|
|
if (!$res['result']) {
|
|
throw new Exception($res['msg']);
|
|
}
|
|
|
|
/*删除部门*/
|
|
$all_department_id_list = array_column($res['data']['department'], 'id');
|
|
Department::business($business_id)->where('wechat_department_id', '<>', 0)->whereNotIn('wechat_department_id', $all_department_id_list)->delete();
|
|
/*删除部门*/
|
|
|
|
if ($department = $res['data']['department']) {
|
|
$department = self::formWechatDepartment($department);
|
|
foreach ($department as $k => $v) {
|
|
foreach ($v as $kk => $vv) {
|
|
$is_create = false;
|
|
$this_isset_department = Department::business($business_id)->with('hasOneParentDepartment')
|
|
->where('wechat_department_id', $vv['id'])->first();
|
|
|
|
if ($this_isset_department) { //判断是否存在已绑定了微信部门并且上级id关联正确的数据
|
|
if (($this_isset_department->hasOneParentDepartment->wechat_department_id != $vv['parentid'] && $vv['parentid'] != 0)) {
|
|
if (!$true_parent_department = Department::business($business_id)->where('wechat_department_id', $vv['parentid'])->first()) {
|
|
$this_isset_department->wechat_department_id = 0;
|
|
$this_isset_department->save();
|
|
$is_create = true;
|
|
unset($this_isset_department);
|
|
} else {
|
|
$old_level = $this_isset_department->level;
|
|
$new_level = $true_parent_department->level + 1;
|
|
$change_level = $new_level - $old_level;
|
|
$this_isset_department->parent_id = $true_parent_department->id;
|
|
$this_isset_department->save();
|
|
if ($change_level != 0) {
|
|
$sub_level_id = Department::getAllDepartmentSubId([$this_isset_department->id]);
|
|
Department::whereIn('id', array_merge([$this_isset_department->id], $sub_level_id))->update([
|
|
'level' => DB::raw("level + {$change_level}")
|
|
]);
|
|
}
|
|
}
|
|
} elseif ($vv['parentid'] == 0 && $this_isset_department->hasOneParentDepartment) {
|
|
$this_isset_department->wechat_department_id = 0;
|
|
$this_isset_department->save();
|
|
$is_create = true;
|
|
unset($this_isset_department);
|
|
}
|
|
} else {
|
|
$is_create = true;
|
|
}
|
|
|
|
|
|
if (!$is_create) { //如果存在已绑定了微信部门并且上级id关联正确的数据
|
|
$this_isset_department->name = $vv['name'];
|
|
$this_isset_department->order = $vv['order'] ?: 1;
|
|
$this_isset_department->save();
|
|
continue;
|
|
}
|
|
|
|
|
|
$where = [
|
|
['name', 'like', $vv['name']],
|
|
['level', $vv['level']]
|
|
];
|
|
$this_isset_departments = Department::uniacid()->with('hasOneParentDepartment')
|
|
->where('business_id', SettingService::getBusinessId())
|
|
->where($where)->get();
|
|
|
|
if ($this_isset_departments->isNotEmpty()) { //判断是否存在层级相同、名称相同 并且 没有关联微信部门 并且 微信上级id正确的部门
|
|
$is_break = false;
|
|
$this_isset_departments->each(function ($value) use (&$is_break, $vv) {
|
|
if (!$is_break && ($vv['parentid'] == $value->hasOneParentDepartment->wechat_department_id || $vv['parentid'] == 0)) {
|
|
$value->wechat_department_id = $vv['id'];
|
|
$value->order = $vv['order'];
|
|
$value->save();
|
|
$is_break = true;
|
|
}
|
|
});
|
|
if ($is_break) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ($vv['parentid']) {
|
|
$parent = Department::business($business_id)->where('wechat_department_id', $vv['parentid'])->first();
|
|
$parent_id = $parent->id ?: 0;
|
|
} else {
|
|
$parent_id = 0;
|
|
$department = Department::business($business_id)->where('level', 1)->first();
|
|
if ($department) {
|
|
$department->name = $vv['name'] ?: '';
|
|
$department->en_name = $vv['en_name'] ?: '';
|
|
$department->order = $vv['order'];
|
|
$department->wechat_department_id = $vv['id'];
|
|
$department->save();
|
|
continue;
|
|
// throw new Exception('只能存在1个一级部门,请将一级部门名称修改为与企业微信一级部门(' . $vv['name'] . ')一致再尝试同步');
|
|
}
|
|
}
|
|
Department::create([
|
|
'uniacid' => \YunShop::app()->uniacid,
|
|
'business_id' => $business_id,
|
|
'name' => $vv['name'] ?: '',
|
|
'en_name' => $vv['en_name'] ?: '',
|
|
'level' => $vv['level'],
|
|
'parent_id' => $parent_id,
|
|
'order' => $vv['order'],
|
|
'wechat_department_id' => $vv['id']
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
BusinessService::flush(SettingService::getBusinessId()); //清除企业缓存
|
|
} catch (Exception $e) {
|
|
return self::returnArr(0, $e->getMessage());
|
|
}
|
|
return self::returnArr(1, '成功');
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* 组装企业微信接口返回的部门列表
|
|
*/
|
|
public static function formWechatDepartment($department)
|
|
{
|
|
$return_data = [];
|
|
$all_data = [];
|
|
do {
|
|
foreach ($department as $k => $v) {
|
|
if ($v['parentid'] == 0) {
|
|
$v['level'] = 1;
|
|
$return_data[$v['level']][] = $all_data[$v['id']] = $v;
|
|
unset($department[$k]);
|
|
} else {
|
|
if (isset($all_data[$v['parentid']])) {
|
|
$v['level'] = $all_data[$v['parentid']]['level'] + 1;
|
|
$return_data[$v['level']][] = $all_data[$v['id']] = $v;
|
|
unset($department[$k]);
|
|
}
|
|
}
|
|
}
|
|
} while (count($department) != 0);
|
|
|
|
return $return_data;
|
|
}
|
|
|
|
|
|
public static function returnArr($result, $msg = '', $data = [])
|
|
{
|
|
return ['result' => $result, 'msg' => $msg, 'data' => $data];
|
|
}
|
|
|
|
// 递归获取当前部门所有下级id
|
|
public static function getDepartmentIds($department_id = 0, $is_identity = false)
|
|
{
|
|
static $ids = array();
|
|
$model = Department::business()->select('id');
|
|
if (!$department_id) {
|
|
$model = $model->where(['level' => 1, 'parent_id' => 0])->get();
|
|
} else {
|
|
$model = $model->where('parent_id', $department_id)->get();
|
|
}
|
|
|
|
if ($model->isNotEmpty()) {
|
|
// $ids = array_unique(array_merge($ids,$model->pluck('id')->toArray()));
|
|
foreach ($model as $v) {
|
|
if ($is_identity) {
|
|
if (!DepartmentService::checkDepartmentIdByMethod('getStaffList', $v->id)) {
|
|
continue;
|
|
}
|
|
}
|
|
$ids[] = $v->id;
|
|
self::getDepartmentIds($v->id, $is_identity);
|
|
}
|
|
}
|
|
|
|
return array_unique($ids);
|
|
}
|
|
|
|
} |