Goods.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <?php
  2. namespace app\controller\merchant;
  3. use app\extra\basic\Base;
  4. use app\extra\dyLife\data\BaseData;
  5. use app\extra\tools\CodeExtend;
  6. use app\middleware\AuthMiddleware;
  7. use app\middleware\DepositMiddleware;
  8. use app\model\saas\SaasGoods;
  9. use app\model\saas\SaasGoodsSku;
  10. use app\model\saas\SaasOrder;
  11. use app\model\saas\SaasStore;
  12. use app\service\saas\GoodsService;
  13. use DI\Attribute\Inject;
  14. use LinFly\Annotation\Attributes\Route\Controller;
  15. use LinFly\Annotation\Attributes\Route\GetMapping;
  16. use LinFly\Annotation\Attributes\Route\Middleware;
  17. use LinFly\Annotation\Attributes\Route\PostMapping;
  18. use support\Request;
  19. use support\Response;
  20. #[Controller("/api/merchant/goods"),Middleware(AuthMiddleware::class)]
  21. class Goods extends Base
  22. {
  23. #[Inject]
  24. protected GoodsService $service;
  25. #[Inject]
  26. protected SaasGoods $model;
  27. #[Inject]
  28. protected SaasGoodsSku $skuModel;
  29. #[Inject]
  30. protected SaasStore $store;
  31. #[GetMapping('list')]
  32. public function getDataList(Request $request): Response
  33. {
  34. try {
  35. $param = $request->all();
  36. $param['poi_id'] = $request->user['store_id'];
  37. if (!empty($param['status'])) $param['status'] = intval($param['status']+1);
  38. $productType = $this->service->productType();
  39. $data = $this->service->setModel()->getList($param,null,true,['types'],['types' => function($query,$resp) use($productType){
  40. $productTypeArr = [];
  41. foreach ($productType as $val) {
  42. $productTypeArr[$val['key']] = $val['name'];
  43. }
  44. return $productTypeArr[$resp['product_type']]??'';
  45. }]);
  46. return successTrans(100010,pageFormat($data),200);
  47. } catch (\Throwable $th) {
  48. return error($th->getMessage());
  49. }
  50. }
  51. /**
  52. * 商品详情
  53. * @param Request $request
  54. * @return Response
  55. */
  56. #[GetMapping('detail')]
  57. public function getGoodDetail(Request $request): Response
  58. {
  59. try {
  60. $param = $this->_valid([
  61. "id.require" => trans("empty.require"),
  62. "product_id.require" => trans("empty.require"),
  63. ],$request->method());
  64. if (!is_array($param)) return error($param);
  65. $detail = $this->model->where("id",$param["id"])->with(['skuSpecs'])->findOrEmpty();
  66. if ($detail->isEmpty()) return errorTrans("empty.data");
  67. if ($detail['poi_id'] <> $request->user['store_id']) return errorTrans("error.param");
  68. $detail['sold_start_times'] = [(string)$detail['sold_start_time'],(string)$detail['sold_end_time']];
  69. $detail['use_times'] = null;
  70. if ($detail['use_date_type'] == 2) {
  71. $detail['use_times'] = [(string)$detail['use_time_start'],(string)$detail['use_time_end']];
  72. }
  73. return successTrans('success.data',$detail->toArray());
  74. } catch (\Throwable $throwable) {
  75. return error($throwable->getMessage());
  76. }
  77. }
  78. #[PostMapping("template")]
  79. public function getTemplate(Request $request): Response
  80. {
  81. try {
  82. $param = $this->_valid([
  83. "product_type.require" => trans("empty.require"),
  84. "category.require" => trans("empty.require"),
  85. ],$request->method());
  86. if (!is_array($param)) return error($param);
  87. $data = (new BaseData)->config([
  88. "appid" => sConf("wechat.appid"),
  89. "secret" => sConf("wechat.secret"),
  90. "account" => sConf("wechat.shop_id"),
  91. ])->token()->getStoreCategoryTemplate($param['category'][2],$param['product_type']);
  92. return success("ok",$data);
  93. } catch (\Throwable $throwable) {
  94. return error($throwable->getMessage());
  95. }
  96. }
  97. #[GetMapping('type')]
  98. public function getProductType(Request $request): Response
  99. {
  100. try {
  101. $poiId = $request->user['store_id'];
  102. $productType = $this->store->where("poi_id", $poiId)->value("product_type");
  103. if (empty($productType)) return error("未配置");
  104. $typeData = [];
  105. foreach ($this->service->productType() as $key => $value) {
  106. if (in_array($value['key'],json_decode($productType,true))) {
  107. $typeData[] = $value;
  108. }
  109. }
  110. return success('ok', $typeData);
  111. } catch (\Throwable $th) {
  112. return error($th->getMessage());
  113. }
  114. }
  115. /**
  116. * 新增商品
  117. * @param Request $request
  118. * @return Response
  119. */
  120. #[PostMapping("save")]
  121. public function saveGoods(Request $request): Response
  122. {
  123. try {
  124. [$state,$msg] = $this->checkDeposit($request->user['store_id']);
  125. if (!$state) return error($msg);
  126. $param = $request->post();
  127. if (empty($param['auto_renew'])) $param['auto_renew'] = 0;
  128. $param['image_list'] = empty($param['image_list']) ? [] : json_encode($param['image_list']);
  129. $param['detail_image_list'] = empty($param['detail_image_list']) ? [] : json_encode($param['detail_image_list']);
  130. $param['environment_image_list'] = empty($param['environment_image_list']) ? [] : json_encode($param['environment_image_list']);
  131. // $param['notification'] = empty($param['notification']) ? [] : json_encode($param['notification']);
  132. if (empty($param['specs'])) return error("至少添加一组搭配信息");
  133. if (is_array($param['specs'])) $param['specs'] = json_encode($param['specs']);
  134. if (is_array($param['category'])) {
  135. $param['category_id'] = $param['category'][2]??0;
  136. $param['category'] = json_encode($param['category']);
  137. }
  138. if ($param['day_duration'] < 30) return error("顾客可消费日期不可低于30天");
  139. if (!isset($param['id'])) {
  140. $param['product_id'] = strtoupper(CodeExtend::random(18,3));
  141. }
  142. $param['price'] = $param['price']*100;
  143. $param['poi_id'] = $request->user['store_id'];
  144. if (!empty($param['no_use_weeks']) && count($param['no_use_weeks']) == 7) return error("至少需要保留一天可用");
  145. $skuData = [];
  146. if (is_array($param['skuSpecs'])) {
  147. foreach ($param['skuSpecs'] as $key => $value) {
  148. $skuData[$key] = $value;
  149. $skuData[$key]['product_id'] = $param['product_id'];
  150. $skuData[$key]['specs'] = json_encode($value['specs']);
  151. }
  152. }
  153. if (!isset($param['id'])) {
  154. $param['spu_id'] = CodeExtend::uniqidDate(18);
  155. } else {
  156. $param['status'] = 0;
  157. }
  158. unset($param['skuSpecs']);
  159. $param['line_price'] = $param['line_price'] * 100;
  160. // if (empty($param['notification'])) return error("请最少添加一组添加使用规则");
  161. // foreach (json_decode($param['notification'],true) as $key => $value) {
  162. // if (empty($value['title'])) return error("规则标题不能为空");
  163. // if (empty($value['content'])) return error("规则内容不能为空");
  164. // }
  165. $store = (new SaasStore)->where("poi_id",$request->user['store_id'])->findOrEmpty();
  166. if ($store->isEmpty()) return errorTrans("error.data");
  167. // 获取attr_key_value_map参数
  168. $valMap = (new BaseData)->config([
  169. "appid" => sConf("wechat.appid"),
  170. "secret" => sConf("wechat.secret"),
  171. "account" => sConf("wechat.shop_id"),
  172. ])->token()->getStoreCategoryTemplate($param['category_id'],$param['product_type']);
  173. if (empty($valMap['product_attrs'])) return errorTrans("error.data");
  174. $data = (new BaseData)->config([
  175. "appid" => sConf("wechat.mini_appid"),
  176. "secret" => sConf("wechat.mini_secret"),
  177. ])->token()->createGoodsData($param,$skuData,$store->toArray(),$valMap);
  178. // return errorTrans("error.data");
  179. if (empty($data['product_id'])) return error($data['description']);
  180. $param['goods_id'] = $data['product_id'];
  181. // return errorTrans("error.data");
  182. $stateSku = false;
  183. if (!empty($skuData)) {
  184. [$stateSku,$msg] = $this->skuData($skuData);
  185. if (!$stateSku) return error($msg);
  186. }
  187. $state = $this->model->setAutoData($param);
  188. if (!$state && !$stateSku) return errorTrans("error.data");
  189. return successTrans("success.data");
  190. } catch (\Throwable $throwable) {
  191. echo $throwable->getLine()."\n";
  192. echo $throwable->getFile()."\n";
  193. echo $throwable->getMessage()."\n";
  194. return error($throwable->getMessage());
  195. }
  196. }
  197. /**
  198. * SKU编辑
  199. * @param array $skuData
  200. * @return array
  201. */
  202. protected function skuData(array $skuData = []): array
  203. {
  204. try {
  205. if (empty($skuData)) return [0,trans('empty.require')];
  206. foreach ($skuData as $vo) {
  207. $sku = $this->skuModel->where("sku_id",$vo['sku_id'])->findOrEmpty();
  208. if ($sku->isEmpty()) {
  209. $sku->insertGetId($vo);
  210. } else {
  211. $sku->update($vo);
  212. }
  213. }
  214. return [1,'success'];
  215. } catch (\Throwable $throwable) {
  216. return [0,$throwable->getMessage()];
  217. }
  218. }
  219. /**
  220. * 商品下架
  221. * @param Request $request
  222. * @return Response
  223. */
  224. #[PostMapping("off")]
  225. public function offGood2Life(Request $request): Response
  226. {
  227. try {
  228. $param = $this->_valid([
  229. "id.require" => trans("empty.require"),
  230. ],$request->method());
  231. if (!is_array($param)) return error($param);
  232. $detail = $this->model->where("id",$param["id"])->with(['skuSpecs'])->findOrEmpty();
  233. if ($detail->isEmpty()) return errorTrans("empty.data");
  234. if ($detail['poi_id'] <> $request->user['store_id']) return errorTrans("error.param");
  235. $store = (new SaasStore)->where("poi_id",$request->user['store_id'])->findOrEmpty();
  236. if ($store->isEmpty()) return errorTrans("error.data");
  237. $data = (new BaseData)->config([
  238. "appid" => sConf("wechat.mini_appid"),
  239. "secret" => sConf("wechat.mini_secret"),
  240. ])->token()->goodsOffOn(2,$store['store_id'],$detail['goods_id']);
  241. if ($data['error_code'] <> 0) return error("操作失败,请稍后重试");
  242. $detail->status = 2;
  243. $detail->save();
  244. return successTrans("success.data");
  245. } catch (\Throwable $throwable) {
  246. return error($throwable->getMessage());
  247. }
  248. }
  249. #[PostMapping("del")]
  250. public function delGoods(Request $request)
  251. {
  252. try {
  253. $param = $this->_valid([
  254. "id.require" => trans("empty.require"),
  255. ],$request->method());
  256. if (!is_array($param)) return error($param);
  257. $detail = $this->model->where("id",$param["id"])->findOrEmpty();
  258. if ($detail->isEmpty()) return errorTrans("empty.data");
  259. if ($detail['poi_id'] <> $request->user['store_id']) return error("非法操作");
  260. $state = $detail->delete();
  261. if (!$state) return errorTrans("error.data");
  262. (new SaasOrder)->where("product_id",$detail["product_id"])->delete();
  263. return successTrans("success.data");
  264. } catch (\Throwable $throwable) {
  265. return error($throwable->getMessage());
  266. }
  267. }
  268. }