Purchase.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. namespace app\api\controller\product;
  3. use app\common\controller\Frontend;
  4. use app\common\service\CompanyPackageService;
  5. use think\facade\Db;
  6. class Purchase extends Frontend
  7. {
  8. protected array $noNeedPermission = ['createOrder', 'orderDetail'];
  9. /**
  10. * 创建购买订单
  11. */
  12. public function createOrder(): void
  13. {
  14. if (!$this->request->isPost()) {
  15. $this->error('非法请求');
  16. }
  17. $userId = $this->auth->id;
  18. if (!$userId) {
  19. $this->error('请先登录');
  20. }
  21. // 获取参数
  22. $packageId = $this->request->post('package_id', 0);
  23. $quantity = $this->request->post('quantity', 1);
  24. $distributorId = $this->request->post('distributor_id', 0); // 分销人ID
  25. if ($packageId <= 0) {
  26. $this->error('请选择套餐');
  27. }
  28. if ($quantity < 1) {
  29. $this->error('购买数量错误');
  30. }
  31. // 查询套餐详情
  32. $package = Db::table('ba_package_price')
  33. ->alias('pp')
  34. ->leftJoin('ba_package p', 'p.id = pp.package_id')
  35. ->where('pp.id', $packageId)
  36. ->field('
  37. pp.*,
  38. p.name as package_name
  39. ')
  40. ->find();
  41. if (!$package) {
  42. $this->error('套餐不存在');
  43. }
  44. // 检查库存
  45. if ($package['stock'] < $quantity) {
  46. $this->error('库存不足');
  47. }
  48. // 在原有验证后,添加企业套餐验证
  49. if ($package['type'] == 2) { // 企业套餐
  50. $companyService = new CompanyPackageService();
  51. $validationResult = $companyService->validateCompanyPurchase($userId, $packageId, $quantity);
  52. if (!$validationResult['valid']) {
  53. $this->error('企业套餐购买验证失败');
  54. }
  55. $companyId = $validationResult['company_id'];
  56. }
  57. // 查找关联的产品
  58. $product = Db::table('ba_product')
  59. ->where('package_id', $package['package_id'])
  60. ->field('id, name')
  61. ->find();
  62. if (!$product) {
  63. $this->error('关联产品不存在');
  64. }
  65. // 计算金额
  66. $totalAmount = $package['price'] * $quantity;
  67. // 计算分销佣金
  68. $commissionService = new \app\common\service\CommissionService();
  69. $commissionResult = $commissionService->calculateCommission($totalAmount, $distributorId);
  70. $commissionAmount = $commissionResult['commission_amount'];
  71. $commissionRate = $commissionResult['commission_rate'];
  72. $hasCommission = $commissionResult['has_commission'];
  73. // 生成订单号
  74. $orderNo = 'BUY' . date('YmdHis') . mt_rand(1000, 9999);
  75. Db::startTrans();
  76. try {
  77. // 1. 创建订单
  78. $orderData = [
  79. 'order_no' => $orderNo,
  80. 'user_id' => $userId,
  81. 'company_id' => $companyId,
  82. 'total_amount' => $totalAmount,
  83. 'discount_amount' => 0.00,
  84. 'pay_amount' => $totalAmount,
  85. 'pay_method' => null, // 支付方式待选择
  86. 'pay_status' => 0, // 0=待支付
  87. 'order_status' => 0, // 0=待处理
  88. 'is_commission' => $hasCommission ? 0 : 0, // 0=未处理佣金,1=已处理
  89. 'distributor_id' => $hasCommission ? $distributorId : null,
  90. 'commission_amount' => $commissionAmount,
  91. 'order_time' => date('Y-m-d H:i:s'),
  92. 'create_time' => date('Y-m-d H:i:s'),
  93. 'update_time' => date('Y-m-d H:i:s')
  94. ];
  95. $orderId = Db::table('ba_order')->insertGetId($orderData);
  96. // 2. 创建订单商品
  97. $itemData = [
  98. 'order_id' => $orderId,
  99. 'product_id' => $product['id'],
  100. 'package_id' => $package['package_id'],
  101. 'package_price_id' => $packageId,
  102. 'company_id' => $companyId,
  103. 'item_type' => 2, // 套餐
  104. 'item_name' => $product['name'] . ' - ' . $package['spec_name'],
  105. 'spec_name' => $package['spec_name'],
  106. 'quantity' => $quantity,
  107. 'unit_price' => $package['price'],
  108. 'total_price' => $totalAmount,
  109. 'create_time' => date('Y-m-d H:i:s')
  110. ];
  111. Db::table('ba_order_item')->insert($itemData);
  112. // 3. 如果存在分销,创建分销记录
  113. if ($hasCommission && $distributorId > 0) {
  114. $commissionService->createDistributionRecord([
  115. 'order_id' => $orderId,
  116. 'product_id' => $product['id'],
  117. 'buyer_id' => $userId,
  118. 'distributor_id' => $distributorId,
  119. 'commission_rate' => $commissionRate,
  120. 'commission_amount' => $commissionAmount
  121. ]);
  122. }
  123. // 如果是企业套餐,处理企业套餐相关逻辑
  124. // if ($package['type'] == 2) {
  125. // // 在企业购买配额表中记录
  126. // $companyService->processCompanyPackagePurchase(
  127. // $orderId,
  128. // $companyId,
  129. // $packageId,
  130. // $quantity,
  131. // $package['card_type'],
  132. // $package['unit_value'],
  133. // $package['points_value']
  134. // );
  135. //
  136. // $orderData['company_id'] = $companyId;
  137. // }
  138. Db::commit();
  139. } catch (\Throwable $e) {
  140. Db::rollback();
  141. throw $e;
  142. }
  143. $this->success('订单创建成功', [
  144. 'order_id' => $orderId,
  145. 'order_no' => $orderNo,
  146. 'product_name' => $product['name'],
  147. 'package_name' => $package['spec_name'],
  148. 'total_amount' => $totalAmount,
  149. 'quantity' => $quantity,
  150. 'has_commission' => $hasCommission,
  151. 'commission_amount' => $commissionAmount
  152. ]);
  153. }
  154. /**
  155. * 获取订单详情
  156. */
  157. public function orderDetail(): void
  158. {
  159. try {
  160. $userId = $this->auth->id;
  161. $orderId = $this->request->get('order_id', 0);
  162. $orderNo = $this->request->get('order_no', '');
  163. if (empty($orderId) && empty($orderNo)) {
  164. $this->error('参数错误');
  165. }
  166. // 查询订单
  167. if ($orderId) {
  168. $order = Db::table('ba_order')
  169. ->where('id', $orderId)
  170. ->where('user_id', $userId)
  171. ->find();
  172. } else {
  173. $order = Db::table('ba_order')
  174. ->where('order_no', $orderNo)
  175. ->where('user_id', $userId)
  176. ->find();
  177. }
  178. if (!$order) {
  179. $this->error('订单不存在');
  180. }
  181. // 查询订单商品
  182. $orderItem = Db::table('ba_order_item')
  183. ->where('order_id', $order['id'])
  184. ->find();
  185. if ($orderItem) {
  186. // 查询套餐详情
  187. $package = Db::table('ba_package_price')
  188. ->where('id', $orderItem['package_price_id'])
  189. ->find();
  190. if ($package) {
  191. $orderItem['package_info'] = [
  192. 'name' => $package['spec_name'],
  193. 'price' => $package['price'],
  194. 'type' => $package['type'],
  195. 'type_text' => $package['type'] == 1 ? '个人' : '企业'
  196. ];
  197. }
  198. // 查询产品信息
  199. $product = Db::table('ba_product')
  200. ->where('id', $orderItem['product_id'])
  201. ->field('id, name')
  202. ->find();
  203. if ($product) {
  204. $orderItem['product_info'] = $product;
  205. }
  206. $order['item'] = $orderItem;
  207. }
  208. // 格式化状态
  209. $order['pay_status_text'] = $this->getPayStatusText($order['pay_status']);
  210. $order['order_status_text'] = $this->getOrderStatusText($order['order_status']);
  211. // 格式化时间
  212. $order['order_time_formatted'] = $order['order_time']
  213. ? date('m-d H:i', strtotime($order['order_time']))
  214. : '';
  215. $order['pay_time_formatted'] = $order['pay_time']
  216. ? date('m-d H:i', strtotime($order['pay_time']))
  217. : '';
  218. $this->success('', $order);
  219. } catch (\Throwable $e) {
  220. \think\facade\Log::error('获取订单详情失败: ' . $e->getMessage());
  221. $this->error('获取订单详情失败');
  222. }
  223. }
  224. /**
  225. * 获取支付状态文本
  226. */
  227. private function getPayStatusText($status): string
  228. {
  229. $texts = [
  230. 0 => '待支付',
  231. 1 => '已支付',
  232. 2 => '支付失败'
  233. ];
  234. return $texts[$status] ?? '未知';
  235. }
  236. /**
  237. * 获取订单状态文本
  238. */
  239. private function getOrderStatusText($status): string
  240. {
  241. $texts = [
  242. 0 => '待处理',
  243. 1 => '已确认',
  244. 2 => '已发货',
  245. 3 => '已完成',
  246. 4 => '已取消'
  247. ];
  248. return $texts[$status] ?? '未知';
  249. }
  250. }