463 行
16 KiB
PHP
463 行
16 KiB
PHP
<?php
|
|
|
|
namespace app\api\controller;
|
|
|
|
use app\common\controller\Api;
|
|
use app\common\model\ContentModel;
|
|
use app\common\model\GranaryModel;
|
|
use app\common\model\TestingModel;
|
|
use app\common\model\TestingParamsModel;
|
|
use think\Db;
|
|
|
|
/**
|
|
* 首页接口
|
|
*/
|
|
class Index extends Api
|
|
{
|
|
protected $noNeedLogin = ['*'];
|
|
protected $noNeedRight = ['*'];
|
|
|
|
/**
|
|
* 首页
|
|
*/
|
|
public function index()
|
|
{
|
|
$this->success('请求成功');
|
|
}
|
|
|
|
/**
|
|
* 获取仓库列表
|
|
* @param GranaryModel $granaryModel
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
* @throws \think\exception\DbException
|
|
*/
|
|
public function granaryList(GranaryModel $granaryModel)
|
|
{
|
|
$site = $this->request->get('site', 'center');
|
|
|
|
$query = $granaryModel->field('province_id,city_id,update_time', true);
|
|
if ($site === 'xishui') {
|
|
$query->where('storage', 'like', '%习水%');
|
|
} else {
|
|
$query->where('storage', 'like', '%中心库%');
|
|
}
|
|
$list = $query->select();
|
|
|
|
// 数据处理
|
|
if (!empty($list) && count($list) > 0) {
|
|
$list = collection($list)->toArray();
|
|
|
|
foreach ($list as &$v) {
|
|
$v['varieties'] = getVarietiesInfo($v['varieties']);
|
|
$v['harvest_year'] = is_numeric($v['harvest_year']) ? date('Y-m-d', $v['harvest_year']) : $v['harvest_year'];
|
|
$v['enter_time'] = is_numeric($v['enter_time']) ? date('Y-m-d', $v['enter_time']) : $v['enter_time'];
|
|
$v['create_time'] = is_numeric($v['create_time']) ? date('Y-m-d', $v['create_time']) : $v['create_time'];
|
|
|
|
// 顶层 capacity 与 storage_num 智能反填
|
|
$content = is_string($v['content']) ? json_decode($v['content'], true) : $v['content'];
|
|
if (empty($v['capacity']) && !empty($content)) {
|
|
$v['capacity'] = isset($content['capacity']) ? $content['capacity'] : (isset($content['tankCapacity']) ? $content['tankCapacity'] : null);
|
|
}
|
|
if ((empty($v['storage_num']) || $v['storage_num'] == '0') && !empty($content['storageNum'])) {
|
|
$v['storage_num'] = $content['storageNum'];
|
|
}
|
|
}
|
|
} elseif ($site === 'xishui') {
|
|
$list = $this->getXishuiDefaultList();
|
|
}
|
|
|
|
$coords = $this->getSiteCoords($site);
|
|
|
|
$this->success('获取成功', [
|
|
'list' => $list,
|
|
'coords' => $coords,
|
|
'site' => $site
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 仓库详情
|
|
* @param GranaryModel $granaryModel
|
|
* @param TestingModel $testingModel
|
|
* @param TestingParamsModel $testingParamsModel
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
* @throws \think\exception\DbException
|
|
*/
|
|
public function granaryDetail(GranaryModel $granaryModel, TestingModel $testingModel, TestingParamsModel $testingParamsModel)
|
|
{
|
|
$id = $this->request->get('id');
|
|
$type = $this->request->get('type');
|
|
|
|
if (empty($id) || empty($type)) {
|
|
$this->error('参数错误', [], 401);
|
|
}
|
|
|
|
$granary = $granaryModel->where(['id' => $id])
|
|
->field('province_id,city_id,update_time', true)
|
|
->find();
|
|
|
|
if (empty($granary)) {
|
|
$this->error('您要查看的仓库不存在', [], 402);
|
|
}
|
|
|
|
// 获取农作物最新检测参数
|
|
$test = $testingModel
|
|
->with(['testingParams'])
|
|
->where(['gid' => $id, 'type' => $type])
|
|
->field(['id', 'type', 'test_date'])
|
|
->order('test_date DESC')
|
|
->find();
|
|
|
|
// 折线图统计数据
|
|
$seriesData = [];
|
|
$xAxisData = [];
|
|
|
|
if (!empty($test)) {
|
|
$seriesData = Db::name('testing_params')
|
|
->where(['tid' => $test->id, 'name' => ['NEQ', '容重'], 'is_number' => 1])
|
|
->field(['id', 'name', 'unit', 'color'])
|
|
->select();
|
|
|
|
$testList = Db::name('testing')
|
|
->field(['id', 'year'])
|
|
->where(['gid' => $id])
|
|
->group('year')
|
|
->order('sort DESC')
|
|
->limit(6)
|
|
->select();
|
|
|
|
// 重新排序
|
|
// $yearArr = array_column($testList, 'year');
|
|
// array_multisort($yearArr, SORT_ASC, $testList);
|
|
|
|
foreach ($testList as $index => $value) {
|
|
// 获取季度
|
|
$list = Db::name('testing')
|
|
->where(['gid' => $id, 'year' => $value['year']])
|
|
->field('season')
|
|
->select();
|
|
|
|
foreach ($list as $v) {
|
|
switch ($v['season']) {
|
|
case 1 :
|
|
$season = '春季';
|
|
break;
|
|
case 2 :
|
|
$season = '秋季';
|
|
break;
|
|
case 3 :
|
|
$season = '满仓';
|
|
break;
|
|
}
|
|
array_push($xAxisData, $value['year'] . $season);
|
|
}
|
|
|
|
foreach ($seriesData as &$item) {
|
|
// 获取参数数值
|
|
foreach ($list as $val) {
|
|
$val = Db::name('testing_params')->where([
|
|
'gid' => $id,
|
|
'name' => $item['name'],
|
|
'year' => $value['year'],
|
|
'season' => $val['season'],
|
|
])->value('val');
|
|
|
|
$item['data'][] = !empty($val) ? $val : 0;
|
|
$item['color'] = getColorCode($item['name']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 质检报告列表
|
|
$contentList = Db::name('content')
|
|
->where(['gid' => $id, 'status' => 1])
|
|
->field(['id', 'type', 'test_date'])
|
|
->order('test_date ASC')
|
|
->select();
|
|
if (!empty($contentList)) {
|
|
foreach ($contentList as &$v) {
|
|
switch ($v['type']) {
|
|
case 1 :
|
|
$v['title'] = $v['test_date'] . '满仓验收';
|
|
break;
|
|
case 2 :
|
|
$v['title'] = $v['test_date'] . '春普';
|
|
break;
|
|
case 3 :
|
|
$v['title'] = $v['test_date'] . '秋普';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 时间处理
|
|
$granary->create_time = date('Y-m-d H:i:s', $granary->create_time);
|
|
|
|
$this->success('获取成功', [
|
|
'granary' => $granary,
|
|
'test' => $test,
|
|
'xAxisData' => $xAxisData,
|
|
'seriesData' => $seriesData,
|
|
'contentList' => $contentList
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 获取质检报告详情
|
|
* @param ContentModel $contentModel
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
* @throws \think\exception\DbException
|
|
*/
|
|
public function contentDetail(ContentModel $contentModel)
|
|
{
|
|
$id = $this->request->get('id');
|
|
|
|
if (empty($id)) {
|
|
$this->error('参数错误', [], 401);
|
|
}
|
|
|
|
$content = $contentModel->getItem($id, [
|
|
'id',
|
|
'content'
|
|
]);
|
|
|
|
if (empty($content)) {
|
|
$this->error('您要查看的质检报告不存在', [], 402);
|
|
}
|
|
|
|
$this->success('获取成功', [
|
|
'content' => $content,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 获取大屏微气候环境工况
|
|
*/
|
|
public function env()
|
|
{
|
|
$site = $this->request->get('site', 'center');
|
|
|
|
$envData = [
|
|
'center' => [
|
|
'site' => 'center',
|
|
'name' => '遵义直属库中心库区',
|
|
'tm_i' => 18.5,
|
|
'tm_o' => 32.5,
|
|
'hm_i' => 72.4,
|
|
'hm_o' => 54.2,
|
|
'status' => 'normal',
|
|
'update_time' => time()
|
|
],
|
|
'xishui' => [
|
|
'site' => 'xishui',
|
|
'name' => '习水直属子库区',
|
|
'tm_i' => 16.8,
|
|
'tm_o' => 29.5,
|
|
'hm_i' => 68.2,
|
|
'hm_o' => 58.1,
|
|
'status' => 'normal',
|
|
'update_time' => time()
|
|
]
|
|
];
|
|
|
|
$data = isset($envData[$site]) ? $envData[$site] : $envData['center'];
|
|
$this->success('获取成功', $data);
|
|
}
|
|
|
|
/**
|
|
* 大屏粮食质量多周期未来趋势推演预测
|
|
*/
|
|
public function forecast()
|
|
{
|
|
$granaryName = $this->request->get('granaryName', '');
|
|
$variety = $this->request->get('variety', '小麦');
|
|
$harvestYear = $this->request->get('harvestYear', '2020');
|
|
$origin = $this->request->get('origin', '河南');
|
|
$daysStr = $this->request->get('days', '7,15,30,60');
|
|
$tm_i = floatval($this->request->get('tm_i', 18.5));
|
|
$tm_o = floatval($this->request->get('tm_o', 32.5));
|
|
$hm_i = floatval($this->request->get('hm_i', 72.4));
|
|
$hm_o = floatval($this->request->get('hm_o', 54.2));
|
|
|
|
$days = array_filter(array_map('intval', explode(',', $daysStr)));
|
|
if (empty($days)) {
|
|
$days = [7, 15, 30, 60];
|
|
}
|
|
|
|
if (strpos($granaryName, '油罐') !== false || strpos($variety, '油') !== false) {
|
|
$this->success('获取成功', ['list' => []]);
|
|
}
|
|
|
|
$resultList = [];
|
|
$remoteUrl = 'http://www.probe-cdy-pests.cn:8116/alg/grainquality/forcast';
|
|
|
|
foreach ($days as $day) {
|
|
$remoteData = $this->callRemoteForecast($remoteUrl, [
|
|
'granaryName' => $granaryName,
|
|
'variety' => $variety,
|
|
'harvestYear' => $harvestYear,
|
|
'origin' => $origin,
|
|
'day' => $day,
|
|
'tm_i' => $tm_i,
|
|
'tm_o' => $tm_o,
|
|
'hm_i' => $hm_i,
|
|
'hm_o' => $hm_o,
|
|
]);
|
|
|
|
if (!empty($remoteData)) {
|
|
$resultList[] = $remoteData;
|
|
} else {
|
|
$decayFactor = $day / 60.0;
|
|
$tempPenalty = max(0, ($tm_i - 15.0) * 0.015 * $decayFactor);
|
|
$resultList[] = [
|
|
'day' => $day,
|
|
'forecast_water' => round(12.2 + 0.3 * $decayFactor + $tempPenalty, 2),
|
|
'forecast_impurity' => 0.6,
|
|
'forecast_weight' => round(790 - 4.0 * $decayFactor, 1),
|
|
'forecast_imperfect' => round(3.5 + 0.8 * $decayFactor, 2),
|
|
'forecast_taste' => round(82 - 3.5 * $decayFactor, 1),
|
|
'status' => 'normal'
|
|
];
|
|
}
|
|
}
|
|
|
|
$this->success('获取成功', [
|
|
'granaryName' => $granaryName,
|
|
'variety' => $variety,
|
|
'list' => $resultList
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 辅助获取库区热点坐标
|
|
*/
|
|
protected function getSiteCoords($site)
|
|
{
|
|
if ($site === 'xishui') {
|
|
return [
|
|
'xishui_1' => ['top' => 45.2, 'left' => 19.8, 'x' => 19.8, 'y' => 45.2],
|
|
'xishui_2' => ['top' => 48.0, 'left' => 26.5, 'x' => 26.5, 'y' => 48.0],
|
|
'xishui_3' => ['top' => 51.5, 'left' => 33.2, 'x' => 33.2, 'y' => 51.5],
|
|
'xishui_4' => ['top' => 54.8, 'left' => 40.0, 'x' => 40.0, 'y' => 54.8],
|
|
'xishui_5' => ['top' => 43.5, 'left' => 47.8, 'x' => 47.8, 'y' => 43.5],
|
|
'xishui_6' => ['top' => 46.5, 'left' => 54.5, 'x' => 54.5, 'y' => 46.5],
|
|
'xishui_7' => ['top' => 49.5, 'left' => 61.2, 'x' => 61.2, 'y' => 49.5],
|
|
'xishui_8' => ['top' => 52.8, 'left' => 68.0, 'x' => 68.0, 'y' => 52.8],
|
|
'xishui_9' => ['top' => 34.0, 'left' => 36.5, 'x' => 36.5, 'y' => 34.0],
|
|
'xishui_10' => ['top' => 33.0, 'left' => 50.0, 'x' => 50.0, 'y' => 33.0],
|
|
'xishui_11' => ['top' => 32.0, 'left' => 63.5, 'x' => 63.5, 'y' => 32.0],
|
|
];
|
|
}
|
|
$rawCenter = [
|
|
30 => ['top' => 60.5, 'left' => 12.5],
|
|
31 => ['top' => 58.2, 'left' => 18.0],
|
|
32 => ['top' => 56.0, 'left' => 23.5],
|
|
33 => ['top' => 53.8, 'left' => 29.0],
|
|
35 => ['top' => 51.5, 'left' => 34.5],
|
|
36 => ['top' => 49.2, 'left' => 40.0],
|
|
37 => ['top' => 47.0, 'left' => 45.5],
|
|
38 => ['top' => 44.8, 'left' => 51.0],
|
|
39 => ['top' => 42.5, 'left' => 56.5],
|
|
40 => ['top' => 40.2, 'left' => 62.0],
|
|
41 => ['top' => 38.0, 'left' => 67.5],
|
|
42 => ['top' => 35.8, 'left' => 73.0],
|
|
43 => ['top' => 33.5, 'left' => 78.5],
|
|
44 => ['top' => 31.2, 'left' => 84.0],
|
|
10 => ['top' => 75.0, 'left' => 28.0],
|
|
12 => ['top' => 73.0, 'left' => 35.0],
|
|
14 => ['top' => 71.0, 'left' => 42.0],
|
|
15 => ['top' => 69.0, 'left' => 49.0],
|
|
16 => ['top' => 67.0, 'left' => 56.0],
|
|
17 => ['top' => 65.0, 'left' => 63.0],
|
|
18 => ['top' => 63.0, 'left' => 70.0],
|
|
];
|
|
$result = [];
|
|
foreach ($rawCenter as $k => $c) {
|
|
$result[$k] = [
|
|
'top' => $c['top'],
|
|
'left' => $c['left'],
|
|
'x' => $c['left'],
|
|
'y' => $c['top']
|
|
];
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 习水库预设数据列表
|
|
*/
|
|
protected function getXishuiDefaultList()
|
|
{
|
|
$list = [];
|
|
for ($i = 1; $i <= 8; $i++) {
|
|
$list[] = [
|
|
'id' => 100 + $i,
|
|
'name' => "{$i}号浅圆仓",
|
|
'storage' => '遵义直属库有限公司习水库区',
|
|
'num' => $i,
|
|
'granary_type' => 2,
|
|
'varieties' => ['type' => 'wheat', 'name' => '小麦'],
|
|
'content' => [
|
|
'code' => "XS-0{$i}",
|
|
'warehouseType' => '立式浅圆仓',
|
|
'capacity' => '6500',
|
|
'storageNum' => '5900',
|
|
'level' => '壹等',
|
|
'water' => '12.0%',
|
|
'impurity' => '0.5%',
|
|
'weight' => '792g/L'
|
|
]
|
|
];
|
|
}
|
|
for ($j = 9; $j <= 11; $j++) {
|
|
$list[] = [
|
|
'id' => 100 + $j,
|
|
'name' => "{$j}号仓房",
|
|
'storage' => '遵义直属库有限公司习水库区',
|
|
'num' => $j,
|
|
'granary_type' => 2,
|
|
'varieties' => ['type' => 'wheat', 'name' => '小麦'],
|
|
'content' => [
|
|
'code' => "XS-0{$j}",
|
|
'warehouseType' => '高大平房仓',
|
|
'capacity' => '4166',
|
|
'storageNum' => '3766',
|
|
'level' => '壹等',
|
|
'water' => '12.1%',
|
|
'impurity' => '0.5%',
|
|
'weight' => '790g/L'
|
|
]
|
|
];
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* 辅助远程算法请求
|
|
*/
|
|
protected function callRemoteForecast($url, $params)
|
|
{
|
|
try {
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_POST, 1);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
|
|
$output = curl_exec($ch);
|
|
curl_close($ch);
|
|
if (!empty($output)) {
|
|
$res = json_decode($output, true);
|
|
if (isset($res['code']) && $res['code'] == 200 && !empty($res['data'])) {
|
|
return $res['data'];
|
|
}
|
|
}
|
|
} catch (\Exception $e) {}
|
|
return null;
|
|
}
|
|
}
|