CopyProjectJob.php 8.0 KB
<?php

namespace App\Jobs;

use App\Events\CopyProject;
use App\Events\UpdateHtml;
use App\Jobs\updateHtmlJob;
use App\Models\Project\After;
use App\Models\Project\DeployBuild;
use App\Models\Project\DeployOptimize;
use App\Models\Project\Payment;
use App\Models\Project\Project;
use App\Models\Template\Setting;
use App\Models\User\User as UserModel;
use App\Services\ProjectServer;
use Hashids\Hashids;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;

class CopyProjectJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $tries = 3; // 可配置任务重试次数

    protected $param;

    /**
     * Create a new job instance.
     *
     * @param  CopyImageFile  $event
     * @return void
     */
    public function __construct($data)
    {
        $this->param = $data;
    }


    /**
     * Handle the event.
     *
     * @param  UpdateHtml  $event
     * @return void
     */
    public function handle()
    {
        $projectModel = new Project();
        DB::beginTransaction();
        try {
            $this->output('CopyProjectJob start, project_id: ' . $this->param['project_id']);
            //复制初始项目
            $data = $projectModel::where('id', $this->param['project_id'])->first();
            $data = $data->getAttributes();
            $type = $data['type'];
            $data['type'] = 0;
            $data['status'] = 0;
            $data['finish_remain_day'] = 0;
            $data['title'] = $data['title'].'-copy';
            $data['delete_status'] = 0;
            unset($data['id'],$data['robots'],$data['is_translate_tag'],$data['is_translate'],$data['is_minor_languages'],$data['uptime']);
            $project_id = $projectModel->insertGetId($data);
            $hashids = new Hashids($data['from_order_id'], 13, 'abcdefghjkmnpqrstuvwxyz1234567890');
            $projectModel->edit(['from_order_id'=>$hashids->encode($project_id)],['id'=>$project_id]);
            //复制设置的模版
            $settingTemplateModel = new Setting();
            $settingData = $settingTemplateModel::where('project_id', $this->param['project_id'])->first();
            if(!empty($settingData)){
                $data = [
                    'template_id' =>$settingData['template_id'],
                    'project_id' => $project_id
                ];
                $settingTemplateModel->add($data);
            }
            //复制部署表
            $buildModel = new DeployBuild();
            $buildData = $buildModel::where('project_id', $this->param['project_id'])->first();
            if(!empty($buildData)){
                $buildData = $buildData->getAttributes();
                $buildData['project_id'] = $project_id;
                $hashids = new Hashids('test_domain', 5, 'abcdefghjkmnpqrstuvwxyz1234567890');
                $code = $hashids->encode($project_id);
                $buildData['test_domain'] = 'https://v6-' . $code . '.globalso.site/';
                unset($buildData['id']);
                $buildModel->insert($buildData);
            }
            //复制优化表
            $optimizeModel = new DeployOptimize();
            $optimizeData = $optimizeModel::where('project_id', $this->param['project_id'])->first();
            if(!empty($optimizeData)){
                $optimizeData = $optimizeData->getAttributes();
                unset($optimizeData['id'],$optimizeData['domain'],$optimizeData['backlink'],$optimizeData['ai_video']);
                $optimizeData['project_id'] = $project_id;
                $optimizeData['api_no'] = 0;
                $optimizeModel->insert($optimizeData);
            }
            //复制付费表
            $paymentModel = new Payment();
            $paymentData = $paymentModel::where('project_id', $this->param['project_id'])->first();
            if(!empty($paymentData)){
                $paymentData = $paymentData->getAttributes();
                unset($paymentData['id']);
                $paymentData['project_id'] = $project_id;
                $paymentModel->insert($paymentData);
            }
            //复制售后表
            $afterModel = new After();
            $afterData = $afterModel::where('project_id', $this->param['project_id'])->first();
            if(!empty($afterData)){
                $afterData = $afterData->getAttributes();
                unset($afterData['id']);
                $afterData['project_id'] = $project_id;
                $afterModel->insert($afterData);
            }
            //复制用户
            $userModel = new UserModel();
            $userData = $userModel::where('project_id', $this->param['project_id'])->where('role_id',0)->first();
            if(!empty($userData)){
                $userData = $userData->getAttributes();
                unset($userData['id']);
                $userData['project_id'] = $project_id;
                $userModel->insert($userData);
            }
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            $this->output('CopyProjectJob error, error message: ' . $e->getMessage());
            $this->fail('error');
        }
        if($type != 0){
            $this->copyMysql($this->param['project_id'],$project_id);
        }
        //修改项目状态
        $projectModel->edit(['delete_status'=>0],['id'=>$project_id]);
        $this->output('CopyProjectJob end, old project_id: ' . $this->param['project_id'] . ', new project_id: ' . $project_id);
        return true;
    }

    //复制数据库
    public function copyMysql($project_id,$new_project_id){
        //切换数据库配置
        $project = ProjectServer::useProject($new_project_id);
        //创建数据库
        ProjectServer::createDatabase($project);
        //创建表
        $this->initTable($project_id,$new_project_id);
    }

    /**
     * @remark :创建数据库
     * @name   :initTable
     * @author :lyh
     * @method :post
     * @time   :2023/12/11 10:09
     */
    public  function initTable($project_id,$news_project_id)
    {
        config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_'.$project_id]);
        $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName();
        $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables();
        $tables = array_column($tables, 'Tables_in_' . $database_name);
        foreach ($tables as $table) {
            $has_table = Schema::connection('custom_mysql')->hasTable($table);
            if (!$has_table) {
                $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}");
                DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']);
            }
            if($table == 'gl_customer_visit' ||  $table == 'gl_customer_visit_item' || $table == 'gl_inquiry_other' || $table == 'gl_inquiry_form_data' || $table == 'gl_inquiry_form'){
                continue;
            }
            DB::connection('custom_mysql')->table($table)->truncate(); // 清空目标表数据
            DB::connection('custom_mysql')->table($table)->insertUsing(
                [], // 列名数组,留空表示插入所有列
                function ($query) use ($table,$project_id) {
                    $name = 'gl_data_'.$project_id.'.'.$table;
                    $query->select('*')->from("{$name}");
                }
            );
            if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) {
                DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]);
            }
        }
        return true;
    }

    /**
     * @param $message
     * @return bool
     */
    public function output($message)
    {
        $date = date('Y-m-d H:i:s');
        $output = $date . ', ' . $message . PHP_EOL;
        echo $output;
        Log::info($output);
        return true;
    }
}