PlaceOrderValidate.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeshop100%开源免费商用商城系统
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | 商业版本务必购买商业授权,以免引起法律纠纷
  8. // | 禁止对系统程序代码以任何目的,任何形式的再发布
  9. // | gitee下载:https://gitee.com/likeshop_gitee
  10. // | github下载:https://github.com/likeshop-github
  11. // | 访问官网:https://www.likeshop.cn
  12. // | 访问社区:https://home.likeshop.cn
  13. // | 访问手册:http://doc.likeshop.cn
  14. // | 微信公众号:likeshop技术社区
  15. // | likeshop团队 版权所有 拥有最终解释权
  16. // +----------------------------------------------------------------------
  17. // | author: likeshopTeam
  18. // +----------------------------------------------------------------------
  19. namespace app\shopapi\validate;
  20. use app\common\enum\BargainEnum;
  21. use app\common\enum\DeliveryEnum;
  22. use app\common\enum\LuckyDrawEnum;
  23. use app\common\enum\OrderEnum;
  24. use app\common\enum\PresellEnum;
  25. use app\common\enum\SeckillEnum;
  26. use app\common\enum\TeamEnum;
  27. use app\common\model\BargainInitiate;
  28. use app\common\model\Goods;
  29. use app\common\model\GoodsItem;
  30. use app\common\model\LuckyDrawPrize;
  31. use app\common\model\PresellGoodsItem;
  32. use app\common\model\SeckillGoodsItem;
  33. use app\common\model\TeamFound;
  34. use app\common\model\TeamGoodsItem;
  35. use app\common\model\TeamJoin;
  36. use app\common\model\User;
  37. use app\common\validate\BaseValidate;
  38. /**
  39. * 订单提交验证
  40. * Class OrderValidate
  41. * @package app\shopapi\validate
  42. */
  43. class PlaceOrderValidate extends BaseValidate
  44. {
  45. protected $rule = [
  46. // 下单用户
  47. 'user_id' => 'checkUser',
  48. // 下单来源(立即购买/购物车购买)
  49. 'source' => 'require',
  50. // 下单动作(结算/下单)
  51. 'action' => 'require',
  52. // 订单类型
  53. 'order_type' => 'require|checkGoods|checkOrderType',
  54. // 配送方式
  55. 'delivery_type' => 'require|checkDeliveryType'
  56. ];
  57. protected $message = [
  58. 'source.require' => '下单来源缺失',
  59. 'action.require' => '下单动作缺失',
  60. 'order_type.require' => '订单类型缺失',
  61. 'delivery_type.require' => '配送参数缺失',
  62. ];
  63. /**
  64. * @notes 检测用户是否登录
  65. * @param $value
  66. * @param $rule
  67. * @param $data
  68. * @return bool|string
  69. * @author Tab
  70. * @date 2021/10/14 11:59
  71. */
  72. public static function checkUser($value, $rule, $data)
  73. {
  74. $user = User::findOrEmpty($value);
  75. if ($user->isEmpty()) {
  76. return '请先登录';
  77. }
  78. return true;
  79. }
  80. /**
  81. * @notes 检查配送方式
  82. * @param $value
  83. * @param $rule
  84. * @param $data
  85. * @author Tab
  86. * @date 2021/10/9 10:59
  87. */
  88. public function checkDeliveryType($value, $rule, $data)
  89. {
  90. if (!in_array($data['delivery_type'],DeliveryEnum::DELIVERY_TYPE)) {
  91. return '无效的配送方式';
  92. }
  93. return true;
  94. }
  95. /**
  96. * @notes 验证商品参数
  97. * @param $value
  98. * @param $rule
  99. * @param $data
  100. * @return bool|string
  101. * @author 段誉
  102. * @date 2021/7/26 17:22
  103. */
  104. public function checkGoods($value, $rule, $data)
  105. {
  106. // 购物车下单 或 砍价订单 无需商品信息
  107. if ($data['source'] == 'cart' || $data['order_type'] == OrderEnum::BARGAIN_ORDER) {
  108. return true;
  109. }
  110. if (!isset($data['goods'])) {
  111. return '商品信息参数缺失';
  112. }
  113. if (!is_array($data['goods'])) {
  114. return '商品信息格式不正确';
  115. }
  116. foreach ($data['goods'] as $item) {
  117. if (!isset($item['item_id']) || !isset($item['goods_num'])) {
  118. return '商品信息参数不完整';
  119. }
  120. }
  121. return true;
  122. }
  123. /**
  124. * @notes 校验订单类型
  125. * @param $value
  126. * @param $rule
  127. * @param $data
  128. * @return bool|string
  129. * @author Tab
  130. * @date 2021/10/8 18:59
  131. */
  132. public function checkOrderType($value, $rule, $data)
  133. {
  134. if (!in_array($value, OrderEnum::ORDER_TYPE)) {
  135. return '无效的订单类型';
  136. }
  137. // 营销活动验证
  138. switch($value)
  139. {
  140. // 拼团验证
  141. case OrderEnum::TEAM_ORDER:
  142. return $this->checkTeam($data);
  143. // 秒杀验证
  144. case OrderEnum::SECKILL_ORDER:
  145. return $this->checkSeckill($data);
  146. // 砍价验证
  147. case OrderEnum::BARGAIN_ORDER:
  148. return $this->checkBargain($data);
  149. case OrderEnum::PRESELL_ORDER:
  150. return $this->checkPresell($data);
  151. //抽奖订单验证
  152. case OrderEnum::DRAW_ORDER:
  153. return $this->checkDraw($data);
  154. }
  155. return true;
  156. }
  157. /**
  158. * @notes 拼团验证
  159. * @param $data
  160. * @author Tab
  161. * @date 2021/10/8 19:06
  162. */
  163. public function checkTeam($data)
  164. {
  165. if (!isset($data['team_id'])) {
  166. return '拼团活动ID缺失';
  167. }
  168. // 拼团商品信息
  169. $teamGoodsItem = (new TeamGoodsItem())->alias('TGI')
  170. ->field('TGI.*,TG.goods_snap,TA.name,TA.people_num,
  171. TA.min_buy,TA.max_buy,TA.is_coupon,TA.is_distribution,TA.effective_time')
  172. ->join('team_activity TA', 'TA.id = TGI.team_id')
  173. ->join('team_goods TG', 'TG.id = TGI.team_gid')
  174. ->where([
  175. ['TGI.team_id', '=', (int)$data['team_id']],
  176. ['TGI.item_id', '=', (int)$data['goods'][0]['item_id']],
  177. ['TA.status', '=', TeamEnum::TEAM_STATUS_CONDUCT],
  178. ['TA.start_time', '<=', time()],
  179. ['TA.end_time', '>=', time()],
  180. ])->findOrEmpty()->toArray();
  181. if (empty($teamGoodsItem)) {
  182. return '拼团活动已结束';
  183. }
  184. if ($teamGoodsItem['max_buy'] > 0 && $data['goods'][0]['goods_num'] > $teamGoodsItem['max_buy']) {
  185. return '下单数量不能大于'.$teamGoodsItem['max_buy'].'件';
  186. }
  187. // 参团
  188. if (isset($data['found_id']) && !empty($data['found_id'])) {
  189. $teamFound = (new TeamFound())->where(['id'=>$data['found_id']])->findOrEmpty()->toArray();
  190. if (empty($teamFound)) {
  191. return '选择的团不存在';
  192. }
  193. if ($teamFound['status'] != 0) {
  194. return '当前拼团已结束,请重新选择拼团';
  195. }
  196. if ($teamFound['invalid_time'] <= time()) {
  197. return '当前拼团已结束,请重新选择拼团';
  198. }
  199. if ($teamFound['user_id'] == $data['user_id']) {
  200. return '您是该团发起人,不能参团哦';
  201. }
  202. if ($teamFound['people'] == $teamFound['join']) {
  203. return '当前拼团已满员,请重新选择拼团';
  204. }
  205. // 获取已参团记录
  206. $people = (new TeamJoin())->where(['found_id'=>$data['found_id'], 'user_id'=>$data['user_id']])->findOrEmpty()->toArray();
  207. if (!empty($people)) {
  208. return '您已是该团成员了,不能重复参团哦!';
  209. }
  210. }
  211. return true;
  212. }
  213. /**
  214. * @notes 秒杀验证
  215. * @author Tab
  216. * @date 2021/10/8 19:07
  217. */
  218. public function checkSeckill($data)
  219. {
  220. if (!isset($data['seckill_id'])) {
  221. return '秒杀活动ID缺失';
  222. }
  223. // 秒杀商品信息
  224. $seckillGoodsItem = (new SeckillGoodsItem())->alias('SGI')
  225. ->field('SGI.*,SG.goods_snap,SA.name,SA.min_buy,SA.max_buy,SA.is_coupon,SA.is_distribution')
  226. ->join('seckill_activity SA', 'SA.id = SGI.seckill_id')
  227. ->join('seckill_goods SG', 'SG.id = SGI.seckill_gid')
  228. ->where([
  229. ['SGI.seckill_id', '=', (int)$data['seckill_id']],
  230. ['SGI.item_id', '=', (int)$data['goods'][0]['item_id']],
  231. ['SA.status', '=', SeckillEnum::SECKILL_STATUS_CONDUCT],
  232. ['SA.start_time', '<=', time()],
  233. ['SA.end_time', '>=', time()],
  234. ])->findOrEmpty()->toArray();
  235. if (empty($seckillGoodsItem)) {
  236. return '秒杀活动已结束';
  237. }
  238. if ($seckillGoodsItem['max_buy'] > 0 && $data['goods'][0]['goods_num'] > $seckillGoodsItem['max_buy']) {
  239. return '下单数量不能大于' . $seckillGoodsItem['max_buy'] . '件';
  240. }
  241. return true;
  242. }
  243. /**
  244. * @notes 砍价验证
  245. * @author Tab
  246. * @date 2021/10/8 19:07
  247. */
  248. public function checkBargain($data)
  249. {
  250. if (!isset($data['initiate_id'])) {
  251. return '发起砍价ID缺失';
  252. }
  253. if (!isset($data['buy_condition'])) {
  254. return '购买条件缺失';
  255. }
  256. $bargainInitiate = BargainInitiate::findOrEmpty($data['initiate_id'])->toArray();
  257. if (empty($bargainInitiate)) {
  258. return '砍价信息不存在';
  259. }
  260. if ($bargainInitiate['status'] != BargainEnum::STATUS_SUCCESS && $bargainInitiate['bargain_snapshot']['buy_condition'] != BargainEnum::BUY_CONDITION_RAND) {
  261. return '未砍价成功 或 不支持任意金额购买';
  262. }
  263. if (!empty($bargainInitiate['order_id'])) {
  264. return '已下过单,不能重复购买';
  265. }
  266. if ($bargainInitiate['bargain_snapshot']['order_limit'] > 0 && $bargainInitiate['goods_snapshot']['goods_num'] > $bargainInitiate['bargain_snapshot']['order_limit']) {
  267. return '超出每单购买限制';
  268. }
  269. return true;
  270. }
  271. function checkPresell($data)
  272. {
  273. if (!isset($data['presell_id'])) {
  274. return '预售活动ID缺失';
  275. }
  276. $presellGoodsItem = PresellGoodsItem::alias('pgi')
  277. ->join('presell p', 'pgi.presell_id=p.id')
  278. ->field([ 'p.id', 'p.buy_limit', 'p.buy_limit_num' ])
  279. ->where('pgi.item_id', $data['goods'][0]['item_id'])
  280. ->where('pgi.presell_id', $data['presell_id'])
  281. ->where('p.status', PresellEnum::STATUS_START)
  282. ->where('p.start_time', '<=', time())
  283. ->where('p.end_time', '>=', time())
  284. ->findOrEmpty()->toArray();
  285. if (empty($presellGoodsItem['id'])) {
  286. return '预售活动已结束';
  287. }
  288. if ($presellGoodsItem['buy_limit'] && $data['goods'][0]['goods_num'] > $presellGoodsItem['buy_limit_num']) {
  289. return '下单数量不能大于' . $presellGoodsItem['buy_limit_num'] . '件';
  290. }
  291. return true;
  292. }
  293. /**
  294. * @notes 校验抽奖订单
  295. * @param $data
  296. * @return string|true
  297. * @author ljj
  298. * @date 2024/7/30 下午2:16
  299. */
  300. function checkDraw($data)
  301. {
  302. if (!isset($data['draw_record_id'])) {
  303. return '抽奖记录ID缺失';
  304. }
  305. $LuckyDrawPrize = LuckyDrawPrize::alias('ldp')
  306. ->join('lucky_draw_record ldr', 'ldr.prize_id = ldp.id')
  307. ->where(['ldr.id'=>$data['draw_record_id']])
  308. ->field('ldr.is_send,ldr.prize_type,ldp.type_value')
  309. ->findOrEmpty();
  310. if ($LuckyDrawPrize->isEmpty()) {
  311. return '不存在抽奖记录';
  312. }
  313. if ($LuckyDrawPrize->is_send == 1) {
  314. return '抽奖已兑现';
  315. }
  316. if ($LuckyDrawPrize->prize_type != LuckyDrawEnum::GOODS) {
  317. return '该抽奖记录非商品类型';
  318. }
  319. $goods_id = GoodsItem::where(['id'=>$data['goods'][0]['item_id']])->value('goods_id');
  320. if ($LuckyDrawPrize->type_value != $goods_id) {
  321. return '商品错误';
  322. }
  323. if (1 != $data['goods'][0]['goods_num']) {
  324. return '商品数量错误';
  325. }
  326. return true;
  327. }
  328. }