SmsService.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace crmeb\services;
  12. use think\facade\Log;
  13. use app\common\repositories\store\broadcast\BroadcastRoomRepository;
  14. use app\common\repositories\store\order\StoreGroupOrderRepository;
  15. use app\common\repositories\store\order\StoreOrderRepository;
  16. use app\common\repositories\store\order\StoreRefundOrderRepository;
  17. use app\common\repositories\store\product\ProductAssistSetRepository;
  18. use app\common\repositories\store\product\ProductGroupBuyingRepository;
  19. use app\common\repositories\store\product\ProductGroupUserRepository;
  20. use app\common\repositories\store\product\ProductRepository;
  21. use app\common\repositories\store\product\ProductTakeRepository;
  22. use app\common\repositories\store\service\StoreServiceRepository;
  23. use app\common\repositories\system\financial\FinancialRepository;
  24. use app\common\repositories\user\UserBillRepository;
  25. use app\common\repositories\user\UserExtractRepository;
  26. use crmeb\services\sms\Sms;
  27. use think\facade\Cache;
  28. class SmsService
  29. {
  30. const SMS_YUNXIN = 1;
  31. const SMS_ALIYUN = 2;
  32. public static function create($gateway = null)
  33. {
  34. $gateway = $gateway ?: ((int)systemConfig('sms_use_type') ?: 1);
  35. switch ($gateway) {
  36. case 1:
  37. $name = 'yunxin';
  38. $config = [
  39. 'account' => systemConfigNoCache('serve_account'),
  40. 'secret' => systemConfigNoCache('serve_token')
  41. ];
  42. break;
  43. case 2:
  44. $name = 'aliyun';
  45. $config = [
  46. 'account' => '',
  47. 'secret' => ''
  48. ];
  49. break;
  50. default:
  51. $name = 'yunxin';
  52. $config = [
  53. 'account' => systemConfigNoCache('serve_account'),
  54. 'secret' => systemConfigNoCache('serve_token')
  55. ];
  56. break;
  57. }
  58. return new Sms($name, $config);
  59. }
  60. /**
  61. * @Author:Qinii
  62. * @Date: 2020/9/19
  63. * @param $phone
  64. * @param $code
  65. * @param $type
  66. * @return bool
  67. */
  68. public function checkSmsCode($phone, $code, $type)
  69. {
  70. if (!env('DEVELOPMENT',false)) {
  71. $sms_key = $this->sendSmsKey($phone, $type);
  72. if (!$cache_code = Cache::get($sms_key)) return false;
  73. if ($code != $cache_code) return false;
  74. Cache::delete($sms_key);
  75. }
  76. return true;
  77. }
  78. /**
  79. * @Author:Qinii
  80. * @Date: 2020/9/19
  81. * @param $phone
  82. * @param string $type
  83. * @return string
  84. */
  85. public function sendSmsKey($phone, $type = 'login')
  86. {
  87. switch ($type) {
  88. case 'login': //登录
  89. return 'api_login_' . $phone;
  90. break;
  91. case 'binding': //绑定手机号
  92. return 'api_binding_' . $phone;
  93. break;
  94. case 'intention': //申请入住
  95. return 'merchant_intention_' . $phone;
  96. break;
  97. case 'change_pwd': //修改密码
  98. return 'change_pwd_' . $phone;
  99. break;
  100. case 'change_phone': //修改手机号
  101. return 'change_phone_' . $phone;
  102. break;
  103. default:
  104. return 'crmeb_' . $phone;
  105. break;
  106. }
  107. }
  108. public static function sendMessage($data)
  109. {
  110. $tempId = $data['tempId'];
  111. $id = $data['id'];
  112. $params = $data['params'] ?? [];
  113. switch ($tempId) {
  114. case 'ASSIST_SUCCESS' :
  115. $res = app()->make(ProductAssistSetRepository::class)->get($id);
  116. if (!$res->user || !$res->user->phone) return true;
  117. self::create()->send($res->user->phone, $tempId, ['date' => $res->create_time]);
  118. break;
  119. //发货提醒 -2.1
  120. case 'DELIVER_GOODS_CODE':
  121. $order = app()->make(StoreOrderRepository::class)->get($id);
  122. if (!$order || !$order->user_phone) return true;
  123. $nickname = $order->user->nickname;
  124. $store_name = $order->orderProduct[0]['cart_info']['product']['store_name'] . (count($order->orderProduct) ? '等' : '');
  125. $order_id = $order->order_sn;
  126. self::create()->send($order->user_phone, $tempId, compact('nickname', 'store_name', 'order_id'));
  127. break;
  128. //确认收货短信提醒 -2.1
  129. case 'ORDER_TAKE_SUCCESS':
  130. $order = app()->make(StoreOrderRepository::class)->get($id);
  131. if (!$order || !$order->user_phone) return true;
  132. $order_id = $order->order_sn;
  133. $store_name = $order->orderProduct[0]['cart_info']['product']['store_name'] . (count($order->orderProduct) ? '等' : '');
  134. self::create()->send($order->user_phone, $tempId, compact('store_name', 'order_id'));
  135. break;
  136. //用户支付成功提醒 -2.1
  137. case 'ORDER_PAY_SUCCESS':
  138. $order = app()->make(StoreGroupOrderRepository::class)->get($id);
  139. $pay_price = $order->pay_price;
  140. $order_id = $order->group_order_sn;
  141. self::create()->send($order->user_phone, $tempId, compact('pay_price', 'order_id'));
  142. break;
  143. //改价提醒 -2.1
  144. case 'PRICE_REVISION_CODE':
  145. $order = app()->make(StoreOrderRepository::class)->get($id);
  146. if (!$order || !$order->user_phone) return;
  147. $pay_price = $order->pay_price;
  148. $order_id = $order->order_sn;
  149. self::create()->send($order->user_phone, $tempId, compact('pay_price', 'order_id'));
  150. break;
  151. //提醒付款通知 -2.1
  152. case 'ORDER_PAY_FALSE':
  153. $order = app()->make(StoreGroupOrderRepository::class)->get($id);
  154. if (!$order || !$order->user_phone) return;
  155. $order_id = $order->group_order_sn;
  156. self::create()->send($order->user_phone, $tempId, compact('order_id'));
  157. break;
  158. //商家拒绝退款提醒 -2.1
  159. case 'REFUND_FAIL_CODE':
  160. $order = app()->make(StoreRefundOrderRepository::class)->get($id);
  161. if (!$order || !$order->order->user_phone) return;
  162. $order_id = $order->order->order_sn;
  163. $store_name = $order->refundProduct[0]->product['cart_info']['product']['store_name'] . (count($order->refundProduct) ? '等' : '');
  164. self::create()->send($order->order->user_phone, $tempId, compact('order_id', 'store_name'));
  165. break;
  166. //商家同意退款提醒 -2.1
  167. case 'REFUND_SUCCESS_CODE':
  168. //notbreak;
  169. //退款确认提醒 -2.1
  170. case 'REFUND_CONFORM_CODE':
  171. $order = app()->make(StoreRefundOrderRepository::class)->get($id);
  172. if (!$order || !$order->order->user_phone) return;
  173. $order_id = $order->order->order_sn;
  174. $store_name = $order->refundProduct[0]->product['cart_info']['product']['store_name'] . (count($order->refundProduct) ? '等' : '');
  175. self::create()->send($order->order->user_phone, $tempId, compact('order_id', 'store_name'));
  176. break;
  177. //管理员 支付成功提醒 -2.1
  178. case 'ADMIN_PAY_SUCCESS_CODE':
  179. $order = app()->make(StoreGroupOrderRepository::class)->get($id);
  180. if (!$order) return;
  181. foreach ($order->orderList as $_order) {
  182. self::sendMerMessage($_order->mer_id, $tempId, ['order_id' => $_order->order_sn]);
  183. }
  184. break;
  185. //管理员退款单提醒 -2.1
  186. case 'ADMIN_RETURN_GOODS_CODE':
  187. //notbreak
  188. //退货信息提醒
  189. case 'ADMIN_DELIVERY_CODE':
  190. $order = app()->make(StoreRefundOrderRepository::class)->get($id);
  191. if (!$order) return;
  192. self::sendMerMessage($order->mer_id, $tempId, ['order_id' => $order->refund_order_sn]);
  193. break;
  194. //管理员确认收货提醒 2.1
  195. case 'ADMIN_TAKE_DELIVERY_CODE':
  196. $order = app()->make(StoreOrderRepository::class)->get($id);
  197. if (!$order) return;
  198. self::sendMerMessage($order->mer_id, $tempId, ['order_id' => $order->order_sn]);
  199. break;
  200. //直播审核通过主播通知 2.1
  201. case 'BROADCAST_ROOM_CODE':
  202. $room = app()->make(BroadcastRoomRepository::class)->get($id);
  203. if (!$room) return;
  204. self::create()->send($room->phone, $tempId, [
  205. 'wechat' => $room->anchor_wechat,
  206. 'date' => date('Y年m月d日 H时i分', strtotime($room->start_time))
  207. ]);
  208. break;
  209. //直播未通过通知 2.1
  210. case 'BROADCAST_ROOM_FAIL':
  211. $room = app()->make(BroadcastRoomRepository::class)->get($id);
  212. if (!$room) return;
  213. self::create()->send($room->phone, $tempId, [
  214. 'wechat' => $room->anchor_wechat
  215. ]);
  216. break;
  217. //预售尾款支付通知 2.1
  218. case 'PAY_PRESELL_CODE':
  219. $order = app()->make(StoreOrderRepository::class)->get($id);
  220. if (!$order || !$order->user_phone || !$order->pay_time) return;
  221. self::create()->send($order->user_phone, $tempId, [
  222. 'date' => date('Y-m-d', strtotime($order->pay_time)),
  223. 'product_name' => $order->orderProduct[0]['cart_info']['product']['store_name'] ?? ''
  224. ]);
  225. break;
  226. //入驻申请通过提醒 2.1
  227. case 'APPLY_MER_SUCCESS':
  228. self::create()->send($id['phone'], $tempId, [
  229. 'date' => $id['date'],
  230. 'mer' => $id['mer'],
  231. 'phone' => $id['phone'],
  232. 'pwd' => $id['pwd'],
  233. 'site_name' => systemConfig('site_name'),
  234. ]);
  235. break;
  236. //入驻申请未通过提醒 2.1
  237. case 'APPLY_MER_FAIL':
  238. self::create()->send($id['phone'], $tempId, [
  239. 'date' => $id['date'],
  240. 'mer' => $id['mer'],
  241. 'site' => systemConfig('site_name'),
  242. ]);
  243. break;
  244. //到货提醒通知 2.1
  245. case 'PRODUCT_INCREASE':
  246. $product = app()->make(ProductRepository::class)->getWhere(['product_id' => $id], '*', ['attrValue']);
  247. if (!$product) return ;
  248. $unique[] = 1;
  249. foreach ($product['attrValue'] as $item) {
  250. if ($item['stock'] > 0) $unique[] = $item['unique'];
  251. }
  252. $make = app()->make(ProductTakeRepository::class);
  253. $query = $make->getSearch(['product_id' => $id, 'status' => 0, 'type' => 1])->where('unique', 'in', $unique);
  254. $ret = $query->select();
  255. if (!$ret) return ;
  256. foreach ($ret as $item) {
  257. if ($item->user->phone) {
  258. self::create()->send($item->user->phone, $tempId, [
  259. 'product' => $product->store_name,
  260. 'site' => systemConfig('site_name'),
  261. ]);
  262. $tak_id[] = $item->product_take_id;
  263. }
  264. }
  265. if (!empty($tak_id)) app()->make(ProductTakeRepository::class)->updates($tak_id, ['status' => 1]);
  266. break;
  267. //积分即将到期提醒 2.1
  268. case 'INTEGRAL_INVALID':
  269. self::create()->send($id['phone'], $tempId, [
  270. 'integral' => $id['integral'],
  271. 'date' => date('m月d日', strtotime($id['date'])),
  272. 'site' => systemConfig('site_name'),
  273. ]);
  274. break;
  275. //保证金退回申请通过通知 2.1
  276. case 'REFUND_MARGIN_SUCCESS':
  277. //nobreak;
  278. //保证金退回申请未通过通知 2.1
  279. case 'REFUND_MARGIN_FAIL':
  280. self::create()->send($id['phone'], $tempId, ['name' => $id['name'], 'time' => $id['time'],]);
  281. break;
  282. //分账商户申请通过 2.1
  283. case 'APPLYMENTS_SUCCESS':
  284. //nobreak;
  285. //商户申请分账待验证
  286. case 'APPLYMENTS_SIGN':
  287. //nobreak;
  288. //商户申请分账未通过
  289. case 'APPLYMENTS_FAIL':
  290. self::create()->send($id['phone'], $tempId, ['mer_name' => $id['mer_name']]);
  291. break;
  292. //付费会员支付成功
  293. case 'SVIP_PAY_SUCCESS':
  294. self::create()->send($id['phone'], $tempId, ['store_name' => systemConfig('site_name'),'date' => $id['date']]);
  295. break;
  296. case 'GROUP_BUYING_SUCCESS':
  297. //${nickname}您好,您于${date}在${store_name}商城参加拼团活动已成功,详情请前往商城查询-我的订单。
  298. $res = app()->make(ProductGroupUserRepository::class)->getSearch(['group_buying_id' => $id])->select();
  299. foreach ($res as $item) {
  300. if ($item && $item->user->phone) {
  301. self::create()->send($item->user->phone, $tempId,
  302. ['nickname' => $item['nickname'],'store_name' => systemConfig('site_name'),'date' => date('Y-m-d H:i:s')]);
  303. }
  304. }
  305. break;
  306. case 'USER_BALANCE_CHANGE':
  307. //您好,您于${date}在${store_name}商城${is_status}元,现账户余额为${number}元,祝您购物愉快!
  308. $res = app()->make(UserBillRepository::class)->get($id);
  309. if (!$res || !$res->user->phone) return ;
  310. $is_status = ($res['mp'] == 1 ? '余额充值' : '余额消费').$res['number'];
  311. self::create()->send($res->user->phone, $tempId, ['store_name' => systemConfig('site_name'),'date' => $res['create_time'],'number' => $res['balance'],'is_status' => $is_status]);
  312. break;
  313. case 'EXTRACT_NOTICE':
  314. //您好,您于${date}在${store_name}商城申请提现${number}元,系统审核${is_status},详情请联系商城管理员。
  315. $res = app()->make(UserExtractRepository::class)->get($id);
  316. if (!$res || !$res->user->phone) return true;
  317. $is_status = $params['is_status'] == 1 ? '已通过' : '已驳回';
  318. $msg = ['store_name' => systemConfig('site_name'),'date' => date('Y-m-d H:i:s'),'number' => $res['extract_price'],'is_status' => $is_status];
  319. Log::info('EXTRACT_NOTICE:'.var_export([$msg,$data],1));
  320. self::create()->send($res->user->phone, $tempId,$msg);
  321. break;
  322. case 'TRANSFER_ACCOUNTS_SUCCESS': // 平台审核转账结果通知
  323. $res = app()->make(FinancialRepository::class)->get($id);
  324. if (!$res || !$res->merchant->mer_phone) return;
  325. self::create()->send($res->merchant->mer_phone, $tempId, ['mer_name' => $res->merchant->mer_name, 'site_name' => systemConfig('site_name'), 'datetime' => date('Y年m月d日 H时i分'), 'amount' => $res->extract_money]);
  326. break;
  327. }
  328. }
  329. public static function sendMerMessage($merId, string $tempId, array $data)
  330. {
  331. $noticeServiceInfo = app()->make(StoreServiceRepository::class)->getNoticeServiceInfo($merId);
  332. $yunxinSmsService = self::create();
  333. foreach ($noticeServiceInfo as $service) {
  334. if (!$service['phone']) continue;
  335. $yunxinSmsService->send($service['phone'], $tempId, array_merge(['admin_name' => $service['nickname']], $data));
  336. }
  337. }
  338. }