GoodsService.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. namespace app\data\service;
  3. use app\data\model\ShopGoods;
  4. use app\data\model\ShopGoodsCate;
  5. use app\data\model\ShopGoodsItem;
  6. use app\data\model\ShopGoodsMark;
  7. use app\data\model\ShopGoodsStock;
  8. use app\data\model\ShopOrder;
  9. use think\admin\extend\DataExtend;
  10. use think\admin\Service;
  11. /**
  12. * 商品数据服务
  13. * Class GoodsService
  14. * @package app\data\service
  15. */
  16. class GoodsService extends Service
  17. {
  18. /**
  19. * 获取商品标签数据
  20. * @return array
  21. */
  22. public function getMarkData(): array
  23. {
  24. $map = ['status' => 1];
  25. return ShopGoodsMark::mk()->where($map)->order('sort desc,id desc')->column('name');
  26. }
  27. /**
  28. * 获取分类数据
  29. * @param string $type 数据格式 arr2tree | arr2table
  30. * @return array
  31. * @throws \think\db\exception\DataNotFoundException
  32. * @throws \think\db\exception\DbException
  33. * @throws \think\db\exception\ModelNotFoundException
  34. */
  35. public function getCateTree(string $type = 'arr2tree'): array
  36. {
  37. $query = ShopGoodsCate::mk()->where(['deleted' => 0, 'status' => 1])->order('sort desc,id desc');
  38. return DataExtend::$type($query->withoutField('sort,status,deleted,create_at')->select()->toArray());
  39. }
  40. /**
  41. * 获取分类数据
  42. * @param boolean $simple 简化数据
  43. * @return array
  44. */
  45. public function getCateData(bool $simple = true): array
  46. {
  47. $cates = ShopGoodsCate::mk()->where(['status' => 1, 'deleted' => 0])->column('id,pid,name', 'id');
  48. foreach ($cates as $cate) if (isset($cates[$cate['pid']])) $cates[$cate['id']]['parent'] =& $cates[$cate['pid']];
  49. foreach ($cates as $key => $cate) {
  50. $id = $cate['id'];
  51. $cates[$id]['ids'][] = $cate['id'];
  52. $cates[$id]['names'][] = $cate['name'];
  53. while (isset($cate['parent']) && $cate = $cate['parent']) {
  54. $cates[$id]['ids'][] = $cate['id'];
  55. $cates[$id]['names'][] = $cate['name'];
  56. }
  57. $cates[$id]['ids'] = array_reverse($cates[$id]['ids']);
  58. $cates[$id]['names'] = array_reverse($cates[$id]['names']);
  59. if (isset($pky) && $simple && in_array($cates[$pky]['name'], $cates[$id]['names'])) {
  60. unset($cates[$pky]);
  61. }
  62. $pky = $key;
  63. }
  64. return $cates;
  65. }
  66. /**
  67. * 更新商品库存数据
  68. * @param string $code
  69. * @return boolean
  70. * @throws \think\db\exception\DataNotFoundException
  71. * @throws \think\db\exception\DbException
  72. * @throws \think\db\exception\ModelNotFoundException
  73. */
  74. public function stock(string $code): bool
  75. {
  76. // 商品入库统计
  77. $query = ShopGoodsStock::mk()->field('goods_code,goods_spec,ifnull(sum(goods_stock),0) stock_total');
  78. $stockList = $query->where(['goods_code' => $code])->group('goods_code,goods_spec')->select()->toArray();
  79. // 商品销量统计
  80. $query = ShopOrder::mk()->alias('a')->field('b.goods_code,b.goods_spec,ifnull(sum(b.stock_sales),0) stock_sales');
  81. $query->leftJoin('shop_order_item b', 'a.order_no=b.order_no')->where("b.goods_code='{$code}' and a.status>0 and a.deleted_status<1");
  82. $salesList = $query->group('b.goods_code,b.goods_spec')->select()->toArray();
  83. // 组装更新数据
  84. $dataList = [];
  85. foreach (array_merge($stockList, $salesList) as $vo) {
  86. $key = "{$vo['goods_code']}@@{$vo['goods_spec']}";
  87. $dataList[$key] = isset($dataList[$key]) ? array_merge($dataList[$key], $vo) : $vo;
  88. if (empty($dataList[$key]['stock_sales'])) $dataList[$key]['stock_sales'] = 0;
  89. if (empty($dataList[$key]['stock_total'])) $dataList[$key]['stock_total'] = 0;
  90. }
  91. unset($salesList, $stockList);
  92. // 更新商品规格销量及库存
  93. foreach ($dataList as $vo) {
  94. $map = ['goods_code' => $code, 'goods_spec' => $vo['goods_spec']];
  95. $set = ['stock_total' => $vo['stock_total'], 'stock_sales' => $vo['stock_sales']];
  96. ShopGoodsItem::mk()->where($map)->update($set);
  97. }
  98. // 更新商品主体销量及库存
  99. ShopGoods::mk()->where(['code' => $code])->update([
  100. 'stock_total' => intval(array_sum(array_column($dataList, 'stock_total'))),
  101. 'stock_sales' => intval(array_sum(array_column($dataList, 'stock_sales'))),
  102. 'stock_virtual' => ShopGoodsItem::mk()->where(['goods_code' => $code])->sum('number_virtual'),
  103. ]);
  104. return true;
  105. }
  106. /**
  107. * 商品数据绑定
  108. * @param array $data 商品主数据
  109. * @param boolean $simple 简化数据
  110. * @return array
  111. * @throws \think\db\exception\DataNotFoundException
  112. * @throws \think\db\exception\DbException
  113. * @throws \think\db\exception\ModelNotFoundException
  114. */
  115. public function bindData(array &$data = [], bool $simple = true): array
  116. {
  117. [$cates, $codes] = [$this->getCateData(), array_unique(array_column($data, 'code'))];
  118. $marks = ShopGoodsMark::mk()->where(['status' => 1])->column('name');
  119. $items = ShopGoodsItem::mk()->whereIn('goods_code', $codes)->where(['status' => 1])->select()->toArray();
  120. foreach ($data as &$vo) {
  121. [$vo['marks'], $vo['cateids'], $vo['cateinfo']] = [str2arr($vo['marks'], ',', $marks), str2arr($vo['cateids']), []];
  122. [$vo['slider'], $vo['specs'], $vo['items']] = [str2arr($vo['slider'], '|'), json_decode($vo['data_specs'], true), []];
  123. foreach ($cates as $cate) if (in_array($cate['id'], $vo['cateids'])) $vo['cateinfo'] = $cate;
  124. foreach ($items as $item) if ($item['goods_code'] === $vo['code']) $vo['items'][] = $item;
  125. if ($simple) unset($vo['marks'], $vo['sort'], $vo['status'], $vo['deleted'], $vo['data_items'], $vo['data_specs'], $vo['cateinfo']['parent']);
  126. }
  127. return $data;
  128. }
  129. }