| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- <?php
- namespace services\common;
- use common\enums\AppEnum;
- use common\models\common\AddonsInvoker;
- use Yii;
- use yii\db\ActiveQuery;
- use yii\db\Exception;
- use yii\helpers\Json;
- use yii\web\NotFoundHttpException;
- use common\helpers\Url;
- use common\helpers\AddonHelper;
- use common\models\common\Addons;
- use common\enums\StatusEnum;
- use common\components\Service;
- use common\helpers\StringHelper;
- use common\helpers\ArrayHelper;
- use common\enums\RedisKeyEnum;
- use common\components\BaseAddonConfig;
- use common\helpers\Auth;
- use Overtrue\Pinyin\Pinyin;
- /**
- *
- * Class AddonsService
- * @package services\common
- * @author qimall
- */
- class AddonsService extends Service
- {
- /**
- * @return array
- * @throws \yii\web\UnauthorizedHttpException
- */
- public function getMenus()
- {
- $models = Addons::find()
- ->select(['title', 'name', 'group'])
- ->with('bindingMenu')
- ->asArray()
- ->all();
- $isSuperAdmin = Yii::$app->services->auth->isSuperAdmin();
- foreach ($models as $k => &$model) {
- $model['menuUrl'] = '';
- foreach ($model['bindingMenu'] as $bindingMenu) {
- if (isset($bindingMenu['route']) && empty($model['menuUrl'])) {
- $params = isset($bindingMenu['params']) ? Json::decode($bindingMenu['params']) : [];
- $model['menuUrl'] = Url::to(ArrayHelper::merge([$bindingMenu['route']], $params));
- if (!$isSuperAdmin && !Auth::verify($bindingMenu['route'])) {
- $model['menuUrl'] = '';
- }
- }
- }
- if (empty($model['menuUrl'])) {
- unset($models[$k]);
- } else {
- $model['menuUrl'] = urldecode($model['menuUrl']);
- }
- }
- // 创建分类数组
- $groups = array_keys(Yii::$app->params['addonsGroup']);
- $addons = [];
- foreach ($groups as $group) {
- !isset($addons[$group]) && $addons[$group] = [];
- }
- // 模块分类插入
- foreach ($models as $record) {
- $addons[$record['group']][] = $record;
- }
- // 删除空模块分类
- foreach ($addons as $key => $vlaue) {
- if (empty($vlaue)) {
- unset($addons[$key]);
- }
- }
- return $addons;
- }
- /**
- * 获取配置文件
- *
- * @param $name
- * @return bool|string
- */
- public function getConfigClass($name)
- {
- $class = AddonHelper::getAddonConfig($name);
- if (!class_exists($class)) {
- return false;
- }
- return $class;
- }
- /**
- * 获取本地插件列表
- *
- * @return array
- */
- public function getLocalList()
- {
- $addonDir = Yii::getAlias('@addons');
- // 获取插件列表
- $dirs = array_map('basename', glob($addonDir . '/*'));
- $list = Addons::find()
- ->where(['in', 'name', $dirs])
- ->asArray()
- ->all();
- $tmpAddons = [];
- foreach ($list as $addon) {
- $tmpAddons[$addon['name']] = $addon;
- }
- $addons = [];
- foreach ($dirs as $value) {
- // 判断是否安装
- if (!isset($tmpAddons[$value])) {
- $class = AddonHelper::getAddonConfig($value);
- // 实例化插件失败忽略执行
- if (class_exists($class)) {
- $config = new $class;
- $addons[$value] = $config->info;
- $addons[$value]['group'] = $config->group;
- }
- }
- }
- return $addons;
- }
- /**
- * 更新配置
- *
- * @param $name
- * @param BaseAddonConfig $config
- * @param $default_config
- * @return array|Addons|\yii\db\ActiveRecord|null
- * @throws NotFoundHttpException
- */
- public function update($name, $config, $default_config)
- {
- if (!($model = $this->findByName($name))) {
- $model = new Addons();
- }
- if (!empty($model->title)) $config->info['title'] = $model->title;
- $model->attributes = $config->info;
- $model->is_setting = $config->isSetting ? StatusEnum::ENABLED : StatusEnum::DISABLED;
- $model->is_rule = $config->isRule ? StatusEnum::ENABLED : StatusEnum::DISABLED;
- $model->is_merchant_route_map = $config->isMerchantRouteMap ? StatusEnum::ENABLED : StatusEnum::DISABLED;
- $model->group = $config->group;
- $model->bootstrap = $config->bootstrap ?? '';
- $model->service = $config->service ?? '';
- $model->default_config = $default_config;
- $model->console = $config->console ?? [];
- $model->wechat_message = $config->wechatMessage;
- $model->updated_at = time();
- // 首先字母转大写拼音
- if (($chinese = StringHelper::strToChineseCharacters($model->title)) && !empty($chinese[0])) {
- $title_initial = mb_substr($chinese[0][0], 0, 1, 'utf-8');
- // $model->title_initial = ucwords((new Pinyin())->abbr($title_initial));
- }
- if (!$model->save()) {
- throw new NotFoundHttpException($model->getErrorMessage());
- }
- // 更新缓存
- Yii::$app->services->addons->updateCacheByName($name);
- return $model;
- }
- /**
- * 获取列表
- *
- * @return array|\yii\db\ActiveRecord[]
- */
- public function getList()
- {
- return Addons::find()
- ->where(['status' => StatusEnum::ENABLED])
- ->asArray()
- ->all();
- }
- /**
- * @param $name
- * @return array|null|\yii\db\ActiveRecord
- */
- public function findByName($name)
- {
- return Addons::find()
- ->where(['name' => $name, 'status' => StatusEnum::ENABLED])
- ->one();
- }
- /**
- * @param array $names
- * @return array|\yii\db\ActiveRecord[]
- */
- public function findByNames(array $names)
- {
- return Addons::find()
- ->select(['id', 'name', 'title'])
- ->where(['status' => StatusEnum::ENABLED])
- ->andWhere(['in', 'name', $names])
- ->all();
- }
- /**
- * @param $name
- * @return array|null|\yii\db\ActiveRecord
- */
- public function findByNameWithBinding($name, $noCache = false)
- {
- $cacheKey = 'addonsConfig'. ':' . Yii::$app->id . ':' . $name;
- if (!$noCache && Yii::$app->cache->exists($cacheKey)) {
- return Yii::$app->cache->get($cacheKey);
- }
- $data = Addons::find()
- ->where(['name' => $name, 'status' => StatusEnum::ENABLED])
- ->with([
- 'bindingMenu' => function (ActiveQuery $query) {
- return $query->andWhere(['app_id' => Yii::$app->id]);
- },
- 'bindingCover'
- ])
- ->one();
- // 控制台避免写入缓存权限为 644 导致 www 用户组失败
- if (Yii::$app->id != AppEnum::CONSOLE && false == Yii::$app->cache->exists($cacheKey) ) {
- Yii::$app->cache->set($cacheKey, $data, 7200);
- }
- return $data;
- }
- /**
- * 获取插件名称列表
- *
- * @param bool $noCache
- * @return array|mixed|\yii\db\ActiveRecord[]
- */
- public function findAllNames($noCache = false)
- {
- if (Yii::$app->id == AppEnum::CONSOLE) {
- return $this->findAllInitData();
- }
- $cacheKey = RedisKeyEnum::suffix('addonsName');
- if (!$noCache && Yii::$app->cache->exists($cacheKey)) {
- return Yii::$app->cache->get($cacheKey);
- }
- $models = $this->findAllInitData();
- Yii::$app->cache->set($cacheKey, $models, 7200);
- return $models;
- }
- /**
- * @return array|\yii\db\ActiveRecord[]
- */
- public function findAllInitData()
- {
- return Addons::find()
- ->select(['name', 'is_merchant_route_map', 'service', 'updated_at'])
- ->where(['status' => StatusEnum::ENABLED])
- ->asArray()
- ->all();
- }
- /**
- * 触发更新缓存
- *
- * @param $name
- */
- public function updateCacheByName($name)
- {
- $this->findAllNames(true);
- $this->findByNameWithBinding($name, true);
- }
- /**
- * 创建公共调用
- */
- public function createInvoker(string $addons_name, array $invokers)
- {
- if (empty($invokers)) return;
- $time = time();
- $rows = [];
- $new_element_arr = [];
- foreach ($invokers as $key => $item) {
- foreach ($item as $k => $value) {
- $invoker_model = AddonsInvoker::findOne(['invoker_id'=>$value['invoker_id'],'addons_name' => $addons_name,'class'=>$value['class']]);
- if(!empty($invoker_model)){
- if($invoker_model['class']!=$value['class']||$invoker_model['method']!=$value['method']){
- $invoker_model->class = $value['class'];
- $invoker_model->method = $value['method'];
- $res = $invoker_model->save();
- if($res==false) throw new Exception('更新invoker失败');
- }
- }else{
- $row = [];
- $row['addons_name'] = $addons_name;
- $row['invoker_id'] = $value['invoker_id'];
- $row['class'] = $value['class'] ;
- $row['method'] = $value['method'];
- $row['status'] = StatusEnum::ENABLED;
- $row['created_at'] = $time;
- $row['updated_at'] = $time;
- $rows[] = $row;
- }
- $new_element_arr[$value['invoker_id']][]=['class'=>$value['class'],'method'=>$value['method'],'addons_name'=>$addons_name];
- }
- }
- $field = ['addons_name', 'invoker_id', 'class', 'method', 'status', 'created_at', 'updated_at'];
- // 批量插入数据
- if(!empty($rows)){
- $res = Yii::$app->db->createCommand()->batchInsert(AddonsInvoker::tableName(), $field, $rows)->execute();
- if($res==false) throw new Exception('插入invoker失败');
- }
- $redis = Yii::$app->redis;
- if(!empty($new_element_arr)){
- foreach ($new_element_arr as $invoker_id => $new_elements){
- $redis_key = RedisKeyEnum::suffix(RedisKeyEnum::GLOBAL_INVOKE, '',true) .':'. $invoker_id;
- $invokes = $redis->smembers($redis_key);
- $cache_arr = [];
- foreach ($invokes as $k=>$v){
- $temp_v = json_decode($v,true);
- $cache_arr[$temp_v['addons_name']] = $temp_v;
- }
- foreach ($new_elements as $new_element) {
- $cache_arr[$new_element['addons_name']] = $new_element;
- }
- $redis->del($redis_key);
- foreach ($cache_arr as $new_element) {
- $redis->sadd($redis_key, json_encode($new_element));
- }
- }
- }
- }
- }
|