FinancialRepository.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <?php
  2. namespace app\common\repositories\system\financial;
  3. use app\common\dao\system\financial\FinancialDao;
  4. use app\common\repositories\BaseRepository;
  5. use app\common\repositories\system\merchant\MerchantRepository;
  6. use app\common\repositories\user\UserBillRepository;
  7. use FormBuilder\Factory\Elm;
  8. use think\exception\ValidateException;
  9. use think\facade\Db;
  10. use think\facade\Route;
  11. class FinancialRepository extends BaseRepository
  12. {
  13. public function __construct(FinancialDao $dao)
  14. {
  15. $this->dao = $dao;
  16. }
  17. public function financialAccountForm($id)
  18. {
  19. $merchant = app()->make(MerchantRepository::class)->search(['mer_id' => $id])->find();
  20. $form = Elm::createForm(Route::buildUrl('merchantFinancialAccountSave',['id' => $id])->build());
  21. $form->setRule([
  22. Elm::radio('financial_type', '转账类型', $merchant->financial_type)
  23. ->setOptions([
  24. ['value' => 1, 'label' => '银行卡'],
  25. ['value' => 2, 'label' => '微信'],
  26. ['value' => 3, 'label' => '支付宝'],
  27. ])->control([
  28. [
  29. 'value' => 1,
  30. 'rule'=> [
  31. Elm::input('name', '姓名')->value($merchant->financial_bank->name??'')->required(),
  32. Elm::input('bank', '开户银行')->value($merchant->financial_bank->bank??'')->required(),
  33. Elm::input('bank_code', '银行卡号')->value($merchant->financial_bank->bank_code??'')->required(),
  34. ]
  35. ],
  36. [
  37. 'value' => 2,
  38. 'rule'=> [
  39. Elm::input('name', '姓名')->value($merchant->financial_wechat->name??'')->required(),
  40. Elm::input('wechat', '微信号')->value($merchant->financial_wechat->wechat??'')->required(),
  41. Elm::frameImage('wechat_code', '收款二维码', '/' . config('admin.merchant_prefix') . '/setting/uploadPicture?field=wechat_code&type=1')->value($merchant->financial_wechat->wechat_code??'')->modal(['modal' => false])->width('896px')->height('480px'),
  42. ]
  43. ],
  44. [
  45. 'value' => 3,
  46. 'rule'=> [
  47. Elm::input('name', '姓名')->value($merchant->financial_alipay->name??'')->required(),
  48. Elm::input('alipay', '支付宝账号')->value($merchant->financial_alipay->alipay??'')->required(),
  49. Elm::frameImage('alipay_code', '收款二维码', '/' . config('admin.merchant_prefix') . '/setting/uploadPicture?field=alipay_code&type=1')->value($merchant->financial_alipay->alipay_code??'')->modal(['modal' => false])->width('896px')->height('480px'),
  50. ]
  51. ],
  52. ]),
  53. ]);
  54. return $form->setTitle('转账信息');
  55. }
  56. /**
  57. * TODO 保存转账信息
  58. * @param int $merId
  59. * @param array $data
  60. * @author Qinii
  61. * @day 3/18/21
  62. */
  63. public function saveAccount(int $merId,array $data)
  64. {
  65. switch ($data['financial_type'])
  66. {
  67. case 1:
  68. $key = 'financial_bank' ;
  69. $update = [
  70. 'name' => $data['name'],
  71. 'bank' => $data['bank'],
  72. 'bank_code' => $data['bank_code'],
  73. ];
  74. break;
  75. case 2:
  76. $key = 'financial_wechat' ;
  77. $update = [
  78. 'name' => $data['name'],
  79. //'idcard' => $data['idcard'],
  80. 'wechat' => $data['wechat'],
  81. 'wechat_code' => $data['wechat_code'],
  82. ];
  83. break;
  84. case 3:
  85. $key = 'financial_alipay' ;
  86. $update = [
  87. 'name' => $data['name'],
  88. //'idcard' => $data['idcard'],
  89. 'alipay' => $data['alipay'],
  90. 'alipay_code' => $data['alipay_code'],
  91. ];
  92. break;
  93. }
  94. return app()->make(MerchantRepository::class)->update($merId,[$key => json_encode($update),'financial_type' => $data['financial_type']]);
  95. }
  96. public function applyForm(int $merId)
  97. {
  98. $merchant = app()->make(MerchantRepository::class)->search(['mer_id' => $merId])->field('mer_id,mer_name,mer_money,financial_bank,financial_wechat,financial_alipay,financial_type')->find();
  99. $extract_minimum_line = systemConfig('extract_minimum_line') ?: 0;
  100. $extract_minimum_num = systemConfig('extract_minimum_num');
  101. $_line = bcsub($merchant->mer_money,$extract_minimum_line,2);
  102. $_extract = ($_line < 0) ? 0 : $_line;
  103. $form = Elm::createForm(Route::buildUrl('merchantFinancialCreateSave')->build());
  104. $form->setRule([
  105. [
  106. 'type' => 'span',
  107. 'title' => '商户名称:',
  108. 'children' => [$merchant->mer_name]
  109. ],
  110. [
  111. 'type' => 'span',
  112. 'title' => '商户ID:',
  113. 'children' => ["$merId"]
  114. ],
  115. // [
  116. // 'type' => 'span',
  117. // 'title' => '',
  118. // 'children' => []
  119. // ],
  120. [
  121. 'type' => 'span',
  122. 'title' => '提示:',
  123. 'children' => ['最低可提现额度:'.$extract_minimum_line.'元;最低提现金额:'.$extract_minimum_num.'元']
  124. ],
  125. [
  126. 'type' => 'span',
  127. 'title' => '商户余额:',
  128. 'children' => [$merchant->mer_money]
  129. ],
  130. [
  131. 'type' => 'span',
  132. 'title' => '商户可提现金额:',
  133. 'children' => [$_extract]
  134. ],
  135. Elm::radio('financial_type', '转账类型:', $merchant->financial_type)
  136. ->setOptions([
  137. ['value' => 1, 'label' => '银行卡'],
  138. ['value' => 2, 'label' => '微信'],
  139. ['value' => 3, 'label' => '支付宝'],
  140. ])->control([
  141. [
  142. 'value' => 1,
  143. 'rule'=> [
  144. [
  145. 'type' => 'span',
  146. 'title' => '姓名',
  147. 'native' => false,
  148. 'children' => [$merchant->financial_bank->name??'未填写']
  149. ],
  150. [
  151. 'type' => 'span',
  152. 'title' => '开户银行',
  153. 'native' => false,
  154. 'children' => [$merchant->financial_bank->bank??'未填写']
  155. ],
  156. [
  157. 'type' => 'span',
  158. 'title' => '银行卡号',
  159. 'native' => false,
  160. 'children' => [$merchant->financial_bank->bank_code??'未填写']
  161. ],
  162. ]
  163. ],
  164. [
  165. 'value' => 2,
  166. 'rule'=> [
  167. [
  168. 'type' => 'span',
  169. 'title' => '姓名',
  170. 'native' => false,
  171. 'children' => [$merchant->financial_wechat->name??'未填写']
  172. ],
  173. [
  174. 'type' => 'span',
  175. 'title' => '微信号',
  176. 'native' => false,
  177. 'children' => [$merchant->financial_wechat->wechat??'未填写']
  178. ],
  179. [
  180. 'type' => 'img',
  181. 'title' => '收款二维码',
  182. 'native' => false,
  183. 'attrs' => ['src' => $merchant->financial_wechat->wechat_code ?? ''],
  184. 'style' => ['width' => '86px','height' => '48px']
  185. ],
  186. ]
  187. ],
  188. [
  189. 'value' => 3,
  190. 'rule'=> [
  191. [
  192. 'type' => 'span',
  193. 'title' => '姓名',
  194. 'native' => false,
  195. 'children' => [$merchant->financial_alipay->name??'未填写']
  196. ],
  197. [
  198. 'type' => 'span',
  199. 'title' => '支付宝账号',
  200. 'native' => false,
  201. 'children' => [$merchant->financial_alipay->alipay??'未填写']
  202. ],
  203. [
  204. 'type' => 'img',
  205. 'title' => '收款二维码',
  206. 'native' => false,
  207. 'attrs' => ['src' => $merchant->financial_alipay->alipay_code ?? ''],
  208. 'style' => ['width' => '86px','height' => '48px']
  209. ],
  210. ]
  211. ],
  212. ]),
  213. Elm::number('extract_money', '申请金额:')->value($extract_minimum_num)->required(),
  214. ]);
  215. return $form->setTitle('申请转账');
  216. }
  217. /**
  218. * TODO 保存申请
  219. * @param int $merId
  220. * @param array $data
  221. * @author Qinii
  222. * @day 3/19/21
  223. */
  224. public function saveApply(int $merId,array $data)
  225. {
  226. $make = app()->make(MerchantRepository::class);
  227. $merchant = $make->search(['mer_id' => $merId])->field('mer_id,mer_name,mer_money,financial_bank,financial_wechat,financial_alipay')->find();
  228. if($merchant['mer_money'] <= 0) throw new ValidateException('余额不足');
  229. if($data['financial_type'] == 1){
  230. $financial_account = $merchant->financial_bank;
  231. }elseif ($data['financial_type'] == 2){
  232. $financial_account = $merchant->financial_wechat;
  233. }elseif ($data['financial_type'] == 3){
  234. $financial_account = $merchant->financial_alipay;
  235. }
  236. if(empty($financial_account)) throw new ValidateException('未填写银行转账信息');
  237. $extract_maxmum_num = systemConfig('extract_maxmum_num');
  238. if($extract_maxmum_num !== 0 && $data['extract_money'] > $extract_maxmum_num) throw new ValidateException('单次申请金额不得大于'.$extract_maxmum_num.'元');
  239. //最低提现额度
  240. $extract_minimum_line = systemConfig('extract_minimum_line') ? systemConfig('extract_minimum_line') : 0;
  241. $_line = bcsub($merchant->mer_money,$extract_minimum_line,2);
  242. if($_line < $extract_minimum_line) throw new ValidateException('余额大于'.$extract_minimum_line.'才可提现');
  243. if($data['extract_money'] > $_line) throw new ValidateException('提现金额大于可提现金额');
  244. //最低提现金额
  245. $extract_minimum_num = systemConfig('extract_minimum_num');
  246. if($data['extract_money'] < $extract_minimum_num) throw new ValidateException('最低提现金额'.$extract_minimum_num);
  247. //可提现金额
  248. $_line = bcsub($merchant->mer_money,$extract_minimum_line,2);
  249. if($_line < 0) throw new ValidateException('余额大于'.$extract_minimum_line.'才可提现');
  250. //最低提现金额
  251. if($data['extract_money'] < $extract_minimum_num) throw new ValidateException('最低提现金额'.$extract_minimum_num);
  252. //不足提现最低金额
  253. if($_line < $extract_minimum_num) throw new ValidateException('提现金额不足');
  254. $_money = bcsub($merchant['mer_money'],$data['extract_money'],2);
  255. $sn = date('YmdHis'.$merId);
  256. $ret = [
  257. 'status' => 0,
  258. 'mer_id' => $merId,
  259. 'mer_money' => $_money,
  260. 'financial_sn' => $sn,
  261. 'extract_money' => $data['extract_money'],
  262. 'financial_type' => $data['financial_type'],
  263. 'financial_account' => json_encode($financial_account),
  264. 'financial_status' => 0,
  265. 'mer_admin_id' => $data['mer_admin_id'],
  266. 'mark' => $datap['mark']??'',
  267. ];
  268. Db::transaction(function()use($merId,$ret,$data,$make){
  269. $this->dao->create($ret);
  270. $make->subMoney($merId,(float)$data['extract_money']);
  271. });
  272. }
  273. /**
  274. * TODO 商户列表
  275. * @param array $where
  276. * @param int $page
  277. * @param int $limit
  278. * @return array
  279. * @author Qinii
  280. * @day 3/19/21
  281. */
  282. public function getAdminList(array $where,int $page,int $limit)
  283. {
  284. $where['is_del'] = 0;
  285. $query = $this->dao->search($where)->with([
  286. 'merchant' => function($query){
  287. $query->field('mer_id,mer_name,is_trader,mer_avatar,mer_phone,mer_address');
  288. }
  289. ]);
  290. $count = $query->count();
  291. $list = $query->page($page, $limit)->select();
  292. return compact('count','list');
  293. }
  294. /**
  295. * TODO 取消/拒绝 变更状态返还余额
  296. * @param $merId
  297. * @param $id
  298. * @param $data
  299. * @author Qinii
  300. * @day 3/19/21
  301. */
  302. public function cancel(?int $merId,int $id,array $data)
  303. {
  304. $where = [
  305. 'financial_id' => $id,
  306. 'is_del' => 0,
  307. 'status' => 0
  308. ];
  309. if($merId) $where['mer_id'] = $merId;
  310. $res = $this->dao->getWhere($where);
  311. if(!$res) throw new ValidateException('数据不存在');
  312. if($res['financial_status'] == 1) throw new ValidateException('当前状态无法完成此操作');
  313. $merId = $merId?? $res['mer_id'];
  314. Db::transaction(function()use($merId,$res,$id,$data) {
  315. $this->dao->update($id,$data);
  316. app()->make(MerchantRepository::class)->addMoney($merId, (float)$res['extract_money']);
  317. });
  318. }
  319. /**
  320. * TODO
  321. * @param $id
  322. * @return \FormBuilder\Form
  323. * @author Qinii
  324. * @day 4/21/21
  325. */
  326. public function markForm($id)
  327. {
  328. $data = $this->dao->get($id);
  329. $form = Elm::createForm(Route::buildUrl('merchantFinancialMark', ['id' => $id])->build());
  330. $form->setRule([
  331. Elm::text('mark', '备注', $data['mark'])->required(),
  332. ]);
  333. return $form->setTitle('修改备注');
  334. }
  335. /**
  336. * TODO
  337. * @param $id
  338. * @return \FormBuilder\Form
  339. * @author Qinii
  340. * @day 4/21/21
  341. */
  342. public function adminMarkForm($id)
  343. {
  344. $data = $this->dao->get($id);
  345. $form = Elm::createForm(Route::buildUrl('systemFinancialMark', ['id' => $id])->build());
  346. $form->setRule([
  347. Elm::text('admin_mark', '备注', $data['admin_mark'])->required(),
  348. ]);
  349. return $form->setTitle('修改备注');
  350. }
  351. /**
  352. * TODO 详情
  353. * @param $id
  354. * @return array|\think\Model|null
  355. * @author Qinii
  356. * @day 4/22/21
  357. */
  358. public function detail($id,$merId=0)
  359. {
  360. $where[$this->dao->getPk()] = $id;
  361. if($merId) $where['mer_id'] = $merId;
  362. $data = $this->dao->getSearch($where)->with(['merchant' => function($query){
  363. $query->field('mer_id,mer_name,mer_avatar');
  364. }])->find();
  365. if(!$data) throw new ValidateException('数据不存在');
  366. return $data;
  367. }
  368. /**
  369. * TODO 头部统计
  370. * @return array
  371. * @author Qinii
  372. * @day 4/22/21
  373. */
  374. public function getTitle()
  375. {
  376. $make = app()->make(MerchantRepository::class);
  377. //应付商户金额 = 所有商户的余额之和
  378. $all = $make->search(['is_del' => 0])->sum('mer_money');
  379. //商户可提现金额 = (每个商户的余额 - 平台设置的最低提现额度) 之和
  380. $extract_minimum_line = systemConfig('extract_minimum_line') ?: 0;
  381. $ret = $make->search(['is_del' => 0])->where('mer_money','>',$extract_minimum_line)
  382. ->field("sum(mer_money - $extract_minimum_line) as money")
  383. ->find();
  384. $money = $ret->money;
  385. //申请转账的商户数 = 申请提现且未转账的商户数量
  386. $where = [
  387. "financial_status" => 0
  388. ];
  389. $query = $this->dao->getSearch($where)->where('status','>',-1);
  390. $count = $query->group('mer_id')->count();
  391. //申请转账的总金额 = 申请提现已通过审核,且未转账的申请金额 之和
  392. $where['status'] = 1;
  393. $all_ = $this->dao->getSearch($where)->sum('extract_money');
  394. $where['status'] = 0;
  395. $all_0 = $this->dao->getSearch($where)->sum('extract_money');
  396. $merLockMoney = app()->make(UserBillRepository::class)->merchantLickMoney();
  397. $stat = [
  398. [
  399. 'className' => 'el-icon-s-goods',
  400. 'count' => $all,
  401. 'field' => '元',
  402. 'name' => '应付商户金额'
  403. ],
  404. [
  405. 'className' => 'el-icon-s-goods',
  406. 'count' => $money,
  407. 'field' => '元',
  408. 'name' => '商户可提现金额'
  409. ],
  410. [
  411. 'className' => 'el-icon-s-goods',
  412. 'count' => $count,
  413. 'field' => '个',
  414. 'name' => '申请转账的商户数'
  415. ],
  416. [
  417. 'className' => 'el-icon-s-goods',
  418. 'count' => $all_,
  419. 'field' => '元',
  420. 'name' => '申请转账的总金额'
  421. ],
  422. [
  423. 'className' => 'el-icon-s-goods',
  424. 'count' => $all_0,
  425. 'field' => '元',
  426. 'name' => '待审核的总金额'
  427. ],
  428. [
  429. 'className' => 'el-icon-s-goods',
  430. 'count' => $merLockMoney,
  431. 'field' => '元',
  432. 'name' => '商户冻结金额'
  433. ],
  434. ];
  435. return $stat;
  436. }
  437. }