123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- <?php
- /*
- * This file is part of the ZhMead/laravel-logger.
- *
- * (c) Mead <751066209@qql.com>
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
- namespace App\Jobs\Manage;
- use App\Repositories\Enums\Manage\AnalysisStatusEnum;
- use App\Repositories\Models\Manage\Category;
- use App\Repositories\Models\Manage\Message;
- use App\Repositories\Models\Manage\PreMessage;
- use App\Repositories\Models\Manage\Task;
- use App\Repositories\Models\Manage\TaskResult;
- use Carbon\Carbon;
- use Illuminate\Bus\Queueable;
- use Illuminate\Contracts\Queue\ShouldQueue;
- use Illuminate\Queue\InteractsWithQueue;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- class AnalysisMessageJob implements ShouldQueue
- {
- use InteractsWithQueue;
- use Queueable;
- private $recordId;
- /**
- * Create a new job instance.
- */
- public function __construct($recordId)
- {
- $this->recordId = $recordId;
- }
- /**
- * 确定任务应该超时的时间
- *
- * @return \DateTime
- */
- public function retryUntil()
- {
- return Carbon::now()->addHours(24);
- }
- public $tries = 1;
- public $timeout = 1440;
- /**
- * Execute the job.
- */
- public function handle()
- {
- $this->analysis();
- }
- /**
- * 导入数据
- * @return false|void
- */
- public function analysis()
- {
- $model = Task::query()->find($this->recordId);
- $model->status = AnalysisStatusEnum::IN;
- $model->save();
- $main_ids = $model->message_ids;
- $is_main = false;
- if (is_array($main_ids)) {
- $is_main = count($main_ids);
- }
- TaskResult::query()->where('task_id', $model->id)->delete();
- Message::query()->where('task_id', $model->id)->update(['task_id' => 0]);
- PreMessage::query()->where('task_id', $model->id)->forceDelete();
- TaskResult::query()->where('task_id', $model->id)->forceDelete();
- DB::beginTransaction();
- try {
- Log::error('*************分析数据中*****************');
- $type_ids = $model->type_ids;
- $category_id = $model->category_id;
- $start_date = $model->start_date;
- $end_date = $model->end_date;
- $deal_department_id = $model->department_id;
- $arr = [];
- if ($category_id) $arr = Category::byCategoryIdGetCategoryArr($category_id);
- $category_1_id = 0;
- $category_2_id = 0;
- $category_3_id = 0;
- $category_4_id = 0;
- $category_5_id = 0;
- if (count($arr) >= 1) $category_1_id = $arr[0];
- if (count($arr) >= 2) $category_2_id = $arr[1];
- if (count($arr) >= 3) $category_3_id = $arr[2];
- if (count($arr) >= 4) $category_3_id = $arr[3];
- if (count($arr) >= 5) $category_3_id = $arr[4];
- $messages = Message::query()
- ->when($type_ids, function ($query) use ($type_ids) {
- return $query->whereIn('type_id', $type_ids);
- })
- ->when($deal_department_id, function ($query) use ($deal_department_id) {
- return $query->whereIn('deal_department_id', $deal_department_id);
- })
- ->when($category_1_id, function ($query) use ($category_1_id) {
- return $query->where('category_1_id', $category_1_id);
- })
- ->when($category_2_id, function ($query) use ($category_2_id) {
- return $query->where('category_2_id', $category_2_id);
- })
- ->when($category_3_id, function ($query) use ($category_3_id) {
- return $query->where('category_3_id', $category_3_id);
- })
- ->when($category_4_id, function ($query) use ($category_4_id) {
- return $query->where('category_4_id', $category_4_id);
- })
- ->when($category_5_id, function ($query) use ($category_5_id) {
- return $query->where('category_5_id', $category_5_id);
- })
- ->when($start_date, function ($query) use ($start_date) {
- return $query->whereDate('complain_date', '>=', $start_date);
- })
- ->when($end_date, function ($query) use ($end_date) {
- return $query->whereDate('complain_date', '<', $end_date);
- })
- ->when($is_main, function ($query) use ($main_ids) {
- return $query->whereNotIn('id', $main_ids);
- })->whereNotIn('id', $main_ids)
- ->where("more_pid", 0)
- ->select(['id', 'keywords', 'type_id', 'category_1_id', 'category_2_id', 'category_3_id', 'category_4_id', 'category_5_id', 'name', 'mobile', 'address_name', 'address_id', 'body', 'complain_date', 'warn_type_id', 'deal_department_id'])
- ->get();
- $t = $messages->count();
- $dbMessage = false;
- if ($t <= 1) throw new \Exception('分析的数据量太小');
- if (!$is_main) {
- if ($t > 2) {
- $total = $this->C($messages->count(), 2);
- } else {
- $total = 1;
- }
- $dbMessage = $messages;
- } else {
- $dbMessage = Message::query()->whereIn('id', $main_ids)->where("more_pid", 0)->select(['id', 'keywords', 'type_id', 'category_1_id', 'category_2_id', 'category_3_id', 'category_4_id', 'category_5_id', 'name', 'mobile', 'address_name', 'address_id', 'body', 'complain_date', 'warn_type_id', 'deal_department_id'])->get();
- $total = $dbMessage->count() * $t;
- foreach ($dbMessage as $message) {
- $data = $message->toArray();
- $data['message_id'] = $data['id'];
- unset($data['id']);
- $data['task_id'] = $model->id;
- $data['is_check'] = 1;
- PreMessage::query()->create($data);
- }
- }
- foreach ($messages as $message) {
- $data = $message->toArray();
- $data['message_id'] = $data['id'];
- unset($data['id']);
- $data['task_id'] = $model->id;
- $data['is_check'] = 1;
- PreMessage::query()->create($data);
- }
- $model->nums = $total;
- $use_nums = 0;
- $rateData = [];
- $rateSData = [];
- foreach ($dbMessage as $k => $message) {
- foreach ($messages as $kk => $m) {
- if ($k >= $kk) continue;
- $rate = $this->get_similar_percent($message->keywords, $m->keywords);
- TaskResult::query()->create([
- 'task_id' => $model->id,
- 'message_1_id' => $message->id,
- 'message_2_id' => $m->id,
- 'rate' => $rate,
- 'is_match' => ($rate >= $model->rate) ? 1 : 0,
- ]);
- $use_nums++;
- if ($rate >= $model->rate) {
- if (in_array($m->id, $rateSData)) continue;
- $rateSData[] = $m->id;
- $rateData[$message->id][] = $m->id;
- }
- }
- $progress = bcdiv($use_nums, $total, 2) * 100;
- DB::table('manage_tasks')->where('id', $model->id)->update(['progress' => $progress]);
- }
- foreach ($rateData as $m_id => $ids) {
- //合并
- $mainMessage = PreMessage::query()->where('message_id', $m_id)->where('task_id', $model->id)->first();
- PreMessage::query()->whereIn('message_id', $ids)->where('task_id', $model->id)->update([
- 'pid' => $mainMessage->id,
- // 'task_id' => $model->id,
- 'is_check' => 0,
- ]);
- $mainMessage->similar_nums = count($ids);
- $mainMessage->is_check = 0;
- $mainMessage->is_main = 1;
- // $mainMessage->task_id = $model->id;
- $mainMessage->save();
- }
- DB::commit();
- $model->status = AnalysisStatusEnum::OK;
- $model->message = '执行成功';
- } catch (\Exception $exception) {
- DB::rollBack();
- Log::error($exception);
- $model->status = AnalysisStatusEnum::ERROR;
- $model->message = $exception;
- }
- $model->save();
- Log::error("-----------完成---------------");
- }
- /**
- * 相似度
- * @param $str1_arr
- * @param $str2_arr
- * @return float|int
- */
- function get_similar_percent($str1_arr, $str2_arr)
- {
- $res_arr = [];
- foreach ($str1_arr as $word) {
- if (!isset($res_arr[$word])) {
- $res_arr[$word] = ['A' => 1, 'B' => 0];
- } else {
- $res_arr[$word]['A'] += 1;
- }
- }
- foreach ($str2_arr as $word2) {
- if (!isset($res_arr[$word2])) {
- $res_arr[$word2] = ['A' => 0, 'B' => 1];
- } else {
- $res_arr[$word2]['B'] += 1;
- }
- }
- $x = 0;
- $y1 = 0;
- $y2 = 0;
- foreach ($res_arr as $v) {
- $x += $v['A'] * $v['B'];
- $y1 += $v['A'] * $v['A'];
- $y2 += $v['B'] * $v['B'];
- }
- return ($y1 == 0 || $y2 == 0) ? -1 : ($x / (sqrt($y1) * sqrt($y2))) * 100;
- }
- public function factorial($n)
- {
- return array_product(range(1, $n));
- }
- // 计算排列个数
- public function A($n, $m)
- {
- return $this->factorial($n) / $this->factorial($n - $m);
- }
- // 计算组合个数
- public function C($n, $m)
- {
- return $this->A($n, $m) / $this->factorial($m);
- }
- }
|