| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589 |
- <?php
- /**
- * Created by PhpStorm.
- * User: sunmoon<i@liming.me>
- * Date: 2019-07-31
- * Time: 09:22
- */
- namespace common\libs\logging\operate;
- use common\helpers\Form;
- use common\helpers\Tool;
- use common\libs\logging\operate\provider\BatchProvider;
- use common\libs\logging\operate\provider\SingleProvider;
- use common\models\User;
- use SebastianBergmann\CodeCoverage\Report\PHP;
- use yii\base\Component;
- use yii\base\ErrorException;
- use yii\base\Exception;
- use yii\helpers\ArrayHelper;
- abstract class AbstractOperate extends Component {
- /**
- * 保存日志的model
- * @var null
- */
- public $logModel = null;
- /**
- * 保存日志的form
- * @var null
- */
- public $logForm = null;
- /**
- * 用于查询保存存数据的model
- * @var
- */
- public $fetchClass = null;
- /**
- * @var array
- */
- public $attrLabels = [];
- /**
- * @var null
- */
- public $saveBeforeContent = null;
- /**
- * @var null
- */
- public $saveAfterContent = null;
- /**
- * @var array
- */
- public $columns = [];
- /**
- * @var null
- */
- public $data = null;
- /**
- * @var null
- */
- protected $_dataType = null;
- /**
- * @var array
- */
- public $params = [];
- /**
- * @var bool
- */
- protected $_isBatch = false;
- /**
- * @var string
- */
- protected $_batchField = 'ID';
- /**
- * @var string
- */
- protected $_optObjField = 'USER_ID';
- /**
- * @var null
- */
- protected $_errors = null;
- /**
- * Factory constructor.
- * @param array $config
- */
- public function __construct($config = []) {
- parent::__construct($config);
- }
- /**
- * @param array $format
- * @param array $params
- * @return array
- */
- public function paramsFormat(array $format, array $params = []){
- if(!$params){
- return $format;
- }
- return ArrayHelper::merge($format, $params);
- }
- /**
- * @return |null
- */
- public function getDataType(){
- return $this->_dataType;
- }
- /**
- * @param $value
- * @return $this
- */
- public function setDataType($value){
- $this->_dataType = $value;
- return $this;
- }
- /**
- * @return mixed
- */
- public function getIsBatch(){
- return $this->_isBatch;
- }
- /**
- * @param $value
- * @return $this
- */
- public function setIsBatch($value){
- $this->_isBatch = $value;
- return $this;
- }
- /**
- * @param $value
- * @return $this
- */
- public function setBatchField($value){
- $this->_batchField = $value;
- return $this;
- }
- /**
- * @param $value
- * @return $this
- */
- public function setOptObjField($value){
- $this->_optObjField = $value;
- return $this;
- }
- /**
- * @param $value
- * @return $this
- */
- public function setSaveBeforeContent($value){
- $this->saveBeforeContent = $value;
- return $this;
- }
- /**
- * @param $value
- * @return $this
- */
- public function setSaveAfterContent($value){
- $this->saveAfterContent = $value;
- return $this;
- }
- /**
- * 分发器
- * @param $method
- * @return array|null
- */
- public function dispatcher($method){
- $initParams = $this->paramsFormat([
- 'data' => $this->data,
- 'fetchClass' => $this->fetchClass,
- 'dataType' => $this->_dataType,
- 'attrLabels' => $this->attrLabels,
- ], $this->params);
- if($this->_isBatch){
- $entryClass = new BatchProvider($initParams);
- }else{
- $entryClass = new SingleProvider($initParams);
- }
- if(method_exists($entryClass, $method)){
- $entryClass->{$method}();
- return $entryClass->result;
- }
- return null;
- }
- /**
- * 更新之前
- * @param null $data
- * @param null $dataType
- * @param array $params
- * @return $this|bool
- */
- public function beforeUpdate($data = null, $dataType = null, array $params = []){
- if(!$data){
- return false;
- }
- $this->data = $data;
- $this->_dataType = $dataType;
- $this->params = $params;
- $this->saveBeforeContent = $this->dispatcher('beforeUpdate');
- return $this;
- }
- /**
- * @param $data
- * @param null $dataType
- * @param array $params
- * @return $this|bool
- */
- public function afterUpdate($data, $dataType = null, array $params = []){
- if(!$data){
- return false;
- }
- $this->data = $data;
- $this->_dataType = $dataType;
- $this->params = $params;
- $this->saveAfterContent = $this->dispatcher('afterUpdate');
- return $this;
- }
- /**
- * @param $data
- * @param null $dataType
- * @param array $params
- * @return $this|bool
- */
- public function beforeDelete($data, $dataType = null, array $params = []){
- if(!$data){
- return false;
- }
- $this->data = $data;
- $this->params = $params;
- $this->_dataType = $dataType;
- $this->saveBeforeContent = $this->dispatcher('beforeDelete');
- return $this;
- }
- /**
- * @param $data
- * @param string $dataType
- * @param array $params
- * @return $this|bool
- */
- public function afterInsert($data, $dataType = 'ID', array $params = []){
- if(!$data || !$dataType){
- return false;
- }
- $this->data = $data;
- $this->params = $params;
- $this->_dataType = $dataType;
- $this->saveAfterContent = $this->dispatcher('afterInsert');
- return $this;
- }
- /**
- * @return $this
- */
- public function clean(){
- $this->columns = [];
- return $this;
- }
- /**
- * @param array $params
- * @return bool
- */
- public function save(array $params = []){
- $this->setColumn($params);
- if(!$this->columns){
- return false;
- }
- // $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('log/save', [
- // 'logModel' => $this->logModel,
- // 'logForm' => $this->logForm,
- // 'isBatch' => $this->_isBatch,
- // 'batchField' => $this->_batchField,
- // 'optObjField' => $this->_optObjField,
- // 'columns' => $this->columns,
- // ]);
- // if ($taskKey === false) {
- // $this->setErrors('异步请求日志服务失败');
- // return false;
- // }
- if($this->_isBatch){
- $modelClass = $this->logModel;
- // mongodb 的批量添加要特殊处理
- $db = $modelClass::getDb();
- $collectionName = $modelClass::collectionName();
- if(is_array($collectionName)){
- $collection = count($collectionName) > 1 ? $collectionName[1] : $collectionName[0];
- }else{
- $collection = $collectionName;
- }
- $batchList = [];
- $saveAfterContent = $this->columns[0]['save_after_content'] ?? [];
- $saveBeforeContent = $this->columns[0]['save_before_content'] ?? [];
- if( $saveBeforeContent && $saveAfterContent ) {
- $saveBeforeContentList = [];
- foreach ($saveBeforeContent as $key => $beforeItem) {
- if (isset($beforeItem[$this->_batchField])) {
- $saveBeforeContentList[$beforeItem[$this->_batchField]['value']] = $beforeItem;
- } else {
- $saveBeforeContentList[$key] = $beforeItem;
- }
- }
- foreach ($saveAfterContent as $key => $afterItem) {
- if (isset($afterItem[$this->_batchField])) {
- if (!isset($saveBeforeContentList[$afterItem[$this->_batchField]['value']])) continue;
- $beforeItem = $saveBeforeContentList[$afterItem[$this->_batchField]['value']];
- } else {
- if (!isset($saveBeforeContentList[$key])) continue;
- $beforeItem = $saveBeforeContentList[$key];
- }
- $mergeData = [
- 'save_before_content' => $beforeItem,
- 'save_after_content' => $afterItem,
- ];
- //记录opt_obj_id 和 opt_obj_name @todo待优化
- $this->_fixOptObjField($collection, $beforeItem);
- $batchList[] = array_merge($this->columns[0], $mergeData);
- }
- unset($saveBeforeContentList);
- }else if( $saveBeforeContent && !$saveAfterContent ) {
- foreach ($saveBeforeContent as $key => $beforeItem) {
- $mergeData = [
- 'save_before_content' => $beforeItem,
- 'save_after_content' => null,
- ];
- //记录opt_obj_id 和 opt_obj_name @todo待优化
- $this->_fixOptObjField($collection, $beforeItem);
- $batchList[] = array_merge($this->columns[0], $mergeData);
- }
- }else if( !$saveBeforeContent && $saveAfterContent ) {
- foreach ($saveAfterContent as $key => $afterItem) {
- $mergeData = [
- 'save_before_content' => null,
- 'save_after_content' => $afterItem,
- ];
- //记录opt_obj_id 和 opt_obj_name @todo待优化
- $this->_fixOptObjField($collection, $afterItem);
- $batchList[] = array_merge($this->columns[0], $mergeData);
- }
- }else {
- $this->setErrors('日志批量写入错误');
- return false;
- }
- unset($saveBeforeContent, $saveAfterContent);
- if (!$batchList) {
- $this->setErrors('数据无效');
- return false;
- }
- if(!$db->createCommand()->batchInsert($collection, $batchList)){
- $this->setErrors('日志批量写入失败');
- return false;
- }
- // if(!$db->createCommand()->batchInsert($collection, $this->columns)){
- // $this->setErrors('日志批量写入失败');
- // return false;
- // }
- return true;
- }else {
- $modelFormClass = $this->logForm;
- $logForm = new $modelFormClass($this->columns[0]);
- if(!$logForm->add()){
- $this->setErrors($logForm->getErrors());
- return false;
- }
- }
- return true;
- }
- /**
- * 异步保存(异步控制器调用此方法)
- * @return bool
- */
- public function asyncSave() {
- try {
- if( !$this->columns || !isset($this->columns[0]) ) {
- throw new Exception('储存的数据错误');
- }
- if ($this->_isBatch) {
- $this->_batchInsert();
- } else {
- $modelFormClass = $this->logForm;
- $logForm = new $modelFormClass($this->columns[0]);
- if (!$logForm->add()) {
- throw new Exception(Form::formatErrorsForApi($logForm->getErrors()));
- }
- }
- return true;
- }catch (\Exception $e) {
- $this->setErrors($e->getMessage());
- return false;
- }
- }
- /**
- * console里面记日志,直接保存,无需调用异步,因为本身就是异步
- * @param array $params
- * @return bool
- */
- public function saveByConsole(array $params = []){
- $this->setColumn($params);
- if(!$this->columns){
- return false;
- }
- try {
- if( !$this->columns || !isset($this->columns[0]) ) {
- throw new Exception('储存的数据错误');
- }
- if ($this->_isBatch) {
- $this->_batchInsert();
- } else {
- $modelFormClass = $this->logForm;
- $logForm = new $modelFormClass($this->columns[0]);
- if (!$logForm->add()) {
- throw new Exception(Form::formatErrorsForApi($logForm->getErrors()));
- }
- }
- }catch (\Exception $e) {
- $this->setErrors($e->getMessage());
- return false;
- }
- return true;
- }
- /**
- * 批量写入
- * @return bool
- * @throws ErrorException
- * @throws \yii\base\InvalidConfigException
- */
- protected function _batchInsert() {
- $modelClass = $this->logModel;
- // mongodb 的批量添加要特殊处理
- $db = $modelClass::getDb();
- $collectionName = $modelClass::collectionName();
- if(is_array($collectionName)){
- $collection = count($collectionName) > 1 ? $collectionName[1] : $collectionName[0];
- }else{
- $collection = $collectionName;
- }
- $batchList = [];
- $saveAfterContent = $this->columns[0]['save_after_content'] ?? [];
- $saveBeforeContent = $this->columns[0]['save_before_content'] ?? [];
- if( $saveBeforeContent && $saveAfterContent ) {
- $saveBeforeContentList = [];
- foreach ($saveBeforeContent as $key => $beforeItem) {
- if (isset($beforeItem[$this->_batchField])) {
- $saveBeforeContentList[$beforeItem[$this->_batchField]['value']] = $beforeItem;
- } else {
- $saveBeforeContentList[$key] = $beforeItem;
- }
- }
- foreach ($saveAfterContent as $key => $afterItem) {
- if (isset($afterItem[$this->_batchField])) {
- if (!isset($saveBeforeContentList[$afterItem[$this->_batchField]['value']])) continue;
- $beforeItem = $saveBeforeContentList[$afterItem[$this->_batchField]['value']];
- } else {
- if (!isset($saveBeforeContentList[$key])) continue;
- $beforeItem = $saveBeforeContentList[$key];
- }
- $mergeData = [
- 'save_before_content' => $beforeItem,
- 'save_after_content' => $afterItem,
- ];
- //记录opt_obj_id 和 opt_obj_name @todo待优化
- $this->_fixOptObjField($collection, $beforeItem);
- $batchList[] = array_merge($this->columns[0], $mergeData);
- }
- unset($saveBeforeContentList);
- }else if( $saveBeforeContent && !$saveAfterContent ) {
- foreach ($saveBeforeContent as $key => $beforeItem) {
- $mergeData = [
- 'save_before_content' => $beforeItem,
- 'save_after_content' => null,
- ];
- //记录opt_obj_id 和 opt_obj_name @todo待优化
- $this->_fixOptObjField($collection, $beforeItem);
- $batchList[] = array_merge($this->columns[0], $mergeData);
- }
- }else if( !$saveBeforeContent && $saveAfterContent ) {
- foreach ($saveAfterContent as $key => $afterItem) {
- $mergeData = [
- 'save_before_content' => null,
- 'save_after_content' => $afterItem,
- ];
- //记录opt_obj_id 和 opt_obj_name @todo待优化
- $this->_fixOptObjField($collection, $afterItem);
- $batchList[] = array_merge($this->columns[0], $mergeData);
- }
- }else {
- throw new ErrorException('日志批量写入错误');
- }
- unset($saveBeforeContent, $saveAfterContent);
- if (!$batchList) {
- throw new ErrorException('数据无效' . var_export($this->columns, true));
- }
- if(!$db->createCommand()->batchInsert($collection, $batchList)){
- throw new ErrorException('日志批量写入失败');
- }
- return true;
- }
- /**
- * 修正批量时的补操作对象信息
- * @param $collection
- * @param $item
- * @return bool
- * @throws \yii\base\InvalidConfigException
- */
- private function _fixOptObjField($collection, $item) {
- if( $collection !== 'ar_bonus_admin_log') {
- return false;
- }
- if( !isset( $item[$this->_optObjField] ) ) {
- return false;
- }
- $this->columns[0]['opt_obj_id'] = $item[$this->_optObjField]['value'];
- if( isset( $item['USER_NAME'] ) ) {
- $this->columns[0]['opt_obj_name'] = $item['USER_NAME']['value'];
- }else {
- //@todo
- $userOne = User::find()->select(['USER_NAME'])->where('ID=:ID', ['ID'=>$item[$this->_optObjField]['value']])->asArray()->one();
- if( $userOne && isset($userOne['USER_NAME']) ) {
- $this->columns[0]['opt_obj_name'] = $userOne['USER_NAME'];
- }
- }
- return true;
- }
- /**
- * @param $error
- * @return $this
- */
- public function setErrors($error){
- $this->_errors = $error;
- return $this;
- }
- /**
- * @return array|null
- */
- public function getErrors(){
- return $this->_errors;
- }
- }
|