├── MeritBehavior.php ├── Module.php ├── README.md ├── composer.json ├── controllers ├── MeritController.php ├── MeritLogController.php └── MeritTemplateController.php ├── migrations └── m160320_093621_create_merit_table.php ├── models ├── Merit.php ├── MeritLog.php ├── MeritLogSearch.php ├── MeritSearch.php ├── MeritTemplate.php └── MeritTemplateSearch.php └── views ├── merit-log ├── _search.php └── index.php ├── merit-template ├── _form.php ├── _search.php ├── create.php ├── index.php ├── update.php └── view.php └── merit ├── _search.php └── index.php /MeritBehavior.php: -------------------------------------------------------------------------------- 1 | 4 | * createTime : 16/3/20 下午5:42 5 | * description: 6 | */ 7 | namespace yiier\merit; 8 | 9 | use yii\base\Behavior; 10 | use yii\db\Exception; 11 | use yii\web\Controller; 12 | use yiier\merit\models\Merit; 13 | use yiier\merit\models\MeritLog; 14 | use yiier\merit\models\MeritTemplate; 15 | use Yii; 16 | 17 | class MeritBehavior extends Behavior 18 | { 19 | public function events() 20 | { 21 | return [ 22 | Controller::EVENT_AFTER_ACTION => 'afterAction', 23 | ]; 24 | } 25 | 26 | public function afterAction() 27 | { 28 | if (!Yii::$app->user->isGuest) { 29 | if ($meritTemplates = $this->hasMeritTemplate()) { 30 | /** @var MeritTemplate $meritTemplate */ 31 | foreach ($meritTemplates as $meritTemplate) { 32 | switch ($meritTemplate->rule_key) { 33 | case 2: 34 | if ($meritTemplate->rule_value <= $this->getMeritLogTimes($meritTemplate, Yii::$app->user->id)) { 35 | return false; 36 | } 37 | break; 38 | case 1: 39 | if ($meritTemplate->rule_value <= $this->getMeritLogDay($meritTemplate, Yii::$app->user->id)) { 40 | return false; 41 | } 42 | break; 43 | default: 44 | # code... 45 | break; 46 | } 47 | $this->update($meritTemplate); 48 | } 49 | } 50 | } 51 | return false; 52 | } 53 | 54 | public function hasMeritTemplate() 55 | { 56 | $uniqueId = Yii::$app->controller->action->uniqueId; 57 | // 必须是 GET 或者 POST 请求 58 | if (!in_array(Yii::$app->request->method, MeritTemplate::getMethods())) { 59 | return false; 60 | } 61 | 62 | $method = array_flip(MeritTemplate::getMethods())[Yii::$app->request->method]; 63 | // 支持同一个 $uniqueId 不同 Type 64 | $meritTemplates = MeritTemplate::find() 65 | ->where(['unique_id' => $uniqueId, 'status' => MeritTemplate::STATUS_ACTIVE, 'method' => $method]) 66 | ->all(); 67 | if (!$meritTemplates) { 68 | return false; 69 | } 70 | return $meritTemplates; 71 | } 72 | 73 | /** 74 | * 查看次数 75 | * @param MeritTemplate $meritTemplate 76 | * @param $userId 77 | * @return int|string 78 | */ 79 | public function getMeritLogTimes(MeritTemplate $meritTemplate, $userId) 80 | { 81 | return MeritLog::find() 82 | ->where(['merit_template_id' => $meritTemplate->id, 'type' => $meritTemplate->type, 'user_id' => $userId]) 83 | ->count(); 84 | } 85 | 86 | /** 87 | * 按次查看 88 | * @param MeritTemplate $meritTemplate 89 | * @param $userId 90 | * @return int|string 91 | */ 92 | public function getMeritLogDay(MeritTemplate $meritTemplate, $userId) 93 | { 94 | return MeritLog::find() 95 | ->where(['merit_template_id' => $meritTemplate->id, 'type' => $meritTemplate->type, 'user_id' => $userId]) 96 | ->andWhere(['between', 'created_at', strtotime(date('Ymd') . '000000'), strtotime(date('Ymd') . '235959')]) 97 | ->count(); 98 | } 99 | 100 | /** 101 | * @param MeritTemplate $meritTemplate 102 | * @throws Exception 103 | */ 104 | public function update(MeritTemplate $meritTemplate) 105 | { 106 | $meritLog = new MeritLog(); 107 | $user = \Yii::$app->user->identity; 108 | 109 | $transaction = \Yii::$app->db->beginTransaction(); 110 | try { 111 | /** @var Merit $userMerit */ 112 | $userMerit = Merit::findOne(['user_id' => $user->getId(), 'type' => $meritTemplate->type]); 113 | // is sub 判断是否是减法 114 | $actionSub = ($meritTemplate->action_type == MeritTemplate::ACTIVE_TYPE_SUB); 115 | if ($userMerit) { 116 | $merit = call_user_func($actionSub ? 'bcsub' : 'bcadd', $userMerit->merit, $meritTemplate->increment); 117 | $userMerit->setAttributes([ 118 | 'merit' => (integer)$merit 119 | ]); 120 | } else { 121 | $userMerit = new Merit(); 122 | $userMerit->setAttributes([ 123 | 'merit' => ($actionSub ? '-' : '') . $meritTemplate->increment, 124 | 'user_id' => $user->getId(), 125 | 'username' => $user->username, 126 | 'type' => $meritTemplate->type, 127 | ]); 128 | } 129 | if (!$userMerit->save()) { 130 | Yii::error('Merit 操作失败' . json_encode(array_values($userMerit->getFirstErrors())), 'error'); 131 | throw new Exception(array_values($userMerit->getFirstErrors())[0]); 132 | } 133 | $description = $meritTemplate->title . ': ' 134 | . MeritTemplate::getActionTypes()[$meritTemplate->action_type] 135 | . $meritTemplate->increment 136 | . MeritTemplate::getTypes()[$meritTemplate->type]; 137 | 138 | $meritLog->setAttributes([ 139 | 'user_id' => $user->getId(), 140 | 'username' => $user->username, 141 | 'merit_template_id' => $meritTemplate->id, 142 | 'type' => $meritTemplate->type, 143 | 'description' => $description, 144 | 'action_type' => $meritTemplate->action_type, 145 | 'increment' => $meritTemplate->increment, 146 | 'created_at' => time(), 147 | ]); 148 | if (!$meritLog->save()) { 149 | throw new Exception(array_values($meritLog->getFirstErrors())[0]); 150 | } 151 | 152 | $transaction->commit(); 153 | } catch (Exception $e) { 154 | $transaction->rollBack(); 155 | } 156 | 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | types) { 15 | $this->types = [ 16 | 1 => '积分', 17 | 2 => '声望', 18 | 3 => '徽章', 19 | ]; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Reputation engine for Yii2 2 | ========================== 3 | [![Latest Stable Version](https://poser.pugx.org/yiier/yii2-merit/v/stable)](https://packagist.org/packages/yiier/yii2-merit) 4 | [![Total Downloads](https://poser.pugx.org/yiier/yii2-merit/downloads)](https://packagist.org/packages/yiier/yii2-merit) 5 | [![Latest Unstable Version](https://poser.pugx.org/yiier/yii2-merit/v/unstable)](https://packagist.org/packages/yiier/yii2-merit) 6 | [![License](https://poser.pugx.org/yiier/yii2-merit/license)](https://packagist.org/packages/yiier/yii2-merit) 7 | 8 | 用于实现积分,等级功能的设计 9 | 10 | Installation 11 | ------------ 12 | 13 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 14 | 15 | Either run 16 | 17 | ``` 18 | php composer.phar require --prefer-dist yiier/yii2-merit "*" 19 | ``` 20 | 21 | or add 22 | 23 | ``` 24 | "yiier/yii2-merit": "*" 25 | ``` 26 | 27 | to the require section of your `composer.json` file. 28 | 29 | Migrations 30 | ---------- 31 | 32 | Run the following command 33 | 34 | ``` 35 | php yii migrate --migrationPath=@yiier/merit/migrations/ 36 | ``` 37 | 38 | Usage 39 | ----- 40 | 41 | Configure Controller class as follows : 42 | 43 | ```php 44 | use use yiier\merit\MeritBehavior; 45 | 46 | class Controller extends \yii\web\Controller 47 | { 48 | public function behaviors() 49 | { 50 | return [ 51 | MeritBehavior::className(), 52 | ]; 53 | } 54 | } 55 | ``` 56 | 57 | Once the extension is installed, simply modify your application configuration as follows: 58 | 59 | ```php 60 | return [ 61 | 'modules' => [ 62 | 'merit' => [ 63 | 'class' => 'yiier\merit\Module', 64 | 'types' => [1 => '积分', 2 => '声望'] // Optional 65 | ], 66 | ], 67 | ]; 68 | ``` 69 | 70 | You can then access Merit Module through the following URL: 71 | 72 | ``` 73 | http://localhost/path/to/index.php?r=merit/merit 74 | http://localhost/path/to/index.php?r=merit/merit-log 75 | http://localhost/path/to/index.php?r=merit/merit-template 76 | ``` 77 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiier/yii2-merit", 3 | "description": "用于实现积分,等级功能的设计", 4 | "type": "yii2-extension", 5 | "keywords": ["yii2","extension","merit","reputation"], 6 | "license": "BSD-3-Clause", 7 | "authors": [ 8 | { 9 | "name": "forecho", 10 | "email": "caizhenghai@gmail.com" 11 | } 12 | ], 13 | "require": { 14 | "yiisoft/yii2": "*" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "yiier\\merit\\": "" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /controllers/MeritController.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'class' => VerbFilter::className(), 22 | 'actions' => [ 23 | 'delete' => ['post'], 24 | ], 25 | ], 26 | ]; 27 | } 28 | 29 | /** 30 | * Lists all Merit models. 31 | * @return mixed 32 | */ 33 | public function actionIndex() 34 | { 35 | $searchModel = new MeritSearch(); 36 | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 37 | 38 | return $this->render('index', [ 39 | 'searchModel' => $searchModel, 40 | 'dataProvider' => $dataProvider, 41 | ]); 42 | } 43 | 44 | /** 45 | * Deletes an existing Merit model. 46 | * If deletion is successful, the browser will be redirected to the 'index' page. 47 | * @param integer $id 48 | * @return mixed 49 | */ 50 | public function actionDelete($id) 51 | { 52 | $this->findModel($id)->delete(); 53 | 54 | return $this->redirect(['index']); 55 | } 56 | 57 | /** 58 | * Finds the Merit model based on its primary key value. 59 | * If the model is not found, a 404 HTTP exception will be thrown. 60 | * @param integer $id 61 | * @return Merit the loaded model 62 | * @throws NotFoundHttpException if the model cannot be found 63 | */ 64 | protected function findModel($id) 65 | { 66 | if (($model = Merit::findOne($id)) !== null) { 67 | return $model; 68 | } else { 69 | throw new NotFoundHttpException('The requested page does not exist.'); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /controllers/MeritLogController.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'class' => VerbFilter::className(), 22 | 'actions' => [ 23 | 'delete' => ['post'], 24 | ], 25 | ], 26 | ]; 27 | } 28 | 29 | /** 30 | * Lists all MeritLog models. 31 | * @return mixed 32 | */ 33 | public function actionIndex() 34 | { 35 | $searchModel = new MeritLogSearch(); 36 | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 37 | 38 | return $this->render('index', [ 39 | 'searchModel' => $searchModel, 40 | 'dataProvider' => $dataProvider, 41 | ]); 42 | } 43 | 44 | /** 45 | * Deletes an existing MeritLog model. 46 | * If deletion is successful, the browser will be redirected to the 'index' page. 47 | * @param integer $id 48 | * @return mixed 49 | */ 50 | public function actionDelete($id) 51 | { 52 | $this->findModel($id)->delete(); 53 | 54 | return $this->redirect(['index']); 55 | } 56 | 57 | /** 58 | * Finds the MeritLog model based on its primary key value. 59 | * If the model is not found, a 404 HTTP exception will be thrown. 60 | * @param integer $id 61 | * @return MeritLog the loaded model 62 | * @throws NotFoundHttpException if the model cannot be found 63 | */ 64 | protected function findModel($id) 65 | { 66 | if (($model = MeritLog::findOne($id)) !== null) { 67 | return $model; 68 | } else { 69 | throw new NotFoundHttpException('The requested page does not exist.'); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /controllers/MeritTemplateController.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'class' => VerbFilter::className(), 22 | 'actions' => [ 23 | 'delete' => ['post'], 24 | ], 25 | ], 26 | ]; 27 | } 28 | 29 | /** 30 | * Lists all MeritTemplate models. 31 | * @return mixed 32 | */ 33 | public function actionIndex() 34 | { 35 | $searchModel = new MeritTemplateSearch(); 36 | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 37 | 38 | return $this->render('index', [ 39 | 'searchModel' => $searchModel, 40 | 'dataProvider' => $dataProvider, 41 | ]); 42 | } 43 | 44 | /** 45 | * Displays a single MeritTemplate model. 46 | * @param integer $id 47 | * @return mixed 48 | */ 49 | public function actionView($id) 50 | { 51 | return $this->render('view', [ 52 | 'model' => $this->findModel($id), 53 | ]); 54 | } 55 | 56 | /** 57 | * Creates a new MeritTemplate model. 58 | * If creation is successful, the browser will be redirected to the 'view' page. 59 | * @return mixed 60 | */ 61 | public function actionCreate() 62 | { 63 | $model = new MeritTemplate(); 64 | 65 | if ($model->load(Yii::$app->request->post()) && $model->save()) { 66 | return $this->redirect(['view', 'id' => $model->id]); 67 | } else { 68 | return $this->render('create', [ 69 | 'model' => $model, 70 | ]); 71 | } 72 | } 73 | 74 | /** 75 | * Updates an existing MeritTemplate model. 76 | * If update is successful, the browser will be redirected to the 'view' page. 77 | * @param integer $id 78 | * @return mixed 79 | */ 80 | public function actionUpdate($id) 81 | { 82 | $model = $this->findModel($id); 83 | 84 | if ($model->load(Yii::$app->request->post()) && $model->save()) { 85 | return $this->redirect(['view', 'id' => $model->id]); 86 | } else { 87 | return $this->render('update', [ 88 | 'model' => $model, 89 | ]); 90 | } 91 | } 92 | 93 | /** 94 | * Deletes an existing MeritTemplate model. 95 | * If deletion is successful, the browser will be redirected to the 'index' page. 96 | * @param integer $id 97 | * @return mixed 98 | */ 99 | public function actionDelete($id) 100 | { 101 | $this->findModel($id)->delete(); 102 | 103 | return $this->redirect(['index']); 104 | } 105 | 106 | /** 107 | * Finds the MeritTemplate model based on its primary key value. 108 | * If the model is not found, a 404 HTTP exception will be thrown. 109 | * @param integer $id 110 | * @return MeritTemplate the loaded model 111 | * @throws NotFoundHttpException if the model cannot be found 112 | */ 113 | protected function findModel($id) 114 | { 115 | if (($model = MeritTemplate::findOne($id)) !== null) { 116 | return $model; 117 | } else { 118 | throw new NotFoundHttpException('The requested page does not exist.'); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /migrations/m160320_093621_create_merit_table.php: -------------------------------------------------------------------------------- 1 | db->driverName === 'mysql') { //Mysql 表选项 25 | $engine = $this->useTransaction ? 'InnoDB' : 'MyISAM'; 26 | $this->tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=' . $engine; 27 | } 28 | } 29 | 30 | public function up() 31 | { 32 | $this->execute($this->delMeritTable()); 33 | $this->createTable('{{%merit_template}}', [ 34 | 'id' => Schema::TYPE_PK, 35 | 'type' => Schema::TYPE_INTEGER . "(2) DEFAULT 1 COMMENT '类型 1:积分 2:声望 3:徽章'", 36 | 'title' => Schema::TYPE_STRING . " NOT NULL COMMENT '标题'", 37 | 'unique_id' => Schema::TYPE_STRING . " NOT NULL COMMENT 'action uniqueId'", 38 | 'method' => Schema::TYPE_INTEGER . "(2) DEFAULT 2 COMMENT '请求方式 1 get 2 post'", 39 | 'event' => Schema::TYPE_INTEGER . "(2) DEFAULT 0 COMMENT '事件 0:不绑定'", 40 | 'action_type' => Schema::TYPE_INTEGER . "(2) DEFAULT 2 COMMENT '操作类型 1减去 2新增'", 41 | 'rule_key' => Schema::TYPE_INTEGER . "(2) DEFAULT 0 COMMENT '规则类型 0:不限制 1:按天限制 2:按次限制'", 42 | 'rule_value' => Schema::TYPE_INTEGER . " DEFAULT 0 COMMENT '规则值'", 43 | 'increment' => Schema::TYPE_INTEGER . " UNSIGNED DEFAULT NULL COMMENT '变化值'", 44 | 'status' => Schema::TYPE_BOOLEAN . " DEFAULT 1 COMMENT '状态 0暂停 1开启'", 45 | 'created_at' => Schema::TYPE_INTEGER . " UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间'", 46 | 'updated_at' => Schema::TYPE_INTEGER . " UNSIGNED NOT NULL DEFAULT '0' COMMENT '更新时间'", 47 | ], $this->tableOptions); 48 | $this->createIndex('type', '{{%merit_template}}', 'type'); 49 | $this->createIndex('unique_id', '{{%merit_template}}', 'unique_id'); 50 | 51 | $this->createTable('{{%merit}}', [ 52 | 'id' => Schema::TYPE_PK, 53 | 'user_id' => Schema::TYPE_INTEGER . " UNSIGNED DEFAULT NULL COMMENT '用户ID'", 54 | 'username' => Schema::TYPE_STRING . "(20) DEFAULT NULL COMMENT '用户名'", 55 | 'type' => Schema::TYPE_INTEGER . "(2) DEFAULT 1 COMMENT '类型 1:积分 2:声望 3:徽章'", 56 | 'merit' => Schema::TYPE_INTEGER . " DEFAULT NULL COMMENT '总值'", 57 | 'created_at' => Schema::TYPE_INTEGER . " UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间'", 58 | 'updated_at' => Schema::TYPE_INTEGER . " UNSIGNED NOT NULL DEFAULT '0' COMMENT '更新时间'", 59 | ], $this->tableOptions); 60 | $this->createIndex('type', '{{%merit}}', 'type'); 61 | $this->createIndex('user_id', '{{%merit}}', 'user_id'); 62 | 63 | $this->createTable('{{%merit_log}}', [ 64 | 'id' => Schema::TYPE_PK, 65 | 'user_id' => Schema::TYPE_INTEGER . " UNSIGNED NULL NULL COMMENT '用户ID'", 66 | 'username' => Schema::TYPE_STRING . "(20) DEFAULT NULL COMMENT '用户名'", 67 | 'merit_template_id' => Schema::TYPE_INTEGER . " UNSIGNED NULL NULL COMMENT '模板ID'", 68 | 'type' => Schema::TYPE_INTEGER . "(2) DEFAULT 1 COMMENT '类型 1:积分 2:声望 3:徽章'", 69 | 'description' => Schema::TYPE_STRING . " NOT NULL COMMENT '描述'", 70 | 'action_type' => Schema::TYPE_INTEGER . "(2) DEFAULT 2 COMMENT '操作类型 1减去 2新增'", 71 | 'increment' => Schema::TYPE_INTEGER . " UNSIGNED DEFAULT NULL COMMENT '变化值'", 72 | 'created_at' => Schema::TYPE_INTEGER . " UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间'", 73 | ], $this->tableOptions); 74 | $this->createIndex('type', '{{%merit_log}}', 'type'); 75 | $this->createIndex('user_id', '{{%merit_log}}', 'user_id'); 76 | $this->createIndex('merit_template_id', '{{%merit_log}}', 'merit_template_id'); 77 | } 78 | 79 | public function down() 80 | { 81 | echo "m150807_082458_create_merit_table cannot be reverted.\n"; 82 | $this->dropTable('{{%merit_template}}'); 83 | $this->dropTable('{{%merit}}'); 84 | $this->dropTable('{{%merit_log}}'); 85 | return false; 86 | } 87 | 88 | /** 89 | * @return string 90 | */ 91 | private function delMeritTable() 92 | { 93 | return 'DROP TABLE IF EXISTS {{%merit_template}}; 94 | DROP TABLE IF EXISTS {{%merit}}; 95 | DROP TABLE IF EXISTS {{%merit_log}}; 96 | '; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /models/Merit.php: -------------------------------------------------------------------------------- 1 | 4 | * createTime : 16/3/20 下午5:47 5 | * description: 6 | */ 7 | 8 | namespace yiier\merit\models; 9 | 10 | 11 | use Yii; 12 | use yii\behaviors\TimestampBehavior; 13 | 14 | /** 15 | * This is the model class for table "{{%merit}}". 16 | * 17 | * @property integer $id 18 | * @property integer $user_id 19 | * @property string $username 20 | * @property integer $type 21 | * @property integer $merit 22 | * @property integer $created_at 23 | * @property integer $updated_at 24 | */ 25 | class Merit extends \yii\db\ActiveRecord 26 | { 27 | /** 28 | * 自动更新created_at和updated_at时间 29 | * @return array 30 | */ 31 | public function behaviors() 32 | { 33 | return [ 34 | TimestampBehavior::className(), 35 | ]; 36 | } 37 | 38 | /** 39 | * @inheritdoc 40 | */ 41 | public static function tableName() 42 | { 43 | return '{{%merit}}'; 44 | } 45 | 46 | /** 47 | * @inheritdoc 48 | */ 49 | public function rules() 50 | { 51 | return [ 52 | [['user_id', 'type', 'merit', 'created_at', 'updated_at'], 'integer'], 53 | [['username'], 'string', 'max' => 20] 54 | ]; 55 | } 56 | 57 | /** 58 | * @inheritdoc 59 | */ 60 | public function attributeLabels() 61 | { 62 | return [ 63 | 'id' => Yii::t('app', 'ID'), 64 | 'user_id' => Yii::t('app', '用户ID'), 65 | 'username' => Yii::t('app', '用户名'), 66 | 'type' => Yii::t('app', '类型'), 67 | 'merit' => Yii::t('app', '总值'), 68 | 'created_at' => Yii::t('app', '创建时间'), 69 | 'updated_at' => Yii::t('app', '更新时间'), 70 | ]; 71 | } 72 | } -------------------------------------------------------------------------------- /models/MeritLog.php: -------------------------------------------------------------------------------- 1 | 4 | * createTime : 16/3/20 下午5:47 5 | * description: 6 | */ 7 | 8 | namespace yiier\merit\models; 9 | 10 | use Yii; 11 | 12 | /** 13 | * This is the model class for table "{{%merit_log}}". 14 | * 15 | * @property integer $id 16 | * @property integer $user_id 17 | * @property string $username 18 | * @property integer $merit_template_id 19 | * @property integer $type 20 | * @property string $description 21 | * @property integer $action_type 22 | * @property integer $increment 23 | * @property integer $created_at 24 | */ 25 | class MeritLog extends \yii\db\ActiveRecord 26 | { 27 | /** 28 | * @inheritdoc 29 | */ 30 | public static function tableName() 31 | { 32 | return '{{%merit_log}}'; 33 | } 34 | 35 | /** 36 | * @inheritdoc 37 | */ 38 | public function rules() 39 | { 40 | return [ 41 | [['user_id', 'merit_template_id', 'type', 'action_type', 'increment', 'created_at'], 'integer'], 42 | [['description'], 'required'], 43 | [['username'], 'string', 'max' => 20], 44 | [['description'], 'string', 'max' => 255] 45 | ]; 46 | } 47 | 48 | /** 49 | * @inheritdoc 50 | */ 51 | public function attributeLabels() 52 | { 53 | return [ 54 | 'id' => Yii::t('app', 'ID'), 55 | 'user_id' => Yii::t('app', '用户ID'), 56 | 'username' => Yii::t('app', '用户名'), 57 | 'merit_template_id' => Yii::t('app', '模板ID'), 58 | 'type' => Yii::t('app', '类型'), 59 | 'description' => Yii::t('app', '描述'), 60 | 'action_type' => Yii::t('app', '操作类型'), 61 | 'increment' => Yii::t('app', '变化值'), 62 | 'created_at' => Yii::t('app', '创建时间'), 63 | ]; 64 | } 65 | } -------------------------------------------------------------------------------- /models/MeritLogSearch.php: -------------------------------------------------------------------------------- 1 | $query, 47 | ]); 48 | 49 | $this->load($params); 50 | 51 | if (!$this->validate()) { 52 | // uncomment the following line if you do not want to return any records when validation fails 53 | // $query->where('0=1'); 54 | return $dataProvider; 55 | } 56 | 57 | $query->andFilterWhere([ 58 | 'id' => $this->id, 59 | 'user_id' => $this->user_id, 60 | 'merit_template_id' => $this->merit_template_id, 61 | 'type' => $this->type, 62 | 'action_type' => $this->action_type, 63 | 'increment' => $this->increment, 64 | 'created_at' => $this->created_at, 65 | ]); 66 | 67 | $query->andFilterWhere(['like', 'description', $this->description]) 68 | ->andFilterWhere(['like', 'username', $this->username]); 69 | 70 | return $dataProvider; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /models/MeritSearch.php: -------------------------------------------------------------------------------- 1 | $query, 47 | ]); 48 | 49 | $this->load($params); 50 | 51 | if (!$this->validate()) { 52 | // uncomment the following line if you do not want to return any records when validation fails 53 | // $query->where('0=1'); 54 | return $dataProvider; 55 | } 56 | 57 | $query->andFilterWhere([ 58 | 'id' => $this->id, 59 | 'user_id' => $this->user_id, 60 | 'type' => $this->type, 61 | 'merit' => $this->merit, 62 | 'created_at' => $this->created_at, 63 | 'updated_at' => $this->updated_at, 64 | ]); 65 | 66 | $query->andFilterWhere(['like', 'username', $this->username]); 67 | 68 | return $dataProvider; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /models/MeritTemplate.php: -------------------------------------------------------------------------------- 1 | 4 | * createTime : 16/3/20 下午5:48 5 | * description: 6 | */ 7 | 8 | namespace yiier\merit\models; 9 | 10 | use Yii; 11 | use yii\behaviors\TimestampBehavior; 12 | use yiier\merit\Module; 13 | 14 | /** 15 | * This is the model class for table "{{%merit_template}}". 16 | * 17 | * @property integer $id 18 | * @property integer $type 19 | * @property string $title 20 | * @property string $unique_id 21 | * @property integer $method 22 | * @property integer $event 23 | * @property integer $action_type 24 | * @property integer $rule_key 25 | * @property integer $rule_value 26 | * @property integer $increment 27 | * @property integer $status 28 | * @property integer $created_at 29 | * @property integer $updated_at 30 | */ 31 | class MeritTemplate extends \yii\db\ActiveRecord 32 | { 33 | /** 34 | * @inheritdoc 35 | */ 36 | const MERIT_POST = 2; 37 | 38 | /** 39 | * @inheritdoc 40 | */ 41 | const MERIT_GET = 1; 42 | 43 | const STATUS_ACTIVE = 1; 44 | 45 | const STATUS_DELETE = 0; 46 | 47 | /** 48 | * @var int 减法 49 | */ 50 | const ACTIVE_TYPE_SUB = 1; 51 | 52 | /** 53 | * @var int 加法 54 | */ 55 | const ACTIVE_TYPE_ADD = 2; 56 | 57 | /** 58 | * 自动更新created_at和updated_at时间 59 | * @return array 60 | */ 61 | public function behaviors() 62 | { 63 | return [ 64 | TimestampBehavior::className(), 65 | ]; 66 | } 67 | 68 | /** 69 | * @inheritdoc 70 | */ 71 | public static function tableName() 72 | { 73 | return '{{%merit_template}}'; 74 | } 75 | 76 | /** 77 | * @inheritdoc 78 | */ 79 | public function rules() 80 | { 81 | return [ 82 | [['type', 'method', 'event', 'action_type', 'rule_key', 'rule_value', 'increment', 'status', 'created_at', 'updated_at'], 'integer'], 83 | [['title', 'unique_id'], 'required'], 84 | [['title', 'unique_id'], 'string', 'max' => 255] 85 | ]; 86 | } 87 | 88 | /** 89 | * @inheritdoc 90 | */ 91 | public function attributeLabels() 92 | { 93 | return [ 94 | 'id' => Yii::t('app', 'ID'), 95 | 'type' => Yii::t('app', '类型'), 96 | 'title' => Yii::t('app', '标题'), 97 | 'unique_id' => Yii::t('app', 'action uniqueId'), 98 | 'method' => Yii::t('app', '请求方式'), 99 | 'event' => Yii::t('app', '事件 0:不绑定'), 100 | 'action_type' => Yii::t('app', '操作类型'), 101 | 'rule_key' => Yii::t('app', '规则类型'), 102 | 'rule_value' => Yii::t('app', '规则值'), 103 | 'increment' => Yii::t('app', '变化值'), 104 | 'status' => Yii::t('app', '状态'), 105 | 'created_at' => Yii::t('app', '创建时间'), 106 | 'updated_at' => Yii::t('app', '更新时间'), 107 | ]; 108 | } 109 | 110 | public static function getMethods() 111 | { 112 | return [ 113 | static::MERIT_POST => 'POST', 114 | static::MERIT_GET => 'GET', 115 | ]; 116 | } 117 | 118 | public static function getActionTypes() 119 | { 120 | return [ 121 | 2 => '+', 122 | 1 => '-', 123 | ]; 124 | } 125 | 126 | public static function getRuleKeys() 127 | { 128 | return [ 129 | Yii::t('app', '不限制'), 130 | Yii::t('app', '按天限制'), 131 | Yii::t('app', '按次限制'), 132 | ]; 133 | } 134 | 135 | public static function getTypes() 136 | { 137 | /** @var Module $merit */ 138 | $merit = new Module('merit'); 139 | return $merit->types; 140 | } 141 | 142 | public static function getStatuses() 143 | { 144 | return [ 145 | self::STATUS_ACTIVE => '开启', 146 | self::STATUS_DELETE => '停用', 147 | ]; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /models/MeritTemplateSearch.php: -------------------------------------------------------------------------------- 1 | $query, 47 | ]); 48 | 49 | $this->load($params); 50 | 51 | if (!$this->validate()) { 52 | // uncomment the following line if you do not want to return any records when validation fails 53 | // $query->where('0=1'); 54 | return $dataProvider; 55 | } 56 | 57 | $query->andFilterWhere([ 58 | 'id' => $this->id, 59 | 'type' => $this->type, 60 | 'method' => $this->method, 61 | 'event' => $this->event, 62 | 'action_type' => $this->action_type, 63 | 'rule_key' => $this->rule_key, 64 | 'rule_value' => $this->rule_value, 65 | 'increment' => $this->increment, 66 | 'status' => $this->status, 67 | 'created_at' => $this->created_at, 68 | 'updated_at' => $this->updated_at, 69 | ]); 70 | 71 | $query->andFilterWhere(['like', 'title', $this->title]) 72 | ->andFilterWhere(['like', 'unique_id', $this->unique_id]); 73 | 74 | return $dataProvider; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /views/merit-log/_search.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 44 | -------------------------------------------------------------------------------- /views/merit-log/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', 'Merit Logs'); 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 | 16 |

title) ?>

17 | render('_search', ['model' => $searchModel]); ?> 18 | 19 | $dataProvider, 21 | 'filterModel' => $searchModel, 22 | 'columns' => [ 23 | 'user_id', 24 | 'username', 25 | 'merit_template_id', 26 | [ 27 | 'attribute' => 'type', 28 | 'value' => function ($data) { 29 | return MeritTemplate::getTypes()[$data->type]; 30 | } 31 | ], 32 | 'description', 33 | [ 34 | 'attribute' => 'action_type', 35 | 'value' => function ($data) { 36 | return MeritTemplate::getActionTypes()[$data->action_type]; 37 | } 38 | ], 39 | 'increment', 40 | 'created_at:datetime', 41 | 42 | ['class' => 'yii\grid\ActionColumn', 'template' => '{view} {delete}'], 43 | ], 44 | ]); ?> 45 | 46 |
47 | -------------------------------------------------------------------------------- /views/merit-template/_form.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 | 14 | 15 | 16 | field($model, 'type')->dropDownList(MeritTemplate::getTypes()) ?> 17 | 18 | field($model, 'title')->textInput(['maxlength' => true]) ?> 19 | 20 | field($model, 'unique_id')->textInput(['maxlength' => true]) ?> 21 | 22 | field($model, 'method')->dropDownList(MeritTemplate::getMethods()) ?> 23 | 24 | field($model, 'event')->textInput() ?> 25 | 26 | field($model, 'action_type')->dropDownList(MeritTemplate::getActionTypes()) ?> 27 | 28 | field($model, 'increment')->textInput() ?> 29 | 30 | field($model, 'rule_key')->dropDownList(MeritTemplate::getRuleKeys()) ?> 31 | 32 | field($model, 'rule_value')->textInput() ?> 33 | 34 | field($model, 'status')->dropDownList(MeritTemplate::getStatuses()) ?> 35 | 36 |
37 | isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> 38 |
39 | 40 | 41 | 42 |
43 | -------------------------------------------------------------------------------- /views/merit-template/_search.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 52 | -------------------------------------------------------------------------------- /views/merit-template/create.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', 'Create Merit Template'); 10 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Merit Templates'), 'url' => ['index']]; 11 | $this->params['breadcrumbs'][] = $this->title; 12 | ?> 13 |
14 | 15 |

title) ?>

16 | 17 | render('_form', [ 18 | 'model' => $model, 19 | ]) ?> 20 | 21 |
22 | -------------------------------------------------------------------------------- /views/merit-template/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', 'Merit Templates'); 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 | 16 |

title) ?>

17 | render('_search', ['model' => $searchModel]); ?> 18 | 19 |

20 | 'btn btn-success']) ?> 21 |

22 | 23 | $dataProvider, 25 | 'filterModel' => $searchModel, 26 | 'columns' => [ 27 | 28 | 'title', 29 | [ 30 | 'attribute' => 'type', 31 | 'value' => function ($data) { 32 | return MeritTemplate::getTypes()[$data->type]; 33 | } 34 | ], 35 | 'unique_id', 36 | [ 37 | 'attribute' => 'method', 38 | 'value' => function ($data) { 39 | return MeritTemplate::getMethods()[$data->method]; 40 | } 41 | ], 42 | // 'event', 43 | [ 44 | 'attribute' => 'action_type', 45 | 'value' => function ($data) { 46 | return MeritTemplate::getActionTypes()[$data->action_type]; 47 | } 48 | ], 49 | 'increment', 50 | [ 51 | 'attribute' => 'rule_key', 52 | 'value' => function ($data) { 53 | return MeritTemplate::getRuleKeys()[$data->rule_key]; 54 | } 55 | ], 56 | 'rule_value', 57 | [ 58 | 'attribute' => 'status', 59 | 'value' => function ($data) { 60 | return MeritTemplate::getStatuses()[$data->status]; 61 | } 62 | ], 63 | 'created_at:datetime', 64 | 'updated_at:datetime', 65 | 66 | ['class' => 'yii\grid\ActionColumn'], 67 | ], 68 | ]); ?> 69 | 70 |
71 | -------------------------------------------------------------------------------- /views/merit-template/update.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', 'Update {modelClass}: ', [ 9 | 'modelClass' => 'Merit Template', 10 | ]) . ' ' . $model->title; 11 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Merit Templates'), 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = ['label' => $model->title, 'url' => ['view', 'id' => $model->id]]; 13 | $this->params['breadcrumbs'][] = Yii::t('app', 'Update'); 14 | ?> 15 |
16 | 17 |

title) ?>

18 | 19 | render('_form', [ 20 | 'model' => $model, 21 | ]) ?> 22 | 23 |
24 | -------------------------------------------------------------------------------- /views/merit-template/view.php: -------------------------------------------------------------------------------- 1 | title = $model->title; 11 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Merit Templates'), 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 | 16 |

title) ?>

17 | 18 |

19 | $model->id], ['class' => 'btn btn-primary']) ?> 20 | $model->id], [ 21 | 'class' => 'btn btn-danger', 22 | 'data' => [ 23 | 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'), 24 | 'method' => 'post', 25 | ], 26 | ]) ?> 27 |

28 | 29 | $model, 31 | 'attributes' => [ 32 | 'id', 33 | 'title', 34 | [ 35 | 'attribute' => 'type', 36 | 'value' => MeritTemplate::getTypes()[$model->type] 37 | ], 38 | 'unique_id', 39 | [ 40 | 'attribute' => 'method', 41 | 'value' => MeritTemplate::getMethods()[$model->method] 42 | ], 43 | // 'event', 44 | [ 45 | 'attribute' => 'action_type', 46 | 'value' => MeritTemplate::getActionTypes()[$model->action_type] 47 | ], 48 | 'increment', 49 | [ 50 | 'attribute' => 'rule_key', 51 | 'value' => MeritTemplate::getRuleKeys()[$model->rule_key] 52 | ], 53 | 'rule_value', 54 | [ 55 | 'attribute' => 'status', 56 | 'value' => MeritTemplate::getStatuses()[$model->status] 57 | ], 58 | 'created_at:datetime', 59 | 'updated_at:datetime', 60 | ], 61 | ]) ?> 62 | 63 |
64 | -------------------------------------------------------------------------------- /views/merit/_search.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 40 | -------------------------------------------------------------------------------- /views/merit/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', 'Merits'); 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 | 16 |

title) ?>

17 | render('_search', ['model' => $searchModel]); ?> 18 | 19 | $dataProvider, 21 | 'filterModel' => $searchModel, 22 | 'columns' => [ 23 | 24 | 'user_id', 25 | 'username', 26 | [ 27 | 'attribute' => 'type', 28 | 'value' => function ($data) { 29 | return MeritTemplate::getTypes()[$data->type]; 30 | } 31 | ], 32 | 'merit', 33 | 'created_at:datetime', 34 | 'updated_at:datetime', 35 | 36 | ['class' => 'yii\grid\ActionColumn', 'template' => '{view} {delete}'], 37 | ], 38 | ]); ?> 39 | 40 |
41 | --------------------------------------------------------------------------------