request->get('card_no', ''); $since = $this->request->get('since', 0); if (empty($cardNo)) { return json(['code' => -1, 'data' => null, 'msg' => '缺少号码牌']); } $query = MessageModel::where('card_no', $cardNo) ->order('created_at', 'asc'); if ($since > 0) { $query->where('id', '>', intval($since)); } $messages = $query->select()->toArray(); $list = array_map(function ($m) { return [ 'id' => $m['id'], 'cardNo' => $m['card_no'], 'senderType' => $m['sender_type'], 'content' => $m['content'], 'time' => date('H:i', strtotime($m['created_at'])), 'staffId' => $m['staff_id'] ?? null, ]; }, $messages); return json(['code' => 0, 'data' => $list, 'msg' => 'ok']); } // BUG-03: 增加输入校验 + XSS防护 public function send() { $cardNo = $this->request->post('cardNo', ''); $senderType = $this->request->post('senderType', 'customer'); $content = $this->request->post('content', ''); $staffId = $this->request->post('staffId', null); // 必填校验 if (empty($cardNo) || empty($content)) { return json(['code' => -1, 'data' => null, 'msg' => '参数不完整']); } // senderType 枚举校验 if (!in_array($senderType, ['customer', 'staff', 'system'])) { return json(['code' => -1, 'data' => null, 'msg' => '发送者类型无效']); } // 内容长度校验 (DB VARCHAR 500) if (mb_strlen($content) > 500) { return json(['code' => -1, 'data' => null, 'msg' => '消息过长,最多500字']); } // XSS 防护 — HTML 转义 $content = htmlspecialchars($content, ENT_QUOTES, 'UTF-8'); $msg = MessageModel::create([ 'card_no' => $cardNo, 'sender_type' => $senderType, 'staff_id' => $staffId, 'content' => $content, ]); return json(['code' => 0, 'data' => ['id' => $msg->id], 'msg' => 'ok']); } }