wzq пре 5 година
родитељ
комит
64a7c8032d

+ 88 - 0
app/Console/Commands/AddNoticeRule.php

@@ -0,0 +1,88 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\NoticeRule;
+use App\Service\RabbitMqUtil;
+use App\Traits\PostTrait;
+use Illuminate\Console\Command;
+use Illuminate\Database\QueryException;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+use PhpAmqpLib\Connection\AMQPStreamConnection;
+
+class AddNoticeRule extends Command
+{
+    use PostTrait;
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'notice:add';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '添加发送通知';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct(NoticeRule $noticeRule, RabbitMqUtil $rabbitMqUtil)
+    {
+        parent::__construct();
+        $this->noticeRule = $noticeRule;
+        $this->rabbitMqUtil = $rabbitMqUtil;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->line("开始添加发送通知");
+
+        $this->noticeRule
+            ->where('notice_type', 0)
+            ->where('notice_status', 0)
+            ->where('send_time', '<', Carbon::now()->toDateTimeString())
+            ->whereNotNUll('send_time')
+            ->chunk(100, function($notices){
+                foreach($notices as $notice){
+                    DB::beginTransaction();
+                    try{
+                        $notice->notice_status = 1;
+                        $noticeUsers = json_decode($notice->notice_users, true);
+                        if(isset($noticeUsers['category']) && $noticeUsers['category']){
+                            $uids = $this->getCategoryUids(json_encode($noticeUsers['category']));
+                            Log::debug('uids'.json_encode($uids));
+                            if(!$uids){
+                                DB::rollBack();
+                                Log::error('获取关注分类用户失败:');
+                            }
+                            $noticeUsers['category_uids'] = $uids;
+                            $notice->notice_users = json_encode($noticeUsers);
+                        }
+                        $notice->save();
+                        DB::commit();
+                        $this->rabbitMqUtil->push('add_notice_rule', $notice);
+                        Log::info('添加发送通知成功:'.$notice->id);
+                    }catch (QueryException $exception){
+                        DB::rollBack();
+                        Log::error('添加发送通知失败:'.$exception->getMessage());
+                    }
+                }
+            });
+
+        $this->line("添加发送消息结束");
+
+    }
+}

+ 102 - 0
app/Console/Commands/UpdateNoticeRule.php

@@ -0,0 +1,102 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Repositories\NoticeRuleRepository;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+use PhpAmqpLib\Connection\AMQPStreamConnection;
+
+class UpdateNoticeRule extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'notice:update_status';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新规则通知状态';
+
+    protected $channel;
+    protected $connection;
+
+    protected $queue = 'update_status_notice_rule';
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct(NoticeRuleRepository $noticeRuleRepository)
+    {
+        parent::__construct();
+        $this->noticeRuleRepository = $noticeRuleRepository;
+        $this->connection = $this->getConnection();
+        $this->channel = $this->connection->channel();
+        $this->channel->exchange_declare($this->queue, 'fanout', false, true, false);
+    }
+
+    public function getConnection()
+    {
+        $conn = false;
+        if ($this->connection) {
+            return $this->connection;
+        }
+        for ($i = 0; $i < 3; $i++) {
+            $connection = $this->createConn();
+            if ($connection) {
+                $conn = $connection;
+                break;
+            }
+            Log::info("create amqp conn retry=" . $i);
+        }
+        return $conn;
+    }
+
+    public function createConn()
+    {
+        try {
+            $connection = new AMQPStreamConnection(env('MQ_HOST'), env('MQ_PORT'), env('MQ_USERNAME'), env('MQ_PWD'), env('MQ_VHOST'));
+        } catch (\Exception $exception) {
+            Log::info("AMQP connection Error" . $exception->getMessage());
+            $connection = false;
+        }
+        return $connection;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        Log::info('发送消息结果');
+        $queue_name = $this->queue;
+        $this->channel->queue_declare($queue_name, false, true, false, false);
+        $this->channel->queue_bind($queue_name, $this->queue);
+        $callback = function ($msg) {
+            Log::info($msg->body);
+            $data = \GuzzleHttp\json_decode($msg->body, true);
+            $this->line('收到数据' . $msg->body);
+            $res = $this->noticeRuleRepository->updateStatus($data);
+            if($res){
+                $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
+            }
+        };
+        $this->channel->basic_consume($queue_name, '', false, false, false, false, $callback);
+
+        while (count($this->channel->callbacks)) {
+            $this->channel->wait();
+        }
+        $this->channel->close();
+        $this->connection->close();
+
+
+    }
+}

+ 8 - 0
app/Console/Kernel.php

@@ -3,8 +3,10 @@
 namespace App\Console;
 
 use App\Console\Commands\AddMessageRule;
+use App\Console\Commands\AddNoticeRule;
 use App\Console\Commands\Apollo;
 use App\Console\Commands\UpdateMessageRule;
+use App\Console\Commands\UpdateNoticeRule;
 use Illuminate\Console\Scheduling\Schedule;
 use Laravel\Lumen\Console\Kernel as ConsoleKernel;
 
@@ -17,7 +19,9 @@ class Kernel extends ConsoleKernel
      */
     protected $commands = [
         AddMessageRule::class,
+        AddNoticeRule::class,
         UpdateMessageRule::class,
+        UpdateNoticeRule::class,
         Apollo::class
     ];
 
@@ -34,5 +38,9 @@ class Kernel extends ConsoleKernel
         $schedule->command('message:add')
             ->everyMinute()
             ->withoutOverlapping()->appendOutputTo($path);
+
+        $schedule->command('notice:add')
+            ->everyMinute()
+            ->withoutOverlapping()->appendOutputTo($path);
     }
 }

+ 30 - 0
app/Http/Controllers/ConfigController.php

@@ -128,6 +128,36 @@ class ConfigController extends Controller
                     '2' => '已发送未隐藏',
                     '3' => '已发送并隐藏',
                 ],
+                //通知类型
+                'notice_type' =>[
+                    '1' => '短信',
+                    '0' => 'push',
+                ],
+                //通知状态
+                'notice_status' =>[
+                    '1' => '发送中',
+                    '0' => '未发送',
+                    '2' => '已发送',
+                ],
+                //通知用户类型
+                'notice_user_type' =>[
+                    '1' => '条件筛选',
+                    '0' => '全部用户',
+                    '2' => 'uid群发',
+                ],
+                //用户属性
+                'attribute' =>[
+                    '1' => '原始用户',
+                    '0' => '不限',
+                    '2' => '正式用户',
+                ],
+                //跳转类型
+                'action_type' =>[
+                    'post' => '内容',
+                    'star' => '首页',
+                    'activity' => '活动',
+                    'product' => '商品',
+                ],
         ];
     }
 }

+ 117 - 0
app/Http/Controllers/NoticeRuleController.php

@@ -0,0 +1,117 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Repositories\NoticeRuleRepository;
+use App\Transformers\MessageRuleDetailTransformer;
+use App\Transformers\NoticeRuleDetailTransformer;
+use App\Transformers\NoticeRuleListTransformer;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rule;
+use League\Fractal\Manager;
+use League\Fractal\Pagination\IlluminatePaginatorAdapter;
+use League\Fractal\Resource\Collection;
+use League\Fractal\Resource\Item;
+
+class NoticeRuleController extends Controller
+{
+    public function __construct(NoticeRuleRepository $noticeRuleRepository)
+    {
+        $this->noticeRuleRepository = $noticeRuleRepository;
+    }
+
+    /**
+     * 通知规则列表
+     */
+    public function index(Request $request)
+    {
+        $productList = $this->noticeRuleRepository->lists($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($productList, new NoticeRuleListTransformer());
+        $resource->setPaginator(new IlluminatePaginatorAdapter($productList));
+        $data = $fractal->createData($resource)->toArray();
+        $data['extra'] = [
+            'filters' => [
+                'title',
+            ],
+            'columns' => [
+                'id',
+                'title',
+                'cover',
+                'updated_at',
+                'send_count',
+                'notice_user_type',
+                'notice_status'
+            ]
+        ];
+        return $data;
+    }
+
+    /**
+     * 创建通知规则
+     */
+    public function create(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'title' => 'required|string|max:30',
+            'notice_user_type' => ['required',Rule::in(0, 1, 2)],
+            'action_type' => ['required',Rule::in('post', 'star', 'activity', 'product')],
+            'action_id' => 'required_unless:action_type,star|integer|min:1',
+            'content' => 'required|string|max:60',
+            'send_time' => 'nullable|date',
+            'attribute' => ['nullable',Rule::in(0, 1, 2)],
+            'category' => 'nullable|array',
+            'category.*' => 'nullable|integer',
+        ]);
+        if ($validator->fails()) {
+            return $this->response->error($validator->errors()->first(), 500);
+        }
+        return  $this->noticeRuleRepository->create($request->all());
+    }
+
+
+    /**
+     * 通知规则详情
+     */
+    public function detail(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:notice_rule'
+        ]);
+        if ($validator->fails()) {
+            return $this->response->error($validator->errors()->first(), 500);
+        }
+
+        $post = $this->noticeRuleRepository->detail($request->all());
+        return $this->response->item($post, new NoticeRuleDetailTransformer());
+    }
+
+    /**
+     * 发送通知规则
+     */
+    public function send(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:notice_rule'
+        ]);
+        if ($validator->fails()) {
+            return $this->response->error($validator->errors()->first(), 500);
+        }
+        return  $this->noticeRuleRepository->send($request->all());
+    }
+
+    /**
+     * 删除通知
+     */
+    public function delete(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:notice_rule'
+        ]);
+        if ($validator->fails()) {
+            return $this->response->error($validator->errors()->first(), 500);
+        }
+        return  $this->noticeRuleRepository->delete($request->all());
+    }
+}

+ 18 - 0
app/Models/NoticeRule.php

@@ -0,0 +1,18 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/9/5
+ * Time: 10:12
+ */
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class NoticeRule extends Model
+{
+    use SoftDeletes;
+    protected $table = 'notice_rule';
+    protected $guarded = [];
+}

+ 218 - 0
app/Repositories/NoticeRuleRepository.php

@@ -0,0 +1,218 @@
+<?php
+
+namespace App\Repositories;
+
+use App\Models\NoticeRule;
+use App\Traits\PostTrait;
+use Illuminate\Database\QueryException;
+use Dingo\Api\Http\Response;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+use Tymon\JWTAuth\Facades\JWTAuth;
+
+class NoticeRuleRepository
+{
+    use PostTrait;
+    public function __construct(NoticeRule $noticeRule)
+    {
+        $this->noticeRule = $noticeRule;
+    }
+
+    /**
+     * 通知列表
+     */
+    public function lists($request)
+    {
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+        $where = [];
+        if(isset($request['title'])){
+            $where[] = ['title', 'like', "%{$request['title']}%"];
+        }
+        $where[] = ['notice_type', 0];
+        return $this->noticeRule
+            ->where($where)
+            ->orderBy('id','desc')
+            ->paginate($perPage);
+    }
+
+    /**
+     * 创建通知规则
+     */
+    public function create($request)
+    {
+        $noticeUsers = [];
+        $post_type = '';
+        if($request['notice_user_type'] == 1){
+            if(!(isset($request['attribute']) && $request['attribute']) && !(isset($request['category']) && $request['category'])){
+                return Response::create([
+                    'message'  => '请选择属性或分类',
+                    'status_code'   => 500
+                ]);
+            }
+            if(isset($request['attribute']) && $request['attribute']){
+                $noticeUsers['attribute'] = $request['attribute'];
+            }
+
+            if(isset($request['category']) && $request['category']){
+                $noticeUsers['category'] = array_unique($request['category']);
+            }
+        }elseif($request['notice_user_type'] == 2){
+            if(!(isset($request['uids']) && $request['uids'])){
+                return Response::create([
+                    'message'  => '请输入用户uid',
+                    'status_code'   => 500
+                ]);
+            }
+            $uids = $noticeGroups = explode('、', $request['uids']);
+            $noticeUsers['uids'] = array_unique($uids);
+        }
+
+        if(isset($request['action_type']) && $request['action_type'] == 'post'){
+            //查看内容的类型
+            $post_type = $this->getPostType($request['action_id']);
+            if(!$post_type){
+                return Response::create([
+                    'message'  => '请输入有效内容id',
+                    'status_code'   => 500
+                ]);
+            }
+        }
+
+        $data = [
+            'notice_type' => 0,
+            'title' => $request['title'],
+            'content' => $request['content'],
+            'notice_user_type' => $request['notice_user_type'],
+            'notice_users' => json_encode($noticeUsers),
+            'action_type' => $request['action_type']??'',
+            'action_id' => $request['action_id']??0,
+            'post_type' => $post_type,
+            'cover' => $request['cover']??'',
+            'notice_status' => 0,
+            'send_time' => isset($request['send_time']) && $request['send_time']? $request['send_time']:null,
+            'send_count' => 0,
+        ];
+
+        DB::beginTransaction();
+        try{
+            $this->noticeRule->create($data);
+
+            DB::commit();
+            return Response::create();
+
+        }catch (QueryException $exception){
+            DB::rollBack();
+            Log::debug('创建通知规则失败:'.$exception->getMessage());
+            return Response::create([
+                'message'  => '添加失败,请重试',
+                'error' => $exception->getMessage(),
+                'status_code'   => 500
+            ]);
+        }
+    }
+
+    /**
+     * 通知规则详情
+     */
+    public function detail($request)
+    {
+        return $this->noticeRule->find($request['id']);
+    }
+
+    /**
+     * 发送通知规则
+     */
+    public function send($request)
+    {
+        $notice = $this->noticeRule->find($request['id']);
+        if(!$notice || $notice->notice_status != 0){
+            return Response::create([
+                'message'  => '只能发送未发送通知',
+                'status_code'   => 500
+            ]);
+        }
+
+        $notice->send_time = Carbon::now()->toDateTimeString();
+
+        DB::beginTransaction();
+        try{
+            $notice->save();
+
+            DB::commit();
+            return Response::create();
+
+        }catch (QueryException $exception){
+            DB::rollBack();
+            Log::debug('发送通知规则失败:'.$exception->getMessage());
+            return Response::create([
+                'message'  => '发送失败,请重试',
+                'error' => $exception->getMessage(),
+                'status_code'   => 500
+            ]);
+        }
+    }
+
+    /**
+     * 删除通知
+     */
+    public function delete($request)
+    {
+        $notice = $this->noticeRule->find($request['id']);
+        if(!$notice || $notice->notice_status != 0){
+            return Response::create([
+                'message'  => '只能删除未发送通知',
+                'status_code'   => 500
+            ]);
+        }
+
+
+        DB::beginTransaction();
+        try{
+            $notice->delete();
+
+            DB::commit();
+            return Response::create();
+
+        }catch (QueryException $exception){
+            DB::rollBack();
+            Log::debug('删除通知规则失败:'.$exception->getMessage());
+            return Response::create([
+                'message'  => '删除失败,请重试',
+                'error' => $exception->getMessage(),
+                'status_code'   => 500
+            ]);
+        }
+    }
+
+    /**
+     * 更新通知规则
+     */
+    public function updateStatus($data)
+    {
+        Log::debug('更新通知规则收到数据:'.json_encode($data));
+        $notice = $this->noticeRule->find($data['id']);
+        if(!$notice || $notice->notice_status != 1){
+            Log::error('更新通知规则状态失败:'.$data['id']);
+            return false;
+        }
+
+        $notice->notice_status = 2;
+        $notice->send_count = $data['num'];
+
+        DB::beginTransaction();
+        try{
+            $notice->save();
+
+            DB::commit();
+            return true;
+
+        }catch (QueryException $exception){
+            DB::rollBack();
+            Log::error('更新通知规则状态:'.$data['id'].$exception->getMessage());
+            return false;
+        }
+    }
+}

+ 13 - 0
app/Traits/PostTrait.php

@@ -23,4 +23,17 @@ trait PostTrait
         }
 
     }
+
+    public function getCategoryUids($category) {
+        try {
+            $url = config("customer.manage_service_url").'/community/post/getCategoryUids';
+            $array = [
+                'json' => ['category' => $category], 'query' => [], 'http_errors' => false,'headers'=>['Authorization'=>"Bearer ".JWTAuth::getToken()]
+            ];
+            return http($url,$array, 'get');
+        } catch (\Exception $e) {
+            return [];
+        }
+
+    }
 }

+ 40 - 0
app/Transformers/NoticeRuleDetailTransformer.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Transformers;
+
+use App\Models\NoticeRule;
+use Illuminate\Support\Carbon;
+use League\Fractal\TransformerAbstract;
+
+class NoticeRuleDetailTransformer extends TransformerAbstract
+{
+    public function transform(NoticeRule $noticeRule)
+    {
+        $noticeStatus = $noticeRule['notice_status'];
+        if($noticeStatus == 0 && $noticeRule['send_time'] && $noticeRule['send_time'] <= Carbon::now()->toDateTimeString()){
+            $noticeStatus = 1;
+        }
+        $noticeUsers = json_decode($noticeRule['notice_users'], true);
+        $attribute = $noticeUsers['attribute']??0;
+        $category = $noticeUsers['category']??[];
+        $uids = '';
+        if(isset($noticeUsers['uids'])){
+            $uids = implode('、', $noticeUsers['uids']);
+        }
+        return [
+            'id' => $noticeRule['id'],
+            'title' => $noticeRule['title'],
+            'content' => $noticeRule['content'],
+            'cover' => $noticeRule['cover'],
+            'send_time' => $noticeRule['send_time']?Carbon::parse($noticeRule['send_time'])->toDateTimeString():'',
+            'send_count' => $noticeRule['send_count'],
+            'notice_user_type' => $noticeRule['notice_user_type'],
+            'notice_status' => $noticeStatus,
+            'attribute' => $attribute,
+            'category' => $category,
+            'uids' => $uids,
+            'action_type' => $noticeRule['action_type'],
+            'action_id' => $noticeRule['action_id'],
+        ];
+    }
+}

+ 27 - 0
app/Transformers/NoticeRuleListTransformer.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Transformers;
+
+use App\Models\NoticeRule;
+use Illuminate\Support\Carbon;
+use League\Fractal\TransformerAbstract;
+
+class NoticeRuleListTransformer extends TransformerAbstract
+{
+    public function transform(NoticeRule $noticeRule)
+    {
+        $noticeStatus = $noticeRule['notice_status'];
+        if($noticeStatus == 0 && $noticeRule['send_time'] && $noticeRule['send_time'] <= Carbon::now()->toDateTimeString()){
+            $noticeStatus = 1;
+        }
+        return [
+            'id' => $noticeRule['id'],
+            'title' => $noticeRule['title'],
+            'cover' => $noticeRule['cover'],
+            'updated_at' => Carbon::parse($noticeRule['updated_at'])->toDateTimeString(),
+            'send_count' => $noticeRule['send_count'],
+            'notice_user_type' => $noticeRule['notice_user_type'],
+            'notice_status' => $noticeStatus,
+        ];
+    }
+}

+ 82 - 0
database/migrations/2019_09_05_094541_create_table_notice_rule.php

@@ -0,0 +1,82 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateTableNoticeRule extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('notice_rule', function (Blueprint $table) {
+            $table->bigIncrements('id');
+
+            $table->string('title', 32)
+                ->default('')
+                ->comment('标题');
+
+            $table->string('content', 500)
+                ->default('')
+                ->comment('内容');
+
+            $table->tinyInteger('notice_status')
+                ->default(0)
+                ->comment('通知状态:0:未发送,1发送中,2已发送');
+
+            $table->tinyInteger('notice_type')
+                ->default(0)
+                ->comment('通知类型:0push,1短信');
+
+            $table->tinyInteger('notice_user_type')
+                ->default(0)
+                ->comment('通知用户类型:0全部,1条件筛选,2ID群发');
+
+            $table->json('notice_users')
+                ->nullable()
+                ->comment('通知用户:attribute,category,ids');
+
+            $table->string('action_type', 16)
+                ->default('')
+                ->comment('跳转内容');
+
+            $table->integer('action_id')
+                ->default(0)
+                ->comment('跳转id');
+
+            $table->string('post_type', 16)
+                ->default('')
+                ->comment('内容类型');
+
+            $table->string('cover', 255)
+                ->default('')
+                ->comment('封面图');
+
+            $table->integer('send_count')
+                ->default(0)
+                ->comment('发送数量');
+
+            $table->dateTime('send_time')
+                ->nullable()
+                ->comment('发送时间');
+
+            $table->softDeletes();
+
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('notice_rule');
+    }
+}

+ 4 - 0
resources/lang/zh-CN/validation.php

@@ -109,6 +109,10 @@ return [
         'cover' => '封面图',
         'send_time' => '发送时间',
         'activity_time' => '活动时间',
+        'notice_type' => '通知类型',
+        'notice_user_type' => '通知用户类型',
+        'action_type' => '跳转内容',
+        'action_id' => '跳转id',
     ],
 
 ];

+ 11 - 0
routes/api.php

@@ -77,6 +77,17 @@ $api->version('v1', [
         //创建版本号
         $api->post('upgrade', 'UpgradeController@create');
 
+        //通知规则列表
+        $api->get('notice', 'NoticeRuleController@index');
+        //添加通知规则
+        $api->post('notice', 'NoticeRuleController@create');
+        //删除通知规则
+        $api->delete('notice', 'NoticeRuleController@delete');
+        //发送通知规则
+        $api->put('notice/send', 'NoticeRuleController@send');
+        //通知规则详情
+        $api->get('notice/detail', 'NoticeRuleController@detail');
+
 
     });
     //配置文件