上文写到 添加可见范围,此文 如果查询可见范围。话不多说,直接上代码!
// 说白了 就是实例化 表!
$cache = new LotteryListCache(['eid' => $this->eid]);
// 实例化 用户表
$userinfo = new Userinfo();
// 取缓存里面的 用户信息
$user = $userinfo->queryCache($this->uid, ['did','lableid'], $this->eid);
表配置 详情见 存储用户 可见范围,用户可见范围表创建
$assigns = [
'prize_configure' => ['field' => 'toall', 'toall' => '1,2'],
'isrange' => '1',
'uid' => $this->uid,
'did' => empty($user['did']) ? '0' : '0,' . $user['did'],
'lid' => $user['lableid'],
];
// 调用方法 查询用户 是否有相关权限
$lotteryId = $cache->getAsID($assigns,'');
if (empty($lotteryId)){
$lotteryId = [0];
}
$redisCache = Yii::app()->redisCache;
$prizeConfigSet = [];
foreach ($lotteryId as $key => $val){
$prizeConfigSet[$key] = $redisCache->hgetall((new Lottery())->getRedisKey($json['eid'],$val),$val);
}
/**
* @param array $assigns
* @return array
* 用户可见范围 课程/专题/活动 ID集合
* $assigns = [
* 'course'=> ['field'=>'toall' , 'toall'=> '1,2'],
* 'isrange'=> '0,1,3',
* 'uid'=> '33349b03_50b7_980a_c820_754aec93e232',
* 'did'=> '29,681',
* 'lid'=> '41,46',
* ];
*/
public function getAsID($assigns = [], $intersect = 'list', $asid = NULL, $fixData = false)
{
$uid = isset($assigns['uid']) ? UtilsHelper::ArrayImplodeString($assigns['uid']) : '';
$db = Yii::app()->db;
if (isset($assigns['uid']) && !isset($assigns['did']) && !isset($assigns['lid'])) {
$userinfo = $db->createCommand()->select('did,lableid,joiningdate,position')->from('{{userinfo}}')->where('eid = :eid AND uid = :uid', ['eid' => $this->eid, 'uid' => $assigns['uid']])->queryRow();
$assigns['did'] = UtilsHelper::stringExplodeArray(ArrayHelper::getValue($userinfo, 'did'));
$assigns['lid'] = UtilsHelper::stringExplodeArray(ArrayHelper::getValue($userinfo, 'lableid'));
}
// 用户ID
$assigns['uid'] = isset($assigns['uid']) ? UtilsHelper::stringExplodeArray($assigns['uid']) : [];
// 部门 ID
$assigns['did'] = isset($assigns['did']) ? UtilsHelper::stringExplodeArray($assigns['did']) : [];
// 岗位 ID
$assigns['lid'] = isset($assigns['lid']) ? UtilsHelper::stringExplodeArray($assigns['lid']) : [];
// 角色 ID
$assigns['role'] = isset($assigns['role']) ? UtilsHelper::stringExplodeArray($assigns['role']) : [];
$ids = [];
$is_staffing = true;
if ($assigns['uid']) {
$staffing = Userinfo::queryCache(UtilsHelper::ArrayImplodeString($assigns['uid']), 'staffing', $this->eid);
if ($staffing && in_array($this->tableName(), ['exam', 'train', 'course', 'training'])) {
$is_staffing = false;
// 发消息的 消息类型
$type = Messages::msgType($this->tableName(), 'msgType');
$ids = Yii::app()->db->createCommand()->select('asid')->from('{{messages_outsiders}}')->where('eid =:eid and uid=:uid and type=:type', [':eid' => $this->eid, ':uid' => UtilsHelper::ArrayImplodeString($assigns['uid']), ':type' => $type])->queryColumn();
}
}
$this->autoMatchTag = [];
$toall = isset($assigns['toall']) ? $assigns['toall'] : null;
if ($is_staffing) {
//exit(json_encode($assigns));
if (is_array($assigns)) foreach ($assigns as $target => $array) {
if ($target != 'isrange' && $target != 'toall') {
$assign = $array;
if ($target == $this->tableName()) {
$toall = strval(isset($array[$array['field']]) ? $array[$array['field']] : $toall);
foreach (UtilsHelper::stringExplodeArray($toall) as $field) {
$id = $this->getAsidByAssignCache($target, $array['field'], $field);
if ($id) {
$ids = array_merge($ids, $id);
}
}
} else {
foreach ($assigns['isrange'] as $isrange) {
if ($assigns['isrange'] != ['*']) foreach ($assign as $key => $did) {
$field = $did;//规则的字段 toall
$id = $this->getAsidByAssignCache($target, $isrange, $field);
if ($id) {
$ids = array_merge($ids, $id);
}
}
}
}
}
}
//标签自动匹配成员的
$autoMatchLid = SelectAssign::getAutoMatchLid($this->eid);
if ($autoMatchLid && is_array($assigns['isrange'])) {
// 添加 lableid 添加查询标签ID(匹配tag、post)
$this->userInfo = Yii::app()->db->createCommand()->select('joiningdate,position,lableid lid')->from('{{userinfo}}')->where('eid =:eid and uid=:uid', [':eid' => $this->eid, ':uid' => UtilsHelper::ArrayImplodeString($assigns['uid'])])->queryRow();
$this->autoMatchTag = SelectAssign::getAutoMatchTag($this->eid);
if ($this->autoMatchTag) foreach ($this->autoMatchTag as $lid => $rules) {
foreach ($assigns['isrange'] as $isrange) {
$id = $this->getAsidByAssignCache('lid', $isrange, $lid);
if ($id && SelectAssign::autoMatchTag($this->eid, $lid, $rules, $this->userInfo)) {
$ids = array_merge($ids, $id);
}
}
}
}
}
$ids = array_filter($ids);
$ids = array_merge($ids, $this->getLabelDidCid($assigns));
$ids = $this->assignFilter($assigns, $ids);
rsort($ids);
//return $arrays;
if ($intersect != '') {
//去掉下架的数据,取和list的交集
$listID = [];
if ($intersect == 'list') {
$lrangeID = $this->lrange();
if ($toall == '*') {
$ids = $lrangeID;
} else {
$ids = array_intersect($ids, $lrangeID ? $lrangeID : []);
}
//不在可见范围,二次判断
if ($is_staffing && in_array($this->tableName(), ['train', 'exam']) && $asid && $fixData) {
$asid = intval(UtilsHelper::ArrayImplodeString($asid));
if (!in_array($asid, $ids)) {
$ids = $this->getFixAssignData($assigns, $intersect, $asid, $uid, $ids);
}
}
} else if ($intersect == 'set') {
$listID = $this->zrevrange(false, 0, -1, 'set');
if ($toall == '*') {
$ids = $listID;
} else {
$ids = array_intersect_key(array_flip($ids), $listID ? $listID : []);
foreach ($ids as $key => $value) {
$ids[$key] = $listID[$key];
}
}
}
}
return $ids;
}
/**
* 不在可见范围,二次判断
* @param $assigns
* @param $intersect
* @param $asid
* @param $uid
* @param $ids
* @return array|false|mixed
* @throws CException
*/
protected function getFixAssignData($assigns, $intersect, $asid, $uid, $ids)
{
$userInfo = [
'uid' => $uid,
'did' => $assigns['did'],
'lid' => $assigns['lid']
];
$selectAssign = new SelectAssignData($this->eid);
$hasUserVisible = $selectAssign->isUserVisibleContent($this->tableName(), $asid, $userInfo);
if ($hasUserVisible) {
$this->fixAssignData($assigns, $intersect, $asid, $uid, $ids);
$ids[] = $asid;
}
return array_unique($ids);
}
/**
* 修复可见范围缓存。
* @param $assigns
* @param $intersect
* @param $asid
* @param $uid
* @param $ids
* @return array|false
* @throws CDbException
* @throws CException
*/
protected function fixAssignData($assigns, $intersect, $asid, $uid, $ids)
{
//$result = $this->queryAssignArray($this->tableName(), $asid);
//$this->updateAssigns($result, $asid, true);
//$ids = $this->getAsID($assigns, $intersect);
//记录数据后期分析原因
$key = 'assignFixData_' . $this->tableName();
$fixData = Yii::app()->db->createCommand()->select('value')->from('{{userinfo_extend_setting}}')->where("`eid` = :eid AND `uid` = :uid AND `key` = :key", ['eid' => $this->eid, 'uid' => $uid, 'key' => $key])->queryScalar();
$fixData = $fixData ? @json_decode($fixData, true) : [];
$fix = in_array($asid, $ids) ? 1 : 0;
$fixData = array_unique(array_merge(is_array($fixData) ? $fixData : [], [$asid . '-' . $fix]));
$sql = "REPLACE INTO {{userinfo_extend_setting}} (`eid`,`uid`,`key`, `value`) values (" . $this->eid . ", '" . $uid . "', '" . $key . "', '" . json_encode($fixData) . "')";
Yii::app()->db->createCommand($sql)->execute();
return $ids;
}
//从可见范围缓存里读取 asid
protected function getAsidByAssignCache($target, $isrange, $asid)
{
$cacheKey = $this->assignHashCacheKey($target, $isrange);
$id = str_replace(array('"', "[", "]"), "", BaseRedis::hget($cacheKey, $asid));
return $id ? explode(',', $id) : null;
}
protected function getLabelDidCid($assigns)
{
$tagData = $this->getTagDid();
$tagDid = [];
$ids = [];
if ($assigns['did'] && $tagData) {
$this->parentDid = $this->getParentDid($assigns['did']);
$tagId = [];
foreach ($tagData as $did => $tagArray) {
if (in_array($did, $this->parentDid)) {
$tagId = array_merge($tagId, UtilsHelper::stringExplodeArray($tagArray));
}
}
if ($tagId) foreach ($assigns['isrange'] as $isrange) {
$cacheKey = $this->assignHashCacheKey('lid', $isrange);
foreach ($tagId as $lid) {
$cid = BaseRedis::hget($cacheKey, $lid);
if (!empty($cid)) {
$ids = array_merge($ids, explode(',', $cid));
}
}
}
}
return array_unique($ids);
}
/**
* 获取标签关联部门的 可见范围ID
* 标签A包含部门A时,课程A分配给了标签A,当用户在部门A时,也有课程A的可见权限(考试,活动等也一样)
* @param $assigns
* @param $isrange
* @return array
* Created on 2018/3/2 14:27
* Created by xiongyouliang
*/
protected function getLabelDidCid2($assigns, $isrange, $userinfoDid = null)
{
$ids = [];
if (isset($assigns['did'])) {
$cacheKey = 'userinfo_label:hash:eid:' . $this->eid . ':did';
// var_dump($userinfoDid);
$userinfoLabels = BaseRedis::hgetall($cacheKey);
$cacheKey = $this->assignHashCacheKey('lid', $isrange);
$qmodel = new Userinfo();
$userinfoDid = !is_null($userinfoDid) ? $userinfoDid : $qmodel->getUserDepartments($assigns['did']['did'], $this->eid); //查出用户全部部门
if ($userinfoLabels) foreach ($userinfoLabels as $labelDid => $labels) {
//$labelDid 标签指派的部门id
//$userinfoDid 用户所在的部门id
if (in_array($labelDid, $userinfoDid)) {
if (!empty($userinfoLabels)) foreach (explode(',', $labels) as $labelid) {
$cid = BaseRedis::hget($cacheKey, $labelid);
if (!empty($cid)) {
$ids = array_merge($ids, explode(',', $cid));
}
}
}
}
}
return $ids;
}
protected function assignsFilterArray()
{
if ($this->assignFilterTableName) {
return Yii::app()->db->createCommand()->from($this->assignFilterTableName)->select("did,lid,uid,role,asid,isrange,fetch_child_did")->where('eid = :eid', ['eid' => $this->eid])->queryAll();
}
return [];
}
/**
* @param string $target
* @return array
* 可见范围查询数据
*/
protected function assignsArray($target = '', $asid = false)
{
$params = ['eid' => $this->eid];
if ($asid !== false) {
$params['asid'] = $asid;
}
$and = '';
$fields = '`asid`, `isrange`, `fetch_child_did`';
switch ($target) {
case 'uid':
$fields .= ',`uid`';
$and .= ' AND `uid` IS NOT NULL';
break;
case 'did':
$fields .= ',`did`';
$and .= ' AND `did` IS NOT NULL';
break;
case 'lid':
$fields .= ',`lid`';
$and .= ' AND `lid` IS NOT NULL';
break;
case 'classes_id':
$fields .= ', `classes_id`';
$and .= ' AND `classes_id` IS NOT NULL';
break;
case $this->tableName():
if ($this instanceof TrainAssignCache || $this instanceof MessagesAssignCache) {
$fields .= ',`uid`,`did`,`lid`, `classes_id`';
} else {
$fields .= ',`uid`,`did`,`lid`';
}
break;
default:
$results = [];
break;
}
if (!isset($results)) {
$fields .= ',`eid`,`isrange`, `fetch_child_did`';
$sql = $this->assignSql($fields, $asid);
$sql .= $and;
$sql .= ' ORDER BY `isrange` ASC';
$results = $this->query($sql, $params, 'all');
}
return $results;
}
更新缓存 单独拿出来
/**
* 更新权限缓存
*/
public function updateAssigns($target = '', $asid = false, $fixData = false)
{
try {
$stime = microtime(true); //获取程序开始执行的时间
if (is_array($target)) {
$assigns = $target;
} else {
$target = !empty($target) ? $target : $this->tableName();
$assigns = $this->assignArray($target, $asid);
$this->deleteHashAssigns($target);
//BaseRedis::delKeys($target.':assign:'.$this->eid.':*');
}
$assignKeys = [];
$assignsKeys = [];
if (!isset($assigns[$this->eid])) {
// $assigns = $assigns;
} else {
$assigns = $assigns[$this->eid];
}
if (is_array($assigns)) foreach ($assigns as $target => $array) {
foreach ($array as $isrange => $value) {
$cacheKey = $this->assignHashCacheKey($target, $isrange);
$data = [];
$assignsKeys[] = $cacheKey;
foreach ($value as $field => $id) {
if ($target == $this->tableName()) {
$assignKeys[] = $this->assignCacheKey($target, $isrange, $field);
} else {
$assignKeys[] = $this->assignCacheKey($target, $field, $isrange);
}
if ($asid && $fixData) {
$orgAsid = UtilsHelper::stringExplodeArray(BaseRedis::hget($cacheKey, $field));
if ($orgAsid) {
$id = array_merge($orgAsid, $id);
}
}
$data[$field] = join(',', array_unique($id));
//var_dump($assignKeys);
// BaseRedis::hset($cacheKey, $field, join(',', array_unique($id)));
}
if (!empty($data)) {
BaseRedis::hmset($cacheKey, $data);
}
}
}
//缓存筛选框数据
$filterData = $this->getDefaultFilterData();
$assignsFilter = $this->assignsFilterArray();
if ($assignsFilter) foreach ($assignsFilter as $value) {
$target = $this->getAssignTargetRows($value);
if ($target === false) continue;
$fetchChildDid = isset($value['fetch_child_did']) ? intval($value['fetch_child_did']) : 0;
$field = ($fetchChildDid ? '@' : '') . $value[$target];
$isrange = isset($value['isrange']) ? $value['isrange'] : 1;
$filterData[$target][$isrange][$field][] = $value['asid'];
}
if (is_array($filterData)) foreach ($filterData as $target => $array) {
foreach ($array as $isrange => $value) {
$cacheKey = $this->assignHashCacheKey($target . '_filter', $isrange);
BaseRedis::del($cacheKey);
$data = [];
$assignsKeys[] = $cacheKey;
foreach ($value as $field => $id) {
if ($target == $this->tableName()) {
$assignKeys[] = $this->assignCacheKey($target, $isrange, $field);
} else {
$assignKeys[] = $this->assignCacheKey($target, $field, $isrange);
}
rsort($id);
$data[$field] = join(',', array_unique($id));
}
if (!empty($data)) {
BaseRedis::hmset($cacheKey, $data);
}
}
}
$results = [
'assigns' => $assigns,
'assignsKeys' => $assignsKeys,
'assignKeys' => $assignKeys,
'time' => microtime(true) - $stime
];
$this->afterUpdateAssigns($target, $asid, $results, $fixData);
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
/**查询企业全部可见范围数据,用于全量更新缓存
* @param string $target
* @param false $asid
* @param false $returnArray
* @return array|void
*/
protected function assignArray($target = 'course', $asid = false, $returnArray = false)
{
ini_set('memory_limit', '1524M');
$stime = microtime(true); //获取程序开始执行的时间
if (is_array($target)) {
$results = $target;
} else {
$results = $this->assignsArray($target);
}
if ($returnArray == true) {
return $results;
}
return $this->formatAssignArray($target, $results, $asid);
}
/**
*
* 删除可见范围缓存
*/
protected function deleteHashAssigns($target)
{
$cacheKey = $this->assignsKeys($target);
$keys = BaseRedis::smembers($cacheKey);
foreach ($keys as $key) {
BaseRedis::del($key);
}
BaseRedis::del($cacheKey);
}
/**
* 用户可见范围专题列表缓存 按分配对象类型
* @param $id
* @return string
*/
public function assignHashCacheKey($target, $isrange)
{
return $this->tableName() . ':assigns:' . $this->eid . ':' . $target . ':' . $isrange;
}
//筛选框数据
protected function assignsFilterArray()
{
if ($this->assignFilterTableName) {
return Yii::app()->db->createCommand()->from($this->assignFilterTableName)->select("did,lid,uid,role,asid,isrange,fetch_child_did")->where('eid = :eid', ['eid' => $this->eid])->queryAll();
}
return [];
}
/**
* 获取 可见范围对象
* @param array $rows
* @return false|string
*/
public function getAssignTargetRows($rows)
{
$target = false;
if (!empty($rows['toall'])) {
$target = $this->tableName();
} else if (!empty($rows['uid'])) {
$target = 'uid';
} else if (isset($rows['did']) && !is_null($rows['did'])) {
$target = 'did';
} else if (isset($rows['lid']) && !is_null($rows['lid'])) {
$target = 'lid';
} else if (isset($rows['classes_id']) && !is_null($rows['classes_id'])) { // 班级ID
$target = 'classes_id';
} else if (isset($rows['role']) && !is_null($rows['role'])) { // 角色
$target = 'role';
}
return $target;
}
protected function afterUpdateAssigns($target = '', $asid = false, $results = [])
{
//保存包含子部门的数据到缓存
foreach ($this->fetchChildDid as $isrange => $array) {
$fetchChildDidHashCacheKey = $this->assignFetchChildDidHashCacheKey($isrange);
BaseRedis::del($fetchChildDidHashCacheKey);
if ($array) {
$data = [];
foreach ($array as $key => $value) {
$data[$key] = join(',', array_unique($value));
}
BaseRedis::hmset($fetchChildDidHashCacheKey, $data);
if (empty($results['assignsKeys'])) {
$results['assignsKeys'] = [];
}
$results['assignsKeys'][] = $fetchChildDidHashCacheKey;
}
}
if (isset($results['assignsKeys'])) {
$cacheKey = $this->assignsKeys($target);
BaseRedis::del($cacheKey);
BaseRedis::sadd($cacheKey, $results['assignsKeys']);
}
}
/**
* 用户可见范围专题列表缓存 按分配对象类型
* @param $id
* @return string
*/
public function assignFetchChildDidHashCacheKey($isrange)
{
return $this->tableName() . ':assigns:' . $this->eid . ':fetchChild:' . $isrange;
}