diff --git a/Envoy.blade.php b/Envoy.blade.php index 6562fe6..39d6cc9 100644 --- a/Envoy.blade.php +++ b/Envoy.blade.php @@ -21,7 +21,7 @@ cd /lanzu_api git pull origin master @if($composer == true) - composer update --lock + composer update --no-dev --lock @endif supervisorctl restart lanzu_api @endtask diff --git a/app/Amqp/Consumer/DevicOrderConsumer.php b/app/Amqp/Consumer/DevicOrderConsumer.php new file mode 100644 index 0000000..d0aa997 --- /dev/null +++ b/app/Amqp/Consumer/DevicOrderConsumer.php @@ -0,0 +1,71 @@ +getBody(); + $order = Order::query() + ->select(['id', 'store_id', 'money']) + ->where(['order_main_id' => $orderMainId, 'type' => 4, 'dm_state' => 2]) + ->first(); + + if (is_null($order)||!$order) { + return Result::ACK; + } + + $deviceNames = SpeakerDevic::query() + ->select(['device_name']) + ->where(['store_id' => $order['store_id'], 'is_bind' => SpeakerDevic::IS_BIND_YES]) + ->get() + ->toArray(); + + if (empty($deviceNames)||!$deviceNames) { + return Result::ACK; + } + + $msg = "{\"msg\":\"到账".$order['money']."元\"}"; + $res = $this->deviceService->pubMsgToStoreByDevName($deviceNames, $msg); + + if ($res == true) { + return Result::ACK; + } else { + return Result::REQUEUE; + } + + } catch (\Exception $e) { + return Result::REQUEUE; + } + } + + public function isEnable(): bool + { + // if(env('APP_ENV')!='prod') return false; + return parent::isEnable(); + } +} diff --git a/app/Commons/Log.php b/app/Commons/Log.php new file mode 100644 index 0000000..29a4e84 --- /dev/null +++ b/app/Commons/Log.php @@ -0,0 +1,88 @@ +clientFactory = $clientFactory; + } + + public function getClient() + { + // $options 等同于 GuzzleHttp\Client 构造函数的 $config 参数 + $options = [ + 'timeout' => 2.0, + ]; + // $client 为协程化的 GuzzleHttp\Client 对象 + $client = $this->clientFactory->create($options); + + return $client; + } + + public function event($labels=null,$datas){ + + co(function () use ($labels,$datas){ + + $client = $this->getClient(); + $kv = []; + foreach ($datas as $key => $value) { + $kv[] = $key."=".$value; + } + $pushLabels = []; + + $event_name = 'event_'.env('APP_ENV'); + if(!empty($labels)) $pushLabels[$event_name] = $labels; + + /* + * data format: + curl -v -H "Content-Type: application/json" -XPOST -s "http://39.96.12.39:3100/loki/api/v1/push" --data-raw \ + '{"streams": [{ "stream": { "foo": "bar2" }, "values": [ [ "1596274538882028800", "fizzbuzz" ] ] }]}' + */ + $ts = $this->getMsecTime() . '000000'; + $datas = implode("&",$kv); + $values = [[$ts,$datas]]; + $app_name = env('APP_NAME').'_'.env('APP_ENV'); + + $pushLabels['app']= $app_name; + $pushDatas = [ + 'streams'=>[ + [ + 'stream'=>$pushLabels, + 'values'=>$values, + ] + ] + ]; + $client->post( + env('LOG_HOST','http://39.96.12.39:3100').'/loki/api/v1/push', + [ + 'headers'=>[ + 'Content-Type'=>'application/json' + ], + 'body' => json_encode($pushDatas) + ] + ); + //var_dump(json_encode($pushDatas) ); + }); + } + + + public function push($datas){ + $this->event(null,$datas); + } + + public function getMsecTime() + { + list($msec, $sec) = explode(' ', microtime()); + $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000); + return $msectime; + } + +} diff --git a/app/Constants/ErrorCode.php b/app/Constants/ErrorCode.php index a7fee16..f6dde1c 100644 --- a/app/Constants/ErrorCode.php +++ b/app/Constants/ErrorCode.php @@ -33,4 +33,8 @@ class ErrorCode extends AbstractConstants * @Message("Save failure!"); */ const SAVE_FAILURE = 100; -} + + /** + * @Message("Upload failure!") + */ + const UPLOAD_INVALID = 200;} diff --git a/app/Constants/LogLabel.php b/app/Constants/LogLabel.php new file mode 100644 index 0000000..b3cadb4 --- /dev/null +++ b/app/Constants/LogLabel.php @@ -0,0 +1,24 @@ +request->file('upload'); + $type = $this->request->input('type', ''); + + $fileName = $this->attachmentService->formUpload($file, $type, $filesystem, 'file'); + + return $this->success(['file_path' => $fileName]); + } + + /** + * 单图表单上传 + * @param ImageRequest $request + * @param Filesystem $filesystem + * @return \Psr\Http\Message\ResponseInterface + */ + public function uploadImage(ImageRequest $request, Filesystem $filesystem) + { + $file = $this->request->file('upload'); + $type = $this->request->input('type', ''); + + $fileName = $this->attachmentService->formUpload($file, $type, $filesystem); + + return $this->success(['file_path' => $fileName]); + } + + /** + * 单图base64上传 + * @param ImageBase64Request $request + * @param Filesystem $filesystem + * @return \Psr\Http\Message\ResponseInterface + */ + public function uploadImageByBase64(ImageBase64Request $request, Filesystem $filesystem) + { + $base64Code = $this->request->input('upload'); + $type = $this->request->input('type', ''); + + $fileName = $this->attachmentService->base64Upload($base64Code, $type, $filesystem); + + return $this->success(['file_path' => $fileName]); + } + +} \ No newline at end of file diff --git a/app/Controller/CouponRebateController.php b/app/Controller/CouponRebateController.php new file mode 100644 index 0000000..7ed921d --- /dev/null +++ b/app/Controller/CouponRebateController.php @@ -0,0 +1,28 @@ +success('创建成功'); + } +} diff --git a/app/Controller/DeviceController.php b/app/Controller/DeviceController.php new file mode 100644 index 0000000..ee315b3 --- /dev/null +++ b/app/Controller/DeviceController.php @@ -0,0 +1,114 @@ +validationFactory->make( + $this->request->all(), + [ + 'store_id' => 'required|nonempty|integer', + 'device_name' => 'required|nonempty|alpha_num', + ], + [ + 'store_id.required' => '参数不正确', + 'store_id.nonempty' => '参数不正确', + 'store_id.integer' => '参数不正确', + 'device_name.required' => '参数不正确', + 'device_name.nonempty' => '参数不正确', + 'device_name.alpha_num' => '参数不正确', + ] + ); + + if ($validator->fails()) { + // Handle exception + throw new ValidationException($validator); + return; + } + + $store_id = $this->request->input('store_id'); + $device_name = $this->request->input('device_name'); + + $sd = $this->deviceService->bindByStoreId($device_name, $store_id); + + if (is_null($sd)) { + return $this->result(100, '', '绑定失败: 设备号已经被绑定或不存在'); + } + + return $this->success($sd, '绑定成功'); + + } + + public function list() + { + $validator = $this->validationFactory->make( + $this->request->all(), + [ + 'store_id' => 'required|nonempty|integer', + ], + [ + 'store_id.required' => '参数不正确', + 'store_id.nonempty' => '参数不正确', + 'store_id.integer' => '参数不正确', + ] + ); + + if ($validator->fails()) { + // Handle exception + throw new ValidationException($validator); + return; + } + + $store_id = $this->request->input('store_id'); + + $devices = $this->deviceService->getListByStoreId($store_id); + + return $this->success($devices); + } + + public function unbind() + { + $validator = $this->validationFactory->make( + $this->request->all(), + [ + 'bind_id' => 'required|nonempty|integer', + ], + [ + 'bind_id.required' => '参数不正确', + 'bind_id.nonempty' => '参数不正确', + 'bind_id.integer' => '参数不正确', + ] + ); + + if ($validator->fails()) { + // Handle exception + throw new ValidationException($validator); + return; + } + + $bind_id = $this->request->input('bind_id'); + + $unbind_num = $this->deviceService->unbindById($bind_id); + + if ($unbind_num == 0) { + return $this->result(100, '', '解绑失败: 设备已经解绑或不存在'); + } + + return $this->success(['unbind' => $unbind_num]); + } +} \ No newline at end of file diff --git a/app/Controller/FileUpload.php b/app/Controller/FileUpload.php new file mode 100644 index 0000000..385a02f --- /dev/null +++ b/app/Controller/FileUpload.php @@ -0,0 +1,51 @@ +createBucket($bucket); + $result = $ossClient->putObject($bucket, $object, $content); + return $result; + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return false; + } + } +} \ No newline at end of file diff --git a/app/Controller/IndexController.php b/app/Controller/IndexController.php index 3864423..417e4d4 100644 --- a/app/Controller/IndexController.php +++ b/app/Controller/IndexController.php @@ -11,6 +11,13 @@ declare(strict_types=1); */ namespace App\Controller; +use Hyperf\HttpServer\Annotation\AutoController; +use League\Flysystem\Filesystem; + +/** + * @AutoController() + * @package App\Controller + */ class IndexController extends AbstractController { public function index() @@ -20,7 +27,23 @@ class IndexController extends AbstractController return [ 'method' => $method, - 'message' => "Hello22222 {$user}.", + 'message' => floatval(2.00), ]; } + + public function example(Filesystem $filesystem) + { + $file = $this->request->file('upload'); + + var_dump($file);die; + $fileContent = file_get_contents($file->getRealPath()); + var_dump($fileContent);die; + + + + + $stream = fopen($file->getRealPath(),'r+'); + $filesystem->writeStream('uplaods/'.$file->getClientFilename(),$stream); + fclose($stream); + } } diff --git a/app/Controller/ParamsTokenController.php b/app/Controller/ParamsTokenController.php new file mode 100644 index 0000000..0120c41 --- /dev/null +++ b/app/Controller/ParamsTokenController.php @@ -0,0 +1,28 @@ +paramsTokenService->generate($this->request->all()); + return $this->success($res); + } + + public function analyze() + { + $res = $this->paramsTokenService->analyze($this->request->input('token')); + return $this->success($res); + } +} \ No newline at end of file diff --git a/app/Controller/StoreController.php b/app/Controller/StoreController.php new file mode 100644 index 0000000..d39decf --- /dev/null +++ b/app/Controller/StoreController.php @@ -0,0 +1,86 @@ +request->input('id'); + if (empty($id)) { + return $this->result(1, [], 'id不能为空'); + } + if ($this->request->isMethod('post')) { + $logo = $this->request->input('logo'); + $name = $this->request->input('name'); + $tel = $this->request->input('tel'); + $address = $this->request->input('address'); + $coordinates = $this->request->input('coordinates'); + $capita = $this->request->input('capita'); + $start_at = $this->request->input('start_at'); + $announcement = $this->request->input('announcement'); + $environment = $this->request->input('environment'); + + //>>1上传logo到阿里云oss + //>>2.上传商家环境到阿里云oss + //>>3.保存数据到数据库存 + $fileNameLogo = $object = 'public/upload/' . date('Y') . '/' . date('m-d') . '/' . rand(0, 9999999999999999) . '.jpg'; + $fileUpload = new FileUpload(); + $resLogo = $fileUpload->ossUpload($logo, $fileNameLogo); + if (isset($resLogo['info']['http_code']) && $resLogo['info']['http_code'] == 200) { + $logo_url = $fileNameLogo; + } else { + return $this->result(1, []); + } + $environments = explode(',', $environment); + $envPaths = []; + foreach ($environments as $env) { + $fileNameEnv = $object = 'public/upload/' . date('Y') . '/' . date('m-d') . '/' . rand(0, 9999999999999999) . '.jpg'; + $resEnv = $fileUpload->ossUpload($env, $fileNameEnv); + if (isset($resEnv['info']['http_code']) && $resLogo['info']['http_code'] == 200) { + $envPaths[] = $fileNameEnv; + } + } + if (count($envPaths)) { + $envPath = implode(',', $envPaths); + } + + $res = Db::table('ims_cjdc_store')->where('id', $id)->update([ + 'logo' => $logo_url ?? "", + 'name' => $name, + 'tel' => $tel, + 'address' => $address, + 'coordinates' => $coordinates, + 'capita' => $capita, + 'start_at' => $start_at, + 'announcement' => $announcement, + 'environment' => $envPath ?? "", + ]); + return $this->success($res); + } +//'id','name','logo','tel','address','coordinates','capita','start_at','announcement','environment' + //获取店铺信息 + $data = Db::table('ims_cjdc_store') + ->select(['id','name','logo','tel','address','coordinates','capita','start_at','announcement','environment']) + ->where('id',$id) + ->first(); + if ($data){ + $data->site = config('site_host'); + } + return $this->success($data); + + + + } +} \ No newline at end of file diff --git a/app/Controller/TestController.php b/app/Controller/TestController.php new file mode 100644 index 0000000..f69cea8 --- /dev/null +++ b/app/Controller/TestController.php @@ -0,0 +1,60 @@ +get(TaskExecutor::class); + // $result = $exec->execute(new Task([MethodTask::class, 'handle'], [Coroutine::id()])); + + // $client = ApplicationContext::getContainer()->get(SSDBTask::class); + // $result = $client->exec("set","bar","1234"); + // $result = $client->exec("get","bar"); + + // $client = ApplicationContext::getContainer()->get(MethodTask::class); + // $result = $client->handle("set"); + + + //$log = ApplicationContext::getContainer()->get(Log::class); + $log = $this->log; + + $log->push(['test'=>1,'user_id'=>290,'msg'=>'order']); + $log->event('t1',['test'=>1,'user_id'=>290,'msg'=>'order']); + + //$this->name = 'index1 action '. $result; + return $this->name; + } + + public function index2(RequestInterface $request) + { + $this->name = 'index2 action'; + return $this->name; + } + + public function index3(RequestInterface $request) + { + return $this->name; + } +} \ No newline at end of file diff --git a/app/Exception/Handler/FilesystemExceptionHandler.php b/app/Exception/Handler/FilesystemExceptionHandler.php new file mode 100644 index 0000000..f5f1b1c --- /dev/null +++ b/app/Exception/Handler/FilesystemExceptionHandler.php @@ -0,0 +1,35 @@ +stopPropagation(); + + $content = json_encode([ + "status" => 'error', + "code" => ErrorCode::UPLOAD_INVALID, + "result" => [], + "message" => $throwable->getMessage() + ]); + + return $response->withHeader('Content-Type', 'application/json') + ->withStatus($throwable->status) + ->withBody(new SwooleStream($content)); + } + + public function isValid(Throwable $throwable): bool + { + return $throwable instanceof FilesystemException; + } +} \ No newline at end of file diff --git a/app/Libs/SimpleSSDB.php b/app/Libs/SimpleSSDB.php new file mode 100644 index 0000000..b6920b2 --- /dev/null +++ b/app/Libs/SimpleSSDB.php @@ -0,0 +1,622 @@ +easy(); + } +} + +class SSDB_Response +{ + public $cmd; + public $code; + public $data = null; + public $message; + + function __construct($code='ok', $data_or_message=null){ + $this->code = $code; + if($code == 'ok'){ + $this->data = $data_or_message; + }else{ + $this->message = $data_or_message; + } + } + + function __toString(){ + if($this->code == 'ok'){ + $s = $this->data === null? '' : json_encode($this->data); + }else{ + $s = $this->message; + } + return sprintf('%-13s %12s %s', $this->cmd, $this->code, $s); + } + + function ok(){ + return $this->code == 'ok'; + } + + function not_found(){ + return $this->code == 'not_found'; + } +} + +// Depricated, use SimpleSSDB instead! +class SSDB +{ + private $debug = false; + public $sock = null; + private $_closed = false; + private $recv_buf = ''; + private $_easy = false; + public $last_resp = null; + + function __construct($host, $port, $timeout_ms=2000){ + $timeout_f = (float)$timeout_ms/1000; + $this->sock = @stream_socket_client("[$host]:$port", $errno, $errstr, $timeout_f); + if(!$this->sock){ + throw new SSDBException("$errno: $errstr"); + } + $timeout_sec = intval($timeout_ms/1000); + $timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000; + @stream_set_timeout($this->sock, $timeout_sec, $timeout_usec); + if(function_exists('stream_set_chunk_size')){ + @stream_set_chunk_size($this->sock, 1024 * 1024); + } + } + + function set_timeout($timeout_ms){ + $timeout_sec = intval($timeout_ms/1000); + $timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000; + @stream_set_timeout($this->sock, $timeout_sec, $timeout_usec); + } + + /** + * After this method invoked with yesno=true, all requesting methods + * will not return a SSDB_Response object. + * And some certain methods like get/zget will return false + * when response is not ok(not_found, etc) + */ + function easy(){ + $this->_easy = true; + } + + function close(){ + if(!$this->_closed){ + @fclose($this->sock); + $this->_closed = true; + $this->sock = null; + } + } + + function closed(){ + return $this->_closed; + } + + private $batch_mode = false; + private $batch_cmds = array(); + + function batch(){ + $this->batch_mode = true; + $this->batch_cmds = array(); + return $this; + } + + function multi(){ + return $this->batch(); + } + + function exec(){ + $ret = array(); + foreach($this->batch_cmds as $op){ + list($cmd, $params) = $op; + $this->send_req($cmd, $params); + } + foreach($this->batch_cmds as $op){ + list($cmd, $params) = $op; + $resp = $this->recv_resp($cmd, $params); + $resp = $this->check_easy_resp($cmd, $resp); + $ret[] = $resp; + } + $this->batch_mode = false; + $this->batch_cmds = array(); + return $ret; + } + + function request(){ + $args = func_get_args(); + $cmd = array_shift($args); + return $this->__call($cmd, $args); + } + + private $async_auth_password = null; + + function auth($password){ + $this->async_auth_password = $password; + return null; + } + + function __call($cmd, $params=array()){ + $cmd = strtolower($cmd); + if($this->async_auth_password !== null){ + $pass = $this->async_auth_password; + $this->async_auth_password = null; + $auth = $this->__call('auth', array($pass)); + if($auth !== true){ + throw new Exception("Authentication failed"); + } + } + + if($this->batch_mode){ + $this->batch_cmds[] = array($cmd, $params); + return $this; + } + + try{ + if($this->send_req($cmd, $params) === false){ + $resp = new SSDB_Response('error', 'send error'); + }else{ + $resp = $this->recv_resp($cmd, $params); + } + }catch(SSDBException $e){ + if($this->_easy){ + throw $e; + }else{ + $resp = new SSDB_Response('error', $e->getMessage()); + } + } + + if($resp->code == 'noauth'){ + $msg = $resp->message; + throw new Exception($msg); + } + + $resp = $this->check_easy_resp($cmd, $resp); + return $resp; + } + + private function check_easy_resp($cmd, $resp){ + $this->last_resp = $resp; + if($this->_easy){ + if($resp->not_found()){ + return NULL; + }else if(!$resp->ok() && !is_array($resp->data)){ + return false; + }else{ + return $resp->data; + } + }else{ + $resp->cmd = $cmd; + return $resp; + } + } + + function multi_set($kvs=array()){ + $args = array(); + foreach($kvs as $k=>$v){ + $args[] = $k; + $args[] = $v; + } + return $this->__call(__FUNCTION__, $args); + } + + function multi_hset($name, $kvs=array()){ + $args = array($name); + foreach($kvs as $k=>$v){ + $args[] = $k; + $args[] = $v; + } + return $this->__call(__FUNCTION__, $args); + } + + function multi_zset($name, $kvs=array()){ + $args = array($name); + foreach($kvs as $k=>$v){ + $args[] = $k; + $args[] = $v; + } + return $this->__call(__FUNCTION__, $args); + } + + function incr($key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function decr($key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function zincr($name, $key, $score=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function zdecr($name, $key, $score=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function zadd($key, $score, $value){ + $args = array($key, $value, $score); + return $this->__call('zset', $args); + } + + function zRevRank($name, $key){ + $args = func_get_args(); + return $this->__call("zrrank", $args); + } + + function zRevRange($name, $offset, $limit){ + $args = func_get_args(); + return $this->__call("zrrange", $args); + } + + function hincr($name, $key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function hdecr($name, $key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + private function send_req($cmd, $params){ + $req = array($cmd); + foreach($params as $p){ + if(is_array($p)){ + $req = array_merge($req, $p); + }else{ + $req[] = $p; + } + } + return $this->send($req); + } + + private function recv_resp($cmd, $params){ + $resp = $this->recv(); + if($resp === false){ + return new SSDB_Response('error', 'Unknown error'); + }else if(!$resp){ + return new SSDB_Response('disconnected', 'Connection closed'); + } + if($resp[0] == 'noauth'){ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + switch($cmd){ + case 'dbsize': + case 'ping': + case 'qset': + case 'getbit': + case 'setbit': + case 'countbit': + case 'strlen': + case 'set': + case 'setx': + case 'setnx': + case 'zset': + case 'hset': + case 'qpush': + case 'qpush_front': + case 'qpush_back': + case 'qtrim_front': + case 'qtrim_back': + case 'del': + case 'zdel': + case 'hdel': + case 'hsize': + case 'zsize': + case 'qsize': + case 'hclear': + case 'zclear': + case 'qclear': + case 'multi_set': + case 'multi_del': + case 'multi_hset': + case 'multi_hdel': + case 'multi_zset': + case 'multi_zdel': + case 'incr': + case 'decr': + case 'zincr': + case 'zdecr': + case 'hincr': + case 'hdecr': + case 'zget': + case 'zrank': + case 'zrrank': + case 'zcount': + case 'zsum': + case 'zremrangebyrank': + case 'zremrangebyscore': + case 'ttl': + case 'expire': + if($resp[0] == 'ok'){ + $val = isset($resp[1])? intval($resp[1]) : 0; + return new SSDB_Response($resp[0], $val); + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + case 'zavg': + if($resp[0] == 'ok'){ + $val = isset($resp[1])? floatval($resp[1]) : (float)0; + return new SSDB_Response($resp[0], $val); + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + case 'get': + case 'substr': + case 'getset': + case 'hget': + case 'qget': + case 'qfront': + case 'qback': + if($resp[0] == 'ok'){ + if(count($resp) == 2){ + return new SSDB_Response('ok', $resp[1]); + }else{ + return new SSDB_Response('server_error', 'Invalid response'); + } + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + break; + case 'qpop': + case 'qpop_front': + case 'qpop_back': + if($resp[0] == 'ok'){ + $size = 1; + if(isset($params[1])){ + $size = intval($params[1]); + } + if($size <= 1){ + if(count($resp) == 2){ + return new SSDB_Response('ok', $resp[1]); + }else{ + return new SSDB_Response('server_error', 'Invalid response'); + } + }else{ + $data = array_slice($resp, 1); + return new SSDB_Response('ok', $data); + } + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + break; + case 'keys': + case 'zkeys': + case 'hkeys': + case 'hlist': + case 'zlist': + case 'qslice': + if($resp[0] == 'ok'){ + $data = array(); + if($resp[0] == 'ok'){ + $data = array_slice($resp, 1); + } + return new SSDB_Response($resp[0], $data); + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + case 'auth': + case 'exists': + case 'hexists': + case 'zexists': + if($resp[0] == 'ok'){ + if(count($resp) == 2){ + return new SSDB_Response('ok', (bool)$resp[1]); + }else{ + return new SSDB_Response('server_error', 'Invalid response'); + } + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + break; + case 'multi_exists': + case 'multi_hexists': + case 'multi_zexists': + if($resp[0] == 'ok'){ + if(count($resp) % 2 == 1){ + $data = array(); + for($i=1; $idebug){ + echo '> ' . str_replace(array("\r", "\n"), array('\r', '\n'), $s) . "\n"; + } + try{ + while(true){ + $ret = @fwrite($this->sock, $s); + if($ret === false || $ret === 0){ + $this->close(); + throw new SSDBException('Connection lost'); + } + $s = substr($s, $ret); + if(strlen($s) == 0){ + break; + } + @fflush($this->sock); + } + }catch(Exception $e){ + $this->close(); + throw new SSDBException($e->getMessage()); + } + return $ret; + } + + function recv(){ + $this->step = self::STEP_SIZE; + while(true){ + $ret = $this->parse(); + if($ret === null){ + try{ + $data = @fread($this->sock, 1024 * 1024); + if($this->debug){ + echo '< ' . str_replace(array("\r", "\n"), array('\r', '\n'), $data) . "\n"; + } + }catch(Exception $e){ + $data = ''; + } + if($data === false || $data === ''){ + if(feof($this->sock)){ + $this->close(); + throw new SSDBException('Connection lost'); + }else{ + throw new SSDBTimeoutException('Connection timeout'); + } + } + $this->recv_buf .= $data; +# echo "read " . strlen($data) . " total: " . strlen($this->recv_buf) . "\n"; + }else{ + return $ret; + } + } + } + + const STEP_SIZE = 0; + const STEP_DATA = 1; + public $resp = array(); + public $step; + public $block_size; + + private function parse(){ + $spos = 0; + $epos = 0; + $buf_size = strlen($this->recv_buf); + // performance issue for large reponse + //$this->recv_buf = ltrim($this->recv_buf); + while(true){ + $spos = $epos; + if($this->step === self::STEP_SIZE){ + $epos = strpos($this->recv_buf, "\n", $spos); + if($epos === false){ + break; + } + $epos += 1; + $line = substr($this->recv_buf, $spos, $epos - $spos); + $spos = $epos; + + $line = trim($line); + if(strlen($line) == 0){ // head end + $this->recv_buf = substr($this->recv_buf, $spos); + $ret = $this->resp; + $this->resp = array(); + return $ret; + } + $this->block_size = intval($line); + $this->step = self::STEP_DATA; + } + if($this->step === self::STEP_DATA){ + $epos = $spos + $this->block_size; + if($epos <= $buf_size){ + $n = strpos($this->recv_buf, "\n", $epos); + if($n !== false){ + $data = substr($this->recv_buf, $spos, $epos - $spos); + $this->resp[] = $data; + $epos = $n + 1; + $this->step = self::STEP_SIZE; + continue; + } + } + break; + } + } + + // packet not ready + if($spos > 0){ + $this->recv_buf = substr($this->recv_buf, $spos); + } + return null; + } +} \ No newline at end of file diff --git a/app/Listener/ValidatorFactoryResolvedListener.php b/app/Listener/ValidatorFactoryResolvedListener.php index 0bfb047..75b3a36 100644 --- a/app/Listener/ValidatorFactoryResolvedListener.php +++ b/app/Listener/ValidatorFactoryResolvedListener.php @@ -48,6 +48,36 @@ class ValidatorFactoryResolvedListener implements ListenerInterface return $message; }); + // 注册了 base64 验证器规则 + $validatorFactory->extend('base64', function ($attribute, $value, $parameters, $validator) { + + preg_match('/^(data:\s*image\/(\w+);base64,)/', $value, $result); + + if (empty($result)) { + return false; + } + + if ( + in_array('image', $parameters) + && !in_array($result[2], ['jpg','jpeg','png','gif','svg','bmp']) + ) { + return false; + } + + return true; + + }); + + // 注册了 ext_not_in 验证器规则 + $validatorFactory->extend('ext_not_in', function ($attribute, $value, $parameters, $validator) { + + if (empty($parameters)) { + $parameters = ['', 'php', 'exe', 'sql', 'sh', 'bat', 'py', 'go', 'c', 'cpp']; + } + return !in_array($value->getExtension(), $parameters); + + }); + // 注册了 exists_enable 验证器规则,参数是table,field,where1,where2... $validatorFactory->extend('exists_enable', function ($attribute, $value, $parameters, $validator) { @@ -79,6 +109,5 @@ class ValidatorFactoryResolvedListener implements ListenerInterface return $builder->exists(); }); - } } \ No newline at end of file diff --git a/app/Middleware/CorsMiddleware.php b/app/Middleware/CorsMiddleware.php new file mode 100644 index 0000000..7fb6495 --- /dev/null +++ b/app/Middleware/CorsMiddleware.php @@ -0,0 +1,34 @@ +withHeader('Access-Control-Allow-Origin', '*') + ->withHeader('Access-Control-Allow-Credentials', 'true') + // Headers 可以根据实际情况进行改写。 + ->withHeader('Access-Control-Allow-Headers', 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,Authorization'); + + Context::set(ResponseInterface::class, $response); + + if ($request->getMethod() == 'OPTIONS') { + return $response; + } + + return $handler->handle($request); + } +} \ No newline at end of file diff --git a/app/Model/OrderMain.php b/app/Model/OrderMain.php index adeb321..1a0a7e9 100644 --- a/app/Model/OrderMain.php +++ b/app/Model/OrderMain.php @@ -6,37 +6,37 @@ namespace App\Model; class OrderMain extends Model { - // 线上订单,外卖 + // ϶ const ORDER_TYPE_ONLINE = 1; - // 线下订单,当面付 + // ¶渶 const ORDER_TYPE_OFFLINE = 4; - // 订单状态 - // 待付款 + // ״̬ + // const ORDER_STATE_UNPAY = 1; - // 待接单 + // ӵ const ORDER_STATE_UNTAKE = 2; - // 待送达 + // ʹ const ORDER_STATE_DELIVERY = 3; - // 已完成 + // const ORDER_STATE_COMPLETE = 4; - // 已评价 + // const ORDER_STATE_EVALUATED = 5; - // 已取消 + // ȡ const ORDER_STATE_CANCEL = 6; - // 已拒单 + // Ѿܵ const ORDER_STATE_REFUSE = 7; - // 退款中 + // ˿ const ORDER_STATE_REFUNDING = 8; - // 已退款 + // ˿ const ORDER_STATE_REFUNDED = 9; - // 拒绝退款 + // ܾ˿ const ORDER_STATE_UNREFUND = 10; - // 订单支付方式 - // 微信支付 + // ֧ʽ + // ΢֧ const ORDER_PAY_WX = 1; - // 余额支付 + // ֧ const ORDER_PAY_BALANCE = 2; protected $table = 'ims_cjdc_order_main'; diff --git a/app/Model/SpeakerDevic.php b/app/Model/SpeakerDevic.php new file mode 100644 index 0000000..4c4816e --- /dev/null +++ b/app/Model/SpeakerDevic.php @@ -0,0 +1,16 @@ + 'required|nonempty|file|ext_not_in', + 'type' => 'nonempty|alpha' + ]; + } + + public function messages(): array + { + return [ + 'upload.required' => '未选择上传的文件', + 'upload.nonempty' => '文件异常', + 'upload.file' => '文件上传不成功', + 'upload.ext_not_in' => '文件不允许上传', + 'type.nonempty' => '文件类型参数异常', + ]; + } + + public function attributes(): array + { + return [ + 'upload' => '文件' + ]; + } +} diff --git a/app/Request/ImageBase64Request.php b/app/Request/ImageBase64Request.php new file mode 100644 index 0000000..88a752a --- /dev/null +++ b/app/Request/ImageBase64Request.php @@ -0,0 +1,46 @@ + 'required|nonempty|base64:image', + 'type' => 'nonempty|alpha' + ]; + } + + public function messages(): array + { + return [ + 'upload.required' => '未选择上传的文件', + 'upload.base64' => '文件不是正常的图片', + 'upload.nonempty' => '文件异常', + 'type.nonempty' => '图片类型参数异常', + ]; + } + + public function attributes(): array + { + return [ + 'upload' => '图片' + ]; + } +} diff --git a/app/Request/ImageRequest.php b/app/Request/ImageRequest.php new file mode 100644 index 0000000..85bad47 --- /dev/null +++ b/app/Request/ImageRequest.php @@ -0,0 +1,46 @@ + 'required|nonempty|file|image', + 'type' => 'nonempty|alpha' + ]; + } + + public function messages(): array + { + return [ + 'upload.required' => '未选择上传的文件', + 'upload.image' => '文件不是正常的图片', + 'upload.nonempty' => '文件异常', + 'type.nonempty' => '图片类型参数异常', + ]; + } + + public function attributes(): array + { + return [ + 'upload' => '图片' + ]; + } +} diff --git a/app/Service/AttachmentService.php b/app/Service/AttachmentService.php new file mode 100644 index 0000000..65ab9a4 --- /dev/null +++ b/app/Service/AttachmentService.php @@ -0,0 +1,73 @@ +getRealPath(); + $fileHash = md5_file($fileRealPath); + + $path = $this->getBasePath($path, $attachmenttype); + $fileName = $path . '/' . $fileHash . '.' . $file->getExtension(); + + $stream = fopen($fileRealPath, 'r+'); + $filesystem->writeStream($fileName, $stream); + fclose($stream); + + return $fileName; + } + + /** + * @inheritDoc + */ + public function base64Upload($contents, $path, $filesystem) + { + + preg_match('/^(data:\s*image\/(\w+);base64,)/', $contents, $result); + if (empty($result)) { + throw new FilesystemNotFoundException(ErrorCode::getMessage(ErrorCode::UPLOAD_INVALID),ErrorCode::UPLOAD_INVALID); + } + + $contents = base64_decode(str_replace($result[1], '', $contents)); + + $fileHash = md5($contents); + $path = $this->getBasePath($path); + $fileName = $path . '/' . $fileHash . '.' . $result[2]; + + $filesystem->write($fileName, $contents); + + return $fileName; + } + + protected function getBasePath($path, $attachmenttype = 'image') + { + switch ($attachmenttype) { + case 'image': + $baseDir = env('IMAGE_BASE', '/attachment/images'); + break; + + case 'file': + $baseDir = env('FILES_BASE', '/attachment/files'); + break; + + default: + $baseDir = env('FILES_BASE', '/attachment'); + break; + } + + $path = $path ? '/'.$path : ''; + $path .= '/'.date('Y').'/'.date('m').'/'.date('d'); + return $baseDir.$path; + } +} \ No newline at end of file diff --git a/app/Service/AttachmentServiceInterface.php b/app/Service/AttachmentServiceInterface.php new file mode 100644 index 0000000..28439b2 --- /dev/null +++ b/app/Service/AttachmentServiceInterface.php @@ -0,0 +1,23 @@ +where(['store_id' => $store_id, 'is_bind' => SpeakerDevic::IS_BIND_YES])->get()->toArray(); + } + + /** + * 绑定 + * @param $dev_name + * @param $store_id + * @return SpeakerDevic|null + * @throws \Throwable + */ + public function bindByStoreId($dev_name, $store_id) + { + $sd = null; + + if ($this->checkDeviceEnable($dev_name)) { + return $sd; + } + + try { + + // 获取市场ID + $market_id = Store::query()->where(['id' => $store_id])->value('market_id'); + + // $sd = new SpeakerDevic; + // $sd->store_id = $store_id; + // $sd->device_name = $dev_name; + // $sd->market_id = $market_id; + // $sd->bind_time = time(); + // $sd->saveOrFail(); + + $sd = SpeakerDevic::query()->updateOrCreate( + ['store_id' => $store_id, 'device_name' => $dev_name], + ['market_id' => $market_id, 'bind_time' => time(), 'is_bind' => SpeakerDevic::IS_BIND_YES] + ); + + } catch (Exception $e) { + $this->log->event(LogLabel::DEVICE_LOG, ['msg' => '绑定设备异常:'.$e->getMessage()]); + } + return $sd; + } + + /** + * 解绑 + * @param $bind_id + * @return int + */ + public function unbindById($bind_id) + { + return SpeakerDevic::query()->where(['id' => $bind_id])->update(['is_bind' => SpeakerDevic::IS_BIND_NO]); + } + + /** + * 发布语音消息 + * @param $store_id + * @param $msg + */ + public function pubMsgToStoreByDevName($dev_names, $msg) + { + foreach ($dev_names as $key => $dev_name) { + $this->IOTService->pub($dev_name['device_name'], $msg); + } + + return true; + } + + /** + * 当前设备是否已经被绑定 + * @param $dev_name + * @return bool + */ + protected function checkDeviceEnable($dev_name) + { + return SpeakerDevic::query()->where(['device_name' => $dev_name, 'is_bind' => SpeakerDevic::IS_BIND_YES])->exists(); + } + +} \ No newline at end of file diff --git a/app/Service/DeviceServiceInterFace.php b/app/Service/DeviceServiceInterFace.php new file mode 100644 index 0000000..15aa23b --- /dev/null +++ b/app/Service/DeviceServiceInterFace.php @@ -0,0 +1,11 @@ +regionId(env('ALI_IOT_REGION')) + ->asDefaultClient(); + + try { + AlibabaCloud::rpc() + ->product('Iot') + ->version('2018-01-20') + ->action('Pub') + ->method('POST') + ->host(env('ALI_IOT_HOST')) + ->options([ + 'query' => [ + 'RegionId' => "cn-shanghai", + 'TopicFullName' => "/".env('ALI_IOT_PRODUCT_KEY')."/".$device_name."/user/get", + 'MessageContent' => base64_encode($msg), + 'ProductKey' => env('ALI_IOT_PRODUCT_KEY'), + ], + ]) + ->request(); + } catch (ClientException $e) { + $this->log->event(LogLabel::DEVICE_LOG, ['msg' => 'ClientException发布失败:'.$e->getErrorMessage()]); + return false; + } catch (ServerException $e) { + $this->log->event(LogLabel::DEVICE_LOG, ['msg' => 'ServerException发布失败:'.$e->getErrorMessage()]); + return false; + } + + return true; + } + +} \ No newline at end of file diff --git a/app/Service/IOTServiceInterface.php b/app/Service/IOTServiceInterface.php new file mode 100644 index 0000000..931aca6 --- /dev/null +++ b/app/Service/IOTServiceInterface.php @@ -0,0 +1,8 @@ + 'zh_cjdianc/pages/couponrebate/index', 'previous_id' => 211, 'is_expired' => 2]; + } +} \ No newline at end of file diff --git a/app/TaskWorker/AliIotTask.php b/app/TaskWorker/AliIotTask.php new file mode 100644 index 0000000..4b3b7b1 --- /dev/null +++ b/app/TaskWorker/AliIotTask.php @@ -0,0 +1,62 @@ +regionId('cn-shanghai') + ->asDefaultClient(); + + try { + AlibabaCloud::rpc() + ->product('Iot') + ->version('2018-01-20') + ->action('Pub') + ->method('POST') + ->host('iot.cn-shanghai.aliyuncs.com') + ->options([ + 'query' => [ + 'RegionId' => "cn-shanghai", + 'TopicFullName' => "/a1ZSurIJmO0/".$device_name."/user/get", + 'MessageContent' => base64_encode($msg), + 'ProductKey' => "a1ZSurIJmO0", + ], + ]) + ->request(); + } catch (ClientException $e) { + echo $e->getErrorMessage() . PHP_EOL; + } catch (ServerException $e) { + echo $e->getErrorMessage() . PHP_EOL; + } + + return true; + } + +} + diff --git a/app/TaskWorker/SSDBTask.php b/app/TaskWorker/SSDBTask.php new file mode 100644 index 0000000..9c6ef29 --- /dev/null +++ b/app/TaskWorker/SSDBTask.php @@ -0,0 +1,39 @@ +client()->__call($method,$args); + + return $result; + } + + protected function client(){ + if ($this->ss instanceof SimpleSSDB) { + return $this->ss; + } + + $this->ss = new SimpleSSDB(env('SSDB_HOST'), env('SSDB_PORT')); + $this->ss->auth(env('SSDB_AUTH')); + + return $this->ss; + + } +} + diff --git a/composer.json b/composer.json index d8f86c6..dfc0c2b 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "hyperf/config": "~2.0.0", "hyperf/db-connection": "~2.0.0", "hyperf/framework": "~2.0.0", - "hyperf/guzzle": "~2.0.0", + "hyperf/guzzle": "^2.0", "hyperf/http-server": "~2.0.0", "hyperf/logger": "~2.0.0", "hyperf/memory": "~2.0.0", @@ -29,9 +29,13 @@ "hyperf/model-cache": "~2.0.0", "hyperf/validation": "^2.0", "hyperf/paginator": "^2.0", + "hyperf/filesystem": "^2.0", + "xxtime/flysystem-aliyun-oss": "^1.5", + "hyperf/task": "^2.0", + "alibabacloud/iot": "^1.8", + "hyperf/amqp": "^2.0", "hyperf/snowflake": "^2.0", - "ext-bcmath": "*", - "hyperf/task": "^2.0" + "ext-bcmath": "*" }, "require-dev": { "swoole/ide-helper": "^4.5", diff --git a/config/autoload/amqp.php b/config/autoload/amqp.php new file mode 100644 index 0000000..e14780a --- /dev/null +++ b/config/autoload/amqp.php @@ -0,0 +1,33 @@ + [ + 'host' => env('RQM_HOST', 'localhost'), + 'port' => 5672, + 'user' => env('RQM_USER','guest'), + 'password' => env('RQM_PASSWORD','guest'), + 'vhost' => '/', + 'concurrent' => [ + 'limit' => 1, + ], + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + ], + 'params' => [ + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'connection_timeout' => 3.0, + 'read_write_timeout' => 6.0, + 'context' => null, + 'keepalive' => false, + 'heartbeat' => 3, + 'close_on_destruct' => false, + ], + ] +]; diff --git a/config/autoload/dependencies.php b/config/autoload/dependencies.php index a4028ee..411bb9f 100644 --- a/config/autoload/dependencies.php +++ b/config/autoload/dependencies.php @@ -11,6 +11,11 @@ declare(strict_types=1); */ return [ \App\Service\ServiceEvaluateServiceInterface::class => \App\Service\ServiceEvaluateService::class, + \App\Service\AttachmentServiceInterface::class => \App\Service\AttachmentService::class, + \App\Service\ParamsTokenServiceInterface::class => \App\Service\ParamsTokenSsdbService::class, + \App\Service\DeviceServiceInterFace::class =>\App\Service\DeviceServiceImp::class, + \App\Commons\Log::class => \App\Commons\Log::class, + \App\Service\IOTServiceInterface::class => \App\Service\IOTAliService::class, \App\Service\OrderServiceInterface::class => \App\Service\OrderService::class, \App\Service\CoupnoServiceInterface::class => \App\Service\CouponService::class, ]; diff --git a/config/autoload/exceptions.php b/config/autoload/exceptions.php index cca06d6..1776a7c 100644 --- a/config/autoload/exceptions.php +++ b/config/autoload/exceptions.php @@ -15,6 +15,7 @@ return [ Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class, App\Exception\Handler\AppExceptionHandler::class, \App\Exception\Handler\ValidationExceptionHandler::class, + \App\Exception\Handler\FilesystemExceptionHandler::class, ], ], ]; diff --git a/config/autoload/file.php b/config/autoload/file.php new file mode 100644 index 0000000..6744d66 --- /dev/null +++ b/config/autoload/file.php @@ -0,0 +1,94 @@ + 'oss', + 'storage' => [ + 'local' => [ + 'driver' => \Hyperf\Filesystem\Adapter\LocalAdapterFactory::class, + 'root' => BASE_PATH . '/attachment', + ], + 'ftp' => [ + 'driver' => \Hyperf\Filesystem\Adapter\FtpAdapterFactory::class, + 'host' => 'ftp.example.com', + 'username' => 'username', + 'password' => 'password', + // 'port' => 21, + // 'root' => '/path/to/root', + // 'passive' => true, + // 'ssl' => true, + // 'timeout' => 30, + // 'ignorePassiveAddress' => false, + ], + 'memory' => [ + 'driver' => \Hyperf\Filesystem\Adapter\MemoryAdapterFactory::class, + ], + 's3' => [ + 'driver' => \Hyperf\Filesystem\Adapter\S3AdapterFactory::class, + 'credentials' => [ + 'key' => env('S3_KEY'), + 'secret' => env('S3_SECRET'), + ], + 'region' => env('S3_REGION'), + 'version' => 'latest', + 'bucket_endpoint' => false, + 'use_path_style_endpoint' => false, + 'endpoint' => env('S3_ENDPOINT'), + 'bucket_name' => env('S3_BUCKET'), + ], + 'minio' => [ + 'driver' => \Hyperf\Filesystem\Adapter\S3AdapterFactory::class, + 'credentials' => [ + 'key' => env('S3_KEY'), + 'secret' => env('S3_SECRET'), + ], + 'region' => env('S3_REGION'), + 'version' => 'latest', + 'bucket_endpoint' => false, + 'use_path_style_endpoint' => true, + 'endpoint' => env('S3_ENDPOINT'), + 'bucket_name' => env('S3_BUCKET'), + ], + 'oss' => [ + 'driver' => \Hyperf\Filesystem\Adapter\AliyunOssAdapterFactory::class, + 'accessId' => env('OSS_ACCESS_ID'), + 'accessSecret' => env('OSS_ACCESS_SECRET'), + 'bucket' => env('OSS_BUCKET'), + 'endpoint' => env('OSS_ENDPOINT'), + // 'timeout' => 3600, + // 'connectTimeout' => 10, + // 'isCName' => false, + // 'token' => '', + ], + 'qiniu' => [ + 'driver' => \Hyperf\Filesystem\Adapter\QiniuAdapterFactory::class, + 'accessKey' => env('QINIU_ACCESS_KEY'), + 'secretKey' => env('QINIU_SECRET_KEY'), + 'bucket' => env('QINIU_BUCKET'), + 'domain' => env('QINBIU_DOMAIN'), + ], + 'cos' => [ + 'driver' => \Hyperf\Filesystem\Adapter\CosAdapterFactory::class, + 'region' => env('COS_REGION'), + 'credentials' => [ + 'appId' => env('COS_APPID'), + 'secretId' => env('COS_SECRET_ID'), + 'secretKey' => env('COS_SECRET_KEY'), + ], + 'bucket' => env('COS_BUCKET'), + 'read_from_cdn' => false, + // 'timeout' => 60, + // 'connect_timeout' => 60, + // 'cdn' => '', + // 'scheme' => 'https', + ], + ], +]; diff --git a/config/autoload/middlewares.php b/config/autoload/middlewares.php index 5269173..5eb19a5 100644 --- a/config/autoload/middlewares.php +++ b/config/autoload/middlewares.php @@ -13,5 +13,6 @@ return [ 'http' => [ \App\Middleware\Auth\ApiMiddleware::class, \Hyperf\Validation\Middleware\ValidationMiddleware::class, + \App\Middleware\CorsMiddleware::class, ], ]; diff --git a/config/config.php b/config/config.php index 7d0c07e..c5ce284 100644 --- a/config/config.php +++ b/config/config.php @@ -28,4 +28,7 @@ return [ LogLevel::WARNING, ], ], + + 'site_host'=>'http://store.api.lanzulive.com/' + ]; diff --git a/config/routes.php b/config/routes.php index c14f389..3979aa7 100644 --- a/config/routes.php +++ b/config/routes.php @@ -23,5 +23,20 @@ Router::addGroup('/v1/',function (){ Router::post('ServiceEvaluate/isPersonnel', 'App\Controller\ServiceEvaluateController@isPersonnel'); Router::post('ServiceEvaluate/getPersonnelInfo', 'App\Controller\ServiceEvaluateController@getPersonnelInfo'); Router::post('ServiceEvaluate/getEvaluateList', 'App\Controller\ServiceEvaluateController@getEvaluateList'); + Router::post('Attachment/uploadImage', 'App\Controller\AttachmentController@uploadImage'); + Router::post('Attachment/uploadImageByBase64', 'App\Controller\AttachmentController@uploadImageByBase64'); + Router::post('Attachment/upload', 'App\Controller\AttachmentController@upload'); + Router::post('ParamsToken/generate', 'App\Controller\ParamsTokenController@generate'); + Router::post('ParamsToken/analyze', 'App\Controller\ParamsTokenController@analyze'); + + //播报器相关 + Router::post('Device/bind', 'App\Controller\DeviceController@bind'); + Router::post('Device/list', 'App\Controller\DeviceController@list'); + Router::post('Device/unbind', 'App\Controller\DeviceController@unbind'); + + //测试路由 + Router::get('test/index1', 'App\Controller\TestController@index1'); + + //订单相关 Router::post('Order/addOnline', 'App\Controller\OrderController@addOnlineOrder'); }); \ No newline at end of file