GoodsService.php 5.8 KB

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