Shop.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <?php
  2. namespace common\components\delivery\platform\shansong;
  3. use common\components\delivery\helpers\HttpClient;
  4. use common\components\delivery\helpers\SignHelper;
  5. use Yii;
  6. /**
  7. * Class Shop
  8. * 门店接口实现
  9. */
  10. class Shop extends Shansong
  11. {
  12. /**
  13. * 查询账号额度
  14. *
  15. * 接口文档:/openapi/developer/v5/getUserAccount
  16. *
  17. * 返回账户余额,单位为分
  18. *
  19. * @return array 返回格式:['success' => true/false, 'balance' => 0, 'message' => '']
  20. * balance: 账户余额,单位为分
  21. */
  22. public function getUserAccount()
  23. {
  24. $url = $this->baseUrl . '/openapi/developer/v5/getUserAccount';
  25. // 获取毫秒级时间戳
  26. $timestamp = (string) (int) (microtime(true) * 1000);
  27. // 构建签名参数(不包括 sign)
  28. $params = [
  29. 'clientId' => $this->clientId,
  30. 'accessToken' => $this->accessToken,
  31. 'timestamp' => $timestamp,
  32. ];
  33. // 计算签名(闪送使用 MD5 签名)
  34. $sign = SignHelper::makeSign(
  35. $params,
  36. $this->appSecret,
  37. 'md5',
  38. true,
  39. 'shansong'
  40. );
  41. $params['sign'] = $sign;
  42. $headers = ['Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8'];
  43. $response = HttpClient::post($url, $params, $headers);
  44. Yii::info("[ShansongUserAccount] Response: " . json_encode($response));
  45. // 检查API响应状态
  46. if (isset($response['status']) && $response['status'] == 200) {
  47. return [
  48. 'success' => true,
  49. 'balance' => $response['data']['balance'],
  50. 'message' => '查询余额成功',
  51. ];
  52. }
  53. return [
  54. 'success' => false,
  55. 'balance' => 0,
  56. 'message' => '查询余额失败',
  57. ];
  58. }
  59. /**
  60. * 新增店铺
  61. *
  62. * 接口文档:/openapi/merchants/v5/storeOperation
  63. * 接口说明:新增店铺接口不支持并发调用,一个请求返回结果后才能进行下一次请求
  64. *
  65. * @param array $data 店铺信息,包括:
  66. * - storeName: 店铺名称 (必传, String(80))
  67. * - cityName: 城市名称 (必传, String(20))
  68. * - address: 店铺地址 (必传, String(80))
  69. * - addressDetail: 店铺详细地址 (必传, String(80))
  70. * - latitude: 店铺纬度-百度坐标系 (必传, String(20))
  71. * - longitude: 店铺经度-百度坐标系 (必传, String(20))
  72. * - phone: 店铺联系人手机号/座机 (必传, String(30))
  73. * - goodType: 店铺业务类型 (必传, Integer(8), 枚举: 1文件、3数码、5蛋糕、6餐饮、7鲜花、9汽配、10其他、12母婴、13医药健康、15商超、16水果)
  74. *
  75. * @return array 返回格式:['success' => true/false, 'storeId' => 0, 'message' => '']
  76. * storeId: 新增店铺ID (只在success=true时有效)
  77. */
  78. public function addShop($data)
  79. {
  80. $url = $this->baseUrl . '/openapi/merchants/v5/storeOperation';
  81. // 获取毫秒级时间戳
  82. $timestamp = (int) (microtime(true) * 1000);
  83. // 补充操作类型:1表示新增
  84. $data['operationType'] = 1;
  85. // 构建完整payload
  86. $payload = [
  87. 'clientId' => $this->clientId,
  88. 'shopId' => $this->accessToken, // 使用 accessToken 作为 shopId
  89. 'timestamp' => $timestamp,
  90. 'data' => json_encode($data, JSON_UNESCAPED_UNICODE),
  91. ];
  92. // 计算签名
  93. $sign = SignHelper::makeSign($payload, $this->appSecret, 'md5', true, 'shansong');
  94. $payload['sign'] = $sign;
  95. $headers = ['Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8'];
  96. $response = HttpClient::post($url, $payload, $headers);
  97. Yii::info("[ShansongAddShop] Response: " . json_encode($response));
  98. // 检查API响应状态
  99. if (isset($response['status']) && $response['status'] == 200 && isset($response['data'])) {
  100. return [
  101. 'success' => true,
  102. 'storeId' => $response['data'],
  103. 'message' => $response['msg'] ?? '店铺创建成功',
  104. ];
  105. }
  106. return [
  107. 'success' => false,
  108. 'storeId' => 0,
  109. 'message' => $response['msg'] ?? '店铺创建失败',
  110. ];
  111. }
  112. /**
  113. * 批量新增店铺
  114. *
  115. * 接口文档:/openapi/merchants/v5/addStores
  116. * 接口说明:每次最多批量新增10个店铺
  117. *
  118. * @param array $storeList 店铺列表数组,每个元素包括:
  119. * - thirdStoreId: 第三方店铺ID (非必传, String(50))
  120. * - storeName: 店铺名称 (必传, String(80))
  121. * - cityName: 城市名称 (必传, String(20))
  122. * - address: 店铺地址 (必传, String(80))
  123. * - addressDetail: 店铺详细地址 (必传, String(80))
  124. * - latitude: 店铺纬度-百度坐标系 (必传, String(20))
  125. * - longitude: 店铺经度-百度坐标系 (必传, String(20))
  126. * - phone: 店铺联系人手机号/座机 (必传, String(30))
  127. * - goodType: 店铺业务类型 (必传, Integer(8))
  128. *
  129. * @return array 返回格式:['success' => true/false, 'failList' => [], 'successList' => []]
  130. * failList: 失败列表,每项包含 dto 和 reason
  131. * successList: 成功列表,每项包含 dto 和 storeId
  132. */
  133. public function batchAddShops($storeList)
  134. {
  135. $url = $this->baseUrl . '/openapi/merchants/v5/addStores';
  136. // 获取毫秒级时间戳
  137. $timestamp = (int) (microtime(true) * 1000);
  138. // 构建完整payload
  139. $payload = [
  140. 'clientId' => $this->clientId,
  141. 'shopId' => $this->accessToken, // 使用 accessToken 作为 shopId
  142. 'timestamp' => $timestamp,
  143. 'data' => json_encode($storeList, JSON_UNESCAPED_UNICODE),
  144. ];
  145. // 计算签名
  146. $sign = SignHelper::makeSign($payload, $this->appSecret, 'md5', true, 'shansong');
  147. $payload['sign'] = $sign;
  148. $headers = ['Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8'];
  149. $response = HttpClient::post($url, $payload, $headers);
  150. Yii::info("[ShansongBatchAddShops] Response: " . json_encode($response));
  151. // 检查API响应状态
  152. if (isset($response['status']) && $response['status'] == 200 && isset($response['data'])) {
  153. $respData = $response['data'];
  154. return [
  155. 'success' => true,
  156. 'failList' => $respData['failList'] ?? [],
  157. 'successList' => $respData['successList'] ?? [],
  158. ];
  159. }
  160. return [
  161. 'success' => false,
  162. 'failList' => [],
  163. 'successList' => [],
  164. ];
  165. }
  166. /**
  167. * 修改店铺
  168. *
  169. * 接口文档:/openapi/merchants/v5/storeOperation
  170. *
  171. * @param array $data 店铺信息,包括:
  172. * - storeId: 店铺ID (必传, Long(20))
  173. * - storeName: 店铺名称 (必传, String(80))
  174. * - cityName: 城市名称 (必传, String(20))
  175. * - address: 店铺地址 (必传, String(80))
  176. * - addressDetail: 店铺详细地址 (必传, String(80))
  177. * - latitude: 店铺纬度-百度坐标系 (必传, String(20))
  178. * - longitude: 店铺经度-百度坐标系 (必传, String(20))
  179. * - phone: 店铺联系人手机号/座机 (必传, String(30))
  180. * - goodType: 店铺业务类型 (必传, Integer(8))
  181. *
  182. * @return array 返回格式:['success' => true/false, 'storeId' => 0, 'message' => '']
  183. * storeId: 修改后的店铺ID (只在success=true时有效)
  184. */
  185. public function updateShop($data)
  186. {
  187. $url = $this->baseUrl . '/openapi/merchants/v5/storeOperation';
  188. // 获取毫秒级时间戳
  189. $timestamp = (int) (microtime(true) * 1000);
  190. // 补充操作类型:2表示修改
  191. $data['operationType'] = 2;
  192. // 构建完整payload
  193. $payload = [
  194. 'clientId' => $this->clientId,
  195. 'shopId' => $this->accessToken, // 使用 accessToken 作为 shopId
  196. 'timestamp' => $timestamp,
  197. 'data' => json_encode($data, JSON_UNESCAPED_UNICODE),
  198. ];
  199. // 计算签名
  200. $sign = SignHelper::makeSign($payload, $this->appSecret, 'md5', true, 'shansong');
  201. $payload['sign'] = $sign;
  202. $headers = ['Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8'];
  203. $response = HttpClient::post($url, $payload, $headers);
  204. Yii::info("[ShansongUpdateShop] Response: " . json_encode($response));
  205. // 检查API响应状态
  206. if (isset($response['status']) && $response['status'] == 200 && isset($response['data'])) {
  207. return [
  208. 'success' => true,
  209. 'storeId' => $response['data'],
  210. 'message' => $response['msg'] ?? '更新店铺成功',
  211. ];
  212. }
  213. return [
  214. 'success' => false,
  215. 'storeId' => 0,
  216. 'message' => $response['msg'] ?? '更新店铺失败',
  217. ];
  218. }
  219. /**
  220. * 分页查询商户店铺
  221. *
  222. * 接口文档:/openapi/merchants/v5/queryAllStores
  223. * 接口说明:分页查询商户创建店铺,供订单计费使用。仅状态为审核通过的店铺可计费使用
  224. *
  225. * @param array $params 查询参数,包括:
  226. * - pageNo: 页码 (必传, Integer(8), 最小值为1)
  227. * - pageSize: 每页数量 (必传, Integer(8), 最小值为1, 最大值为100)
  228. * - storeName: 店铺名称 (非必传, String(20), 模糊搜索)
  229. *
  230. * @return array 返回格式:['success' => true/false, 'data' => [], 'message' => '']
  231. * data: 店铺列表数组,每项包含:
  232. * - storeId: 店铺ID
  233. * - storeName: 店铺名称
  234. * - cityId: 城市ID
  235. * - cityName: 城市名称
  236. * - contactsMobile: 店铺联系人手机号
  237. * - address: 店铺地址
  238. * - addressDetail: 店铺地址详情
  239. * - latitude: 纬度
  240. * - longitude: 经度
  241. * - goodType: 店铺类型标签
  242. * - goodName: 店铺类型标签名称
  243. * - status: 店铺状态 (0-禁用、1-待审核、2-驳回、3-审核通过)
  244. * - totalNum: 店铺总条数
  245. */
  246. public function queryShops($params)
  247. {
  248. $url = $this->baseUrl . '/openapi/merchants/v5/queryAllStores';
  249. // 获取毫秒级时间戳
  250. $timestamp = (int) (microtime(true) * 1000);
  251. // 验证必传参数
  252. if (!isset($params['pageNo']) || !isset($params['pageSize'])) {
  253. return [
  254. 'success' => false,
  255. 'data' => [],
  256. 'message' => '缺少必传参数:pageNo 或 pageSize',
  257. ];
  258. }
  259. // 构建完整payload
  260. $payload = [
  261. 'clientId' => $this->clientId,
  262. 'shopId' => $this->accessToken, // 使用 accessToken 作为 shopId
  263. 'timestamp' => $timestamp,
  264. 'data' => json_encode($params, JSON_UNESCAPED_UNICODE),
  265. ];
  266. // 计算签名
  267. $sign = SignHelper::makeSign($payload, $this->appSecret, 'md5', true, 'shansong');
  268. $payload['sign'] = $sign;
  269. $headers = ['Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8'];
  270. $response = HttpClient::post($url, $payload, $headers);
  271. Yii::info("[ShansongQueryShops] Response: " . json_encode($response));
  272. // 检查API响应状态
  273. if (isset($response['status']) && $response['status'] == 200 && isset($response['data'])) {
  274. return [
  275. 'success' => true,
  276. 'data' => $response['data'],
  277. 'message' => '查询店铺成功',
  278. ];
  279. }
  280. return [
  281. 'success' => false,
  282. 'data' => [],
  283. 'message' => $response['msg'] ?? '查询店铺失败',
  284. ];
  285. }
  286. }