Device.php 8.36 KB
<?php

namespace domain\device;

use Yii;
use common\helpers\Utils;
use domain\device\models\Device as DeviceModel;
use stdClass;

class Device
{


    /**
     * @param $item
     * @return DeviceModel
     */
    static function create($item)
    {
        $newDevice = new DeviceModel();
        $newDevice->serial_no   = $item['serial_no'];
        $newDevice->mac         = $item['mac'];
        $newDevice->device_id   = $item['device_id'];
        $newDevice->batch_id    = $item['batch_id'];
        $newDevice->status      = $item['status'];
        $newDevice->has_re_auth = $item['has_re_auth'];
        $newDevice->apply_at    = $item['apply_at'];
        $newDevice->auth_at     = $item['auth_at'];
        $newDevice->save();

        return $newDevice;
    }

    /**
     * @param $batchId
     * @param $batchNo
     * @param $deviceId
     * @param $applyAt
     * @param $hasReAuth
     * @return DeviceModel
     */
    static function createWithMacSerialNo($batchId, $batchNo, $deviceId, $applyAt, $hasReAuth, $status)
    {
        $exitDeviceModel = DeviceModel::find();
        $exitDeviceModel->where(['batch_id' => $batchId]);
        $exitDeviceModel->orderBy('serial_no desc');
        $exitDevice = $exitDeviceModel->one();
        $serialNo = '';
        if ($exitDevice) {
            $numNo   = mb_substr($exitDevice->serial_no, -4);
            $no1 = hexdec($numNo);
            $no = ($no1 * 1) + 1;
            $newNo = sprintf('%04X', $no);
            $serialNo = $batchNo.$newNo;
        }

        $macAddress = Utils::macGenerate();
        $item = [
            'serial_no'     => strtoupper($serialNo),
            'mac'           => $macAddress,
            'device_id'     => $deviceId,
            'batch_id'      => $batchId,
            'status'        => $status,
            'has_re_auth'   => $hasReAuth,
            'apply_at'      => $applyAt,
            'auth_at'       => null,
        ];

        return self::create($item);
    }

    /**
     * 序列号前缀,也是batchNo
     * @param $manufacture
     * @param $project
     * @param $model
     * @param $production
     * @return string
     */
    static function getBatchNo($manufacture, $project, $model, $production)
    {
        return $manufacture. $project. $model. $production;
    }

    static function explodeBarcode($barcode)
    {
        //建议格式:	0001	0001	0001	0001
        //供参考	厂商ID	项目ID	型号ID	生产日期ID
        $len = mb_strlen($barcode);
        if ($len != 16) {
            return null;
        }
        $manufactureNo  = mb_substr($barcode, 0, 4, 'utf-8');
        $projectNo      = mb_substr($barcode, 4, 4, 'utf-8');
        $modelNo        = mb_substr($barcode, 8, 4, 'utf-8');
        $productionNo   = mb_substr($barcode, 12, 4, 'utf-8');

        return [$manufactureNo, $projectNo, $modelNo, $productionNo];
    }

    /**
     * @param $deviceId
     * @param $manufactureNo
     * @param $projectNo
     * @param $modelNo
     * @param $productionNo
     * @return stdClass
     */
    static function authDevice($deviceId, $manufactureNo, $projectNo, $modelNo, $productionNo)
    {
        $e = new stdClass();
        $e->success = false;
        $e->message = '';
        $e->serial_no = '';
        $e->mac = '';
        $e->status = 0;
        $tt = time();
        $batchNo = self::getBatchNo($manufactureNo, $projectNo, $modelNo, $productionNo);
        $batchModel = CreateBatchRepository::findOne(['batch_no' => $batchNo]);
        if (empty($batchModel)) {
            $e->message = '没有该批次';
            $e->status = 3;
            $item = [
                'manufacture_no'    => $manufactureNo,
                'project_no'        => $projectNo,
                'model_no'          => $modelNo,
                'production_no'     => $productionNo,
                'device_id'         => $deviceId,
            ];
            DeviceAuthFail::create($item);
            return $e;
        }
        $batchId = $batchModel->id;

        $deviceModel = DeviceRepository::findOne(['device_id' => $deviceId, 'batch_id' => $batchId, 'is_delete' => 0]);
        if ($deviceModel) {
            if (DeviceStatus::HAS_AUTH == $deviceModel->status) {
                $e->mac = $deviceModel->mac;
                $e->serial_no = $deviceModel->serial_no;
                $e->message = '授权成功, 重复授权';
                $e->success = true;
                $e->status = 4;
                return $e;
            }

            $deviceModel->status = DeviceStatus::HAS_AUTH;
            $deviceModel->auth_at = $tt;
            if ($deviceModel->save()) {
                $e->mac = $deviceModel->mac;
                $e->serial_no = $deviceModel->serial_no;
                $e->message = '授权成功, 重复授权';
                $e->success = true;
                $e->status = 4;
            } else {
                $e->message = '设备已经存在,授权失败';
                $e->success = false;
                $e->status = 5;
            }

            return $e;
        }
        $needRecord = DeviceRepository::checkNeedRecordFailRecord($batchId, $batchModel->num);
        if ($needRecord) {
            // 超过了限制数,记录到另外一个表里面
            $failRecord = DeviceAuthFailRepository::findOne(['device_id' => $deviceId, 'is_delete' => 0]);
            if (!$failRecord) {
                $item = [
                    'manufacture_no'    => $manufactureNo,
                    'project_no'        => $projectNo,
                    'model_no'          => $modelNo,
                    'production_no'     => $productionNo,
                    'device_id'         => $deviceId,
                ];
                DeviceAuthFail::create($item);
            }
            $e->status = 6;
            $e->message = '授权失败,超过厂商设定的批次数量';
            return $e;
        }

        if (empty($deviceModel)) {
            $needGen = DeviceRepository::checkNeedAutoGen($batchId, $batchModel->num);
            if ($needGen) {
                $genDeviceModel = Device::createWithMacSerialNo($batchId, $batchNo, $deviceId, $tt, 0, DeviceStatus::HAS_AUTH);
                if ($genDeviceModel) {
                    $e->message = '授权成功';
                    $e->success = true;
                    $e->serial_no = $genDeviceModel->serial_no;
                    $e->mac = $genDeviceModel->mac;
                } else {
                    $e->status = 7;
                    $e->message = '授权失败, 下次重试授权!';

                }
                return $e;
            }

            $e = self::updateRecord($batchId, $deviceId);

            return $e;
        }

        return $e;
    }

    /**
     * @param $batchId
     * @param $deviceId
     * @return stdClass
     */
    private static function updateRecord($batchId, $deviceId)
    {
        $e = new stdClass();
        $e->success = false;
        $e->message = '';
        $e->serial_no = '';
        $e->mac = '';
        $e->status = 0;
        $tt = time();
        // 找到未空白未绑定的设备序列号, 必须随机找出对应的序列号,否则多个并发的时候一直都出错
        $newDeviceModel = DeviceRepository::findBatchRandOne($batchId);

        if (empty($newDeviceModel)) {
            $e->status  = 8;
            $e->message = '授权失败,系统异常';
            return $e;
        }
        $status = DeviceStatus::HAS_AUTH;
        // 测试代码
        /*
        if (strpos($deviceId, 'FAILDEVICE') === false) {
            $status = DeviceStatus::HAS_AUTH;
        } else {
            $status = DeviceStatus::FAIL_AUTH;
        }*/
        $newDeviceModel->device_id = $deviceId;
        $newDeviceModel->status = $status;
        $newDeviceModel->apply_at = $tt;
        $newDeviceModel->auth_at = $tt;
        if ($newDeviceModel->save()) {
            $e->message = '授权成功';
            $e->success = true;
            $e->serial_no = $newDeviceModel->serial_no;
            $e->mac = $newDeviceModel->mac;
        } else {
            $e->message = '授权失败,系统异常';
            $e->status  = 8; //系统异常
        }
        /* 测试代码*/
        /*
        if (DeviceStatus::FAIL_AUTH ==  $status) {
            $e->message = '授权失败,系统异常';
            $e->success = false;
            $e->serial_no = '';
            $e->status  = 8;
            $e->mac = '';
        }
        */
        return $e;
    }


}