StoreProduct.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\controller\supplier\product;
  12. use app\jobs\BatchHandleJob;
  13. use app\services\other\queue\QueueServices;
  14. use app\services\product\branch\StoreBranchProductAttrValueServices;
  15. use app\services\product\branch\StoreBranchProductServices;
  16. use app\services\product\category\StoreProductCategoryServices;
  17. use app\services\product\product\StoreProductBatchProcessServices;
  18. use app\services\product\product\StoreProductServices;
  19. use app\services\product\sku\StoreProductAttrServices;
  20. use app\services\product\sku\StoreProductAttrValueServices;
  21. use app\services\user\label\UserLabelCateServices;
  22. use app\services\user\label\UserLabelServices;
  23. use crmeb\services\UploadService;
  24. use think\facade\App;
  25. use app\controller\supplier\AuthController;
  26. /**
  27. * Class StoreProduct
  28. * @package app\controller\supplier\product
  29. */
  30. class StoreProduct extends AuthController
  31. {
  32. protected $services;
  33. protected $branchServices;
  34. /**
  35. * @param App $app
  36. * @param StoreProductServices $service
  37. * @param StoreBranchProductServices $branchServices
  38. */
  39. public function __construct(App $app, StoreProductServices $service, StoreBranchProductServices $branchServices)
  40. {
  41. parent::__construct($app);
  42. $this->services = $service;
  43. $this->branchServices = $branchServices;
  44. }
  45. /**
  46. * 显示资源列表头部
  47. * @return mixed
  48. */
  49. public function type_header(StoreProductCategoryServices $storeProductCategoryServices)
  50. {
  51. $where = $this->request->getMore([
  52. ['store_name', ''],
  53. ['cate_id', ''],
  54. ['type', 1, '', 'status'],
  55. ['show_type', ''],
  56. ['sales', 'normal'],
  57. ['pid', ''],
  58. ['data', '', '', 'time'],
  59. ['store_label_id', ''],
  60. ['brand_id', '']
  61. ]);
  62. $cateId = $where['cate_id'];
  63. if ($cateId) {
  64. $cateId = is_string($cateId) ? [$cateId] : $cateId;
  65. $cateId = array_merge($cateId, $storeProductCategoryServices->getColumn(['pid' => $cateId], 'id'));
  66. $cateId = array_unique(array_diff($cateId, [0]));
  67. }
  68. $where['cate_id'] = $cateId;
  69. $where['supplier_id'] = $this->supplierId;
  70. $list = $this->services->getHeader(0, $where);
  71. return app('json')->success(compact('list'));
  72. }
  73. /**
  74. * 显示资源列表
  75. * @return mixed
  76. */
  77. public function index(StoreProductCategoryServices $storeProductCategoryServices)
  78. {
  79. $where = $this->request->getMore([
  80. ['store_name', ''],
  81. ['cate_id', ''],
  82. ['type', 1, '', 'status'],
  83. ['show_type', ''],
  84. ['sales', 'normal'],
  85. ['pid', ''],
  86. ['data', '', '', 'time'],
  87. ['store_label_id', ''],
  88. ['brand_id', '']
  89. ]);
  90. $cateId = $where['cate_id'];
  91. if ($cateId) {
  92. $cateId = is_string($cateId) ? [$cateId] : $cateId;
  93. $cateId = array_merge($cateId, $storeProductCategoryServices->getColumn(['pid' => $cateId], 'id'));
  94. $cateId = array_unique(array_diff($cateId, [0]));
  95. }
  96. $where['cate_id'] = $cateId;
  97. $where['relation_id'] = $this->supplierId;
  98. $where['type'] = 2;
  99. $data = $this->services->getList($where);
  100. return app('json')->success($data);
  101. }
  102. /**
  103. * 获取选择的商品列表
  104. * @return mixed
  105. */
  106. public function search_list()
  107. {
  108. $where = $this->request->getMore([
  109. ['cate_id', ''],
  110. ['store_name', ''],
  111. ['type', 1, '', 'status'],
  112. ['is_live', 0],
  113. ['is_new', ''],
  114. ['is_vip_product', ''],
  115. ['is_presale_product', ''],
  116. ['data', '', '', 'time'],
  117. ['store_label_id', ''],
  118. ['brand_id', '']
  119. ]);
  120. $where['is_show'] = 1;
  121. $where['is_del'] = 0;
  122. $where['type'] = 2;
  123. $where['relation_id'] = $this->supplierId;
  124. /** @var StoreProductCategoryServices $storeCategoryServices */
  125. $storeCategoryServices = app()->make(StoreProductCategoryServices::class);
  126. if ($where['cate_id'] !== '') {
  127. if ($storeCategoryServices->value(['id' => $where['cate_id']], 'pid')) {
  128. $where['sid'] = $where['cate_id'];
  129. } else {
  130. $where['cid'] = $where['cate_id'];
  131. }
  132. }
  133. unset($where['cate_id']);
  134. $list = $this->services->searchList($where);
  135. return $this->success($list);
  136. }
  137. /**
  138. * 获取分类cascader格式数据
  139. * @param $type
  140. * @return mixed
  141. * @throws \think\db\exception\DataNotFoundException
  142. * @throws \think\db\exception\DbException
  143. * @throws \think\db\exception\ModelNotFoundException
  144. */
  145. public function cascader_list(StoreProductCategoryServices $services)
  146. {
  147. return app('json')->success($services->cascaderList(2, (int)$this->supplierId));
  148. }
  149. /**
  150. * 获取商品详细信息
  151. * @param int $id
  152. * @throws \think\db\exception\DataNotFoundException
  153. * @throws \think\db\exception\DbException
  154. * @throws \think\db\exception\ModelNotFoundException
  155. */
  156. public function read($id = 0)
  157. {
  158. return app('json')->success($this->services->getInfo((int)$id));
  159. }
  160. /**
  161. * 保存新建或编辑
  162. * @param StoreProductAttrServices $attrServices
  163. * @param $id
  164. * @return mixed
  165. * @throws \think\db\exception\DataNotFoundException
  166. * @throws \think\db\exception\DbException
  167. * @throws \think\db\exception\ModelNotFoundException
  168. */
  169. public function save(StoreProductAttrServices $attrServices, $id)
  170. {
  171. $data = $this->request->postMore([
  172. ['product_type', 0],//商品类型
  173. ['supplier_id', 0],//供应商ID
  174. ['cate_id', []],
  175. ['store_name', ''],
  176. ['store_info', ''],
  177. ['keyword', ''],
  178. ['unit_name', '件'],
  179. ['recommend_image', ''],
  180. ['slider_image', []],
  181. ['is_sub', []],//佣金是单独还是默认
  182. ['sort', 0],
  183. // ['sales', 0],
  184. ['ficti', 100],
  185. ['give_integral', 0],
  186. ['is_show', 0],
  187. ['is_hot', 0],
  188. ['is_benefit', 0],
  189. ['is_best', 0],
  190. ['is_new', 0],
  191. ['mer_use', 0],
  192. ['is_postage', 0],
  193. ['is_good', 0],
  194. ['description', ''],
  195. ['spec_type', 0],
  196. ['video_open', 0],
  197. ['video_link', ''],
  198. ['items', []],
  199. ['attrs', []],
  200. ['recommend', []],//商品推荐
  201. ['activity', []],
  202. ['coupon_ids', []],
  203. ['label_id', []],
  204. ['command_word', ''],
  205. ['tao_words', ''],
  206. ['type', 0, '', 'is_copy'],
  207. ['delivery_type', []],//物流设置
  208. ['freight', 1],//运费设置
  209. ['postage', 0],//邮费
  210. ['temp_id', 0],//运费模版
  211. ['recommend_list', []],
  212. ['brand_id', []],
  213. ['soure_link', ''],
  214. ['bar_code', ''],
  215. ['code', ''],
  216. ['is_support_refund', 1],//是否支持退款
  217. ['is_presale_product', 0],//预售商品开关
  218. ['presale_time', []],//预售时间
  219. ['presale_day', 0],//预售发货日
  220. ['is_vip_product', 0],//是否付费会员商品
  221. ['auto_on_time', 0],//自动上架时间
  222. ['auto_off_time', 0],//自动下架时间
  223. ['custom_form', []],//自定义表单
  224. ['system_form_id', 0],//系统表单ID
  225. ['store_label_id', []],//商品标签
  226. ['ensure_id', []],//商品保障服务区
  227. ['specs', []],//商品参数
  228. ['specs_id', 0],//商品参数ID
  229. ['is_limit', 0],//是否限购
  230. ['limit_type', 0],//限购类型
  231. ['limit_num', 0]//限购数量
  232. ]);
  233. $data['is_verify'] = 0;
  234. //供应商商品不支持门店
  235. $data['delivery_type'] = [1];
  236. $this->services->save((int)$id, $data, 2, (int)$this->supplierId);
  237. $this->services->cacheTag()->clear();
  238. $attrServices->cacheTag()->clear();
  239. return $this->success($id ? '保存商品信息成功' : '添加商品成功!');
  240. }
  241. /**
  242. * 保存编辑
  243. * @param int $id
  244. * @param StoreBranchProductServices $services
  245. * @return mixed
  246. */
  247. public function update($id = 0, StoreBranchProductAttrValueServices $services)
  248. {
  249. $data = $this->request->postMore([
  250. ['attrs', []],
  251. ['label_id', []],
  252. ['is_show', 1]
  253. ]);
  254. $storeId = $this->storeId;
  255. $services->updataAll((int)$id, (array)$data, (int)$storeId);
  256. return app('json')->success('保存商品信息成功');
  257. }
  258. /**
  259. * 获取关联用户标签列表
  260. * @param UserLabelServices $service
  261. * @return mixed
  262. */
  263. public function getUserLabel(UserLabelCateServices $userLabelCateServices, UserLabelServices $service)
  264. {
  265. $cate = $userLabelCateServices->getLabelCateAll(2, (int)$this->supplierId);
  266. $data = [];
  267. $label = [];
  268. if ($cate) {
  269. foreach ($cate as $value) {
  270. $data[] = [
  271. 'id' => $value['id'] ?? 0,
  272. 'value' => $value['id'] ?? 0,
  273. 'label_cate' => 0,
  274. 'label_name' => $value['name'] ?? '',
  275. 'label' => $value['name'] ?? '',
  276. 'store_id' => $value['store_id'] ?? 0,
  277. 'type' => $value['type'] ?? 1,
  278. ];
  279. }
  280. $label = $service->getColumn(['type' => 2, 'relation_id' => $this->supplierId], '*');
  281. if ($label) {
  282. foreach ($label as &$item) {
  283. $item['label'] = $item['label_name'];
  284. $item['value'] = $item['id'];
  285. }
  286. }
  287. }
  288. return app('json')->success($service->get_tree_children($data, $label));
  289. }
  290. /**
  291. * 修改状态
  292. * @param string $is_show
  293. * @param string $id
  294. * @return mixed
  295. */
  296. public function set_show($is_show = '', $id = '', StoreBranchProductServices $services)
  297. {
  298. if (!$id) return $this->fail('缺少商品ID');
  299. $services->setShow($this->supplierId, $id, $is_show);
  300. return $this->success($is_show == 1 ? '上架成功' : '下架成功');
  301. }
  302. /**
  303. * 获取规格模板
  304. * @return mixed
  305. * @throws \think\db\exception\DataNotFoundException
  306. * @throws \think\db\exception\DbException
  307. * @throws \think\db\exception\ModelNotFoundException
  308. */
  309. public function get_rule()
  310. {
  311. return $this->success($this->services->getRule(2, (int)$this->supplierId));
  312. }
  313. /**
  314. * 获取商品详细信息
  315. * @param int $id
  316. * @throws \think\db\exception\DataNotFoundException
  317. * @throws \think\db\exception\DbException
  318. * @throws \think\db\exception\ModelNotFoundException
  319. */
  320. public function get_product_info($id = 0)
  321. {
  322. return $this->success($this->services->getInfo((int)$id));
  323. }
  324. /**
  325. * 获取运费模板列表
  326. * @return mixed
  327. */
  328. public function get_template()
  329. {
  330. return $this->success($this->services->getTemp(2, (int)$this->supplierId));
  331. }
  332. /**
  333. * 获取视频上传token
  334. * @return mixed
  335. * @throws \Exception
  336. */
  337. public function getTempKeys()
  338. {
  339. $upload = UploadService::init();
  340. $type = (int)sys_config('upload_type', 1);
  341. $key = $this->request->get('key', '');
  342. $path = $this->request->get('path', '');
  343. $contentType = $this->request->get('contentType', '');
  344. if ($type === 5) {
  345. if (!$key || !$contentType) {
  346. return app('json')->fail('缺少参数');
  347. }
  348. $re = $upload->getTempKeys($key, $path, $contentType);
  349. } else {
  350. $re = $upload->getTempKeys();
  351. }
  352. return $re ? $this->success($re) : $this->fail($upload->getError());
  353. }
  354. /**
  355. * 获取商品所有规格数据
  356. * @param StoreBranchProductAttrValueServices $services
  357. * @param $id
  358. * @return mixed
  359. */
  360. public function getAttrs(StoreBranchProductAttrValueServices $services, $id)
  361. {
  362. if (!$id) {
  363. return $this->fail('缺少商品ID');
  364. }
  365. return $this->success($services->getStoreProductAttr((int)$id));
  366. }
  367. /**
  368. * 删除指定资源
  369. *
  370. * @param int $id
  371. * @return \think\Response
  372. */
  373. public function delete($id)
  374. {
  375. //删除商品检测是否有参与活动
  376. $this->services->checkActivity($id);
  377. $res = $this->services->del($id);
  378. event('product.delete', [$id]);
  379. return $this->success($res);
  380. }
  381. /**
  382. * 生成规格列表
  383. * @param int $id
  384. * @param int $type
  385. * @return mixed
  386. */
  387. public function is_format_attr($id = 0, $type = 0)
  388. {
  389. $data = $this->request->postMore([
  390. ['attrs', []],
  391. ['items', []],
  392. ['product_type', 0]
  393. ]);
  394. if ($id > 0 && $type == 1) $this->services->checkActivity($id);
  395. $info = $this->services->getAttr($data, $id, $type, 2);
  396. return $this->success(compact('info'));
  397. }
  398. /**
  399. * 快速修改商品规格库存
  400. * @param StoreProductAttrValueServices $services
  401. * @param $id
  402. * @return mixed
  403. */
  404. public function saveProductAttrsStock(StoreProductAttrValueServices $services, $id)
  405. {
  406. if (!$id) {
  407. return $this->fail('缺少商品ID');
  408. }
  409. [$attrs] = $this->request->getMore([
  410. ['attrs', []]
  411. ], true);
  412. if (!$attrs) {
  413. return $this->fail('请重新修改规格库存');
  414. }
  415. foreach ($attrs as $attr) {
  416. if (!isset($attr['unique']) || !isset($attr['pm']) || !isset($attr['stock'])) {
  417. return $this->fail('请重新修改规格库存');
  418. }
  419. }
  420. return $this->success(['stock' => $services->saveProductAttrsStock((int)$id, $attrs)]);
  421. }
  422. /**
  423. * 设置批量商品上架
  424. * @return mixed
  425. */
  426. public function product_show()
  427. {
  428. [$ids, $all, $where] = $this->request->postMore([
  429. ['ids', []],
  430. ['all', 0],
  431. ['where', []],
  432. ], true);
  433. if ($all == 0) {//单页不走队列
  434. if (empty($ids)) return $this->fail('请选择需要上架的商品');
  435. $this->services->setShow($ids, 1);
  436. return $this->success('上架成功');
  437. }
  438. if ($all == 1) {
  439. $ids = [];
  440. if (isset($where['type'])) {
  441. $where['status'] = $where['type'];
  442. unset($where['type']);
  443. }
  444. $where['type'] = 2;
  445. $where['relation_id'] = $this->supplierId;
  446. }
  447. $type = 4;//商品上架
  448. /** @var QueueServices $queueService */
  449. $queueService = app()->make(QueueServices::class);
  450. $queueService->setQueueData($where, 'id', $ids, $type);
  451. //加入队列
  452. BatchHandleJob::dispatch(['up', $type]);
  453. return $this->success('后台程序已执商品上架任务!');
  454. }
  455. /**
  456. * 设置批量商品下架
  457. * @return mixed
  458. */
  459. public function product_unshow()
  460. {
  461. [$ids, $all, $where] = $this->request->postMore([
  462. ['ids', []],
  463. ['all', 0],
  464. ['where', []],
  465. ], true);
  466. if ($all == 0) {//单页不走队列
  467. if (empty($ids)) return $this->fail('请选择需要下架的商品');
  468. $this->services->setShow($ids, 0);
  469. return $this->success('下架成功');
  470. }
  471. if ($all == 1) {
  472. $all_ids = $this->services->getColumn(['is_show' => 1, 'is_del' => 0, 'type' => 2, 'relation_id' => $this->supplierId], 'id');
  473. $this->services->checkActivity($all_ids);
  474. $ids = [];
  475. if (isset($where['type'])) {
  476. $where['status'] = $where['type'];
  477. unset($where['type']);
  478. }
  479. $where['type'] = 2;
  480. $where['relation_id'] = $this->supplierId;
  481. }
  482. $type = 4;//商品下架
  483. /** @var QueueServices $queueService */
  484. $queueService = app()->make(QueueServices::class);
  485. $queueService->setQueueData($where, 'id', $ids, $type);
  486. //加入队列
  487. BatchHandleJob::dispatch(['down', $type]);
  488. return $this->success('后台程序已执商品下架任务!');
  489. }
  490. /**
  491. * 商品批量操作
  492. * @param StoreProductBatchProcessServices $batchProcessServices
  493. * @return mixed
  494. */
  495. public function batchProcess(StoreProductBatchProcessServices $batchProcessServices)
  496. {
  497. [$type, $ids, $all, $where, $data] = $this->request->postMore([
  498. ['type', 1],
  499. ['ids', ''],
  500. ['all', 0],
  501. ['where', ""],
  502. ['data', []]
  503. ], true);
  504. if (!$ids && $all == 0) return $this->fail('请选择批处理商品');
  505. if (!$data) {
  506. return $this->fail('请选择批处理数据');
  507. }
  508. if (isset($where['type'])) {
  509. $where['status'] = $where['type'];
  510. unset($where['type']);
  511. }
  512. $where['type'] = 2;
  513. $where['relation_id'] = $this->supplierId;
  514. //批量操作
  515. $batchProcessServices->batchProcess((int)$type, $ids, $data, !!$all, $where);
  516. return app('json')->success('已加入消息队列,请稍后查看');
  517. }
  518. }