| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 | 
							- <?php
 
- namespace App\Http\Controllers\Api;
 
- use App\Model\DispatchSub;
 
- use App\Model\Equipment;
 
- use App\Model\SystemL;
 
- use App\Service\Box\BoxService;
 
- use App\Service\ProductionOrderService;
 
- use Illuminate\Support\Facades\Config;
 
- use Illuminate\Support\Facades\DB;
 
- class TestController extends BaseController
 
- {
 
-     public function delTestQ(){
 
-         (new BoxService())->delBoxLock();
 
-         dd(1);
 
-     }
 
-     public function  delTestQ2(){
 
-         (new ProductionOrderService())->delBoxLock();
 
-         dd(1);
 
-     }
 
-     public function tt(){dd(1);
 
-     }
 
-     public function test(){dd(1);
 
-         $dispatch = DispatchSub::where('del_time',0)
 
-             ->where('finished_num', '>',0)
 
-             ->where('process_id',14)
 
-             ->select('finished_num','dispatch_time_start as upd_time','device_id')
 
-             ->orderBy('dispatch_time_start','asc')
 
-             ->get()->toArray();
 
-         foreach ($dispatch as $key => $value){
 
-             if(! $value['device_id']) $dispatch[$key]['device_id'] = 12;
 
-         }
 
-         // 生成数据
 
-         $generatedData = (new FeederDataGenerator)->generateData($dispatch);
 
-         dd("ok");
 
-     }
 
- }
 
- class FeederDataGenerator
 
- {
 
-     // 设备配置参数
 
-     const CAPACITY = 0.6; // 容器容量(吨)
 
-     const SUCTION_CAPACITY = 0.1; // 容器容量(吨) 下料
 
-     const SUCTION_WEIGHT = 0.1; // 每次吸料重量(吨)
 
-     const SUCTION_TIME_MIN = 300; // 吸料最短时间(秒) - 5分钟
 
-     const SUCTION_TIME_MAX = 360; // 吸料最长时间(秒) - 6分钟
 
-     const SUCTION_INTERVAL_MIN = 300; // 下次吸料最小间隔(秒) -
 
-     const SUCTION_INTERVAL_MAX = 360; // 下次吸料最大间隔(秒) -
 
-     const DISCHARGE_TIME_MIN = 240; // 下料最短时间(秒) - 4分钟
 
-     const DISCHARGE_TIME_MAX = 300; // 下料最长时间(秒) - 5分钟
 
-     const DISCHARGE_INTERVAL_MIN = 300; // 下次下料最小间隔(秒) -
 
-     const DISCHARGE_INTERVAL_MAX = 360; // 下次下料最大间隔(秒) -
 
-     private $devices = []; // 存储设备数据
 
-     /**
 
-      * 处理原始数据并生成设备运行明细
 
-      * @param array $rawData 原始数据源
 
-      * @return array 生成的设备运行明细数据
 
-      */
 
-     public function generateData(array $rawData): array
 
-     {
 
-         // 首先按设备和日期分组汇总产量
 
-         $this->processRawData($rawData);
 
- dd($this->devices);
 
-         // 为每个设备生成运行明细
 
-         $result = [];
 
-         foreach ($this->devices as $deviceId => $deviceData) {
 
-             // 为每一天生成数据
 
-             foreach ($deviceData['daily_totals'] as $date => $total) {
 
-                 $details = $this->generateDeviceDayData($deviceData['device'], $date, $total);
 
-                 $result = array_merge($result, $details);
 
-             }
 
-         }
 
-         try {
 
-             DB::beginTransaction();
 
-             if(! empty($result)){
 
-                 $chunkSize = 200; // 每次插入的数量
 
-                 foreach (array_chunk($result, $chunkSize) as $chunk) {
 
-                     SystemL::insert($chunk); // 使用模型的 insert 方法批量插入
 
-                     echo '200条写入成功' . "\n";
 
-                 }
 
-             }
 
-             DB::commit();
 
-         }catch (\Throwable $exception){
 
-             DB::rollBack();
 
-             return [false, $exception->getMessage()];
 
-         }
 
-         return [true, ''];
 
-     }
 
-     /**
 
-      * 处理原始数据,按设备和日期汇总产量
 
-      * @param array $rawData 原始数据源
 
-      */
 
-     private function processRawData(array $rawData)
 
-     {
 
-         $map = Equipment::select('id','code','title')->get()->toArray();
 
-         foreach ($map as $value){
 
-             $map1[$value['id']] = $value;
 
-         }
 
-         foreach ($rawData as $item) {
 
-             $deviceId = $item['device_id'];
 
-             $t = $map1[$deviceId];
 
-             $timestamp = $item['upd_time'];
 
-             $finishedNum = floatval($item['finished_num']);
 
-             // 解析日期
 
-             $date = date('Y-m-d', $timestamp);
 
-             // 初始化设备数据
 
-             if (!isset($this->devices[$deviceId])) {
 
-                 $this->devices[$deviceId] = [
 
-                     'device' => $t,
 
-                     'total_production' => 0,
 
-                     'daily_totals' => []
 
-                 ];
 
-             }
 
-             // 累加总产量和每日产量
 
-             $this->devices[$deviceId]['total_production'] += $finishedNum;
 
-             if (!isset($this->devices[$deviceId]['daily_totals'][$date])) {
 
-                 $this->devices[$deviceId]['daily_totals'][$date] = 0;
 
-             }
 
-             $this->devices[$deviceId]['daily_totals'][$date] += $finishedNum;
 
-         }
 
-     }
 
-     /**
 
-      * 为单个设备的一天生成详细的运行数据
 
-      * @param int $deviceId 设备ID
 
-      * @param string $date 日期(格式:YYYY-MM-DD)
 
-      * @param float $totalProduction 当天总产量
 
-      * @return array 生成的详细数据条目
 
-      */
 
-     private function generateDeviceDayData(array $device, string $date, float $totalProduction): array
 
-     {
 
-         $result = [];
 
-         // 计算当天需要完成多少轮完整的吸料-下料循环
 
-         $fullCycles = floor($totalProduction / self::SUCTION_CAPACITY);
 
-         $filledAmount = $fullCycles * self::SUCTION_CAPACITY;
 
-         $remainingWeight = bcsub($totalProduction, $filledAmount,2);
 
-         // 设置当天的起始时间戳(早上7:30)
 
-         $currentTime = strtotime($date . ' 07:30:00');
 
-         // 执行完整循环
 
-         for ($i = 0; $i < $fullCycles; $i++) {
 
-             // 执行一次完整的吸料-下料过程
 
-             $cycleData = $this->generateFullCycle($device, $currentTime);
 
-             $result = array_merge($result, $cycleData);
 
-             // 更新当前时间
 
-             $currentTime = end($cycleData)['time'];
 
- //            // 添加随机间隔时间
 
- //            $interval = rand(self::SUCTION_INTERVAL_MIN, self::SUCTION_INTERVAL_MAX);
 
- //            $currentTime += $interval;
 
-         }
 
-         // 如果有剩余量,执行部分吸料过程
 
-         if ($remainingWeight > 0) {
 
-             $lastKey = array_key_last($result); // 获取最后一个键
 
-             $result[$lastKey]['value'] += $remainingWeight;
 
- //            $remainingCyleData = $this->generatePartialCycle($device, $currentTime, $remainingWeight);
 
- //            $result = array_merge($result, $remainingCyleData);
 
-         }
 
-         return $result;
 
-     }
 
-     /**
 
-      * 随机插入急停事件,并模拟急停持续时间
 
-      *
 
-      * @param int $deviceId 设备ID
 
-      * @param int &$currentTime 当前时间戳(引用传递,用于更新)
 
-      * @param array &$result 结果数组(引用传递,用于添加急停记录)
 
-      */
 
-     private function maybeInsertEmergencyStop(array $device, int &$currentTime, array &$result, $data_point_id, $data_point_name): void
 
-     {
 
-         if (rand(1, 100) <= 3) { // 3% 的概率触发急停
 
-             $emergencyStopTime = $currentTime;
 
-             // 插入急停开始事件
 
-             $result[] = [
 
-                 'time' => $emergencyStopTime,
 
-                 'value' => -1, // 标识为急停
 
-                 'device_no' => $device['code'],
 
-                 'device_name' => $device['title'],
 
-                 'data_point_id' => $data_point_id,
 
-                 'data_point_name' => $data_point_name,
 
-                 'push_time' => $emergencyStopTime,
 
- //                 'push_time_day' =>  date("Y-m-d H:i:s",$suctionStartTime)
 
-             ];
 
-             // 模拟急停持续时间(10~15秒)
 
-             $stopDuration = rand(10, 15);
 
-             $currentTime += $stopDuration;
 
-             // 可选:插入急停结束事件(也可以不插,只用时间推移表示)
 
- //            $result[] = [
 
- //                'time' => $currentTime,
 
- //                'value' => -2, // 急停恢复
 
- //                'device_no' => $deviceId,
 
- //                'push_time' => $currentTime
 
- //            ];
 
-         }
 
-     }
 
-     /**
 
-      * 生成一个完整的吸料-下料循环数据
 
-      * @param int $deviceId 设备ID
 
-      * @param int $startTime 起始时间戳
 
-      * @return array 生成的数据条目
 
-      */
 
-     private function generateFullCycle(array $device, int $startTime): array
 
-     {
 
-         $result = [];
 
-         $currentTime = $startTime;
 
-         // 吸料阶段
 
-         for ($i = 0; $i < 1; $i++) {
 
-             // 【吸料前】尝试插入急停
 
-             $this->maybeInsertEmergencyStop($device, $currentTime, $result,5,"吸料急停");
 
-             // 吸料开始
 
-             $suctionStartTime = $currentTime;
 
-             $result[] = [
 
-                 'time' => $suctionStartTime,
 
-                 'value' => 1,
 
-                 'device_no' => $device['code'],
 
-                 'device_name' => $device['title'],
 
-                 'data_point_id' => 1,
 
-                 'data_point_name' => "吸料",
 
-                 'push_time' => $suctionStartTime,
 
- //                 'push_time_day' =>  date("Y-m-d H:i:s",$suctionStartTime)
 
-             ];
 
-             // 吸料结束
 
-             $suctionDuration = rand(self::SUCTION_TIME_MIN, self::SUCTION_TIME_MAX);
 
-             $currentTime += $suctionDuration;
 
-             // 【吸料后】尝试插入急停
 
-             $this->maybeInsertEmergencyStop($device, $currentTime, $result,5,"吸料急停");
 
-             $result[] = [
 
-                 'time' => $currentTime,
 
-                 'value' => self::SUCTION_WEIGHT,
 
-                 'device_no' => $device['code'],
 
-                 'device_name' => $device['title'],
 
-                 'data_point_id' => 2,
 
-                 'data_point_name' => "吸料结束且本次吸料重量",
 
-                 'push_time' => $currentTime,
 
- //                 'push_time_day' => date("Y-m-d H:i:s",$currentTime)
 
-             ];
 
-             // 添加随机间隔时间
 
-             if ($i < 1) {  // 最后一次吸料后不需要等待
 
- //                $interval = rand(self::SUCTION_INTERVAL_MIN, self::SUCTION_INTERVAL_MAX);
 
-                 $interval = rand(10, 15);
 
-                 $currentTime += $interval;
 
-             }
 
-         }
 
-         // 【下料前】尝试插入急停
 
-         $this->maybeInsertEmergencyStop($device, $currentTime, $result,6,"下料急停");
 
-         // 下料阶段
 
-         $dischargeStartTime = $currentTime;
 
-         $result[] = [
 
-             'time' => $dischargeStartTime,
 
-             'value' => 1,
 
-             'device_no' => $device['code'],
 
-             'device_name' => $device['title'],
 
-             'data_point_id' => 3,
 
-             'data_point_name' => "下料",
 
-             'push_time' => $dischargeStartTime,
 
- //             'push_time_day' => date("Y-m-d H:i:s",$dischargeStartTime)
 
-         ];
 
-         $dischargeDuration = rand(self::DISCHARGE_TIME_MIN, self::DISCHARGE_TIME_MAX);
 
-         $currentTime += $dischargeDuration;
 
-         // 【下料后】尝试插入急停
 
-         $this->maybeInsertEmergencyStop($device, $currentTime, $result,6,"下料急停");
 
-         $result[] = [
 
-             'time' => $currentTime,
 
-             'value' => self::SUCTION_CAPACITY,
 
-             'device_no' => $device['code'],
 
-             'device_name' => $device['title'],
 
-             'data_point_id' => 4,
 
-             'data_point_name' => "下料结束且本次下料重量",
 
-             'push_time' => $currentTime,
 
- //             'push_time_day' => date("Y-m-d H:i:s",$currentTime)
 
-         ];
 
-         return $result;
 
-     }
 
-     /**
 
-      * 生成一个不完整的循环(只有吸料部分)
 
-      * @param int $deviceId 设备ID
 
-      * @param int $startTime 起始时间戳
 
-      * @param float $requiredWeight 需要吸的重量
 
-      * @return array 生成的数据条目
 
-      */
 
-     private function generatePartialCycle(array $device, int $startTime, float $requiredWeight): array
 
-     {
 
-         $result = [];
 
-         $currentTime = $startTime;
 
-         // 计算需要多少次吸料
 
-         $suctionsNeeded = ceil($requiredWeight / self::SUCTION_WEIGHT);
 
-         $totalSuctionWeight = 0;
 
-         for ($i = 0; $i < $suctionsNeeded; $i++) {
 
-             // 吸料开始
 
-             $suctionStartTime = $currentTime;
 
-             $result[] = [
 
-                 'time' => $suctionStartTime,
 
-                 'value' => 1,
 
-                 'device_no' => $device['code'],
 
-                 'device_name' => $device['title'],
 
-                 'data_point_id' => 1,
 
-                 'data_point_name' => "吸料",
 
-                 'push_time' => $suctionStartTime,
 
-                 // 'push_time_day' =>  => date("Y-m-d H:i:s",$suctionStartTime)
 
-             ];
 
-             // 吸料结束
 
-             $suctionDuration = rand(self::SUCTION_TIME_MIN, self::SUCTION_TIME_MAX);
 
-             $currentTime += $suctionDuration;
 
-             // 判断这次吸料是否会导致超过所需总量
 
-             $addedWeight = ($i == $suctionsNeeded - 1) ? $requiredWeight - $totalSuctionWeight : self::SUCTION_WEIGHT;
 
-             $totalSuctionWeight += $addedWeight;
 
-             $result[] = [
 
-                 'time' => $currentTime,
 
-                 'value' => $addedWeight,
 
-                 'device_no' => $device['code'],
 
-                 'device_name' => $device['title'],
 
-                 'data_point_id' => 2,
 
-                 'data_point_name' => "吸料结束且本次吸料重量",
 
-                 'push_time' => $currentTime,
 
-                 // 'push_time_day' =>  => date("Y-m-d H:i:s",$currentTime)
 
-             ];
 
-             // 添加随机间隔时间(在40-50分钟之间)
 
-             if ($i < $suctionsNeeded - 1) {
 
-                 $interval = rand(self::SUCTION_INTERVAL_MIN, self::SUCTION_INTERVAL_MAX);
 
-                 $currentTime += $interval;
 
-             }
 
-         }
 
-         return $result;
 
-     }
 
- }
 
 
  |