作者 lms

合并分支 'lms' 到 'develop'

Lms - 推送数据到aicc



查看合并请求 !69
  1 +<?php
  2 +
  3 +namespace App\Console\Commands;
  4 +
  5 +use App\Models\ProjectAssociation\ProjectAssociation;
  6 +use App\Models\File\DataFile;
  7 +use Dompdf\Dompdf;
  8 +use Dompdf\Options;
  9 +use Illuminate\Console\Command;
  10 +
  11 +class ProjectFilePDF extends Command
  12 +{
  13 + /**
  14 + * The name and signature of the console command.
  15 + *
  16 + * @var string
  17 + */
  18 + protected $signature = 'project_file_pdf';
  19 +
  20 + /**
  21 + * The console command description.
  22 + *
  23 + * @var string
  24 + */
  25 + protected $description = '网站项目数据,生成PDF文件';
  26 +
  27 + protected $AiccWechat;
  28 +
  29 + protected $DataFile;
  30 +
  31 + protected $time;
  32 +
  33 + /**
  34 + * Create a new command instance.
  35 + *
  36 + * @return void
  37 + */
  38 + public function __construct()
  39 + {
  40 + $this->AiccWechat = new ProjectAssociation();
  41 + $this->DataFile = new DataFile();
  42 + $this->time = date("Y-m-d");
  43 + parent::__construct();
  44 + }
  45 +
  46 + /**
  47 + * Execute the console command.
  48 + *
  49 + * @return int
  50 + */
  51 + public function handle()
  52 + {
  53 + $data = $this->get_data();
  54 + # 详细数据
  55 + $items = $data['items'];
  56 + # 总分页
  57 + $totalPage = $data['totalPage'];
  58 + $this->dataPush($items);
  59 + if ($totalPage > 1) {
  60 + for ($page = 2; $page <= $totalPage; $page++) {
  61 + $da = $this->get_data();
  62 + $this->dataPush($da['items']);
  63 + }
  64 + }
  65 + $this->info('生成pdf完成');
  66 + return 0;
  67 + }
  68 +
  69 + /**
  70 + * 数据生成并保存
  71 + * @param array $items
  72 + * @return void
  73 + */
  74 + public function dataPush(array $items)
  75 + {
  76 + foreach ($items as $item) {
  77 + $project_id = $item->project_id;
  78 + $application_id = $item->wx_id;
  79 + $wx_user_id = $item->wx_user_id;
  80 + // todo 根据项目查询数据
  81 + $project_data = [];
  82 + $html = $this->html($project_data);
  83 + $filename = hash('md5', $this->time . '-' . $project_id . '-' . $application_id);
  84 + $file_path = $this->savePDF($html, $filename);
  85 + $this->DataFile->saveData(compact('project_id', 'application_id', 'file_path') + ['time' => $this->time]);
  86 + }
  87 + }
  88 +
  89 +
  90 + public function get_data($page = 1, $perPage = 20)
  91 + {
  92 + $data = $this->AiccWechat->allData($page, $perPage);
  93 + # 总条数
  94 + $total = $data['total'];
  95 + if (empty($total)) {
  96 + $this->error('暂无绑定AICC微信数据');
  97 + return 0;
  98 + }
  99 + # 详细数据
  100 + $items = $data['items'];
  101 + # 总分页
  102 + $totalPage = $data['totalPage'];
  103 + # 当前页
  104 + $currentPage = $data['currentPage'];
  105 + return compact('total', 'items', 'totalPage', 'currentPage');
  106 + }
  107 +
  108 + public function savePDF($html, $filename)
  109 + {
  110 + // todo 生成中文有问题
  111 + # 实例化并使用dompdf类
  112 + $options = new Options();
  113 + $options->setDefaultFont('arial');
  114 + $dompdf = new Dompdf($options);
  115 + $dompdf->loadHtml($html);
  116 + #(可选)设置纸张大小和方向
  117 + $dompdf->setPaper('A4', 'landscape');
  118 +
  119 + # 将HTML渲染为PDF
  120 + $dompdf->render();
  121 +
  122 + // 获取PDF内容
  123 + $pdfContent = $dompdf->output();
  124 +
  125 + // 指定保存路径和文件名
  126 + $savePath = public_path('PDF/' . $filename . '.pdf');
  127 +
  128 + // 将PDF内容保存到文件
  129 + file_put_contents($savePath, $pdfContent);
  130 +
  131 + // 输出保存成功消息
  132 + return $savePath;
  133 + }
  134 +
  135 + /**
  136 + * 根据数据生成 Html
  137 + * @param $item
  138 + * @return string
  139 + */
  140 + protected function html($item)
  141 + {
  142 + $html = '<html>';
  143 + $html .= '<body style="font-family:arial">';
  144 + $html .= '<h1>Hello, World!</h1>';
  145 + $html .= '<p>中文内容</p>';
  146 + $html .= '</body>';
  147 + $html .= '</html>';
  148 + return $html;
  149 + }
  150 +}
@@ -81,12 +81,12 @@ class HtmlCollect extends Command @@ -81,12 +81,12 @@ class HtmlCollect extends Command
81 $url_web_config = 'https://' . $collect_info->domain . '/wp-content/cache/user_config.text'; 81 $url_web_config = 'https://' . $collect_info->domain . '/wp-content/cache/user_config.text';
82 $data_config = http_get($url_web_config, ['charset' => 'UTF-8']); 82 $data_config = http_get($url_web_config, ['charset' => 'UTF-8']);
83 if ($data_config) { 83 if ($data_config) {
84 - $web_url_arr = parse_url($data_config['web_url_domain']); 84 + $web_url_arr = parse_url($data_config['web_url_domain'] ?? '');
85 if (isset($web_url_arr['host'])) { 85 if (isset($web_url_arr['host'])) {
86 $web_url_domain = $web_url_arr['host']; 86 $web_url_domain = $web_url_arr['host'];
87 } 87 }
88 88
89 - $home_url_arr = parse_url($data_config['home_url']); 89 + $home_url_arr = parse_url($data_config['home_url'] ?? '');
90 if (isset($home_url_arr['host'])) { 90 if (isset($home_url_arr['host'])) {
91 $home_url = $home_url_arr['host']; 91 $home_url = $home_url_arr['host'];
92 } 92 }
@@ -80,12 +80,12 @@ class HtmlLanguageCollect extends Command @@ -80,12 +80,12 @@ class HtmlLanguageCollect extends Command
80 $url_web_config = 'https://' . $collect_info->domain . '/wp-content/cache/user_config.text'; 80 $url_web_config = 'https://' . $collect_info->domain . '/wp-content/cache/user_config.text';
81 $data_config = http_get($url_web_config, ['charset' => 'UTF-8']); 81 $data_config = http_get($url_web_config, ['charset' => 'UTF-8']);
82 if ($data_config) { 82 if ($data_config) {
83 - $web_url_arr = parse_url($data_config['web_url_domain']); 83 + $web_url_arr = parse_url($data_config['web_url_domain'] ?? '');
84 if (isset($web_url_arr['host'])) { 84 if (isset($web_url_arr['host'])) {
85 $web_url_domain = $web_url_arr['host']; 85 $web_url_domain = $web_url_arr['host'];
86 } 86 }
87 87
88 - $home_url_arr = parse_url($data_config['home_url']); 88 + $home_url_arr = parse_url($data_config['home_url'] ?? '');
89 if (isset($home_url_arr['host'])) { 89 if (isset($home_url_arr['host'])) {
90 $home_url = $home_url_arr['host']; 90 $home_url = $home_url_arr['host'];
91 } 91 }
  1 +<?php
  2 +
  3 +namespace App\Console\Commands;
  4 +
  5 +use App\Models\File\DataFile;
  6 +use Illuminate\Console\Command;
  7 +
  8 +class WebsiteData extends Command
  9 +{
  10 + /**
  11 + * The name and signature of the console command.
  12 + *
  13 + * @var string
  14 + */
  15 + protected $signature = 'website_data';
  16 +
  17 + /**
  18 + * The console command description.
  19 + *
  20 + * @var string
  21 + */
  22 + protected $description = '向AICC推送数据';
  23 +
  24 + /**
  25 + * Create a new command instance.
  26 + *
  27 + * @return void
  28 + */
  29 + public function __construct()
  30 + {
  31 + parent::__construct();
  32 + }
  33 +
  34 + /**
  35 + * Execute the console command.
  36 + *
  37 + * @return int
  38 + */
  39 + public function handle()
  40 + {
  41 + $DataFile = new DataFile();
  42 + $data = $DataFile->allData();
  43 + # 详细数据
  44 + $items = $data['items'];
  45 + # 总分页
  46 + $totalPage = $data['totalPage'];
  47 + $this->post_data($items);
  48 + if ($totalPage > 1) {
  49 + for ($page = 2; $page <= $totalPage; $page++) {
  50 + $da = $DataFile->allData($page);
  51 + $this->post_data($da['items']);
  52 + }
  53 + }
  54 + $this->info('项目文件数据推送完成!');
  55 + return 0;
  56 + }
  57 +
  58 + public function post_data($data)
  59 + {
  60 + return http_post("http://aicc-local.com/api/save_file_data", json_encode(compact('data')));
  61 + }
  62 +
  63 +}
@@ -38,6 +38,8 @@ class Kernel extends ConsoleKernel @@ -38,6 +38,8 @@ class Kernel extends ConsoleKernel
38 $schedule->command('last_inquiry')->dailyAt('04:00')->withoutOverlapping(1);// 最近一次询盘信息 38 $schedule->command('last_inquiry')->dailyAt('04:00')->withoutOverlapping(1);// 最近一次询盘信息
39 $schedule->command('update_progress')->everyThirtyMinutes()->withoutOverlapping(1);//监控更新 39 $schedule->command('update_progress')->everyThirtyMinutes()->withoutOverlapping(1);//监控更新
40 $schedule->command('update_seo_tdk_crontab')->dailyAt('00:00')->withoutOverlapping(1); //更新上线项目TDK 40 $schedule->command('update_seo_tdk_crontab')->dailyAt('00:00')->withoutOverlapping(1); //更新上线项目TDK
  41 + $schedule->command('website_data')->everyMinute()->withoutOverlapping(1); // 向AICC推送数据
  42 + $schedule->command('project_file_pdf')->everyMinute()->withoutOverlapping(1); // 网站项目数据,生成PDF文件
41 } 43 }
42 44
43 /** 45 /**
  1 +<?php
  2 +
  3 +namespace App\Http\Controllers\Bside\ProjectAssociation;
  4 +
  5 +use App\Enums\Common\Code;
  6 +use App\Exceptions\BsideGlobalException;
  7 +use App\Http\Controllers\Bside\BaseController;
  8 +use App\Http\Logic\Aside\ProjectAssociation\ProjectAssociationLogic;
  9 +use Illuminate\Http\Request;
  10 +use Psr\Container\ContainerExceptionInterface;
  11 +use Psr\Container\NotFoundExceptionInterface;
  12 +
  13 +class ProjectAssociationController extends BaseController
  14 +{
  15 + private $ProjectAssociationLogic;
  16 +
  17 + public function __construct(Request $request)
  18 + {
  19 + $this->ProjectAssociationLogic = new ProjectAssociationLogic();
  20 + parent::__construct($request);
  21 + }
  22 +
  23 + /**
  24 + * V6与AICC数据关联
  25 + * @return void
  26 + * @throws BsideGlobalException
  27 + */
  28 + public function saveWeChatData()
  29 + {
  30 + $project_id = (int)request()->post('project_id', 0);
  31 + if (empty($project_id)) {
  32 + $this->fail('请选择项目!', Code::USER_PARAMS_ERROE);
  33 + }
  34 + $status = (bool)request()->post('status', 1); # 1 - 正常, 0 - 禁用
  35 + $wx_user_id = (int)request()->post('user_id', 0);
  36 + if (empty($wx_user_id) && $status) {
  37 + $this->fail('请选择要绑定的AICC用户!', Code::USER_PARAMS_ERROE);
  38 + }
  39 + $wx_id = (int)request()->post('wx_id', 0);
  40 + if (empty($wx_id) && $status) {
  41 + $this->fail('请选择要绑定的AICC项目!', Code::USER_PARAMS_ERROE);
  42 + }
  43 + $wx_nickname = request()->post('nickname', '');
  44 + $wx_user_name = request()->post('user_name', '');
  45 + $wx_image = request()->post('image', '');
  46 + $data = compact('project_id', 'wx_id', 'wx_nickname', 'wx_user_id', 'wx_user_name', 'wx_image');
  47 + $this->ProjectAssociationLogic->saveWeChatData($data);
  48 + $this->response('success');
  49 + }
  50 +}
  1 +<?php
  2 +
  3 +namespace App\Http\Logic\Aside\ProjectAssociation;
  4 +
  5 +use App\Enums\Common\Code;
  6 +use App\Http\Logic\Logic;
  7 +use App\Models\ProjectAssociation\ProjectAssociation;
  8 +use Illuminate\Support\Facades\DB;
  9 +
  10 +class ProjectAssociationLogic extends Logic
  11 +{
  12 + public function saveWeChatData($data)
  13 + {
  14 + $wx = new ProjectAssociation();
  15 + DB::beginTransaction();
  16 + try {
  17 + $status = $wx->saveData($data);
  18 + DB::commit();
  19 + } catch (\Exception $e) {
  20 + DB::rollBack();
  21 + $e->getMessage();
  22 + errorLog('V6与AICC关联失败', $wx, $e);
  23 + $this->fail('请检查操作是否正确!', Code::SERVER_MYSQL_ERROR);
  24 + }
  25 + return $status;
  26 + }
  27 +}
@@ -44,6 +44,7 @@ class NavLogic extends BaseLogic @@ -44,6 +44,7 @@ class NavLogic extends BaseLogic
44 $this->param['group_id'] = BNavGroup::DEFAULT_FOOTER_ID; 44 $this->param['group_id'] = BNavGroup::DEFAULT_FOOTER_ID;
45 } 45 }
46 } 46 }
  47 + unset($this->param['able_import']);
47 $this->param['image'] = str_replace_url(isset($this->param['image']) ? $this->param['image'] : ''); 48 $this->param['image'] = str_replace_url(isset($this->param['image']) ? $this->param['image'] : '');
48 $this->param['remark_image'] = str_replace_url(isset($this->param['remark_image']) ? $this->param['remark_image'] : ''); 49 $this->param['remark_image'] = str_replace_url(isset($this->param['remark_image']) ? $this->param['remark_image'] : '');
49 if(isset($this->param['id']) && !empty($this->param['id'])){ 50 if(isset($this->param['id']) && !empty($this->param['id'])){
  1 +<?php
  2 +
  3 +namespace App\Models\File;
  4 +
  5 +use App\Models\Base;
  6 +
  7 +class DataFile extends Base
  8 +{
  9 + protected $table = 'gl_data_file';
  10 +
  11 + public function saveData(array $data): bool
  12 + {
  13 + $project_id = (int)$data['project_id'] ?? 0;
  14 + $isRes = self::query()->where('project_id', $project_id)->where('created_at', 'like', $data['time'] . '%')->first();
  15 + if (!$isRes) {
  16 + $isRes = new self();
  17 + $isRes->project_id = $project_id;
  18 + }
  19 + $isRes->file_path = $data['file_path'];
  20 + $isRes->application_id = $data['application_id'];
  21 + return $isRes->save();
  22 + }
  23 +
  24 + /**
  25 + * @param int $page
  26 + * @param int $perPage
  27 + * @return array
  28 + */
  29 + public function allData(int $page = 1, int $perPage = 15)
  30 + {
  31 + $lists = self::query()->paginate($perPage, ['*'], 'page', $page);
  32 + $items = $lists->Items();
  33 + $totalPage = $lists->lastPage();
  34 + $total = $lists->total();
  35 + $currentPage = $lists->currentPage();
  36 + return compact('total', 'items', 'totalPage', 'currentPage');
  37 + }
  38 +
  39 +}
  1 +<?php
  2 +
  3 +namespace App\Models\ProjectAssociation;
  4 +
  5 +use Illuminate\Database\Eloquent\Builder;
  6 +use Illuminate\Database\Eloquent\Model;
  7 +
  8 +class ProjectAssociation extends Model
  9 +{
  10 + protected $table = 'gl_project_association';
  11 +
  12 + /**
  13 + * 保存|修改数据
  14 + * @param array $data
  15 + * @return bool
  16 + */
  17 + public function saveData(array $data): bool
  18 + {
  19 + $project_id = (int)$data['project_id'] ?? 0;
  20 + $isRes = self::query()->where('project_id', $project_id)->first();
  21 + if (!$isRes) {
  22 + $isRes = new self();
  23 + $isRes->project_id = $project_id;
  24 + }
  25 + $isRes->wx_id = $data['wx_id'];
  26 + $isRes->wx_nickname = $data['wx_nickname'];
  27 + $isRes->wx_user_id = $data['wx_user_id'];
  28 + $isRes->wx_user_name = $data['wx_user_name'];
  29 + $isRes->wx_image = $data['wx_image'];
  30 + return $isRes->save();
  31 + }
  32 +
  33 + /**
  34 + * 检查项目是否存在
  35 + * @param $project_id
  36 + * @return Builder|Model|object|null
  37 + */
  38 + public function check($project_id)
  39 + {
  40 + return self::query()->where('project_id', $project_id)->first();
  41 + }
  42 +
  43 + /**
  44 + * @param int $page
  45 + * @param int $perPage
  46 + * @return array
  47 + */
  48 + public function allData(int $page = 1, int $perPage = 15)
  49 + {
  50 + $status = 1; # 1 - 正常, 0 - 禁用
  51 + $lists = self::query()->where('status', $status)
  52 + ->whereNotNull('project_id')
  53 + ->whereNotNull('wx_user_id')
  54 + ->paginate($perPage, ['project_id', 'wx_id', 'wx_user_id'], 'page', $page);
  55 + $items = $lists->Items();
  56 + $totalPage = $lists->lastPage();
  57 + $total = $lists->total();
  58 + $currentPage = $lists->currentPage();
  59 + return compact('total', 'items', 'totalPage', 'currentPage');
  60 + }
  61 +}
@@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
8 "bensampo/laravel-enum": "^4.2", 8 "bensampo/laravel-enum": "^4.2",
9 "beyondcode/laravel-websockets": "^1.14", 9 "beyondcode/laravel-websockets": "^1.14",
10 "doctrine/dbal": "^3.6", 10 "doctrine/dbal": "^3.6",
  11 + "dompdf/dompdf": "^2.0",
11 "fruitcake/laravel-cors": "^2.0", 12 "fruitcake/laravel-cors": "^2.0",
12 "guzzlehttp/guzzle": "^7.0.1", 13 "guzzlehttp/guzzle": "^7.0.1",
13 "hashids/hashids": "^4.1", 14 "hashids/hashids": "^4.1",
@@ -13,6 +13,7 @@ Route::middleware(['aloginauth'])->group(function () { @@ -13,6 +13,7 @@ Route::middleware(['aloginauth'])->group(function () {
13 Route::any('/editPassword', [Aside\Com\IndexController::class, 'editPassword'])->name('admin.editPassword.white'); 13 Route::any('/editPassword', [Aside\Com\IndexController::class, 'editPassword'])->name('admin.editPassword.white');
14 Route::get('/logout', [Aside\LoginController::class, 'logout'])->name('admin.logout.white'); 14 Route::get('/logout', [Aside\LoginController::class, 'logout'])->name('admin.logout.white');
15 Route::any('/getAccessAddress', [Aside\LoginController::class, 'getAccessAddress'])->name('admin.getAccessAddress');//获取B端地址 15 Route::any('/getAccessAddress', [Aside\LoginController::class, 'getAccessAddress'])->name('admin.getAccessAddress');//获取B端地址
  16 + Route::post('/aicc/wechat', [\App\Http\Controllers\Bside\ProjectAssociation\ProjectAssociationController::class, 'saveWeChatData'])->name('admin.aicc.wechat');
16 //会员相关 17 //会员相关
17 Route::prefix('user')->group(function () { 18 Route::prefix('user')->group(function () {
18 //会员管理 19 //会员管理