MobileController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <?php
  2. namespace app\api\controller;
  3. use addons\epay\library\Service;
  4. use app\common\controller\UserApi;
  5. use app\common\library\MobileConstant;
  6. use app\common\model\Area;
  7. use app\common\model\Mobile;
  8. use app\common\model\MobileInfo;
  9. use app\common\model\MobileOrder;
  10. use app\common\model\Payment;
  11. use app\common\service\Jdpay;
  12. use app\common\service\SmsSend;
  13. use think\App;
  14. use think\Db;
  15. use think\db\Query;
  16. /**
  17. * 靓号管理
  18. */
  19. class MobileController extends UserApi
  20. {
  21. protected $noNeedLogin = "*";
  22. protected $noNeedRight = '*';
  23. /**
  24. * 列表
  25. * @ApiMethod (POST)
  26. * @ApiParams (name="type",description="1靓号,2流量卡,默认1")
  27. * @ApiParams (name="search_type",description="fuzzy模糊,precise精准")
  28. * @ApiParams (name="search_last",description="0,1是否搜索尾部")
  29. * @ApiParams (name="city_id",description="地区id")
  30. * @ApiParams (name="keyword",description="搜索内容,模糊就是字符串,精准就是数组")
  31. * @ApiParams (name="sort",description="price_asc价格从低到高,price_desc价格从高到低")
  32. * @ApiParams (name="network",description="网络")
  33. * @ApiParams (name="price_min",description="价格最低数字")
  34. * @ApiParams (name="price_max",description="价格最高数字")
  35. * @ApiParams (name="exclude_num",description="排除数字")
  36. * @ApiParams (name="num_max",description="数字较多,传数字")
  37. * @ApiParams (name="rule_position",description="规律位置,middle中间,tail尾部")
  38. * @ApiParams (name="rule_name",description="规律名,AAAA什么的")
  39. * @ApiParams (name="limit",description="limit")
  40. * @ApiParams (name="page",description="page")
  41. * @ApiReturnParams (name=id,description=id)
  42. * @ApiReturnParams (name="type",description="1靓号,2流量卡")
  43. * @ApiReturnParams (name=logo,description=缩略图)
  44. * @ApiReturnParams (name=name,description=号码名称)
  45. * @ApiReturnParams (name=no,description=手机号)
  46. * @ApiReturnParams (name=type,description=1靓号2流量卡)
  47. * @ApiReturnParams (name=network,description=运营商)
  48. * @ApiReturnParams (name=city,description=城市)
  49. * @ApiReturnParams (name=privince,description=省份)
  50. * @ApiReturnParams (name=amount,description=售价)
  51. * @ApiReturnParams (name=amount_original,description=原价)
  52. * @ApiReturnParams (name=amount_exists,description=含话费)
  53. * @ApiReturnParams (name=amount_base,description=售价)
  54. * @ApiReturnParams (name=amount_charge,description=预充)
  55. * @ApiReturnParams (name=summary,description=简介)
  56. * @ApiReturnParams (name=saled,description=是否已出售)
  57. * @ApiReturnParams (name=status,description=0正常1已售2已下架)
  58. * @ApiReturnParams (name=is_activity,description=是否特价号)
  59. * @ApiReturnParams (name=activity_time_end,description=特价过期时间null永不过期)
  60. * @ApiReturnParams (name="info.free_app",description=免流APP列表)
  61. * @ApiReturnParams (name="info.describe",description="套餐说明|资费详情")
  62. * @ApiReturnParams (name="info.content",description="详细内容|注意事项")
  63. * @ApiReturnParams (name="info.flow_year",description="每年流量(G)")
  64. * @ApiReturnParams (name="info.fee",description="资费")
  65. * @ApiReturnParams (name="info.first_month_free",description="首月是否免月租")
  66. * @ApiReturnParams (name="info.discount_title",description="简要优惠介绍")
  67. */
  68. public function list(){
  69. $model=Mobile::show();
  70. $data=input();
  71. $this->validate($data,[
  72. 'keyword'=>['max:11'],
  73. 'num_max'=>['integer','between:0,9'],
  74. 'rule_position'=>['in:middle,tail'],
  75. ]);
  76. if(empty($data['type'])){
  77. $data['type']=1;
  78. }
  79. $model->where('type',$data['type']);
  80. if(!empty($data['search_type']) && !empty($data['keyword'])){
  81. if($data['search_type']=='fuzzy'){
  82. if(isset($data['search_last']) && $data['search_last']==1){
  83. $no=str_pad($data['keyword'],11,'-',STR_PAD_LEFT);
  84. for ($i=1;$i<=11;$i++){
  85. if(substr($no,$i-1,1)=='-'){
  86. continue;
  87. }
  88. $model->where("filter_no_pos_{$i}",substr($no,$i-1,1));
  89. }
  90. }else {
  91. $model->where('no', 'like', "%{$data['keyword']}%");
  92. }
  93. }elseif ($data['search_type']=='precise'){
  94. foreach ($data['keyword'] as $k=>$v){
  95. $pos=$k+1;
  96. if($pos==1||$v===""||is_null($v))continue;
  97. $model->where("filter_no_pos_{$pos}",$v);
  98. }
  99. }
  100. }
  101. if(!empty($data['city_id'])){
  102. $model->where('city_id',$data['city_id']);
  103. }
  104. if(!empty($data['sort'])){
  105. if($data['sort']=='price_asc'){
  106. $model->order('amount','asc');
  107. }elseif($data['sort']=='price_desc'){
  108. $model->order('amount','desc');
  109. }
  110. }else{
  111. $model->order('activity_time','desc')->order('create_time','desc');
  112. }
  113. if(!empty($data['network'])){
  114. $network=array_column(MobileConstant::getNetwork(),'search','name');
  115. $model->whereIn('network',$network[$data['network']]??[0]);
  116. }
  117. if(!empty($data['price_min']) && is_numeric($data['price_min'])){
  118. $model->where('amount','>=',$data['price_min']);
  119. }
  120. if(!empty($data['price_max']) && is_numeric($data['price_max'])){
  121. $model->where('amount','>=',$data['price_max']);
  122. }
  123. if(!empty($data['exclude_num'])){
  124. $model->whereNotLike('no',"%{$data['exclude_num']}%");
  125. }
  126. if(!empty($data['num_max'])){
  127. $model->where("filter_num_{$data['num_max']}",'>',3);
  128. }
  129. $rules=MobileConstant::getFilters();
  130. if(!empty($data['rule_name'])){
  131. if (!isset($rules[$data['rule_name']])) {
  132. $this->error('规律规则不支持');
  133. }
  134. $rule=$rules[$data['rule_name']];
  135. if(!empty($data['rule_position'])) {
  136. $model->where($rule[$data['rule_position']], 1);
  137. }else{
  138. $model->where(function (Query $query)use ($rule){
  139. $query->where($rule['middle'],1)->whereOr($rule['tail'],1);
  140. });
  141. }
  142. }
  143. $list=$model->paginate(input('limit',15));
  144. $this->success('',$list);
  145. }
  146. /**
  147. * 号码详情
  148. * @ApiParams (name=id,description=号码id)
  149. */
  150. public function show(){
  151. $data=$this->_validate([
  152. 'id'=>['require']
  153. ]);
  154. $mobile=Mobile::where('id','id')->with(['info'])->findOrFail($data['id']);
  155. $this->success('',$mobile);
  156. }
  157. /**
  158. * 下单
  159. * @ApiMethod (POST)
  160. * @ApiParams (name=mobile_id,description=手机号ID)
  161. * @ApiParams (name=name,description=姓名)
  162. * @ApiParams (name=phone,description=手机号)
  163. * @ApiParams (name=sms_code,description=验证码)
  164. * @ApiParams (name=id_no,description=身份号码)
  165. * @ApiParams (name=county,description="城市ID,区县id")
  166. * @ApiParams (name=address,description=详细地址)
  167. * @ApiParams (name=remark,description=备注)
  168. * @ApiParams (name=pay_type,description="1微信2支付宝3京东")
  169. * @ApiParams (name=return_url,description="支付完成回调页面链接")
  170. * @ApiReturnParams (name=pay_url,description="支付链接")
  171. *
  172. */
  173. public function apply(){
  174. $data=$this->_validate([
  175. 'mobile_id'=>'require',
  176. 'name'=>'require',
  177. 'phone'=>'require',
  178. 'id_no'=>'require',
  179. 'county'=>'require|integer',
  180. 'address'=>'require',
  181. ]);
  182. $mobile=Mobile::where('status',0)->findOrFail($data['mobile_id']);
  183. if($mobile['type']==1){
  184. $this->_validate([
  185. 'pay_type'=>'require|in:1,2,3',
  186. ]);
  187. }
  188. Area::shouldSend($data['county']);
  189. Db::startTrans();
  190. SmsSend::setMobile($data['phone'])->setCode($data['sms_code'] ?? '')->setEvent('order')->check();
  191. $order = $data;
  192. $order['admin_id'] = $mobile['proxy_id'];
  193. $order['no'] = $mobile['no'];
  194. $order['city'] = implode(',', Area::getTreeId($data['county']));
  195. $order['amount_original'] = $mobile['amount_original'];
  196. $order['amount_hd'] = $mobile['amount'];
  197. $order['amount_charge'] = $mobile['amount_charge'];
  198. $order['amount'] = $mobile['amount'];
  199. $order['type'] = $mobile['type'];
  200. unset($order['county'], $order['status'], $order['sms_code']);
  201. $mobileOrder = (new MobileOrder);
  202. $mobileOrder->allowField(true)->save($order);
  203. $succ=null;
  204. if($mobile['type']==1) {
  205. $succ = $this->pay($mobileOrder, $data);
  206. }
  207. Db::commit();
  208. $this->success('', $succ);
  209. }
  210. protected function pay(MobileOrder $mobileOrder,$data){
  211. $succ=[
  212. 'pay_url'=>'',
  213. ];
  214. $payment=Payment::create([
  215. 'order_no'=>session_create_id('payment'),
  216. 'amount'=>$mobileOrder['amount'],
  217. 'mobile_order_id'=>$mobileOrder['id'],
  218. ]);
  219. if($data['pay_type']==1){
  220. $info=Service::submitOrder($payment['amount'],
  221. $payment['order_no'],'wechat',"购买手机号{$mobileOrder['no']}",
  222. Service::notifyUrl('wechat',$mobileOrder['no']),$data['return_url']??'','wap');
  223. $succ['pay_url']=$info->getTargetUrl();
  224. }elseif ($data['pay_type']==2){
  225. $info=Service::submitOrder($payment['amount'],
  226. $payment['order_no'],'alipay',"购买手机号{$mobileOrder['no']}",
  227. Service::notifyUrl('alipay',$mobileOrder['no']),$data['return_url']??'','wap');
  228. $succ['pay_url']=$info->getTargetUrl();
  229. }elseif ($data['pay_type']==3){
  230. $jdpay=App::invokeClass(Jdpay::class);
  231. $payData=$jdpay->order($payment['order_no'],$payment['amount'],"购买手机号{$mobileOrder['no']}");
  232. $succ=array_merge($succ,$payData);
  233. }
  234. return $succ;
  235. }
  236. /**
  237. * 继续支付
  238. * @ApiParams (name=id,description=订单id)
  239. * @ApiParams (name=pay_type,description=支付方式与下单一样)
  240. * @ApiParams (name=return_url,description="支付完成回调页面链接")
  241. */
  242. public function continue_pay(){
  243. $data=$this->_validate([
  244. 'id'=>['require'],
  245. 'pay_type'=>'require|in:1,2,3',
  246. ]);
  247. $mobileOrder=MobileOrder::whereNull('pay_time')->findOrFail($data['id']);
  248. $mobileOrder->continuePay();
  249. $succ=$this->pay($mobileOrder,$data);
  250. $this->success('',$succ);
  251. }
  252. /**
  253. * 订单详情
  254. * @ApiParams (name=id,description=订单id)
  255. * @ApiReturnParams (name=no,description=手机号)
  256. * @ApiReturnParams (name=order_no,description=订单号)
  257. * @ApiReturnParams (name=amount_hd,description=活动价)
  258. * @ApiReturnParams (name=amount_original,description=原价)
  259. * @ApiReturnParams (name=amount_charge,description=预充)
  260. * @ApiReturnParams (name=describe,description=套餐说明)
  261. * @ApiReturnParams (name=proxy.wx_qr,description=客服二维码)
  262. * @ApiReturnParams (name=name,description=收货人)
  263. * @ApiReturnParams (name=address,description=收货地址)
  264. * @ApiReturnParams (name=remark,description=备注)
  265. * @ApiReturnParams (name=create_time,description=下单时间)
  266. * @ApiReturnParams (name=amount,description=订单金额)
  267. * @ApiReturnParams (name=trans_name,description=快递名称)
  268. * @ApiReturnParams (name=trans_no,description=快递单号)
  269. * @ApiReturnParams (name=status,description="0=>'待付款',10=>'待发货',20=>'待收货',30=>'退款待处理',40=>'已退款',50=>'已关闭',")
  270. * @ApiReturnParams (name=open_uploaded,description=是否已上传开卡资料)
  271. * @ApiReturnParams (name=open_idcard_face_img,description=身份证正面照)
  272. * @ApiReturnParams (name=open_idcard_back_img,description=身份证反面照)
  273. * @ApiReturnParams (name=open_face_img,description=头像照)
  274. * @ApiReturnParams (name=open_name,description=姓名)
  275. * @ApiReturnParams (name=open_id_no,description=身份证号码)
  276. * @ApiReturnParams (name=open_phone,description=手机号)
  277. */
  278. public function order_detail(){
  279. $order=MobileOrder::with(['proxy'])->findOrFail(input('id'));
  280. $order['proxy']->hidden(['password']);
  281. $order['describe']=MobileInfo::where('mobile_id',$order['mobile_id'])->value('describe','');
  282. $this->success('',$order);
  283. }
  284. /**
  285. * 订单列表
  286. * @ApiParams (name=page,description=page)
  287. * @ApiParams (name=limit,description=limit)
  288. * @ApiParams (name=phone,description=手机号)
  289. */
  290. public function order_list(){
  291. $data=$this->_validate([
  292. 'phone|参数'=>['require'],
  293. ]);
  294. $order=MobileOrder::with('proxy')->where('phone',$data['phone'])->order('id','desc')->paginate(input('limit',15));
  295. $this->success('',$order);
  296. }
  297. /**
  298. * 筛选配置
  299. *
  300. */
  301. public function config(){
  302. $config=[];
  303. $networks=array_column(MobileConstant::getNetwork(),'name');
  304. $config['network']=$networks;
  305. $config['rule']=[
  306. 'AAA',
  307. 'AAAA',
  308. 'AAAAA',
  309. '6A',
  310. '7A',
  311. '8A',
  312. 'ABC',
  313. 'ABCD',
  314. 'ABCDE',
  315. 'ABCDEF',
  316. 'AAAB',
  317. 'AAAAB',
  318. 'AAAAAB',
  319. ];
  320. $this->success('',$config);
  321. }
  322. /**
  323. * 上传开卡资料
  324. * @ApiParams (name=id,description=订单id)
  325. * @ApiParams (name=idcard_face_img,description=身份证正面照片)
  326. * @ApiParams (name=idcard_back_img,description=身份证反面照片)
  327. * @ApiParams (name=face_img,description=本人照片)
  328. * @ApiParams (name=name,description=本人姓名)
  329. * @ApiParams (name=id_no,description=本人身份证号码)
  330. * @ApiParams (name=phone,description=本人联系电话)
  331. */
  332. public function upload_identity(){
  333. $data=$this->_validate([
  334. 'id'=>['require'],
  335. 'idcard_face_img'=>['require','url'],
  336. 'idcard_back_img'=>['require','url'],
  337. 'face_img'=>['require','url'],
  338. 'name'=>['require','max:10'],
  339. 'id_no'=>['require'],
  340. 'phone'=>['require','integer'],
  341. ]);
  342. $order=MobileOrder::findOrFail($data['id']);
  343. if($order['open_uploaded']){
  344. $this->error('请勿再次上传');
  345. }
  346. $order['open_uploaded']=1;
  347. $order['open_idcard_face_img']=$data['idcard_face_img'];
  348. $order['open_idcard_back_img']=$data['idcard_back_img'];
  349. $order['open_face_img']=$data['face_img'];
  350. $order['open_name']=$data['name'];
  351. $order['open_id_no']=$data['id_no'];
  352. $order['open_phone']=$data['phone'];
  353. if(!$order->save()){
  354. $this->error('保存失败');
  355. }
  356. $this->success('');
  357. }
  358. }