You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

577 lines
20 KiB

  1. <?php
  2. namespace antgoods\logic\goods;
  3. use common\models\ars\File;
  4. use Yii;
  5. use yii\base\Exception;
  6. use antgoods\models\ars\GoodsAttr;
  7. use antgoods\models\ars\Attribute;
  8. use antgoods\models\ars\GoodsSku;
  9. use antgoods\models\ars\Goods;
  10. use antgoods\models\ars\FilterAttr;
  11. use antgoods\models\ars\Category;
  12. class GoodsManager
  13. {
  14. /**
  15. * @param $newFileIdArr
  16. * @param $goodsModel
  17. * @param array $oldFileIdArr
  18. * @param int $fileType
  19. * @return array
  20. * 保存新文件,删除不需要的文件操作
  21. */
  22. public static function saveFile($newFileIdArr, $goodsModel, $oldFileIdArr = [], $fileType = 1)
  23. {
  24. //判断类名是否存在
  25. if(!class_exists('\backend\logic\file\FileManager') || !class_exists('\common\models\ars\File')) {
  26. return ['status' => false, 'info' => '操作失败'];
  27. }
  28. //需要新建的文件id
  29. $createFileIdArr = array_diff($newFileIdArr, $oldFileIdArr);
  30. //创建文件
  31. $class = new \backend\logic\file\FileManager();
  32. $createFileRes = $class->saveTemFileToFile($createFileIdArr, $goodsModel->id, $fileType);
  33. //需要删除的文件id
  34. $delFileIdArr = array_diff($oldFileIdArr, $newFileIdArr);
  35. //删除文件
  36. $class->deleteFile($delFileIdArr);
  37. //记录第一张图片id
  38. $firstFileId = 0;
  39. //查看修改数组是否为空
  40. if (!$newFileIdArr[0]) {
  41. $firstFileId = null;
  42. }else {
  43. if ($createFileRes['status']) {
  44. $firstFileId = $createFileRes['first_file_id'];
  45. }
  46. }
  47. return ['status' => true, 'info' => '操作成功', 'first_file_id' => $firstFileId];
  48. }
  49. /**
  50. * @param $data
  51. * @param $model
  52. * @param null $coverImageOldIdStr
  53. * @param null $detailImageOldIdStr
  54. * @return array
  55. * @throws \Throwable
  56. * 创建修改商品操作
  57. */
  58. public static function updateGoods($data, $model, $coverImageOldIdStr = null, $detailImageOldIdStr = null)
  59. {
  60. $attribute = $data['attribute'];
  61. $filterAttribute = $data['filterattribute'];
  62. $tra = Yii::$app->db->beginTransaction();
  63. try {
  64. if (!$model->save()) {
  65. throw new Exception('');
  66. }
  67. $saveCoverImageRes = self::saveFile(explode(',', $model->coverImageId), $model, explode(',', $coverImageOldIdStr));
  68. $saveDetailImageRes = self::saveFile(explode(',', $model->detailImageId), $model, explode(',', $detailImageOldIdStr), File::OWN_TYPE_GOODS_DETAILS);
  69. if ($saveCoverImageRes['status'] && $saveDetailImageRes['status']) {
  70. if($saveCoverImageRes['first_file_id'] !== 0) {
  71. $model->image = $saveCoverImageRes['first_file_id'];
  72. if (!$model->save()) {
  73. throw new Exception('图片保存失败');
  74. }
  75. }
  76. } else {
  77. throw new Exception('图片保存失败');
  78. }
  79. self::addAttributeOperating(['id' => $model->id, 'attribute' => $attribute]);
  80. self::addFilterAttributeOperating(['id' => $model->id, 'filterAttribute' => $filterAttribute]);
  81. $tra->commit();
  82. return ['status' => true];
  83. } catch (\yii\base\Exception $e) {
  84. $tra->rollBack();
  85. return ['status' => false, 'info' => $e->getMessage()];
  86. }
  87. }
  88. /**
  89. * @param $data
  90. * @return bool
  91. * @throws Exception
  92. * 创建修改商品属性操作
  93. */
  94. public static function addAttributeOperating($data)
  95. {
  96. if (!$data['attribute']) {
  97. return true;
  98. }
  99. $data['attribute'] = json_decode($data['attribute'], true);
  100. $oldAttr = [];
  101. $goodsAttr = GoodsAttr::find()->where(['goods_id' => $data['id'], 'is_delete' => GoodsAttr::IS_DELETE_NO])->all();
  102. if ($goodsAttr) { //如果商品有旧的属性
  103. if(count($data['attribute']) == 0 && is_array($data['attribute'])) { //如果传上来的是空数组,删除该商品下的全部属性
  104. self::delAttribute($goodsAttr);
  105. return true;
  106. }
  107. foreach ($goodsAttr as $key => $value) { //把旧的商品属性保存到一个数组
  108. $oldAttr[$value->id] = $value->attr_value;
  109. }
  110. }
  111. $newAttr = self::addAttribute($data['attribute'], $data['id']); //添加新的商品属性
  112. $delAttr = array_diff(array_keys($oldAttr), array_keys($newAttr)); //找出需要删除的goodsAttrId
  113. if (!$delAttr) {
  114. return true;
  115. }
  116. foreach ($delAttr as $value) {
  117. $model = GoodsAttr::find()->where(['id' => $value, 'is_delete' => GoodsAttr::IS_DELETE_NO])->One();
  118. if ($model) {
  119. $model->is_delete = GoodsAttr::IS_DELETE_YES;
  120. if (!$model->save()) {
  121. throw new Exception('goodsAttribute delete false');
  122. }
  123. }
  124. }
  125. }
  126. /**
  127. * @param $goodsAttr
  128. * @throws Exception
  129. * 删除商品属性
  130. */
  131. public static function delAttribute($goodsAttr)
  132. {
  133. foreach ($goodsAttr as $key => $value) {
  134. $value->is_delete = GoodsAttr::IS_DELETE_YES;
  135. if (!$value->save()) {
  136. throw new Exception('goods attribute delete false');
  137. }
  138. }
  139. }
  140. /**
  141. * @param $attribute
  142. * @param $goodsId
  143. * @return array
  144. * @throws Exception
  145. * 保存商品属性
  146. */
  147. public static function addAttribute($attribute, $goodsId)
  148. {
  149. $newAttr = [];
  150. if (!$attribute) {
  151. return [];
  152. }
  153. foreach ($attribute as $value) {
  154. foreach ($value['value'] as $k => $v) {
  155. $goodsAttrModel = new GoodsAttr();
  156. $goodsAttrModel->attr_id = $value['id'];
  157. $attr = GoodsAttr::find()->where(['goods_id' => $goodsId, 'attr_id' => $value['id'], 'attr_value' => $v, 'is_delete' => GoodsAttr::IS_DELETE_NO])->one();
  158. if ($attr) {
  159. $newAttr[$attr->id] = $attr->attr_value; //原有的数据
  160. } else {
  161. $goodsAttrModel->goods_id = $goodsId;
  162. $goodsAttrModel->attr_value = $v;
  163. if (!$goodsAttrModel->save()) {
  164. throw new Exception('goodsAttribute save false');
  165. }
  166. $newAttr[$goodsAttrModel->id] = $goodsAttrModel->attr_value; //新增的数据
  167. }
  168. }
  169. }
  170. return $newAttr;
  171. }
  172. /**
  173. * @param $id
  174. * @return Attribute|array|null
  175. * 获取属性信息
  176. */
  177. public static function getAttribute($id)
  178. {
  179. $goodsAttributes = GoodsAttr::find()->where(['goods_id' => $id, 'is_delete' => GoodsAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->all();
  180. $filter = [];
  181. $goodsAttributeModel = [];
  182. if (!$goodsAttributes) {
  183. return $goodsAttributeModel;
  184. }
  185. foreach ($goodsAttributes as $key => $value) {
  186. $attribute = Attribute::findOne($value->attr_id);
  187. if (!in_array($attribute->name, $filter)) {
  188. $filter[] = $attribute->name;
  189. $attribute = ['name' => $attribute->name, 'id' => $attribute->id, 'value' => [$value->attr_value]];
  190. $goodsAttributeModel[] = $attribute;
  191. } else {
  192. foreach ($goodsAttributeModel as $k => $v) {
  193. if ($v['name'] == $attribute->name) {
  194. $goodsAttributeModel[$k]['value'][] = $value->attr_value;
  195. }
  196. }
  197. }
  198. }
  199. return $goodsAttributeModel;
  200. }
  201. /**
  202. * @param $id
  203. * @return array
  204. * 获取sku信息
  205. */
  206. public static function getSkuInfo($id)
  207. {
  208. $skus = GoodsSku::find()->where(['goods_id' => $id, 'is_delete' => GoodsSku::IS_DELETE_NO])->all();
  209. $attrId = [];
  210. foreach ($skus as $sku) {
  211. $attrId = array_merge(explode(',', $sku->goods_attr), $attrId);
  212. }
  213. $attrs = GoodsAttr::find()->where(['id' => $attrId, 'is_delete' => GoodsAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->all();
  214. $checkAttr = [];
  215. $filterAttr = [];
  216. foreach ($attrs as $value) {
  217. $attr = Attribute::findOne(['id' => $value->attr_id, 'is_delete' => Attribute::IS_DELETE_NO]);
  218. if (!in_array($attr->name, $filterAttr)) {
  219. $filterAttr[] = $attr->name;
  220. $newAttr = ['id' => $attr->id, 'name' => $attr->name, 'value' => [$value->attr_value]];
  221. $checkAttr[] = $newAttr;
  222. } else {
  223. foreach ($checkAttr as $key => $item) {
  224. if ($item['name'] == $attr->name) { //如果attr_id与$filter的attr_id相符,入栈
  225. $checkAttr[$key]['value'][] = $value->attr_value;
  226. }
  227. }
  228. }
  229. }
  230. return $checkAttr;
  231. }
  232. /**
  233. * @param $id
  234. * @return mixed
  235. * 已创建sku信息
  236. */
  237. public static function getCreatedSku($id, $type = 0)
  238. {
  239. $goods = Goods::findOne($id);
  240. $data['type'] = $type ?: $goods->sku_mode;
  241. $data['data'] = [];
  242. if ($data['type'] == Goods::SKU_MODE_ATTR) {
  243. $sku = GoodsSku::find()
  244. ->where(['goods_id' => $id, 'is_manaul' => 0])
  245. ->all();
  246. } else {
  247. $sku = GoodsSku::find()
  248. ->where(['goods_id' => $id, 'is_manaul' => 1])
  249. ->all();
  250. }
  251. foreach ($sku as $value) {
  252. $data['data'][] = self::getAttrInfo($data['type'], $value);
  253. }
  254. return $data;
  255. }
  256. /**
  257. * @param $type
  258. * @param $sku
  259. * @return array
  260. * 获取商品详情
  261. */
  262. public static function getAttrInfo($type, $sku)
  263. {
  264. $data = [];
  265. if ($type == Goods::SKU_MODE_ATTR) {
  266. $data['value'] = array_filter(explode(',', $sku->goods_attr));
  267. } else {
  268. $attr = explode(',', $sku->goods_attr);
  269. $goodsAttr = GoodsAttr::findOne($attr[0]);
  270. $data['value'] = $goodsAttr->attr_value;
  271. }
  272. $data['id'] = $sku->id;
  273. $data['price'] = $sku->price;
  274. $data['stock'] = $sku->stock;
  275. $data['weight'] = $sku->weight;
  276. return $data;
  277. }
  278. /**
  279. * @param $id
  280. * @return array
  281. * 获取商品属性
  282. */
  283. public static function getAttrs($id)
  284. {
  285. $attrId = GoodsAttr::find()->where(['goods_id' => $id, 'is_delete' => GoodsAttr::IS_DELETE_NO])
  286. ->andWhere(['>', 'attr_id', 0])
  287. ->select('attr_id')
  288. ->distinct()
  289. ->all();
  290. $attributes = [];
  291. foreach ($attrId as $v) {
  292. $attribute = Attribute::findOne($v);
  293. if ($attribute && $attribute->type == Attribute::TYPE_ATTR) {
  294. $ret['name'] = $attribute->name;
  295. $ret['id'] = $attribute->id;
  296. $ret['attrValue'] = self::getAttrValue($attribute->id, $id);
  297. $attributes[] = $ret;
  298. }
  299. }
  300. return $attributes;
  301. }
  302. /**
  303. * @param $attrId
  304. * @param $goodsId
  305. * @return GoodsAttr[]|GoodsSku[]|array|File[]|\common\models\ars\TemFile[]|\yii\db\ActiveRecord[]
  306. * 获取属性值
  307. */
  308. public static function getAttrValue($attrId, $goodsId)
  309. {
  310. return GoodsAttr::find()
  311. ->select(['id', 'attr_value'])
  312. ->where(['goods_id' => $goodsId])
  313. ->andWhere(['attr_id' => $attrId])
  314. ->asArray()
  315. ->all();
  316. }
  317. /**
  318. * @param $type
  319. * @param $goodsId
  320. * @return array
  321. * 获取已存储的商品sku的id
  322. */
  323. public static function getOriginalIds($type, $goodsId)
  324. {
  325. $ids = [];
  326. if ($type == Goods::SKU_MODE_MANUAL) {
  327. $query = GoodsSku::find()
  328. ->where(['is_manaul' => 1]);
  329. } else {
  330. $query = GoodsSku::find()
  331. ->where(['is_manaul' => 0]);
  332. }
  333. $sku = $query
  334. ->andWhere(['goods_id' => $goodsId])
  335. ->all();
  336. foreach ($sku as $value) {
  337. $ids[] = $value->id;
  338. }
  339. return $ids;
  340. }
  341. /**
  342. * @param $sku
  343. * @throws \yii\db\Exception
  344. * 添加或更新sku数据
  345. */
  346. public static function AddOrUpdateData($sku, $type, $goodsId)
  347. {
  348. $goodsModel = Goods::findOne($goodsId);
  349. if ($sku['id'] > 0) {
  350. $goodsSku = GoodsSku::findOne($sku['id']);
  351. $attrId = array_filter(explode(',', $goodsSku->goods_attr));
  352. $attr = GoodsAttr::findOne($attrId[0]);
  353. } else {
  354. $goodsSku = new GoodsSku();
  355. $attr = new GoodsAttr();
  356. }
  357. if (!$attr || !$goodsSku || !$goodsModel) {
  358. throw new \yii\db\Exception('系统异常');
  359. }
  360. if ($type == Goods::SKU_MODE_MANUAL) {
  361. $attr->attr_value = $sku['value'];
  362. if (!$attr->save()) {
  363. throw new \yii\db\Exception('手动属性修改失败');
  364. }
  365. $goodsSku->goods_attr = (string)$attr->id;
  366. $goodsSku->is_manaul = 1;
  367. } else {
  368. $goodsSku->goods_attr = implode(',', array_filter($sku['value']));
  369. }
  370. $goodsSku->goods_id = $goodsId;
  371. $goodsSku->price = $sku['price'];
  372. $goodsSku->stock = $sku['stock'];
  373. $goodsSku->weight = $sku['weight'];
  374. $goodsSku->goods_sn = $goodsModel->sn;
  375. if (!$goodsSku->save()) {
  376. throw new \yii\db\Exception('保存失败,请检查是否有重复规格');
  377. }
  378. $goods = Goods::findOne($goodsId);
  379. $goods->sku_mode = $type;
  380. if (!$goods->save()) {
  381. throw new \yii\db\Exception('商品sku类型修改失败');
  382. }
  383. }
  384. /**
  385. * @param $type
  386. * @param $data
  387. * @param $goodsId
  388. * @return bool
  389. * @throws \Throwable
  390. * @throws \yii\db\StaleObjectException
  391. * 删除sku
  392. */
  393. public static function deleteSku($type, $data, $goodsId)
  394. {
  395. if (!$data['originalIds']) {
  396. return true;
  397. }
  398. if ($type == Goods::SKU_MODE_MANUAL) {
  399. $query = GoodsSku::find()
  400. ->where(['is_manaul' => 1]);
  401. } else {
  402. $query = GoodsSku::find()
  403. ->where(['is_manaul' => 0]);
  404. }
  405. $sku = $query
  406. ->andWhere(['goods_id' => $goodsId])
  407. ->andWhere(['in', 'id', $data['originalIds']])
  408. ->andWhere(['not in', 'id', $data['acceptIds']])
  409. ->all();
  410. foreach ($sku as $value) {
  411. $value->delete();
  412. }
  413. }
  414. /**
  415. * @param $data
  416. * @return bool
  417. * @throws Exception
  418. * 创建修改商品筛选属性操作
  419. */
  420. public static function addFilterAttributeOperating($data)
  421. {
  422. if (!$data['filterAttribute']) {
  423. return true;
  424. }
  425. $data['filterAttribute'] = json_decode($data['filterAttribute'], true);
  426. $oldFilterAttr = [];
  427. $goodsFilterAttr = FilterAttr::find()->where(['goods_id' => $data['id'], 'is_delete' => FilterAttr::IS_DELETE_NO])->all();
  428. if ($goodsFilterAttr) { //如果商品有旧的属性
  429. if(count($data['filterAttribute']) == 0 && is_array($data['filterAttribute'])) { //如果传上来的是空数组,删除该商品下的全部属性
  430. self::delFilterAttribute($goodsFilterAttr);
  431. return true;
  432. }
  433. foreach ($goodsFilterAttr as $key => $value) { //把旧的商品属性保存到一个数组
  434. $oldFilterAttr[$value->id] = $value->attr_value;
  435. }
  436. }
  437. $newAttr = self::addFilterAttribute($data['filterAttribute'], $data['id']); //添加新的商品属性
  438. $delAttr = array_diff(array_keys($oldFilterAttr), array_keys($newAttr)); //找出需要删除的goodsAttrId
  439. if (!$delAttr) {
  440. return true;
  441. }
  442. foreach ($delAttr as $value) {
  443. $model = FilterAttr::find()->where(['id' => $value, 'is_delete' => FilterAttr::IS_DELETE_NO])->One();
  444. if ($model) {
  445. $model->is_delete = FilterAttr::IS_DELETE_YES;
  446. if (!$model->save()) {
  447. throw new Exception('goodsAttribute delete false');
  448. }
  449. }
  450. }
  451. }
  452. /**
  453. * @param $goodsFilterAttr
  454. * @throws Exception
  455. * 删除商品筛选属性
  456. */
  457. public static function delFilterAttribute($goodsFilterAttr)
  458. {
  459. foreach ($goodsFilterAttr as $key => $value) {
  460. $value->is_delete = FilterAttr::IS_DELETE_YES;
  461. if (!$value->save()) {
  462. throw new Exception('goods attribute delete false');
  463. }
  464. }
  465. }
  466. /**
  467. * @param $attribute
  468. * @param $goodsId
  469. * @return array
  470. * @throws Exception
  471. * 保存商品筛选属性
  472. */
  473. public static function addFilterAttribute($attribute, $goodsId)
  474. {
  475. $newAttr = [];
  476. if (!$attribute) {
  477. return [];
  478. }
  479. foreach ($attribute as $value) {
  480. foreach ($value['value'] as $k => $v) {
  481. $goodsFilterAttrModel = new FilterAttr();
  482. $goodsFilterAttrModel->attr_id = $value['id'];
  483. $attr = FilterAttr::find()->where(['goods_id' => $goodsId, 'attr_id' => $value['id'], 'attr_value' => $v, 'is_delete' => FilterAttr::IS_DELETE_NO])->one();
  484. if ($attr) {
  485. $newAttr[$attr->id] = $attr->attr_value; //原有的数据
  486. } else {
  487. $goodsFilterAttrModel->goods_id = $goodsId;
  488. $goodsFilterAttrModel->attr_value = $v;
  489. if (!$goodsFilterAttrModel->save()) {
  490. throw new Exception('goodsAttribute save false');
  491. }
  492. $newAttr[$goodsFilterAttrModel->id] = $goodsFilterAttrModel->attr_value; //新增的数据
  493. }
  494. }
  495. }
  496. return $newAttr;
  497. }
  498. /**
  499. * @param $id
  500. * @return Attribute|array|null
  501. * 获取筛选属性信息
  502. */
  503. public static function getFilterAttribute($id)
  504. {
  505. $goodsFilterAttributes = FilterAttr::find()->where(['goods_id' => $id, 'is_delete' => FilterAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->all();
  506. $filter = [];
  507. $goodsFilterAttributeModel = [];
  508. if (!$goodsFilterAttributes) {
  509. return $goodsFilterAttributeModel;
  510. }
  511. foreach ($goodsFilterAttributes as $key => $value) {
  512. $attribute = Attribute::findOne($value->attr_id);
  513. if (!in_array($attribute->name, $filter)) {
  514. $filter[] = $attribute->name;
  515. $attribute = ['name' => $attribute->name, 'id' => $attribute->id, 'value' => [$value->attr_value]];
  516. $goodsFilterAttributeModel[] = $attribute;
  517. } else {
  518. foreach ($goodsFilterAttributeModel as $k => $v) {
  519. if ($v['name'] == $attribute->name) {
  520. $goodsFilterAttributeModel[$k]['value'][] = $value->attr_value;
  521. }
  522. }
  523. }
  524. }
  525. return $goodsFilterAttributeModel;
  526. }
  527. /**
  528. * @param $goodsModel
  529. * @return bool
  530. *
  531. */
  532. public static function judgeGoodsCategory($goodsModel)
  533. {
  534. $skus = GoodsSku::find()->where(['goods_id' => $goodsModel->id, 'is_delete' => GoodsSku::IS_DELETE_NO])->all();
  535. $attrId = [];
  536. foreach ($skus as $sku) {
  537. $attrId = array_merge(explode(',', $sku->goods_attr), $attrId);
  538. }
  539. $goodsAttr = array_unique(GoodsAttr::find()->select(['attr_id'])->where(['id' => $attrId, 'is_delete' => GoodsAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->column());
  540. $attrArr = array_unique(Attribute::find()->select(['cat_id'])->where(['is_delete' => Attribute::IS_DELETE_NO, 'id' => $goodsAttr])->column());
  541. if (in_array($goodsModel->cat_id, $attrArr)) {
  542. return true; //存在,则返回true,表示后台分类不得修改
  543. }
  544. return false; //否则返回false,表示后台分类可以修改
  545. }
  546. public static function categoryBtreeList()
  547. {
  548. }
  549. }