MerchantApplymentsRepository.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. <?php
  2. namespace app\common\repositories\system\merchant;
  3. use app\common\dao\system\merchant\MerchantAppymentsDao;
  4. use app\common\model\system\merchant\MerchantApplyments;
  5. use app\common\repositories\BaseRepository;
  6. use ln\services\ImageWaterMarkService;
  7. use ln\services\UploadService;
  8. use ln\services\WechatService;
  9. use ln\services\YunxinSmsService;
  10. use FormBuilder\Factory\Elm;
  11. use function Symfony\Component\String\b;
  12. use think\db\concern\Transaction;
  13. use think\exception\ValidateException;
  14. use think\facade\Cache;
  15. use think\facade\Db;
  16. use think\facade\Queue;
  17. use think\facade\Route;
  18. class MerchantApplymentsRepository extends BaseRepository
  19. {
  20. public function __construct(MerchantAppymentsDao $dao)
  21. {
  22. $this->dao = $dao;
  23. }
  24. /**
  25. * TODO 申请
  26. * @param array $data
  27. * @param $merId
  28. * @return mixed
  29. * @author Qinii
  30. * @day 6/23/21
  31. */
  32. public function create(array $data,$merId)
  33. {
  34. $count = $this->dao->getSearch(['mer_id' => $merId])->count('*');
  35. if($count) throw new ValidateException('此商户已存在申请信息');
  36. $out_request_no = $this->getOutRequestNo($merId);
  37. $ret['mer_name'] = $data['merchant_shortname'];
  38. $ret['out_request_no'] = $out_request_no;
  39. $data['out_request_no'] = $out_request_no;
  40. $ret['info'] = json_encode($data,JSON_UNESCAPED_UNICODE);
  41. $ret['mer_id'] = $merId;
  42. $this->dao->create($ret);
  43. }
  44. /**
  45. * TODO 整理请求数据
  46. * @param $info
  47. * @return mixed
  48. * @author Qinii
  49. * @day 6/24/21
  50. */
  51. public function sltData($info)
  52. {
  53. foreach ($info as $key => $value){
  54. if(is_object($value)){
  55. $value = (array)$value;
  56. }
  57. $data[$key] = $value;
  58. }
  59. $data['id_doc_type'] = $this->dao->getIdDocType($data['id_doc_type']);
  60. //营业执照
  61. if(isset($data['business_license_info'])){
  62. if(isset($data['business_license_info']['business_license_copy'])) {
  63. $business_license_copy = $data['business_license_info']['business_license_copy']->media_id;
  64. unset($data['business_license_info']['business_license_copy']);
  65. $data['business_license_info']['business_license_copy'] = $business_license_copy;
  66. }
  67. if(isset($data['business_license_info']['business_time'])){
  68. $organization_time = json_encode($data['business_license_info']['business_time'],JSON_UNESCAPED_UNICODE);
  69. $data['business_license_info']['business_time'] = $organization_time;
  70. }
  71. }
  72. //组织机构代码
  73. if(isset($data['organization_cert_info'])){
  74. if(isset($data['organization_cert_info']['organization_copy'])) {
  75. $organization_copy = $data['organization_cert_info']['organization_copy']->media_id;
  76. unset($data['organization_cert_info']['organization_copy']);
  77. $data['organization_cert_info']['organization_copy'] = $organization_copy;
  78. }
  79. if(isset($data['organization_cert_info']['organization_time'])){
  80. $organization_time = json_encode($data['organization_cert_info']['organization_time'],JSON_UNESCAPED_UNICODE);
  81. $data['organization_cert_info']['organization_time'] = $organization_time;
  82. }
  83. }
  84. //身份证
  85. if(isset($data['id_card_info'])){
  86. if(isset($data['id_card_info']['id_card_copy'])) {
  87. $id_card_copy = $data['id_card_info']['id_card_copy']->media_id;
  88. unset($data['id_card_info']['id_card_copy']);
  89. $data['id_card_info']['id_card_copy'] = $id_card_copy;
  90. }
  91. if(isset($data['id_card_info']['id_card_national'])) {
  92. $id_card_national = $data['id_card_info']['id_card_national']->media_id;
  93. unset($data['id_card_info']['id_card_national']);
  94. $data['id_card_info']['id_card_national'] = $id_card_national;
  95. }
  96. }
  97. //银行
  98. if(isset($data['account_info'])) {
  99. if(is_array($data['account_info']['bank_address_code'])){
  100. $bank_address_code = (string)$data['account_info']['bank_address_code'][2];
  101. unset($data['account_infoaccount_info']['bank_address_code']);
  102. $data['account_info']['bank_address_code'] = $bank_address_code;
  103. }
  104. $data['account_info']['bank_account_type'] = (string)$data['account_info']['bank_account_type'];
  105. }
  106. //管理员
  107. if(isset($data['contact_info'])) {
  108. $data['contact_info']['contact_type'] = (string)$data['contact_info']['contact_type'];
  109. }
  110. //其他证件
  111. if(isset($data['id_doc_info'])){
  112. $doc_ = json_encode($data['id_doc_info']['doc_period_end'],JSON_UNESCAPED_UNICODE);
  113. $data['id_doc_info']['doc_period_end'] = $doc_;
  114. if(isset($data['id_doc_info']['id_doc_copy'])) {
  115. $id_doc_copy = $data['id_doc_info']['id_doc_copy']->media_id;
  116. unset($data['id_doc_info']['id_doc_copy']);
  117. $data['id_doc_info']['id_doc_copy'] = $id_doc_copy;
  118. }
  119. }
  120. //店铺信息
  121. if(isset($data['sales_scene_info']['store_qr_code']) && $data['sales_scene_info']['store_qr_code']){
  122. $store_qr_code= $data['sales_scene_info']['store_qr_code']->media_id;
  123. unset($data['sales_scene_info']['store_qr_code']);
  124. $data['sales_scene_info']['store_qr_code'] = $store_qr_code;
  125. }
  126. //特殊资质
  127. if(isset($data['qualifications']) && !empty($data['qualifications'])){
  128. $qualifications = [];
  129. foreach ($data['qualifications'] as $item){
  130. $qualifications[] = $item->media_id;
  131. }
  132. unset($data['qualifications']);
  133. $data['qualifications'] = json_encode($qualifications,JSON_UNESCAPED_UNICODE);
  134. }
  135. //补充材料
  136. if(isset($data['business_addition_pics']) && !empty($data['business_addition_pics'])){
  137. $business_addition_pics = [];
  138. foreach ($data['business_addition_pics'] as $item){
  139. $business_addition_pics[] = $item->media_id;
  140. }
  141. unset($data['business_addition_pics']);
  142. $data['business_addition_pics'] = json_encode($business_addition_pics,JSON_UNESCAPED_UNICODE);
  143. }
  144. $data['organization_type'] = (string)$data['organization_type'];
  145. return $data;
  146. }
  147. /**
  148. * TODO 生成申请单
  149. * @param $merId
  150. * @return string
  151. * @author Qinii
  152. * @day 6/24/21
  153. */
  154. public function getOutRequestNo($merId)
  155. {
  156. list($msec, $sec) = explode(' ', microtime());
  157. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  158. $key = 'MERCHANT' . $merId . '_' . $msectime . mt_rand(10000, max(intval($msec * 10000) + 10000, 98369));
  159. do{
  160. $ret = $this->dao->getSearch(['out_request_no' => $key])->count();
  161. }while($ret);
  162. return $key;
  163. }
  164. /**
  165. * TODO 详情
  166. * @param $id
  167. * @param $merId
  168. * @return array|\think\Model|null
  169. * @author Qinii
  170. * @day 6/22/21
  171. */
  172. public function detail(int $merId)
  173. {
  174. if($merId) $where['mer_id'] = $merId;
  175. $data = $this->dao->getSearch($where)->find();
  176. if(!$data) return [];
  177. $data['info'] = json_decode($data['info']);
  178. return $data;
  179. }
  180. /**
  181. * TODO 编辑
  182. * @param $id
  183. * @param $data
  184. * @author Qinii
  185. * @day 6/22/21
  186. */
  187. public function edit($id,$data)
  188. {
  189. //申请状态: 0.平台未提交,-1.平台驳回,10.平台提交审核中,11.需用户操作 ,20.已完成,30.已冻结,40.驳回
  190. $get = $this->dao->get($id);
  191. if(!$get) throw new ValidateException('数据不存在');
  192. if(!in_array($get['status'],[-1,0,40])) throw new ValidateException('数据当前状态不可编辑');
  193. $data['out_request_no'] = $get['out_request_no'];
  194. $ret['info'] = json_encode($data,JSON_UNESCAPED_UNICODE);
  195. $ret['status'] = 0;
  196. $ret['message'] = '';
  197. $this->dao->update($id,$ret);
  198. }
  199. /**
  200. * TODO 查询申请状态
  201. * @param $merId
  202. * @author Qinii
  203. * @day 6/23/21
  204. */
  205. public function check($merId)
  206. {
  207. $ret = $this->dao->getSearch(['mer_id' => $merId])->find();
  208. $data = [];
  209. if($ret['status'] < 10) throw new ValidateException('平台审核中...');
  210. if($ret['status'] == 20) throw new ValidateException('申请已完成,请勿重复查询');
  211. try{
  212. $data = WechatService::create()->applyments()->getApplicationById($ret->applyment_id);
  213. }catch (\Exception $exception){
  214. }
  215. if(!$data){
  216. $data = WechatService::create()->applyments()->getApplicationByNo($ret->out_request_no);
  217. if($data){
  218. $ret->applyment_id = $data['applyment_id'];
  219. $ret->save();
  220. }
  221. }
  222. if($data) {
  223. $result = $this->getApplymentState($data);
  224. $this->sendSms($ret,$result['status']);
  225. return Db::transaction(function () use ($merId, $ret, $result) {
  226. $this->dao->update($ret->mer_applyments_id, $result);
  227. if (isset($result['sub_mchid'])) $this->profitsharingAdd($ret,$result);
  228. });
  229. }else{
  230. return ;
  231. }
  232. }
  233. /**
  234. * TODO 添加分账商户
  235. * @param MerchantApplyments $ret
  236. * @param $result
  237. * @author Qinii
  238. * @day 6/24/21
  239. */
  240. public function profitsharingAdd(MerchantApplyments $ret,$result)
  241. {
  242. $info = json_decode($ret['info']);
  243. $profitsharing = [
  244. "type" => 'MERCHANT_ID',
  245. "account" => $result['sub_mchid'],
  246. "name" => $info->account_info->account_name,
  247. "relation_type" => "PLATFORM"
  248. ];
  249. $res = WechatService::create()->applyments()->profitsharingAdd($profitsharing);
  250. if(isset($res['account'])) app()->make(MerchantRepository::class)->update($ret->mer_id, ['sub_mchid' => $res['account'] ]);
  251. }
  252. /**
  253. * TODO 查询返回的状态整理
  254. * @param $data
  255. * @return array
  256. * @author Qinii
  257. * @day 6/23/21
  258. */
  259. public function getApplymentState($data)
  260. {
  261. //CHECKING:资料校验中
  262. //ACCOUNT_NEED_VERIFY:待账户验证
  263. //AUDITING:审核中
  264. //REJECTED:已驳回
  265. //NEED_SIGN:待签约
  266. //FINISH:完成
  267. //FROZEN:已冻结
  268. $result = [];
  269. $message = '';
  270. $status = 10;
  271. switch (($data['applyment_state']))
  272. {
  273. //申请状态: 0.平台未提交,-1.平台驳回,10.平台提交审核中,11.需用户操作 ,20.已完成,30.已冻结,40.驳回
  274. case 'ACCOUNT_NEED_VERIFY':
  275. $status = 11;
  276. if(isset($data['account_validation'])){
  277. $ret = $data['account_validation'];
  278. $message = '通过申请银行账号向以下信息汇款完成验证'.PHP_EOL;
  279. $message = '收款方信息:'.PHP_EOL;
  280. $message .= "汇款金额:".$ret['pay_amount'].PHP_EOL;
  281. $message .= "收款卡号:".$ret['account_name'].PHP_EOL;
  282. $message .= "收款户名:".$ret['destination_account_name'].PHP_EOL;
  283. $message .= "开户银行:".$ret['destination_account_bank'].PHP_EOL;
  284. $message .= "省市信息:".$ret['city'].PHP_EOL;
  285. $message .= "备注信息:".$ret['remark'].PHP_EOL;
  286. $message .= "汇款截止时间:".$ret['deadline'];
  287. }
  288. if(isset($data['legal_validation_url'])){
  289. $message = '商户法人通过此链接完成验证:'.$data['legal_validation_url'];
  290. }
  291. break;
  292. case 'REJECTED':
  293. $message = '';
  294. foreach ($data['audit_detail'] as $datum){
  295. $message .= '参数名称:'.$datum['param_name'].PHP_EOL;
  296. $message .= '驳回原因:'.$datum['reject_reason'].PHP_EOL;
  297. }
  298. $status = 40;
  299. break;
  300. case 'NEED_SIGN':
  301. $status = 11;
  302. $message = $data['sign_url'];
  303. break;
  304. case 'FINISH':
  305. $result['sub_mchid'] = $data['sub_mchid'];
  306. $status = 20;
  307. $message = '完成';
  308. break;
  309. case 'FROZEN':
  310. $status = 30;
  311. break;
  312. default:
  313. break;
  314. }
  315. $result['status'] = $status;
  316. $result['message'] = $message;
  317. return $result;
  318. }
  319. /**
  320. * TODO 上传图片
  321. * @param $field
  322. * @return array
  323. * @author Qinii
  324. * @day 6/21/21
  325. */
  326. public function uploadImage($field,$water)
  327. {
  328. $upload = UploadService::create(0);
  329. $info = $upload->to('def')->move($field);
  330. if ($info === false) throw new ValidateException($upload->getError());
  331. $res = $upload->getUploadInfo();
  332. $res['path'] = app()->getRootPath().'public'.($res['dir']);
  333. $res['dir'] = tidy_url($res['dir']);
  334. if($res['path']) $ret = WechatService::create()->uploadImages([$res]);
  335. if(!$water) app()->make(ImageWaterMarkService::class)->run($res['path']);
  336. return $ret;
  337. }
  338. /**
  339. * TODO 列表
  340. * @param array $where
  341. * @param int $page
  342. * @param int $limit
  343. * @return array
  344. * @author Qinii
  345. * @day 6/24/21
  346. */
  347. public function getList(array $where, int $page, int $limit)
  348. {
  349. $query = $this->dao->getSearch($where)->with(['merchant' => function($query){
  350. $query->field('mer_id,mer_name');
  351. }])->order('create_time DESC');
  352. $count = $query->count();
  353. $list = $query->page($page,$limit)->select();
  354. return compact('count','list');
  355. }
  356. /**
  357. * TODO 审核操作
  358. * @param int $id
  359. * @param array $data
  360. * @author Qinii
  361. * @day 6/23/21
  362. */
  363. public function switchWithStatus(int $id,array $data)
  364. {
  365. $ret = $this->dao->get($id);
  366. if(!$ret) throw new ValidateException('数据不存在');
  367. if($ret['status'] !== 0) throw new ValidateException('请勿重复审核');
  368. if($data['status'] == 10){
  369. $info = $this->sltData(json_decode($ret['info']));
  370. Db::transaction(function() use($id,$info){
  371. $this->dao->update($id,['status' => 10]);
  372. WechatService::create()->applyments()->submitApplication($info);
  373. });
  374. }
  375. if($data['status'] == -1) {
  376. $this->dao->update($id,$data);
  377. $this->sendSms($ret,-1);
  378. }
  379. return ;
  380. }
  381. /**
  382. * TODO 发送短信
  383. * @param MerchantApplyments $ret
  384. * @param $type
  385. * @author Qinii
  386. * @day 7/9/21
  387. */
  388. public function sendSms(MerchantApplyments $ret,$type)
  389. {
  390. if(!systemConfig('applyments_sms')) return ;
  391. $sms = (YunxinSmsService::create());
  392. $info = json_decode($ret['info']);
  393. switch ($type)
  394. {
  395. case -1:
  396. $tmp = 'APPLYMENTS_FAIL';
  397. break;
  398. case 11:
  399. $tmp = 'APPLYMENTS_SIGN';
  400. break;
  401. case 20:
  402. $tmp = 'APPLYMENTS_SUCCESS';
  403. break;
  404. case 40:
  405. $tmp = 'APPLYMENTS_FAIL';
  406. break;
  407. default:
  408. return ;
  409. break;
  410. }
  411. $sms->send($info->contact_info->mobile_phone, $tmp, ['mer_name' => $info->merchant_shortname]);
  412. }
  413. /**
  414. * TODO 查询商户的分账信息
  415. * @param $merId
  416. * @return mixed
  417. * @author Qinii
  418. * @day 6/24/21
  419. */
  420. public function getMerchant($merId)
  421. {
  422. $data = app()->make(MerchantRepository::class)->get($merId);
  423. if(!$data) throw new ValidateException('数据不存在');
  424. if(!$data['sub_mchid']) throw new ValidateException('该商户不是分账商户');
  425. $ret = WechatService::create()->applyments()->getSubMerchant($data['sub_mchid']);
  426. return $ret;
  427. }
  428. /**
  429. * TODO 备注
  430. * @param $id
  431. * @return \FormBuilder\Form
  432. * @author Qinii
  433. * @day 7/5/21
  434. */
  435. public function markForm($id)
  436. {
  437. $data = $this->dao->get($id);
  438. $form = Elm::createForm(Route::buildUrl('systemMerchantApplymentsMarrkSave', ['id' => $id])->build());
  439. $form->setRule([
  440. Elm::text('mark', '备注', $data['mark'])->required(),
  441. ]);
  442. return $form->setTitle('修改备注');
  443. }
  444. }