Package.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <?php
  2. namespace app\api\controller\product;
  3. use app\common\controller\Frontend;
  4. use think\facade\Db;
  5. class Package extends Frontend
  6. {
  7. protected array $noNeedPermission = ['product_list','list', 'detail'];
  8. protected array $noNeedLogin = ['*'];
  9. /**
  10. * 获取产品列表(简化版)
  11. */
  12. public function product_list(): void
  13. {
  14. // 查询所有上架的产品
  15. $products = Db::table('ba_product')
  16. ->where('status', 1)
  17. ->where('stock_status', 1) // 库存充足
  18. ->order('sort', 'desc')
  19. ->order('id', 'desc')
  20. ->field('id, name, image, description, package_id')
  21. ->select()
  22. ->toArray();
  23. // // 查询每个产品的套餐信息
  24. // foreach ($products as &$product) {
  25. // // 获取产品对应的所有套餐规格
  26. // $product['packages'] = $this->getProductPackages($product['id'], $product['package_id']);
  27. //
  28. // // 获取主图
  29. // $product['main_image'] = $this->getMainImage($product['image']);
  30. // }
  31. $this->success('', $products);
  32. }
  33. /**
  34. * 获取产品对应的套餐
  35. */
  36. private function getProductPackages($productId, $packageId, $detail = false)
  37. {
  38. // 查询套餐规格
  39. $query = Db::table('ba_package_price')
  40. ->alias('pp')
  41. ->leftJoin('ba_package p', 'p.id = pp.package_id')
  42. ->where('p.status', 1)
  43. ->where('pp.price', '>', 0);
  44. // 如果产品有关联的package_id,使用它
  45. if ($packageId) {
  46. $query->where('pp.package_id', $packageId);
  47. } else {
  48. // 如果没有,可能需要其他关联逻辑
  49. // 这里简化处理,返回空
  50. return [];
  51. }
  52. // 如果是详情页,获取更多字段
  53. if ($detail) {
  54. $packages = $query->field('
  55. pp.id,
  56. pp.spec_name,
  57. pp.price,
  58. pp.type,
  59. pp.card_type,
  60. pp.unit_value,
  61. pp.points_value,
  62. pp.stock,
  63. pp.sold_count,
  64. pp.description,
  65. p.name as package_name
  66. ')->select()->toArray();
  67. } else {
  68. // 列表页只需要基本信息
  69. $packages = $query->field('
  70. pp.id,
  71. pp.spec_name,
  72. pp.price,
  73. pp.type,
  74. pp.card_type,
  75. pp.unit_value,
  76. pp.points_value,
  77. pp.stock,
  78. pp.sold_count
  79. ')->select()->toArray();
  80. }
  81. // 格式化数据
  82. $formattedPackages = [];
  83. foreach ($packages as $package) {
  84. $formattedPackage = [
  85. 'id' => $package['id'],
  86. 'name' => $package['spec_name'],
  87. 'type' => $package['type'],
  88. 'type_text' => $package['type'] == 1 ? '个人' : '企业',
  89. 'price' => floatval($package['price']),
  90. 'price_text' => '¥' . number_format($package['price'], 2),
  91. 'stock' => intval($package['stock']),
  92. 'stock_text' => $this->getStockText($package['stock']),
  93. 'sold_count' => intval($package['sold_count']),
  94. 'card_type' => $package['card_type'],
  95. 'card_info' => $this->getCardInfo($package['card_type'], $package['unit_value'], $package['points_value'])
  96. ];
  97. // 如果是详情页,添加更多信息
  98. if ($detail) {
  99. $formattedPackage['description'] = $package['description'] ?? '商品说明';
  100. $formattedPackage['package_name'] = $package['package_name'] ?? '';
  101. }
  102. $formattedPackages[] = $formattedPackage;
  103. }
  104. return $formattedPackages;
  105. }
  106. /**
  107. * 获取套餐列表
  108. */
  109. public function list(): void
  110. {
  111. // 获取参数(可根据产品筛选)
  112. $productId = $this->request->get('product_id', 0);
  113. // 构建查询
  114. $query = Db::table('ba_package_price')
  115. ->alias('pp')
  116. ->leftJoin('ba_package p', 'p.id = pp.package_id')
  117. ->where('p.status', 1)
  118. ->where('pp.price', '>', 0)
  119. ->order('pp.type', 'asc') // 个人在前,企业在后
  120. ->order('pp.price', 'asc'); // 价格从低到高
  121. // 如果有产品ID,筛选对应的套餐
  122. if ($productId > 0) {
  123. $product = Db::table('ba_product')
  124. ->where('id', $productId)
  125. ->field('package_id')
  126. ->find();
  127. if ($product && $product['package_id']) {
  128. $query->where('pp.package_id', $product['package_id']);
  129. }
  130. }
  131. // 获取套餐数据
  132. $packages = $query->field('
  133. pp.id,
  134. pp.spec_name,
  135. pp.image,
  136. pp.price,
  137. pp.type,
  138. pp.card_type,
  139. pp.unit_value,
  140. pp.points_value,
  141. pp.stock,
  142. pp.sold_count,
  143. pp.description
  144. ')->select()->toArray();
  145. // 格式化返回数据(严格按照截图格式)
  146. $formattedPackages = [];
  147. foreach ($packages as $package) {
  148. $formattedPackage = [
  149. 'id' => $package['id'],
  150. 'name' => $package['spec_name'], // 套餐名称
  151. 'type' => $package['type'], // 1个人,2企业
  152. 'type_text' => $package['type'] == 1 ? '个人' : '企业',
  153. 'price' => floatval($package['price']),
  154. 'price_text' => '¥' . number_format($package['price'], 2),
  155. 'description' => $package['description'] ?? '商品说明',
  156. 'stock' => intval($package['stock']),
  157. 'stock_text' => $this->getStockText($package['stock']),
  158. 'sold_count' => intval($package['sold_count']),
  159. 'card_type' => $package['card_type'],
  160. 'image' => $package['image'],
  161. 'card_info' => $this->getCardInfo($package['card_type'], $package['unit_value'], $package['points_value'])
  162. ];
  163. $formattedPackages[] = $formattedPackage;
  164. }
  165. $this->success('', $formattedPackages);
  166. }
  167. /**
  168. * 获取套餐详情(用于购买页面)
  169. */
  170. public function detail(): void
  171. {
  172. $packageId = $this->request->get('id', 0);
  173. if ($packageId <= 0) {
  174. $this->error('套餐ID错误');
  175. }
  176. // 查询套餐详情
  177. $package = Db::table('ba_package_price')
  178. ->alias('pp')
  179. ->leftJoin('ba_package p', 'p.id = pp.package_id')
  180. ->where('pp.id', $packageId)
  181. ->field('
  182. pp.id,
  183. pp.image,
  184. pp.spec_name,
  185. pp.price,
  186. pp.type,
  187. pp.card_type,
  188. pp.unit_value,
  189. pp.points_value,
  190. pp.stock,
  191. pp.sold_count,
  192. pp.description,
  193. p.name as package_name,
  194. p.description as package_description
  195. ')
  196. ->find();
  197. if (!$package) {
  198. $this->error('套餐不存在');
  199. }
  200. // 查询关联的产品信息
  201. $product = Db::table('ba_product')
  202. ->where('package_id', $package['package_id'] ?? 0)
  203. ->field('id, name, image')
  204. ->find();
  205. // 格式化详情数据
  206. $formattedDetail = [
  207. 'id' => $package['id'],
  208. 'name' => $package['spec_name'],
  209. 'type' => $package['type'],
  210. 'type_text' => $package['type'] == 1 ? '个人' : '企业',
  211. 'price' => floatval($package['price']),
  212. 'price_text' => '¥' . number_format($package['price'], 2),
  213. 'description' => $package['description'] ?? ($package['package_description'] ?? '商品说明'),
  214. 'stock' => intval($package['stock']),
  215. 'stock_text' => $this->getStockText($package['stock']),
  216. 'sold_count' => intval($package['sold_count']),
  217. 'card_type' => $package['card_type'],
  218. 'card_info' => $this->getCardInfo($package['card_type'], $package['unit_value'], $package['points_value']),
  219. 'package_name' => $package['package_name'],
  220. 'image' => $package['image'],
  221. 'product' => $product ? [
  222. 'id' => $product['id'],
  223. 'name' => $product['name'],
  224. 'image' => $this->getMainImage($product['image'])
  225. ] : null
  226. ];
  227. $this->success('', $formattedDetail);
  228. }
  229. /**
  230. * 获取库存状态文本
  231. */
  232. private function getStockText($stock): string
  233. {
  234. if ($stock <= 0) {
  235. return '售罄';
  236. } elseif ($stock <= 10) {
  237. return '即将售罄';
  238. } else {
  239. return '充足';
  240. }
  241. }
  242. /**
  243. * 获取卡类型信息
  244. */
  245. private function getCardInfo($cardType, $unitValue, $pointsValue): array
  246. {
  247. $cardTypes = [
  248. 1 => ['name' => '次卡', 'show_value' => $unitValue . '次'],
  249. 2 => ['name' => '积分卡', 'show_value' => $pointsValue . '积分'],
  250. 3 => ['name' => '日卡', 'show_value' => '1天'],
  251. 4 => ['name' => '周卡', 'show_value' => '7天'],
  252. 5 => ['name' => '季卡', 'show_value' => '90天'],
  253. 6 => ['name' => '月卡', 'show_value' => '30天'],
  254. 7 => ['name' => '年卡', 'show_value' => '365天']
  255. ];
  256. return $cardTypes[$cardType] ?? ['name' => '其他', 'show_value' => ''];
  257. }
  258. /**
  259. * 获取主图
  260. */
  261. private function getMainImage($imageJson)
  262. {
  263. if (empty($imageJson)) {
  264. return '';
  265. }
  266. $images = json_decode($imageJson, true);
  267. if (is_array($images) && !empty($images)) {
  268. return $images[0];
  269. }
  270. return '';
  271. }
  272. }