'必须输入价格' ], [ 'num', 'required', 'msg' => '数量必须输入' ], [ 'user_id,itemId', 'integer', 'msg' => '{attr}必须是大于0的整数' ], [ 'num', 'integer', 'min' => 1, 'max' => 10000, 'msg' => '一次最多10000' ], ['price', 'float', 'min' => '0.00001', 'msg' => '价格必须是大于0的数字' ], // 验证交易方向(支持字符串和整数两种格式) [ 'direction', 'in', 'range' => [MEX_DIRECTION::BUY, MEX_DIRECTION::SELL], 'msg' => '交易方向无效' ], // 验证物品是否可交易 [ 'itemId', new MexItemValidator($this), 'msg' => '该物品不支持在农贸市场交易' ], // 注意:根据文档要求,挂单阶段无价格验证,价格验证延后到撮合阶段 // 移除价格验证器,只保留基本的数值验证 // 验证订单创建条件(资金和物品数量验证) [ 'direction', new MexOrderValidator($this, ['user_id', 'itemId', 'num', 'price', 'currency_type']), 'msg' => '订单创建条件不满足' ], [ 'direction', new MexOrderNumberValidator($this, ['user_id', 'itemId', 'num', 'price', 'currency_type']), 'msg' => '订单数量过多' ] ]; } /** * 设置默认值 * * @return array */ public function default(): array { return []; } /** * 数据预处理 * 将 protobuf 枚举字符串转换为对应的整数值 * 添加默认币种信息 * * @return bool */ public function beforeValidate(): bool { // 处理 direction 字段的转换 $direction = $this->getRaw('direction'); if (is_string($direction)) { // 将字符串枚举名转换为对应的整数值 $directionValue = match (strtoupper($direction)) { 'SELL' => MEX_DIRECTION::SELL, 'BUY' => MEX_DIRECTION::BUY, 'DIRECTION_NONE' => MEX_DIRECTION::DIRECTION_NONE, default => $direction // 保持原值,让验证器处理 }; $this->setRaw('direction', $directionValue); } // 添加默认币种信息(钻石)用于验证 // 由于protobuf请求中没有币种字段,我们使用默认币种 $defaultCurrency = FundLogic::getDefaultCurrency(); $this->setRaw('currency_type', $defaultCurrency->value); return true; } /** * 获取交易方向描述 * * @return string */ public function getDirectionText(): string { $direction = $this->getSafe('direction'); return match ($direction) { MEX_DIRECTION::BUY => '买入', MEX_DIRECTION::SELL => '卖出', default => '未知' }; } /** * 是否为买入订单 * * @return bool */ public function isBuyOrder(): bool { return $this->getSafe('direction') === MEX_DIRECTION::BUY; } /** * 是否为卖出订单 * * @return bool */ public function isSellOrder(): bool { return $this->getSafe('direction') === MEX_DIRECTION::SELL; } }