StoreCashController.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\controllers;
  8. use app\constants\OptionSetting;
  9. use app\models\Cash;
  10. use app\models\StoreCash;
  11. use app\models\StoreAccountLog;
  12. use app\models\Admin;
  13. use app\models\Form;
  14. use app\models\IntegralSetting;
  15. use app\models\Option;
  16. use app\models\Store;
  17. use app\models\StoreTemplate;
  18. use app\models\SaasCategory;
  19. use app\models\StoreCopy;
  20. use app\modules\admin\models\SubmitFormForm;
  21. use app\utils\Delivery\Delivery;
  22. use app\utils\yunst\src\OrderYunst;
  23. use Yii;
  24. use app\modules\admin\models\StoreForm;
  25. use app\modules\admin\models\SaasCategoryForm;
  26. use yii\base\BaseObject;
  27. use app\models\SaasUser;
  28. use app\models\Salesman;
  29. use yii\helpers\Json;
  30. use app\utils\IotCloudHelper;
  31. use app\constants\Kefu;
  32. use app\models\Supplier;
  33. class StoreCashController extends BaseController
  34. {
  35. public function actionTestCash() {
  36. $data = [
  37. 'partner_trade_no' => 'CStest001',
  38. 'openid' => 'or1pO5f5zi-atTmKVuni3KGgvCns',
  39. 'check_name' => 'NO_CHECK',
  40. 'amount' => 0.01 * 100,
  41. 'desc' => '转账'
  42. ];
  43. $wechat = \Yii::$app->controller->wechatPay;
  44. $res = $wechat->transfer->toBalance($data);
  45. var_dump($res);die;
  46. }
  47. //商城余额信息
  48. public function actionStoreMoney() {
  49. $store_id = get_store_id();
  50. $store = \app\models\Store::findOne($store_id);
  51. $data = [];
  52. //商城总金额
  53. $maxMoney = StoreCash::getMaxCash($store, $data);
  54. //已提现
  55. $moneyCash = StoreCash::find()->where(['store_id' => $store->id, 'is_delete' => 0, 'status' => 2, 'cash_type' => StoreCash::CASH_TYPE_NORMAL])
  56. ->andWhere(['>', 'price', 0])
  57. ->sum('price');
  58. $user_cash = Cash::find()->where(['store_id' => $store->id, 'is_delete' => 0, 'status' => 2])
  59. ->andWhere(['>', 'price', 0])
  60. ->sum('price') ?: '0.00';
  61. $yunst_money = 0;
  62. $yunst_frozen_money = 0;
  63. $yunst_store_money_total = 0;
  64. if ($store->cusid){
  65. //查询余额账户信息
  66. $orderYunst = new OrderYunst();
  67. $res = $orderYunst->queryAcctInfo($store->store_number);
  68. // $res = $orderYunst->queryAcctInfo('XDQXCJSZPJYB');
  69. if ($res['subCode']=='SUCCESS' ){
  70. $freezenAmount = $res['data']['freezenAmount'];//冻结
  71. $amount = $res['data']['amount'];//可用余额
  72. if (($freezenAmount + $amount) >0){
  73. $yunst_store_money_total = ($freezenAmount + $amount) / 100;//累计
  74. }else{
  75. $yunst_store_money_total = 0;//累计
  76. }
  77. $yunst_frozen_money = $freezenAmount?$freezenAmount/100:0;;//冻结
  78. $yunst_money = $amount?$amount/100:0;//账户总金额 可提现的
  79. }
  80. }
  81. return $this->asJson([
  82. 'code' => 0,
  83. 'msg' => 'ok',
  84. 'data' => [
  85. 'max_cash' => $maxMoney,
  86. 'moneyFrozen' => $data['moneyFrozen'],
  87. 'moneyCash' => $moneyCash ?: '0.00',
  88. 'moneyTotal' => bcadd($data['storeMoneyTotal'], $yunst_store_money_total, 2),
  89. 'user_cash' => $user_cash,
  90. 'yunst_money' => $yunst_money ?: '0.00',
  91. 'yunst_frozen_money' => $yunst_frozen_money ?: '0.00',
  92. 'yunst_store_money_total' => $yunst_store_money_total
  93. ]
  94. ]);
  95. }
  96. //saas余额信息
  97. public function actionSaasMoney() {
  98. $data = [];
  99. $moneyCash = StoreCash::find()->where(['store_id' =>'-1', 'is_delete' => 0, 'status' => 2, 'cash_type' => StoreCash::CASH_TYPE_NORMAL])
  100. ->andWhere(['>', 'price', 0])
  101. ->sum('price');
  102. //查询saas余额账户信息
  103. $orderYunst = new OrderYunst();
  104. $store_id = get_store_id();
  105. $store = \app\models\Store::findOne($store_id);
  106. // $res = $orderYunst->queryAcctInfo($store->store_number);
  107. // $res = $orderYunst->queryAcctInfo('66065100000219T');
  108. $oldConf = Option::get(OptionSetting::SAAS_YUNST_SETTING, 0, 'saas')['value'];
  109. if ($oldConf) {
  110. $oldConf = json_decode($oldConf, true);
  111. if (!empty($oldConf)) {
  112. $customer_number = $oldConf['customer_number'];
  113. $res = $orderYunst->queryAcctInfo($customer_number);
  114. if ($res['subCode']=='SUCCESS' ){
  115. $freezenAmount = $res['data']['freezenAmount'];//冻结
  116. $amount = $res['data']['amount'];//可用余额
  117. if (($freezenAmount + $amount) >0){
  118. $storeMoneyTotal = ($freezenAmount + $amount ) / 100 + $moneyCash;
  119. }else{
  120. $storeMoneyTotal = 0;
  121. }
  122. $data['moneyFrozen'] = $freezenAmount?$freezenAmount/100:0;;//冻结
  123. $data['storeMoneyTotal'] = $storeMoneyTotal;//累计
  124. $maxMoney = $amount?$amount/100:0;//账户总金额 可提现的
  125. }
  126. }
  127. }
  128. return $this->asJson([
  129. 'code' => 0,
  130. 'msg' => 'ok',
  131. 'data' => [
  132. 'max_cash' => $maxMoney,
  133. 'moneyFrozen' => $data['moneyFrozen'],
  134. 'moneyCash' => $moneyCash,
  135. 'moneyTotal' => $data['storeMoneyTotal'],
  136. ]
  137. ]);
  138. }
  139. //商城提现删除
  140. public function actionStoreCashDel() {
  141. $id = post_params('id');
  142. if (empty($id) || !is_array($id)) {
  143. \Yii::error([__METHOD__, $id]);
  144. return $this->asJson([
  145. 'code' => 1,
  146. 'msg' => '数据格式错误'
  147. ]);
  148. }
  149. $del = StoreCash::updateAll(['is_delete' => 1], ['id' => $id]);
  150. return $this->asJson([
  151. 'code' => $del ? 0 : 1 ,
  152. 'msg' => '删除数量:' . $del,
  153. ]);
  154. }
  155. //商城提现
  156. public function actionStoreCashCreate() {
  157. $price = post_params('cash');
  158. $type = post_params('type');
  159. $name = post_params('name');
  160. $mobile = post_params('mobile');
  161. $bank_name = post_params('bank_name');
  162. if (!$price || !in_array($type, ['alipay', 'bank_card', 'wechat','yunst'])) {
  163. return $this->asJson([
  164. 'code' => 1,
  165. 'msg' => '参数非法',
  166. ]);
  167. }
  168. $store_id = get_store_id();
  169. $store = Store::findOne($store_id);
  170. if ($store->cusid){
  171. $orderYunst = new OrderYunst();
  172. $res = $orderYunst->queryAcctInfo($store->store_number);
  173. $amount = 0;
  174. if ($res['subCode'] == 'SUCCESS'){
  175. $amount = $res['data']['amount'];//真的
  176. // $amount = 10;//写的假的
  177. }
  178. if ($price > $amount) {
  179. \Yii::error([__METHOD__, $price, $amount]);
  180. return $this->asJson([
  181. 'code' => 1,
  182. 'msg' => '当前大于可提现金额'
  183. ]);
  184. }
  185. }else{
  186. //商城余额是否充足
  187. $storeMoney = \app\models\StoreCash::getMaxCash($store);
  188. if ($price > $storeMoney) {
  189. \Yii::error([__METHOD__, $price, $storeMoney]);
  190. return $this->asJson([
  191. 'code' => 1,
  192. 'msg' => '当前大于可提现金额'
  193. ]);
  194. }
  195. }
  196. $exit = StoreCash::find()->andWhere(['=', 'status', 0])->andWhere(['store_id' => $store_id, 'cash_type' => StoreCash::CASH_TYPE_NORMAL])->exists();
  197. if ($exit) {
  198. \Yii::error([__METHOD__, $store_id, $exit]);
  199. // return $this->asJson([
  200. // 'code' => 1,
  201. // 'msg' => '尚有未完成的提现申请'
  202. // ]);
  203. }
  204. $t = \Yii::$app->db->beginTransaction();
  205. $cash = new StoreCash();
  206. $cash->order_no = \app\utils\OrderNo::getOrderNo(\app\utils\OrderNo::ORDER_CASH);
  207. $cash->is_delete = 0;
  208. $cash->status = 0;
  209. $cash->price = $price;
  210. $cash->created_at = time();
  211. $cash->store_id = $store_id;
  212. if ($type == 'wechat') {
  213. $cash->type = 0;
  214. $cash->name = $name;
  215. $cash->mobile = $mobile;
  216. }
  217. if ($type == 'alipay') {
  218. $cash->type = 1;
  219. $cash->name = $name;
  220. $cash->mobile = $mobile;
  221. }
  222. if ($type == 'bank_card') {
  223. $cash->type = 2;
  224. $cash->name = $name;
  225. $cash->mobile = $mobile;
  226. $cash->bank_name = $bank_name;
  227. }
  228. if ($type == 'yunst') {
  229. $cash->type =6;//通联提现
  230. $cash->name = $name;
  231. $cash->mobile = $mobile;
  232. }
  233. $cash->pay_time = 0;
  234. $cash->service_charge = 0;
  235. $cash->cash_type = 0;
  236. if ($cash->save()) {
  237. $subMoney = \app\models\Store::subMoney($store, $price, '商城提现');
  238. if (!$subMoney) {
  239. $t->rollBack();
  240. \Yii::error([__METHOD__, $subMoney, $cash]);
  241. return $this->asJson([
  242. 'code' => 1,
  243. 'msg' => '扣款失败',
  244. ]);
  245. }
  246. $t->commit();
  247. return $this->asJson([
  248. 'code' => 0,
  249. 'msg' => '申请成功'
  250. ]);
  251. } else {
  252. \Yii::error([__METHOD__, $cash]);
  253. $t->rollBack();
  254. return $this->asJson([
  255. 'code' => 1,
  256. 'msg' => $cash->errors
  257. ]);
  258. }
  259. }
  260. //平台提现
  261. public function actionSaasCashCreate() {
  262. $price = post_params('cash');
  263. $type = post_params('type');
  264. $store_id = get_store_id();
  265. $name = post_params('name');
  266. $mobile = post_params('mobile');
  267. $bank_name = post_params('bank_name');
  268. if (!$price || !in_array($type, ['alipay', 'bank_card', 'wechat','yunst'])) {
  269. return $this->asJson([
  270. 'code' => 1,
  271. 'msg' => '参数非法',
  272. ]);
  273. }
  274. $orderYunst = new OrderYunst();
  275. $store_id = get_store_id();
  276. $store = \app\models\Store::findOne($store_id);
  277. $res = $orderYunst->queryAcctInfo($store->store_number);
  278. // $res = $orderYunst->queryAcctInfo('XDQXCJSZPJYB');
  279. debug_log($res);
  280. $amount = 0;
  281. if ($res['subCode'] == 'SUCCESS'){
  282. $amount = $res['data']['amount'];//真的
  283. // $amount = 10;//写的假的
  284. }
  285. if ($price > $amount) {
  286. \Yii::error([__METHOD__, $price, $amount]);
  287. return $this->asJson([
  288. 'code' => 1,
  289. 'msg' => '当前大于可提现金额'
  290. ]);
  291. }
  292. $exit = StoreCash::find()->andWhere(['=', 'status', 0])->andWhere(['store_id' => -1, 'cash_type' => StoreCash::CASH_TYPE_NORMAL])->exists();
  293. if ($exit) {
  294. // return $this->asJson([
  295. // 'code' => 1,
  296. // 'msg' => '尚有未完成的提现申请'
  297. // ]);
  298. }
  299. $t = \Yii::$app->db->beginTransaction();
  300. $order_no = \app\utils\OrderNo::getOrderNo(\app\utils\OrderNo::ORDER_CASH);
  301. $orderYunst = new OrderYunst();
  302. $data['bizOrderNo'] = $order_no;
  303. $store = Store::findOne(['id' => $store_id]);
  304. $data['bizUserId'] = $store->store_number;
  305. // $data['bizUserId'] = "XDQXCJSZPJYB";//测试服务端客户号
  306. $data['amount'] = $price * 100;
  307. $data['notifyUrl'] = Yii::$app->request->hostInfo;
  308. $data['remark'] = "";
  309. $data['authWay'] = "3";
  310. $res_cash = $orderYunst->servicerWithdraw($data);
  311. debug_log($res_cash);
  312. if ($res_cash['subCode'] != 'SUCCESS'){
  313. return $this->asJson([
  314. 'code' => 1,
  315. 'msg' =>$res_cash['subMsg']
  316. ]);
  317. }else{
  318. $cash = new StoreCash();
  319. $cash->order_no = \app\utils\OrderNo::getOrderNo(\app\utils\OrderNo::ORDER_CASH);
  320. $cash->is_delete = 0;
  321. $cash->status = 2;
  322. $cash->price = $price;
  323. $cash->created_at = time();
  324. $cash->store_id = -1;
  325. $cash->type =6;//通联提现
  326. $cash->name = $name;
  327. $cash->mobile = $mobile;
  328. $cash->pay_time = time();
  329. $cash->service_charge = 0;
  330. $cash->cash_type = 0;
  331. if ($cash->save()) {
  332. $t->commit();
  333. return $this->asJson([
  334. 'code' => 0,
  335. 'msg' => '提现成功'
  336. ]);
  337. } else {
  338. \Yii::error([__METHOD__, $cash]);
  339. $t->rollBack();
  340. return $this->asJson([
  341. 'code' => 1,
  342. 'msg' => $cash->errors
  343. ]);
  344. }
  345. }
  346. }
  347. /**
  348. * 提现列表
  349. * @return \yii\web\Response
  350. */
  351. public function actionCashList() {
  352. $store_id = get_params('store_id', 0);
  353. $export = get_params('export');
  354. $start_time = get_params('start_time');
  355. $end_time = get_params('end_time');
  356. $status = get_params('status');
  357. $type = get_params('type');
  358. $cash_store_id = get_params('cash_store_id');
  359. $audit_start_time = get_params('audit_start_time');
  360. $audit_end_time = get_params('audit_end_time');
  361. $query = StoreCash::find()->alias('c')->where(['c.is_delete' => 0]);
  362. // $store_id > 0 && $query->andWhere(['c.store_id' => $store_id]);
  363. ($type >= 0 && $type != '') && $query->andWhere(['c.type' => $type]);
  364. if ($start_time) {
  365. $query->andWhere(['>=', 'c.created_at', strtotime($start_time)]);
  366. }
  367. if ($end_time) {
  368. $query->andWhere(['<=', 'c.created_at', strtotime($end_time)]);
  369. }
  370. if ($cash_store_id > 0) {
  371. $query->andWhere(['c.store_id' => $cash_store_id]);
  372. }
  373. if ($store_id <= 0) {
  374. // $query->andWhere(['c.store_id' => [0, -1]]);
  375. } else {
  376. $query->andWhere(['c.store_id' => $store_id]);
  377. }
  378. if ($audit_start_time) {
  379. $query->andWhere(['>=', 'c.updated_at', strtotime($audit_start_time)]);
  380. }
  381. if ($audit_end_time) {
  382. $query->andWhere(['<=', 'c.updated_at', strtotime($audit_end_time)]);
  383. }
  384. if ($status == StoreCash::STATUS_APPLY) { //待审核
  385. $query->andWhere(['c.status' => StoreCash::STATUS_APPLY]);
  386. }
  387. if ($status == StoreCash::STATUS_CONFIRM) { // 待打款
  388. $query->andWhere(['c.status' => StoreCash::STATUS_CONFIRM]);
  389. }
  390. if ($status == StoreCash::STATUS_GIVEN) { // 已打款
  391. $query->andWhere(['in', 'c.status', [StoreCash::STATUS_GIVEN, StoreCash::STATUS_RECHARGE]]);
  392. }
  393. if ($status == StoreCash::STATUS_REFUSE) { // 已拒绝
  394. $query->andWhere(['c.status' => StoreCash::STATUS_REFUSE]);
  395. }
  396. $query->orderBy('c.id DESC');
  397. $pagination = pagination_make($query);
  398. $list = $pagination['list'];
  399. foreach($list as &$value){
  400. $value['service_money'] = $value['service_charge'] * $value['price'] / 100;
  401. $value['money'] = StoreCash::getServiceMoney($value);
  402. if (!$cash_store_id) {
  403. $store = Store::findOne($value['store_id']);
  404. $value['store_name'] = $store->name;
  405. $value['store_logo'] = $store->logo;
  406. $value['store_cat_name'] = '-';
  407. if ($store['category_id'] > 0) {
  408. $cat = SaasCategory::findOne($store['category_id']);
  409. if ($cat) {
  410. $value['store_cat_name'] = $cat->name;
  411. }
  412. }
  413. }
  414. }
  415. if($export){
  416. return $this->export($list);
  417. }
  418. $store_id = get_store_id();
  419. $store = Store::findOne($store_id);
  420. //商城余额是否充足
  421. $storeMoney = \app\models\StoreCash::getMaxCash($store);
  422. return $this->asJson([
  423. 'code' => 0,
  424. 'msg' => 'success',
  425. 'data' => [
  426. 'data' => $list,
  427. 'pageNo' => $pagination['pageNo'],
  428. 'totalCount' => $pagination['totalCount'],
  429. 'store_cash_money' => $storeMoney ?: '0.00'
  430. ],
  431. ]);
  432. }
  433. private function export($list) {
  434. $rows = [[
  435. 'ID',
  436. '提现金额(元)',
  437. '提现方式',
  438. '提现账号',
  439. '提现姓名',
  440. '提现开户行',
  441. '时间',
  442. '说明',
  443. '状态',
  444. ]];
  445. foreach($list as $item){
  446. $r = [
  447. $item['id'],
  448. $item['price'],
  449. StoreCash::getTypeName($item),
  450. $item['mobile'],
  451. $item['name'],
  452. $item['bank_name'],
  453. date('Y-m-d H:i:s', $item['created_at']),
  454. $item['reject_reason'],
  455. StoreCash::getStatusName($item),
  456. ];
  457. $rows[] = $r;
  458. }
  459. $writer = \Spatie\SimpleExcel\SimpleExcelWriter::streamDownload(time() . '.xlsx')->noHeaderRow()
  460. ->addRows($rows)->toBrowser();
  461. }
  462. /**
  463. * 提现申请审核
  464. * @return \yii\web\Response
  465. */
  466. public function actionCashApply()
  467. {
  468. $id = post_params('id');
  469. $status = post_params('status');
  470. $reject_reason = input_params('reject_reason', '');
  471. if (empty($id) || !is_array($id)) {
  472. \Yii::error([__METHOD__, $id]);
  473. return $this->asJson([
  474. 'code' => 1,
  475. 'msg' => '数据格式错误'
  476. ]);
  477. }
  478. $t = \Yii::$app->db->beginTransaction();
  479. foreach ($id as $value) {
  480. $cash = StoreCash::findOne(['id' => $value, 'is_delete' => StoreCash::IS_DELETE_NO]);
  481. if (!$cash) {
  482. $t->rollBack();
  483. \Yii::error([__METHOD__, $value, $cash]);
  484. return $this->asJson([
  485. 'code' => 1,
  486. 'msg' => '提现记录不存在,请刷新重试'
  487. ]);
  488. }
  489. if (!$cash->order_no) {
  490. $order_no = null;
  491. while (true) {
  492. $order_no = date('YmdHis') . mt_rand(100000, 999999);
  493. $exist_order_no = StoreCash::find()->where(['order_no' => $order_no])->exists();
  494. if (!$exist_order_no) {
  495. break;
  496. }
  497. }
  498. $cash->order_no = $order_no;
  499. $cash->save();
  500. }
  501. if (!in_array($status, [1, 3])) {
  502. $t->rollBack();
  503. \Yii::error([__METHOD__, $status, $cash]);
  504. return $this->asJson([
  505. 'code' => 1,
  506. 'msg' => '提现记录ID: ' . $value . '已审核,请刷新重试'
  507. ]);
  508. }
  509. $store = Store::findOne($cash->store_id);
  510. $cash->status = $status;
  511. $cash->reject_reason = $reject_reason;
  512. if ($status == StoreCash::STATUS_REFUSE && $cash->cash_type == StoreCash::CASH_TYPE_NORMAL) {
  513. $addMoney = \app\models\Store::addMoney($store, $cash->price, '商城提现-驳回');
  514. if (!$addMoney) {
  515. \Yii::error([__METHOD__, $addMoney, $cash]);
  516. $t->rollBack();
  517. return $this->asJson([
  518. 'code' => 1,
  519. 'msg' => '网络异常,addMoney失败'
  520. ]);
  521. }
  522. }
  523. if ($status == StoreCash::STATUS_REFUSE && $cash->cash_type == StoreCash::CASH_TYPE_ALLIANCE_COUPON) {
  524. $store = Store::findOne($cash->store_id);
  525. $before = $store->league_price;
  526. $store->updateCounters(['league_price' => floatval($cash->price)]);
  527. \app\models\SaaSLeaguePriceLog::setLeaguePriceLog(
  528. $store->id,
  529. $cash->saas_id,
  530. $cash->price,
  531. $before,
  532. \app\models\SaaSLeaguePriceLog::TYPE_WITHDRAW_REJECT,
  533. \app\models\SaaSLeaguePriceLog::SEND_TYPE,
  534. \app\models\SaaSLeaguePriceLog::ROLE_STORE,
  535. $cash->id
  536. );
  537. }
  538. if (!$cash->save()) {
  539. \Yii::error([__METHOD__, $cash]);
  540. $t->rollBack();
  541. return $this->asJson([
  542. 'code' => 1,
  543. 'msg' => '网络异常,请刷新重试'
  544. ]);
  545. }
  546. }
  547. $t->commit();
  548. return $this->asJson([
  549. 'code' => 0,
  550. 'msg' => '审核成功'
  551. ]);
  552. }
  553. /**
  554. * 打款
  555. * @return \yii\web\Response
  556. */
  557. public function actionCashConfirm()
  558. {
  559. $id = post_params('id');
  560. $cash = StoreCash::findOne(['id' => $id, 'is_delete' => StoreCash::IS_DELETE_NO]);
  561. if (!$cash) {
  562. \Yii::error([__METHOD__, $id, $cash]);
  563. return $this->asJson([
  564. 'code' => 1,
  565. 'msg' => '提现记录不存在,请刷新重试'
  566. ]);
  567. }
  568. if (!$cash->order_no) {
  569. $order_no = null;
  570. while (true) {
  571. $order_no = date('YmdHis') . mt_rand(100000, 999999);
  572. $exist_order_no = StoreCash::find()->where(['order_no' => $order_no])->exists();
  573. if (!$exist_order_no) {
  574. break;
  575. }
  576. }
  577. $cash->order_no = $order_no;
  578. $cash->save();
  579. }
  580. if ($cash->status != 1) {
  581. \Yii::error([__METHOD__, $cash]);
  582. return $this->asJson([
  583. 'code' => 1,
  584. 'msg' => '操作错误,请刷新重试'
  585. ]);
  586. }
  587. // 微信自动打款
  588. if ($cash->type == 4) {
  589. try {
  590. $storeAdmin = Admin::findOne([
  591. 'type' => 'store',
  592. 'type_id' => $cash->store_id,
  593. 'is_delete' => 0,
  594. ]);
  595. if (!$storeAdmin) {
  596. return $this->asJson([
  597. 'code' => 1,
  598. 'msg' => '商城绑定的管理员不存在,操作失败'
  599. ]);
  600. }
  601. $saasUser = SaasUser::findOne($storeAdmin->saas_user_id);
  602. if (!$saasUser) {
  603. return $this->asJson([
  604. 'code' => 1,
  605. 'msg' => '商城绑定的管理员不存在,操作失败'
  606. ]);
  607. }
  608. if (empty($saasUser->platform_open_id_merchant)) {
  609. return $this->asJson([
  610. 'code' => 1,
  611. 'msg' => '商城绑定的管理员open_id不存在,操作失败'
  612. ]);
  613. }
  614. $data = [
  615. 'partner_trade_no' => $cash->order_no,
  616. 'openid' => $saasUser->platform_open_id_merchant,
  617. 'check_name' => 'NO_CHECK',
  618. 'amount' => $cash->price * 100,
  619. 'user_name' => $cash->name,
  620. 'desc' => '商城提现'
  621. ];
  622. $wechat = getServiceClientWxConfig();
  623. $res = (new \app\utils\WechatMerchant\WxV3($wechat))->transferBatches(0, $data);
  624. if ($res['code'] == 1) {
  625. return $this->asJson([
  626. 'code' => 1,
  627. 'msg' => $res['msg'],
  628. ]);
  629. }
  630. $cash->wx_cash_type = Cash::WX_CASH_TYPE_NEW;
  631. $cash->wx_cash_state = $res['data']['state'];
  632. $cash->wx_cash_result_info = json_encode($res['data'], JSON_UNESCAPED_UNICODE);
  633. } catch (\Exception $e) {
  634. return $this->asJson([
  635. 'code' => 1,
  636. 'msg' => '操作失败,保存失败' . $e->getMessage()
  637. ]);
  638. }
  639. }
  640. // 通联提现打款
  641. if ($cash->type == 6) {
  642. $store = Store::findOne(['id' => $cash->store_id]);
  643. if ($store->cusid){
  644. $orderYunst = new OrderYunst();
  645. $data['bizOrderNo'] = $cash->order_no;
  646. $data['bizUserId'] = $store->store_number;
  647. // $data['bizUserId'] = "XDQXCJSZPJYB";
  648. $data['amount'] = ceil($cash->price * 100);
  649. $data['notifyUrl'] = Yii::$app->request->hostInfo;
  650. $data['remark'] = "";
  651. $data['authWay'] = "3";
  652. debug_log('平台审核提现通联');
  653. debug_log($data);
  654. $res = $orderYunst->servicerWithdraw($data);
  655. debug_log($res);
  656. if ($res['subCode'] != 'SUCCESS'){
  657. $order_no = date('YmdHis') . mt_rand(100000, 999999);
  658. $cash->order_no = $order_no;
  659. $cash->save();
  660. return $this->asJson([
  661. 'code' => 1,
  662. 'msg' =>$res['subMsg']
  663. ]);
  664. }
  665. }
  666. }
  667. //手动打款
  668. $cash->status = StoreCash::STATUS_GIVEN;
  669. $cash->pay_time = time();
  670. $cash->pay_type = StoreCash::PAY_TYPE_HAND;
  671. // NoticeSend::CashSuccess($cash->user_id, $user->binding, $price, '手动打款', ($cash->price - $price));
  672. $save = $cash->save();
  673. if ($save) {
  674. return $this->asJson([
  675. 'code' => 0,
  676. 'msg' => '成功'
  677. ]);
  678. } else {
  679. \Yii::error([__METHOD__, $cash]);
  680. return $this->asJson([
  681. 'code' => 1,
  682. 'msg' => '操作失败,保存失败'
  683. ]);
  684. }
  685. }
  686. /**
  687. * 商城账户明细列表
  688. * @return \yii\web\Response
  689. */
  690. public function actionStoreAccountLogList() {
  691. $store_id = get_params('store_id');
  692. $opt = get_params('opt');
  693. $export = get_params('export');
  694. $start_time = get_params('start_time');
  695. $end_time = get_params('end_time');
  696. $cash_store_id = get_params('cash_store_id');
  697. $type = get_params('type');
  698. $query = StoreAccountLog::find()->alias('c');
  699. $store_id > 0 && $query->andWhere(['c.store_id' => $store_id]);
  700. if ($start_time) {
  701. $query->andWhere(['>=', 'c.time', strtotime($start_time)]);
  702. }
  703. if ($end_time) {
  704. $query->andWhere(['<=', 'c.time', strtotime($end_time)]);
  705. }
  706. if ($cash_store_id) {
  707. $query->andWhere(['c.store_id' => $cash_store_id]);
  708. }
  709. if ($type > 0) {
  710. $query->andWhere(['c.type' => $type]);
  711. }
  712. if($opt == 1){
  713. $query->andWhere(['like', 'c.desc', '商城提现']);
  714. }
  715. $query->orderBy('c.id DESC');
  716. $pagination = pagination_make($query);
  717. $list = $pagination['list'];
  718. foreach($list as &$value){
  719. if (!$cash_store_id) {
  720. $store = Store::findOne($value['store_id']);
  721. $value['store_name'] = $store->name;
  722. $value['store_logo'] = $store->logo;
  723. $value['store_cat_name'] = '-';
  724. if ($store['category_id'] > 0) {
  725. $cat = SaasCategory::findOne($store['category_id']);
  726. if ($cat) {
  727. $value['store_cat_name'] = $cat->name;
  728. }
  729. }
  730. }
  731. }
  732. if($export){
  733. return $this->exportStoreAccountLog($list);
  734. }
  735. return $this->asJson([
  736. 'code' => 0,
  737. 'msg' => 'success',
  738. 'data' => [
  739. 'data' => $list,
  740. 'pageNo' => $pagination['pageNo'],
  741. 'totalCount' => $pagination['totalCount']
  742. ],
  743. ]);
  744. }
  745. private function exportStoreAccountLog($list) {
  746. $rows = [[
  747. 'ID',
  748. '余额类型',
  749. '变动金额(元)',
  750. '变动前',
  751. '变动后',
  752. '时间',
  753. '说明',
  754. ]];
  755. foreach($list as $item){
  756. $r = [
  757. $item['id'],
  758. $item['type'] == 1 ? '收入' : '支出',
  759. $item['price'],
  760. $item['before'],
  761. $item['after'],
  762. date('Y-m-d H:i:s', $item['time']),
  763. $item['desc'],
  764. ];
  765. $rows[] = $r;
  766. }
  767. $writer = \Spatie\SimpleExcel\SimpleExcelWriter::streamDownload(time() . '.xlsx')->noHeaderRow()
  768. ->addRows($rows)->toBrowser();
  769. }
  770. }