<?php
/**
 * @link      http://www.u-bo.com
 * @copyright 南京友博网络科技有限公司 
 * @license   http://www.u-bo.com/license/
 */

namespace qcbase\models;

use Yii;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\helpers\Url;
use common\components\Tree;
use common\components\Tool;
use common\models\User;
use yii\helpers\ArrayHelper;

/**
 * 部门信息表 ({{%department}})
 *
 * @property integer $dept_id  (部门信息表)
 * @property string $name  (部门名称)
 * @property integer $parent_id  (上级部门ID)
 * @property string $parent_ids  (父级ID集)
 * @property string $lead_user_id  (部门领导)
 * @property string $verify_user_id (部门审核人)
 * @property string $phone  (部门电话)
 * @property string $fax  (部门传真)
 * @property string $address  (部门地址)
 * @property smallint $sort  (排序)
 * @property smallint $status  (状态：0 禁用 1开启)
 * @property string $remark  (备注部门职能)
 * @property integer $user_id  (创建人)
 * @property integer $create_time  (创建时间)
 * @property integer $update_time  (更新时间)
 *
 * @author Strief http://blog.u-bo.com
 * @since 0.1
 */
class Department extends ActiveRecord
{

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%department}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['name', 'status', 'sort', 'parent_id'], 'required'],
            [['parent_id', 'sort', 'status', 'user_id', 'create_time', 'update_time'], 'integer', 'min' => 0],
            [['name', 'lead_user_id', 'verify_user_id'], 'string', 'max' => 50],
            [['parent_ids', 'child_ids', 'address', 'remark'], 'string', 'max' => 255],
            [['phone', 'fax'], 'string', 'max' => 55]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'dept_id' => 'ID',
            'name' => '部门名称',
            'parent_id' => '上级部门',
            'parent_ids' => 'Parent Ids',
            'child_ids' => 'Child Ids',
            'lead_user_id' => '部门领导',
            'verify_user_id' => '部门审核人',
            'phone' => '部门电话',
            'fax' => '部门传真',
            'address' => '部门地址',
            'sort' => '排序',
            'status' => '状态',
            'remark' => '备注',
            'user_id' => '创建人',
            'create_time' => '创建时间',
            'update_time' => '更新时间',
        ];
    }

    /**
     * 获取领导人信息
     * 
     * @return type
     */
    public function getLeader()
    {
        $fields = User::getSafeFields();
        return $this->hasOne(User::className(), ['user_id' => 'lead_user_id'])->select($fields);
    }

    public static function getDropDownList($needTop = false)
    {
        $list = [];
        $rows = self::getList();
        //\common\components\Tool::dump($rows);
        $needTop && $list[0] = '----顶级部门----';
        foreach ($rows as $row) {
            if (isset($row['dept_id'])) {
                $list[$row['dept_id']] = str_replace('&nbsp;', ' ', $row['tree_spacer']) . $row['name'];
            }
        }
        return $list;
    }

    /**
     * 获取部门列表
     *
     * @param type $field 字段
     * @param type $map 查询条件
     * @param type $order 排序
     * @param type $with 联合
     * @param type $index 索引
     * @param type $tree 返回树形数据 默认true   --HuLimin--20141211
     * @return type
     */
    public static function getList($field = "*", $map = [], $order = [], $with = null, $index = null, $tree = true)
    {
        $query = static::find()
            ->select($field)
            ->orderBy($order);
        if ($map !== null && is_array($map)) {
            foreach ($map as $m) {
                $query->andWhere($m);
            }
        }
        if ($with !== null) {
            $query->with($with);
        }
        if ($index !== null) {
            $query->indexBy($index);
        }
        $list = $query->asArray()->all();
        if ($tree) {
            $list = Tree::getList($list, 'dept_id', 'parent_id');
            $list = ArrayHelper::index($list, 'dept_id');
        }
        return $list;
    }

    /**
     * 获取部门已经其子部门ID
     * 
     * @param type $where
     *
     * @author HuLimin <http://blog.u-bo.com>
     * @since 0.1
     */
    public static function getDeptmentAndChildsIds($where = [])
    {
        $deptIds = static::find()
            ->where($where)
            ->select('child_ids')
            ->column();
        $deptIds = explode(',', implode(',', $deptIds));
        return $deptIds;
    }

    /**
     * 根据以","相隔的部门id获取部门名称
     *
     * @param type $deptStr
     * @return string
     */
    public static function getDeptmentByDot($deptStr)
    {
        if (empty($deptStr)) {
            return '';
        }
        $deptIds = explode(',', $deptStr);
        $dept = static::find()
            ->select('name')
            ->where(['dept_id' => $deptIds])
            ->column();
        return implode('，', $dept);
    }

    /**
     * 设置缓存
     */
    public static function setCache()
    {
        $cache = Yii::$app->cache;

        $deptList = self::getList('*', [], [], null, null, false);
        $cache->set('department_list', $deptList);

        foreach ($deptList as $key => $value) {
            $dropdownList[$value['dept_id']] = $value['name'];
        }
        $cache->set('department_dropdown_list', $dropdownList);

        $deptTreeList = self::getList('*', [], [], null, null, true);
        $cache->set('department_tree_list', $deptTreeList);
    }

    /**
     * 公共搜索所需信息 
     */
    public function search()
    {
        return [
            'title' => '部门名称',
        ];
    }

    /**
     * 插入更新前置操作
     */
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            //判断是否是插入操作
            if ($this->isNewRecord) {
                $this->user_id = Yii::$app->user->identity->user_id;
                $this->create_time = time();
            }
            $this->update_time = time();
            return true;
        } else {
            return false;
        }
    }

    /**
     * 更新后更新部门表
     */
    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        //先更新父级ID集，子集ID集以便更新状态
        self::repairDept();
        //若用户修改了部门的状态则更新其子部门状态
        if ($this->status != $changedAttributes['status']) {
            self::updateStatus($this->dept_id);
        }
        //检查更新部门禁用状态
        self::updateStatusFalse();
        
        \qcbase\models\ActionLog::insertLog('home','修改',json_encode($changedAttributes));
    }

    /**
     * 删除后更新部门表
     */
    public function afterDelete()
    {
        parent::afterDelete();
        self::repairDept();
    }

    /**
     * 更新部门列表里的父级ID集，子ID集，是否有子列
     */
    public static function repairDept()
    {
        $dept = self::find()->indexBy('dept_id')->all();
        if (is_array($dept)) {
            $command = Yii::$app->db->createCommand();
            //先更新父级ID集
            foreach ($dept as $id => $depart) {
                $dept[$id]['parent_ids'] = $parent_ids = self::getParentids($id);
                $command->update('{{%department}}', ['parent_ids' => $parent_ids], 'dept_id=:id', [':id' => $id])->execute();
            }
            //通过更新后的父级ID集更新子ID集
            foreach ($dept as $id => $depart) {
                $dept[$id]['child_ids'] = $child_ids = self::getChildids($id);
                $command->update('{{%department}}', ['child_ids' => $child_ids], 'dept_id=:id', [':id' => $id])->execute();
            }
        }
    }

    /**
     * 获取父级ID集
     * 
     * @param  integer $id          表ID
     * @param  string  $arrparentid 父级ID集
     * @return string  $arrparentid 父级ID集
     */
    public static function getParentids($id, $arrparentid = '')
    {
        $dept = self::find()->indexBy('dept_id')->all();
        if (!is_array($dept) || !isset($dept[$id])) return false;
        $parentid = $dept[$id]['parent_id'];
        $arrparentid = $arrparentid ? $parentid . ',' . $arrparentid : $parentid;
        if ($parentid) {
            $arrparentid = self::getParentids($parentid, $arrparentid);
        } else {
            $dept[$id]['parent_ids'] = $arrparentid;
        }
        return $arrparentid;
    }

    /**
     * 获取子ID集
     * 
     * @param  integer $id         表ID
     * @return string  $arrchildid 子ID集
     */
    public static function getChildids($id)
    {
        $dept = self::find()->indexBy('dept_id')->all();
        $arrchildid = $id;
        if (is_array($dept)) {
            foreach ($dept as $deptid => $depart) {
                if ($depart['parent_id'] && $id != $deptid) {
                    $arrparentids = explode(',', $depart['parent_ids']);
                    if (in_array($id, $arrparentids)) {
                        $arrchildid .= ',' . $deptid;
                    }
                }
            }
        }
        return $arrchildid;
    }

    /**
     * 遍历部门表检查部门禁用状态
     * 
     * @param  integer $parentId 父级ID
     * @param  integer $childId  父级ID下的子ID
     */
    public static function updateStatusFalse()
    {
        $parent = $child = self::find()->indexBy('dept_id')->all();
        if (is_array($parent)) {
            foreach ($parent as $parentId => $parentValue) {
                //若当前状态为禁用将其子部门状态
                if ($parentValue['status'] == 0) {
                    self::updateStatus($parentId);
                }
            }
        }
    }

    /**
     * 更新当前修改部门下的子部门状态
     * 
     * @param  integer $id 当前修改的部门ID
     */
    public static function updateStatus($id)
    {
        $parent = static::findOne(['dept_id' => $id]);
        $parentStatus = $parent['status'];
        $childs = $parent['child_ids'];
        $arrparentids = explode(',', $childs);
        $command = Yii::$app->db->createCommand();
        $child = self::find()->indexBy('dept_id')->all();
        //将当前部门下的所有子部门状态与当前部门的状态保持一致
        if (!is_array($child)) {
            return false;
        }
        foreach ($child as $deptid => $depart) {
            if ($depart['parent_id'] && $id != $deptid && in_array($deptid, $arrparentids)) {
                $command->update(self::tableName(), ['status' => $parentStatus], 'dept_id=:id', [':id' => $deptid])->execute();
            }
        }
    }
}
