feat(forecast): 支持温湿度预测记录编辑与删除,修复组件调用并级联清理周期数据

这个提交包含在:
wikiboss
2026-11-02 14:55:36 +08:00
父节点 4a1e4f1d93
当前提交 f6e454a589
共有 8 个文件被更改,包括 284 次插入 和 61 次删除

查看文件

@@ -32,7 +32,7 @@ class GranaryBackend extends Backend
'granary' => ['index', 'add', 'detail', 'dell'],
'testing' => ['index', 'add', 'edit', 'detail', 'sort', 'dell'],
'content' => ['index', 'add', 'status', 'getcontent', 'dell'],
'forecast' => ['index', 'detail', 'add', 'retry', 'actual'],
'forecast' => ['index', 'detail', 'add', 'edit', 'retry', 'actual', 'dell', 'del'],
];
if (!isset($actions[$controller]) || !in_array($action, $actions[$controller], true)) $this->error('不支持此操作');
$table = $controller === 'forecast' ? 'grain_forecast' : $controller;

查看文件

@@ -88,7 +88,7 @@ class GrainForecast
{
$date = new \DateTimeImmutable($point['target_date']);
$params = array_intersect_key($record, array_flip(['tm_i', 'tm_o', 'hm_i', 'hm_o']));
$params += ['month' => (int)$date->format('n'), 'day' => (int)$date->format('j'), 'type' => $record['grain_type']];
$params += ['month' => (int)$date->format('n'), 'day' => (int)$date->format('j'), 'type' => $record['grain_type'], 'commodity' => $record['grain_type']];
$url = 'http://www.probe-cdy-pests.cn:8116/alg/grainquality/forcast?' . http_build_query($params);
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 3, CURLOPT_TIMEOUT => 6,
@@ -194,4 +194,103 @@ class GrainForecast
if (!$saved) throw new \InvalidArgumentException('实测数据已被其他人更新,请关闭并重新打开后填写');
return (int)$point['forecast_id'];
}
public function delete($id)
{
$ids = is_array($id) ? $id : (strpos((string)$id, ',') !== false ? explode(',', (string)$id) : [(int)$id]);
$ids = array_values(array_filter(array_map('intval', $ids)));
if (empty($ids)) {
throw new \InvalidArgumentException('请选择要删除的记录');
}
return Db::transaction(function () use ($ids) {
Db::name('grain_forecast_point')->where('forecast_id', 'in', $ids)->delete();
return Db::name('grain_forecast')->where('id', 'in', $ids)->delete();
});
}
public function update($id, array $input, $adminId)
{
$id = (int)$id;
$existing = Db::name('grain_forecast')->where('id', $id)->find();
if (!$existing) {
throw new \InvalidArgumentException('预测记录不存在');
}
$gid = isset($input['gid']) && is_scalar($input['gid']) ? (int)$input['gid'] : 0;
$granary = Db::name('granary')->where('id', $gid)->find();
if (!$granary || !in_array($granary['varieties'], ['小麦', '稻谷'], true)) {
throw new \InvalidArgumentException('请选择小麦或稻谷仓库');
}
$date = self::date(isset($input['observed_date']) ? $input['observed_date'] : '', '温湿度采集日期');
$horizons = isset($input['horizons']) ? $input['horizons'] : [];
if (!is_array($horizons) || !$horizons || count($horizons) > 4) {
throw new \InvalidArgumentException('请选择预测周期');
}
foreach ($horizons as $day) {
if (!is_scalar($day) || !in_array((string)$day, ['7', '15', '30', '60'], true)) {
throw new \InvalidArgumentException('预测周期仅支持7、15、30、60天');
}
}
$horizons = array_unique(array_map('intval', $horizons));
sort($horizons);
$grainType = $granary['varieties'] === '小麦' ? 'wheat' : 'rice';
$row = [
'gid' => $gid,
'granary_name' => $granary['name'],
'storage' => $granary['storage'],
'grain_type' => $grainType,
'observed_date' => $date->format('Y-m-d'),
'status' => 'pending',
'error' => '',
'update_time' => time()
];
foreach (['tm_i' => '仓内温度', 'tm_o' => '仓外温度', 'hm_i' => '仓内湿度', 'hm_o' => '仓外湿度'] as $field => $label) {
$isTemp = strpos($field, 'tm_') === 0;
$row[$field] = self::number(isset($input[$field]) ? $input[$field] : null, $label, $isTemp ? -50 : 0, $isTemp ? 80 : 100);
}
Db::transaction(function () use ($id, $row, $horizons, $date, $grainType, $existing) {
Db::name('grain_forecast')->where('id', $id)->update($row);
$oldPoints = Db::name('grain_forecast_point')->where('forecast_id', $id)->select();
$oldPointsByHorizon = [];
foreach ($oldPoints as $op) {
$oldPointsByHorizon[(int)$op['horizon']] = $op;
}
$grainTypeChanged = ($existing['grain_type'] !== $grainType);
foreach ($horizons as $days) {
$targetDate = $date->modify('+' . $days . ' days')->format('Y-m-d');
if (isset($oldPointsByHorizon[$days]) && !$grainTypeChanged) {
Db::name('grain_forecast_point')->where('id', $oldPointsByHorizon[$days]['id'])->update([
'target_date' => $targetDate,
'predicted' => '{}',
'update_time' => time()
]);
} else {
if (isset($oldPointsByHorizon[$days])) {
Db::name('grain_forecast_point')->where('id', $oldPointsByHorizon[$days]['id'])->delete();
}
Db::name('grain_forecast_point')->insert([
'forecast_id' => $id,
'horizon' => $days,
'target_date' => $targetDate,
'predicted' => '{}',
'actual' => '{}',
'version' => 0,
'update_time' => time()
]);
}
}
foreach ($oldPointsByHorizon as $h => $op) {
if (!in_array($h, $horizons, true)) {
Db::name('grain_forecast_point')->where('id', $op['id'])->delete();
}
}
});
return (int)$id;
}
}