Item.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <?php
  2. /*
  3. * FecShop file.
  4. *
  5. * @link http://www.fecshop.com/
  6. * @copyright Copyright (c) 2016 FecShop Software LLC
  7. * @license http://www.fecshop.com/license/
  8. */
  9. namespace fecshop\services\order;
  10. //use fecshop\models\mysqldb\order\Item as MyOrderItem;
  11. use fecshop\services\Service;
  12. use Yii;
  13. /**
  14. * Cart items services.
  15. * @author Terry Zhao <2358269014@qq.com>
  16. * @since 1.0
  17. */
  18. class Item extends Service
  19. {
  20. protected $_itemModelName = '\fecshop\models\mysqldb\order\Item';
  21. protected $_itemModel;
  22. public function init()
  23. {
  24. parent::init();
  25. list($this->_itemModelName, $this->_itemModel) = \Yii::mapGet($this->_itemModelName);
  26. }
  27. /**
  28. * @param $product_id | string , 产品的id
  29. * @param $customer_id | int, 用户的id
  30. * @param $month | int, 几个月内的订单
  31. * 通过product_id和customerId,得到$month个月内下单支付成功的产品
  32. */
  33. protected function actionGetByProductIdAndCustomerId($product_id, $month, $customer_id = 0)
  34. {
  35. if (!$customer_id) {
  36. if (Yii::$app->user->isGuest) {
  37. return false;
  38. } else {
  39. $customer_id = Yii::$app->user->identity->id;
  40. }
  41. }
  42. // 得到产品
  43. $time_gt = strtotime("-0 year -$month month -0 day");
  44. $orderStatusArr = Yii::$service->order->getOrderPaymentedStatusArr();
  45. $orders = Yii::$service->order->coll([
  46. 'select' => ['order_id'],
  47. 'where' => [
  48. ['customer_id' => $customer_id],
  49. ['>', 'created_at', $time_gt],
  50. ['in', 'order_status', $orderStatusArr]
  51. ],
  52. 'asArray' => true,
  53. 'numPerPage' => 500,
  54. ]);
  55. $order_ids = [];
  56. if (isset($orders['coll']) && !empty($orders['coll'])) {
  57. foreach ($orders['coll'] as $order) {
  58. $order_ids[] = $order['order_id'];
  59. }
  60. }
  61. if (empty($order_ids)) {
  62. return false;
  63. }
  64. $items = $this->_itemModel->find()->asArray()->where([
  65. 'product_id' => $product_id,
  66. ])->andWhere([
  67. 'in', 'order_id', $order_ids
  68. ])
  69. ->all();
  70. if (!empty($items)) {
  71. return $items;
  72. } else {
  73. return false;
  74. }
  75. }
  76. /**
  77. * @param $order_id | Int
  78. * @param $onlyFromTable | 从数据库取出不做处理
  79. * @return array
  80. * 通过order_id 得到所有的items
  81. */
  82. protected function actionGetByOrderId($order_id, $onlyFromTable = false)
  83. {
  84. $items = $this->_itemModel->find()->asArray()->where([
  85. 'order_id' => $order_id,
  86. ])->all();
  87. if ($onlyFromTable) {
  88. return $items;
  89. }
  90. foreach ($items as $k=>$one) {
  91. $product_id = $one['product_id'];
  92. $product_one = Yii::$service->product->getByPrimaryKey($product_id);
  93. $productSpuOptions = $this->getProductSpuOptions($product_one);
  94. //var_dump($productSpuOptions);
  95. $items[$k]['spu_options'] = $productSpuOptions;
  96. $items[$k]['custom_option'] = $product_one['custom_option'];
  97. $items[$k]['custom_option_info'] = $this->getProductOptions($items[$k]);
  98. $items[$k]['image'] = $this->getProductImage($product_one, $one);
  99. }
  100. return $items;
  101. }
  102. /**
  103. * @param $order_ids | array
  104. * @param $onlyFromTable | 从数据库取出不做处理
  105. * @return array
  106. * 通过order_id 得到所有的items
  107. */
  108. protected function actionGetByOrderIds($order_ids, $onlyFromTable = false)
  109. {
  110. $items = $this->_itemModel->find()->asArray()->where([
  111. 'in', 'order_id', $order_ids,
  112. ])->all();
  113. if ($onlyFromTable) {
  114. return $items;
  115. }
  116. foreach ($items as $k=>$one) {
  117. $product_id = $one['product_id'];
  118. $product_one = Yii::$service->product->getByPrimaryKey($product_id);
  119. $productSpuOptions = $this->getProductSpuOptions($product_one);
  120. //var_dump($productSpuOptions);
  121. $items[$k]['spu_options'] = $productSpuOptions;
  122. $items[$k]['custom_option'] = $product_one['custom_option'];
  123. $items[$k]['custom_option_info'] = $this->getProductOptions($items[$k]);
  124. $items[$k]['image'] = $this->getProductImage($product_one, $one);
  125. }
  126. return $items;
  127. }
  128. /**
  129. * @param $product_one | Object, product model
  130. * @param $item_one | Array , order item ,是订单产品表取出来的数据
  131. * 得到产品的图片。如果存在custom option image,则返回custom option image,如果不存在,则返回产品的主图
  132. */
  133. public function getProductImage($product_one, $item_one)
  134. {
  135. $custom_option = $product_one['custom_option'];
  136. $custom_option_sku = $item_one['custom_option_sku'];
  137. $image = '';
  138. // 设置图片
  139. if (isset($product_one['image']['main']['image'])) {
  140. $image = $product_one['image']['main']['image'];
  141. }
  142. $custom_option_image = isset($custom_option[$custom_option_sku]['image']) ? $custom_option[$custom_option_sku]['image'] : '';
  143. if ($custom_option_image) {
  144. $image = $custom_option_image;
  145. }
  146. if (!$image) {
  147. $image = $item_one['image'];
  148. }
  149. return $image;
  150. }
  151. /**
  152. * @param $item_one | Array , order item
  153. * 通过$item_one 的$item_one['custom_option_sku'],$item_one['custom_option'] , $item_one['spu_options']
  154. * 将spu的选择属性和自定义属性custom_option 组合起来,返回一个统一的数组
  155. */
  156. public function getProductOptions($item_one)
  157. {
  158. $custom_option_sku = $item_one['custom_option_sku'];
  159. $custom_option_info_arr = [];
  160. $custom_option = isset($item_one['custom_option']) ? $item_one['custom_option'] : '';
  161. if (isset($custom_option[$custom_option_sku]) && !empty($custom_option[$custom_option_sku])) {
  162. $custom_option_info = $custom_option[$custom_option_sku];
  163. foreach ($custom_option_info as $attr=>$val) {
  164. if (!in_array($attr, ['qty', 'sku', 'price', 'image'])) {
  165. $attr = str_replace('_', ' ', $attr);
  166. $attr = ucfirst($attr);
  167. $custom_option_info_arr[$attr] = $val;
  168. }
  169. }
  170. }
  171. $spu_options = isset($item_one['spu_options']) ? $item_one['spu_options'] : '';
  172. if (is_array($spu_options) && !empty($spu_options)) {
  173. foreach ($spu_options as $label => $val) {
  174. $custom_option_info_arr[$label] = $val;
  175. }
  176. }
  177. return $custom_option_info_arr;
  178. }
  179. /**
  180. * @param $productOb | Object,类型:\fecshop\models\mongodb\Product
  181. * 得到产品的spu对应的属性以及值。
  182. * 概念 - spu options:当多个产品是同一个spu,但是不同的sku的时候,他们的产品表里面的
  183. * spu attr 的值是不同的,譬如对应鞋子,size 和 color 就是spu attr,对于同一款鞋子,他们
  184. * 是同一个spu,对于尺码,颜色不同的鞋子,是不同的sku,他们的spu attr 就是 color 和 size。
  185. */
  186. protected function getProductSpuOptions($productOb)
  187. {
  188. $custom_option_info_arr = [];
  189. if (isset($productOb['attr_group']) && !empty($productOb['attr_group'])) {
  190. $productAttrGroup = $productOb['attr_group'];
  191. Yii::$service->product->addGroupAttrs($productAttrGroup);
  192. $productOb = Yii::$service->product->getByPrimaryKey((string) $productOb['_id']);
  193. $spuArr = Yii::$service->product->getSpuAttr($productAttrGroup);
  194. if (is_array($spuArr) && !empty($spuArr)) {
  195. foreach ($spuArr as $spu_attr) {
  196. if (isset($productOb[$spu_attr]) && !empty($productOb[$spu_attr])) {
  197. $custom_option_info_arr[$spu_attr] = $productOb[$spu_attr];
  198. }
  199. }
  200. }
  201. }
  202. return $custom_option_info_arr;
  203. }
  204. /**
  205. * @param $items | Array , example:
  206. * $itmes = [
  207. * [
  208. * 'item_id' => $one['item_id'],
  209. * 'product_id' => $product_id ,
  210. * 'sku' => $product_one['sku'],
  211. * 'name' => Yii::$service->store->getStoreAttrVal($product_one['name'],'name'),
  212. * 'qty' => $qty ,
  213. * 'custom_option_sku' => $custom_option_sku ,
  214. * 'product_price' => $product_price ,
  215. * 'product_row_price' => $product_row_price ,
  216. *
  217. * 'base_product_price' => $base_product_price ,
  218. * 'base_product_row_price' => $base_product_row_price ,
  219. *
  220. * 'product_name' => $product_one['name'],
  221. * 'product_weight' => $p_wt,
  222. * 'product_row_weight'=> $p_wt * $qty,
  223. * 'product_url' => $product_one['url_key'],
  224. * 'product_image' => $product_one['image'],
  225. * 'custom_option' => $product_one['custom_option'],
  226. * 'spu_options' => $productSpuOptions,
  227. * ]
  228. * ];
  229. * @param $order_id | Int
  230. * 保存订单的item信息
  231. */
  232. protected function actionSaveOrderItems($items, $order_id, $store)
  233. {
  234. /**
  235. * 由于是通过session查订单的方式,而不是新建,paypal报错可能多次下单(更新方式),
  236. * 因此在添加订单产品的时候先进行一次删除产品操作。
  237. */
  238. $this->_itemModel->deleteAll(['order_id' => $order_id]);
  239. if (is_array($items) && !empty($items) && $order_id && $store) {
  240. foreach ($items as $item) {
  241. $myOrderItem = new $this->_itemModelName();
  242. $myOrderItem['order_id'] = $order_id;
  243. $myOrderItem['store'] = $store;
  244. $myOrderItem['created_at'] = time();
  245. $myOrderItem['updated_at'] = time();
  246. $myOrderItem['product_id'] = $item['product_id'];
  247. $myOrderItem['sku'] = $item['sku'];
  248. $myOrderItem['name'] = $item['name'];
  249. $myOrderItem['custom_option_sku'] = $item['custom_option_sku'];
  250. $myOrderItem['image'] = isset($item['product_image']['main']['image']) ? $item['product_image']['main']['image'] : '';
  251. $myOrderItem['weight'] = $item['product_weight'];
  252. $myOrderItem['qty'] = $item['qty'];
  253. $myOrderItem['row_weight'] = $item['product_row_weight'];
  254. $myOrderItem['price'] = $item['product_price'];
  255. $myOrderItem['base_price'] = $item['base_product_price'];
  256. $myOrderItem['row_total'] = $item['product_row_price'];
  257. $myOrderItem['base_row_total'] = $item['base_product_row_price'];
  258. $myOrderItem['redirect_url'] = $item['product_url'];
  259. if (!$myOrderItem->validate()) {
  260. $errors = $myOrderItem->errors;
  261. Yii::$service->helper->errors->addByModelErrors($errors);
  262. return false;
  263. }
  264. $saveStatus = $myOrderItem->save();
  265. // 如果保存失败,直接返回。
  266. if (!$saveStatus) {
  267. return $saveStatus;
  268. }
  269. }
  270. }
  271. return true;
  272. }
  273. /**
  274. * @param $filter|array
  275. * @return Array;
  276. * 通过过滤条件,得到coupon的集合。
  277. * example filter:
  278. * [
  279. * 'numPerPage' => 20,
  280. * 'pageNum' => 1,
  281. * 'orderBy' => ['_id' => SORT_DESC, 'sku' => SORT_ASC ],
  282. * 'where' => [
  283. * ['>','price',1],
  284. * ['<=','price',10]
  285. * ['sku' => 'uk10001'],
  286. * ],
  287. * 'asArray' => true,
  288. * ]
  289. * 根据$filter 搜索参数数组,返回满足条件的订单数据。
  290. */
  291. protected function actionColl($filter = '')
  292. {
  293. $query = $this->_itemModel->find();
  294. $query = Yii::$service->helper->ar->getCollByFilter($query, $filter);
  295. $coll = $query->all();
  296. return [
  297. 'coll' => $coll,
  298. 'count'=> $query->limit(null)->offset(null)->count(),
  299. ];
  300. }
  301. }