diff --git a/application/admin/controller/Content.php b/application/admin/controller/Content.php index 68fba54..b9c4c9d 100644 --- a/application/admin/controller/Content.php +++ b/application/admin/controller/Content.php @@ -2,7 +2,8 @@ namespace app\admin\controller; -use app\common\controller\Backend; +use app\common\controller\GranaryBackend; +use app\common\library\GranarySite; use app\common\model\ContentModel; use think\Db; @@ -11,7 +12,7 @@ use think\Db; * Class Content * @package app\admin\controller\Content */ -class Content extends Backend +class Content extends GranaryBackend { /** @@ -49,20 +50,19 @@ class Content extends Backend $endTime = input('param.end_time', ''); $rid = input('param.rid/d'); $date = input('param.date'); - $result = $this->model->getLists([ + $this->scopeRecords($this->model); + $result = $this->model->getLists([ 'keyword' => $key, 'type' => $type, 'status' => $status, 'start_time' => $startTime, 'end_time' => $endTime, - 'rid' => $rid, + 'gid' => $rid, 'date' => $date, ], $rows, $page); // 仓库 - $result['granaryList'] = Db::name('granary') - ->field(['id', 'name']) - ->select(); + $result['granaryList'] = GranarySite::granaries($this->filterSites); return json($result); } @@ -152,9 +152,7 @@ class Content extends Backend $data['content'] = json_decode($data['content'], true); } - $granaryList = Db::name('granary') - ->field(['id', 'name']) - ->select();; + $granaryList = GranarySite::granaries($this->granarySites); return json([ 'code' => 200, diff --git a/application/admin/controller/Forecast.php b/application/admin/controller/Forecast.php new file mode 100644 index 0000000..ff4f19b --- /dev/null +++ b/application/admin/controller/Forecast.php @@ -0,0 +1,109 @@ +request->isAjax()) return $this->fetch(); + $gid = $this->request->get('gid/d', 0); + $page = max(1, $this->request->get('page/d', 1)); + $query = $this->scopeRecords(Db::name('grain_forecast')); + if ($gid) $query->where('gid', $gid); + $total = $query->count(); + $query = $this->scopeRecords(Db::name('grain_forecast')); + if ($gid) $query->where('gid', $gid); + $list = $query->field('request_key', true)->order('id DESC')->page($page, 15)->select(); + $points = $list ? Db::name('grain_forecast_point')->where('forecast_id', 'in', array_column($list, 'id'))->select() : []; + foreach ($list as &$row) { + $row['measured'] = 0; + $row['point_count'] = 0; + foreach ($points as $point) { + if ($point['forecast_id'] != $row['id']) continue; + $row['point_count']++; + $actual = json_decode($point['actual'], true) ?: []; + $filled = count(array_filter($actual, function ($v) { return $v !== null && $v !== ''; })); + if ($filled === count(GrainForecast::metrics($row['grain_type']))) $row['measured']++; + } + } + unset($row); + $granaries = array_values(array_filter(GranarySite::granaries(->filterSites), function () { return in_array(['varieties'], ['小麦', '稻谷'], true); })); + if (!empty()) { + = array_column(, 'id'); + = Db::name('grain_forecast')->where('gid', 'in', ) + ->field('gid,tm_i,hm_i,tm_o,hm_o,observed_date')->order('id DESC')->select(); + = []; + foreach ( as ) { + if (!isset([['gid']])) { + [['gid']] = [ + 'tm_i' => (float)['tm_i'], + 'hm_i' => (float)['hm_i'], + 'tm_o' => (float)['tm_o'], + 'hm_o' => (float)['hm_o'], + 'observed_date' => ['observed_date'] + ]; + } + } + foreach ( as &) { + ['last_env'] = isset([['id']]) ? [['id']] : null; + } + unset(); + } + return json(['code' => 200, 'list' => , 'total' => , 'granaries' => ]); + } + + public function detail() + { + try { + return json(['code' => 200, 'data' => (new GrainForecast())->detail($this->request->get('id/d', 0))]); + } catch (\InvalidArgumentException $e) { + return json(['code' => 400, 'msg' => $e->getMessage()]); + } + } + + public function add() + { + return $this->write(function ($service) { + $id = $service->create($this->request->post(), $this->auth->id); + $service->generate($id); + return $id; + }); + } + + public function retry() + { + return $this->write(function ($service) { + $id = $this->request->post('id/d', 0); + $service->generate($id); + return $id; + }); + } + + public function actual() + { + return $this->write(function ($service) { + return $service->saveActual($this->request->post(), $this->auth->id); + }); + } + + protected function write($action) + { + if (!$this->request->isPost()) return json(['code' => 405, 'msg' => '请使用POST提交']); + try { + $service = new GrainForecast(); + $id = $action($service); + return json(['code' => 200, 'msg' => '保存成功', 'data' => $service->detail($id)]); + } catch (\InvalidArgumentException $e) { + return json(['code' => 400, 'msg' => $e->getMessage()]); + } catch (\Exception $e) { + \think\Log::record('Grain forecast: ' . $e->getMessage(), 'error'); + return json(['code' => 500, 'msg' => '保存失败,请刷新查看记录后重试']); + } + } +} diff --git a/application/admin/controller/Granary.php b/application/admin/controller/Granary.php index 0d034b2..53b8130 100644 --- a/application/admin/controller/Granary.php +++ b/application/admin/controller/Granary.php @@ -2,7 +2,8 @@ namespace app\admin\controller; -use app\common\controller\Backend; +use app\common\controller\GranaryBackend; +use app\common\library\GranarySite; use app\common\model\ChinaModel; use app\common\model\GranaryModel; use app\common\model\TestingModel; @@ -12,7 +13,7 @@ use app\common\model\TestingModel; * Class Granary * @package app\admin\controller */ -class Granary extends Backend +class Granary extends GranaryBackend { /** @@ -50,6 +51,7 @@ class Granary extends Backend $granaryType = input('param.granary_type', ''); $china = input('param.china/a', ''); $varieties = input('param.varieties', ''); + $this->model->where('site', 'in', $this->filterSites ?: ['__none__']); $result = $this->model->getLists([ 'keyword' => $key, 'type' => $type, @@ -99,6 +101,17 @@ class Granary extends Backend { $data = $this->request->post(); if (!empty($data)) { + $site = isset($data['site']) ? $data['site'] : ''; + if (!GranarySite::valid($site) || !in_array($site, $this->granarySites, true)) { + return json(['code' => 400, 'msg' => '请选择有权限的所属库区']); + } + $data['storage'] = GranarySite::STORAGE[$site]; + if (!isset($data['num']) || !preg_match('/^[1-9]\d{0,8}$/D', (string)$data['num'])) { + return json(['code' => 400, 'msg' => '仓号必须是正整数']); + } + $duplicate = $this->model->where('site', $site)->where('num', $data['num']) + ->where('id', '<>', isset($data['id']) ? (int)$data['id'] : 0)->count(); + if ($duplicate) return json(['code' => 400, 'msg' => '该库区的仓号已存在']); $content = isset($data['content']) && is_array($data['content']) ? $data['content'] : []; $position = isset($content['screenPosition']) ? $content['screenPosition'] : ''; $positions = \app\common\library\GranaryScreen::extraPositions(); @@ -106,7 +119,7 @@ class Granary extends Backend return json(['code' => 400, 'msg' => '请选择有效的大屏建筑位置']); } if ($position !== '') { - if (strpos($data['storage'], '习水') !== false) { + if ($site === 'xishui') { return json(['code' => 400, 'msg' => '此建筑位置属于中心库区']); } foreach ($this->model->field('id,content')->select() as $existing) { @@ -119,11 +132,10 @@ class Granary extends Backend } } $data['content'] = $content; - $id = $this->model->where(['num' => $data['num']])->value('id'); if (isset($data['granary_type']) && in_array(intval($data['granary_type']), [1, 2, 3])) { $data['granary_type'] = intval($data['granary_type']); } else { - $data['granary_type'] = $data['num'] > 18 ? 2 : 1; + return json(['code' => 400, 'msg' => '请选择有效仓型']); } if ($position !== '') { $data['granary_type'] = strpos($position, 'center_silo_') === 0 ? 3 : 2; @@ -135,12 +147,6 @@ class Granary extends Backend // 添加 if (empty($data['id'])) { - if (!empty($id)) { - return json([ - 'code' => 401, - 'msg' => '您输入的仓号已存在' - ]); - } unset($data['id'], $data['old_num'], $data['china']); $data['create_time'] = time(); @@ -158,14 +164,6 @@ class Granary extends Backend } } - if ($data['num'] != $data['old_num']) { - if (!empty($id)) { - return json([ - 'code' => 401, - 'msg' => '您输入的仓号已存在' - ]); - } - } // 编辑 $data['update_time'] = time(); diff --git a/application/admin/controller/Testing.php b/application/admin/controller/Testing.php index 6c23e2b..6ae09b3 100644 --- a/application/admin/controller/Testing.php +++ b/application/admin/controller/Testing.php @@ -2,7 +2,8 @@ namespace app\admin\controller; -use app\common\controller\Backend; +use app\common\controller\GranaryBackend; +use app\common\library\GranarySite; use app\common\model\TestingModel; use think\Db; @@ -11,7 +12,7 @@ use think\Db; * Class Testing * @package app\admin\controller */ -class Testing extends Backend +class Testing extends GranaryBackend { /** @@ -48,7 +49,8 @@ class Testing extends Backend $startTime = input('param.start_time', ''); $endTime = input('param.end_time', ''); $season = input('param.season', ''); - $result = $this->model->getLists([ + $this->scopeRecords($this->model); + $result = $this->model->getLists([ 'gid' => $gid, 'type' => $type, 'date' => $date, @@ -60,9 +62,7 @@ class Testing extends Backend ], $rows, $page); // 仓库 - $result['granaryList'] = Db::name('granary') - ->field(['id', 'name', 'varieties']) - ->select(); + $result['granaryList'] = GranarySite::granaries($this->granarySites); if (!empty($result['granaryList'])) { foreach ($result['granaryList'] as &$v) { $w = getVarietiesInfo($v['varieties']); @@ -103,55 +103,151 @@ class Testing extends Backend } /** - * 添加编辑 + * 获取仓房列表下拉数据 + * @return array + */ + protected function getGranaryOptions() + { + $granaryList = GranarySite::granaries($this->granarySites); + if (!empty($granaryList)) { + foreach ($granaryList as &$v) { + $w = getVarietiesInfo($v['varieties']); + $v['type'] = $w['type']; + } + } + return $granaryList; + } + + /** + * 添加(GET返回独立页面,POST执行添加) * @return string|\think\response\Json */ public function add() { - $data = $this->request->post(); + if ($this->request->isPost()) { + $data = $this->request->post(); - if (!empty($data)) { - $content = $data['content']; - $date = $data['record_date']; - $ruleError = \app\common\library\QualityRule::validate($content); - if ($ruleError !== '') { - return json(['code' => 400, 'msg' => $ruleError]); - } + if (!empty($data)) { + $content = $data['content']; + $date = $data['record_date']; + $types = $this->model->getTypeList(); + $originalRules = isset($types[$data['type']]) ? $types[$data['type']]['content'] : []; + if (!empty($data['id'])) { + $existing = $this->model->getItem((int)$data['id'], '*', ['testingParams']); + if (!$existing) { + return json(['code' => 400, 'msg' => '检测记录不存在']); + } + $existing = $existing->toArray(); + $originalRules = $existing['testing_params']; + $allowedIds = array_column($originalRules, 'id'); + foreach (is_array($content) ? $content : [] as $item) { + if (!is_array($item) || empty($item['id']) || !in_array($item['id'], $allowedIds)) { + return json(['code' => 400, 'msg' => '检测参数不属于当前记录,请刷新后重试']); + } + } + } + $ruleError = \app\common\library\QualityRule::validate($content, $originalRules); + if ($ruleError !== '') { + return json(['code' => 400, 'msg' => $ruleError]); + } - // 添加 - if (empty($data['id'])) { - unset($data['id'], $data['content'], $data['record_date']); - $data['create_time'] = time(); + // 添加 + if (empty($data['id'])) { + unset($data['id'], $data['content'], $data['record_date']); + $data['create_time'] = time(); - if ($this->model->add($data, $content, $date)) { + if ($this->model->add($data, $content, $date)) { + return json([ + 'code' => 200, + 'msg' => '添加成功' + ]); + } else { + return json([ + 'code' => 400, + 'msg' => '添加失败' + ]); + } + } + + // 编辑 + $data['update_time'] = time(); + unset($data['content'], $data['record_date']); + + if ($this->model->edit($data, $content, $date)) { return json([ 'code' => 200, - 'msg' => '添加成功' + 'msg' => '编辑成功' ]); } else { return json([ 'code' => 400, - 'msg' => '添加失败' + 'msg' => '编辑失败' ]); } } - - // 编辑 - $data['update_time'] = time(); - unset($data['content'], $data['record_date']); - - if ($this->model->edit($data, $content, $date)) { - return json([ - 'code' => 200, - 'msg' => '编辑成功' - ]); - } else { - return json([ - 'code' => 400, - 'msg' => '编辑失败' - ]); - } } + + $granaryList = $this->getGranaryOptions(); + $typeList = $this->model->getTypeList(); + + $this->assign('item', null); + $this->assign('granaryList', $granaryList); + $this->assign('typeList', $typeList); + $this->assign('siteOptions', $this->granarySites); + + return $this->fetch('edit'); + } + + /** + * 独立编辑页面 + * @param null $ids + * @return string + * @throws \think\Exception + */ + public function edit($ids = null) + { + $id = $ids ? $ids : input('param.id'); + $item = $this->model->getItem((int)$id, '*', ['granary', 'testingParams']); + if (!$item) { + $this->error('检测记录不存在'); + } + $item = $item->toArray(); + + $granaryList = $this->getGranaryOptions(); + $typeList = $this->model->getTypeList(); + + $this->assign('item', $item); + $this->assign('granaryList', $granaryList); + $this->assign('typeList', $typeList); + $this->assign('siteOptions', $this->granarySites); + + return $this->fetch('edit'); + } + + /** + * 独立详情页面 + * @param null $ids + * @return string + * @throws \think\Exception + */ + public function detail($ids = null) + { + $id = $ids ? $ids : input('param.id'); + $item = $this->model->getItem((int)$id, '*', ['granary', 'testingParams']); + if (!$item) { + $this->error('检测记录不存在'); + } + $item = $item->toArray(); + + $granaryList = $this->getGranaryOptions(); + $typeList = $this->model->getTypeList(); + + $this->assign('item', $item); + $this->assign('granaryList', $granaryList); + $this->assign('typeList', $typeList); + $this->assign('siteOptions', $this->granarySites); + + return $this->fetch('detail'); } // 删除 diff --git a/application/admin/controller/auth/Admin.php b/application/admin/controller/auth/Admin.php index 85f8fb4..9ac2b22 100644 --- a/application/admin/controller/auth/Admin.php +++ b/application/admin/controller/auth/Admin.php @@ -60,6 +60,7 @@ class Admin extends Backend } $this->view->assign('groupdata', $groupdata); + $this->view->assign('canSetGranarySites', $this->auth->isSuperAdmin()); $this->assignconfig("admin", ['id' => $this->auth->id]); } @@ -122,6 +123,18 @@ class Admin extends Backend if ($this->request->isPost()) { $this->token(); $params = $this->request->post("row/a"); + if ($params) { + if ($this->auth->isSuperAdmin()) { + $scope = isset($params['granary_sites']) ? $params['granary_sites'] : 'all'; + if (!in_array($scope, ['all', 'center', 'xishui', 'none'], true)) $this->error('无效库区权限'); + $params['granary_sites'] = $scope; + } elseif ($this->request->action() === 'add') { + $ownScope = Db::name('admin')->where('id', $this->auth->id)->value('granary_sites'); + $params['granary_sites'] = $ownScope ?: 'none'; + } else { + unset($params['granary_sites']); + } + } if ($params) { Db::startTrans(); try { @@ -175,6 +188,18 @@ class Admin extends Backend if ($this->request->isPost()) { $this->token(); $params = $this->request->post("row/a"); + if ($params) { + if ($this->auth->isSuperAdmin()) { + $scope = isset($params['granary_sites']) ? $params['granary_sites'] : 'all'; + if (!in_array($scope, ['all', 'center', 'xishui', 'none'], true)) $this->error('无效库区权限'); + $params['granary_sites'] = $scope; + } elseif ($this->request->action() === 'add') { + $ownScope = Db::name('admin')->where('id', $this->auth->id)->value('granary_sites'); + $params['granary_sites'] = $ownScope ?: 'none'; + } else { + unset($params['granary_sites']); + } + } if ($params) { Db::startTrans(); try { diff --git a/application/admin/view/auth/admin/add.html b/application/admin/view/auth/admin/add.html index 3cb174e..58d702b 100644 --- a/application/admin/view/auth/admin/add.html +++ b/application/admin/view/auth/admin/add.html @@ -42,6 +42,14 @@ {:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])} + {if $canSetGranarySites} +
+ +
+ {:build_select('row[granary_sites]', ['all'=>'全部库区', 'center'=>'遵义中心库', 'xishui'=>'习水库', 'none'=>'无库区权限'], 'all', ['class'=>'form-control'])} +
+
+ {/if} + {if $canSetGranarySites} +
+ +
+ {:build_select('row[granary_sites]', ['all'=>'全部库区', 'center'=>'遵义中心库', 'xishui'=>'习水库', 'none'=>'无库区权限'], $row['granary_sites'], ['class'=>'form-control'])} +
+
+ {/if}