Item.php 15 KB

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