SaasController.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\client\controllers\v1;
  8. use app\models\Clerk;
  9. use app\models\Coupon;
  10. use app\models\Goods;
  11. use app\models\MdStaff;
  12. use app\models\SaasProfitCash;
  13. use app\models\SaasUser;
  14. use app\models\SharingReceiver;
  15. use app\models\User;
  16. use app\models\UserCoupon;
  17. use app\modules\client\controllers\BaseController;
  18. use app\modules\client\models\v1\PlatformLoginForm;
  19. use app\plugins\integral\models\SaasIntegralOrder;
  20. use app\plugins\scanCodePay\models\Order;
  21. use app\plugins\scanCodePay\models\OrderDetail;
  22. use app\utils\Ocr\OcrApi;
  23. use app\utils\OrderNo;
  24. use yii\base\BaseObject;
  25. use yii\data\Pagination;
  26. use app\models\Store;
  27. use app\models\Option;
  28. use app\models\SaasHistory;
  29. use yii\helpers\Json;
  30. class SaasController extends BaseController
  31. {
  32. /**
  33. * 福利中心订单,目前只有当面付订单
  34. */
  35. public function actionOrderList() {
  36. $page = get_params('page', 1);
  37. $limit = get_params('limit', 10);
  38. $query = Order::find()->where(['store_id' => get_store_id(), 'user_id' => get_user_id(), 'is_delete' => 0]);
  39. $count = $query->count();
  40. $pagination = new Pagination(['totalCount' => $count, 'pageSize' => $limit, 'page' => $page - 1]);
  41. $list = $query->select('id, pay_price, order_no, is_pay, created_at')->limit($pagination->limit)
  42. ->offset($pagination->offset)
  43. ->asArray()->orderBy(['created_at' => SORT_DESC])->all();
  44. // $count = count($scan_order); // 总条数
  45. // $start = ($page - 1) * $limit; // 偏移量,当前页-1乘以每页显示条数
  46. // $order = array_slice($scan_order, $start, $limit);
  47. foreach ($list as $key => $value) {
  48. $list[$key]['goods_name'] = '当面付';
  49. $goods_id = OrderDetail::findOne(['order_id' => $value['id']])->goods_id;
  50. $list[$key]['goods_pic'] = Goods::findOne($goods_id)->cover_pic;
  51. $list[$key]['type'] = 'scan';
  52. }
  53. return $this->asJson([
  54. 'code' => 0,
  55. 'msg' => 'success',
  56. 'data' => [
  57. 'row_count' => $count,
  58. 'page_count' => $pagination->pageCount,
  59. 'list' => $list,
  60. ]
  61. ]);
  62. }
  63. /**
  64. * 核销员待核销订单,目前只有积分兑换订单 2021-06-30
  65. */
  66. public function actionNotClerkOrderList() {
  67. // $current_user = User::findOne(['id' => get_user_id(), 'is_delete' => User::USER_NOT_DELETE, 'is_saas_clerk' => 1, 'store_id' => get_store_id()]);
  68. $current_user = MdStaff::findOne(['store_id' => get_store_id(), 'saas_user_id' => get_saas_user_id(), 'is_delete' => 0]);
  69. if (!$current_user) {
  70. return $this->asJson([
  71. 'code' => 1,
  72. 'msg' => '您不是核销员,无法核销订单!'
  73. ]);
  74. }
  75. $page = get_params('page', 1);
  76. $limit = get_params('limit', 10);
  77. $user_id = get_params('user_id');
  78. // $user = User::findOne($user_id);
  79. // $clerk = Clerk::findOne(['user_id' => get_user_id(), 'is_delete' => 0]);
  80. // if (!$user || !$clerk) {
  81. // return $this->asJson([
  82. // 'code' => 0,
  83. // 'msg' => 'success',
  84. // 'data' => [
  85. // 'row_count' => 0,
  86. // 'page_count' => 0,
  87. // 'list' => [],
  88. // ]
  89. // ]);
  90. // }
  91. $query = SaasIntegralOrder::find()->where(['store_id' => get_store_id(), 'user_id' => $user_id, 'is_clerk' => 0, 'is_delete' => 0]);
  92. $count = $query->count();
  93. $pagination = new Pagination(['totalCount' => $count, 'pageSize' => $limit, 'page' => $page - 1]);
  94. $list = $query->select('*')->limit($pagination->limit)
  95. ->offset($pagination->offset)
  96. ->asArray()->orderBy(['created_at' => SORT_DESC])->all();
  97. foreach ($list as $key => $value) {
  98. $goods = Goods::findOne($value['goods_id']);
  99. $list[$key]['goods_pic'] = $goods->cover_pic;
  100. $list[$key]['goods_name'] = $goods->name;
  101. $list[$key]['type'] = 'integral';
  102. }
  103. return $this->asJson([
  104. 'code' => 0,
  105. 'msg' => 'success',
  106. 'data' => [
  107. 'row_count' => $count,
  108. 'page_count' => $pagination->pageCount,
  109. 'list' => $list,
  110. ]
  111. ]);
  112. }
  113. /**
  114. * 联盟订单,目前只有积分兑换订单 2021-06-30
  115. */
  116. public function actionLeagueOrderList() {
  117. $page = get_params('page', 1);
  118. $limit = get_params('limit', 10);
  119. $user_id = get_saas_user_id();
  120. $query = SaasIntegralOrder::find()->where(['user_id' => $user_id, 'is_delete' => 0]);
  121. $count = $query->count();
  122. $pagination = new Pagination(['totalCount' => $count, 'pageSize' => $limit, 'page' => $page - 1]);
  123. $list = $query->select('*')->limit($pagination->limit)
  124. ->offset($pagination->offset)
  125. ->asArray()->orderBy(['created_at' => SORT_DESC])->all();
  126. foreach ($list as $key => $value) {
  127. $goods = Goods::findOne($value['goods_id']);
  128. $list[$key]['goods_pic'] = $goods->cover_pic;
  129. $list[$key]['goods_name'] = $goods->name;
  130. $list[$key]['type'] = 'integral';
  131. $list[$key]['shop'] = [
  132. 'latitude' => '',
  133. 'longitude' => '',
  134. 'address' => '',
  135. ];
  136. // 获取商城坐标信息
  137. $store = Store::findOne($value['store_id']);
  138. if ($store) {
  139. if (!empty($store->coordinate)) {
  140. list($latitude, $longitude) = explode(',', $store->coordinate);
  141. $list[$key]['shop']['latitude'] = $latitude;
  142. $list[$key]['shop']['longitude'] = $longitude;
  143. }
  144. $list[$key]['shop']['address'] = $store->address;
  145. $list[$key]['shop']['name'] = $store->name;
  146. $list[$key]['shop']['logo'] = $store->logo;
  147. }
  148. }
  149. return $this->asJson([
  150. 'code' => 0,
  151. 'msg' => 'success',
  152. 'data' => [
  153. 'row_count' => $count,
  154. 'page_count' => $pagination->pageCount,
  155. 'list' => $list,
  156. ]
  157. ]);
  158. }
  159. /**
  160. * 核销订单
  161. */
  162. public function actionClerkOrder() {
  163. $type = get_params('type');
  164. $id = get_params('id');
  165. $store_id = get_store_id();
  166. $user_id = get_user_id();
  167. // $current_user = User::findOne(['id' => $user_id, 'is_delete' => User::USER_NOT_DELETE, 'is_saas_clerk' => 1, 'store_id' => $store_id]);
  168. $current_user = MdStaff::findOne(['store_id' => $store_id, 'saas_user_id' => get_saas_user_id(), 'is_delete' => 0]);
  169. if (!$current_user) {
  170. return $this->asJson([
  171. 'code' => 1,
  172. 'msg' => '您不是核销员,无法核销订单!'
  173. ]);
  174. }
  175. switch ($type) {
  176. case 'integral':
  177. $integral_order = SaasIntegralOrder::findOne(['id' => $id, 'is_delete' => 0]);
  178. if (!$integral_order) {
  179. return $this->asJson([
  180. 'code' => 1,
  181. 'msg' => '订单不存在'
  182. ]);
  183. }
  184. if ($integral_order->is_clerk == 1) {
  185. return $this->asJson([
  186. 'code' => 1,
  187. 'msg' => '订单已核销,无法再次核销'
  188. ]);
  189. }
  190. SaasIntegralOrder::updateAll(['is_clerk' => 1, 'clerk_id' => $user_id], ['store_id' => $store_id, 'id' => $id]);
  191. return $this->asJson([
  192. 'code' => 0,
  193. 'msg' => '核销成功'
  194. ]);
  195. default:
  196. return $this->asJson([
  197. 'code' => 1,
  198. 'msg' => 'fail'
  199. ]);
  200. }
  201. }
  202. /**
  203. * 删除订单
  204. */
  205. public function actionDeleteOrder() {
  206. $type = get_params('type');
  207. $id = get_params('id');
  208. $store_id = get_store_id();
  209. switch ($type) {
  210. case 'scan':
  211. Order::updateAll(['is_delete' => 1], ['store_id' => $store_id, 'id' => $id]);
  212. return $this->asJson([
  213. 'code' => 0,
  214. 'msg' => 'success'
  215. ]);
  216. case 'integral':
  217. SaasIntegralOrder::updateAll(['is_delete' => 1], ['store_id' => $store_id, 'id' => $id]);
  218. return $this->asJson([
  219. 'code' => 0,
  220. 'msg' => 'success'
  221. ]);
  222. default:
  223. return $this->asJson([
  224. 'code' => 1,
  225. 'msg' => 'fail'
  226. ]);
  227. }
  228. }
  229. /**
  230. * 订单详情
  231. */
  232. public function actionOrderDetail() {
  233. $type = get_params('type');
  234. $id = get_params('id');
  235. $order = [];
  236. switch ($type) {
  237. case 'scan':
  238. $scan_temp = Order::findOne(['id' => $id, 'is_delete' => 0]);
  239. $order['goods_name'] = '当面付';
  240. $goods_id = OrderDetail::findOne(['order_id' => $scan_temp->id])->goods_id;
  241. $order['goods_pic'] = Goods::findOne($goods_id)->cover_pic;
  242. $order['cost'] = $scan_temp->pay_price;
  243. $order['order_no'] = $scan_temp->order_no;
  244. $order['coupon'] = Coupon::findOne(UserCoupon::findOne($scan_temp->user_coupon_id)->coupon_id);
  245. $order['status'] = $scan_temp->is_pay == 1 ? '已支付' : '未支付';
  246. $order['created_at'] = $scan_temp->created_at;
  247. break;
  248. case 'integral':
  249. $integral_temp = SaasIntegralOrder::findOne(['id' => $id, 'is_delete' => 0]);
  250. $goods = Goods::findOne($integral_temp->goods_id);
  251. $order['goods_name'] = $goods->name;
  252. $order['goods_pic'] = $goods->cover_pic;
  253. $order['cost'] = $integral_temp->cost;
  254. $order['order_no'] = $integral_temp->order_no;
  255. $order['status'] = $integral_temp->is_clerk == 1 ? '已核销' : '待核销';
  256. $order['created_at'] = $integral_temp->created_at;
  257. break;
  258. default:
  259. return $this->asJson([
  260. 'code' => 1,
  261. 'msg' => 'fail'
  262. ]);
  263. }
  264. return $this->asJson([
  265. 'code' => 0,
  266. 'msg' => 'success',
  267. 'data' => $order
  268. ]);
  269. }
  270. /**
  271. * 个人分账记录
  272. * @return \yii\web\Response
  273. */
  274. public function actionShareProfitRecord() {
  275. $page = get_params('page', 1);
  276. $limit = get_params('limit', 10);
  277. $user = get_user();
  278. $query = SharingReceiver::find();
  279. if (\Yii::$app->isSaas()) {
  280. $users = User::find()->where(['binding' => $user->binding])->select('wechat_open_id')->asArray()->all();
  281. $users_open_id = array_column($users, 'wechat_open_id');
  282. $query->where(['in', 'account', $users_open_id]);
  283. } else {
  284. $query->where(['store_id' => $user->store_id, 'account' => $user->wechat_open_id]);
  285. }
  286. $count = $query->count();
  287. $pagination = new Pagination(['totalCount' => $count, 'pageSize' => $limit, 'page' => $page - 1]);
  288. $list = $query->select('*')->limit($pagination->limit)
  289. ->offset($pagination->offset)
  290. ->asArray()->orderBy(['created_at' => SORT_DESC])->all();
  291. foreach ($list as $key => $value) {
  292. $tmp = [];
  293. $tmp['order_no'] = $value['order_no'];
  294. $tmp['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
  295. $tmp['amount'] = $value['amount'];
  296. $tmp['remark'] = $value['remark'];
  297. $tmp['pay_status'] = $value['is_pay'] == 0 ? '待分账' : ($value['is_pay'] == 1 ? '已分账' : '分账失败');
  298. $list[$key] = $tmp;
  299. }
  300. return $this->asJson([
  301. 'code' => 0,
  302. 'msg' => 'success',
  303. 'data' => [
  304. 'row_count' => $count,
  305. 'page_count' => $pagination->pageCount,
  306. 'list' => $list,
  307. ]
  308. ]);
  309. }
  310. /**
  311. * 联盟佣金提现提交
  312. */
  313. public function actionCashCommit() {
  314. $amount = post_params('amount');
  315. if ($amount < 0.01) {
  316. return $this->asJson([
  317. 'code' => 1,
  318. 'msg' => '提现最小金额不能小于0.01元'
  319. ]);
  320. }
  321. $user = !empty(get_user()) ? get_user() : User::find()->where(['binding'=>get_saas_user()->mobile])->one();
  322. $saas_user = SaasUser::findOne(['mobile' => $user->binding]);
  323. if ($saas_user->share_profit < $amount) {
  324. return $this->asJson([
  325. 'code' => 1,
  326. 'msg' => '当前提现金额大于可提现联盟佣金'
  327. ]);
  328. }
  329. if (!$saas_user->platform_open_id) {
  330. return $this->asJson([
  331. 'code' => 1,
  332. 'msg' => '请先绑定平台小程序openid'
  333. ]);
  334. }
  335. $t = \Yii::$app->db->beginTransaction();
  336. $cash = new SaasProfitCash();
  337. $cash->order_no = OrderNo::getOrderNo(OrderNo::ORDER_SAAS_PROFIT_CASH);
  338. $cash->user_id = get_saas_user_id();
  339. $cash->mobile = $user->binding;
  340. $cash->amount = $amount;
  341. $cash->status = SaasProfitCash::CASH_STATUS_WAIT;
  342. $cash->created_at = time();
  343. if (!$cash->save()) {
  344. return $this->asJson([
  345. 'code' => 1,
  346. 'msg' => $cash->errors[0]
  347. ]);
  348. }
  349. $cash->before_price = $saas_user->share_profit;
  350. $cash->after_price = ($saas_user->share_profit - $amount);
  351. $saas_user->share_profit = $saas_user->share_profit - $amount;
  352. $saas_user->save();
  353. $t->commit();
  354. return $this->asJson([
  355. 'code' => 0,
  356. 'msg' => '提交成功,请等待审核'
  357. ]);
  358. }
  359. /**
  360. * 联盟佣金提现列表
  361. */
  362. public function actionCashList() {
  363. $page = get_params('page', 1);
  364. $limit = get_params('limit', 10);
  365. $user = get_user();
  366. $query = SaasProfitCash::find()->where(['mobile' => !empty($user->binding) ? $user->binding : get_saas_user()->mobile]);
  367. $count = $query->count();
  368. $pagination = new Pagination(['totalCount' => $count, 'pageSize' => $limit, 'page' => $page - 1]);
  369. $list = $query->select('*')->limit($pagination->limit)
  370. ->offset($pagination->offset)
  371. ->asArray()->orderBy(['created_at' => SORT_DESC])->all();
  372. foreach ($list as &$value) {
  373. $value['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
  374. $value['status_text'] = $value['status'] == 0 ? '待审核' : ($value['status'] == 1 ? '已通过' : '已拒绝');
  375. }
  376. return $this->asJson([
  377. 'code' => 0,
  378. 'msg' => 'success',
  379. 'data' => [
  380. 'row_count' => $count,
  381. 'page_count' => $pagination->pageCount,
  382. 'list' => $list,
  383. ]
  384. ]);
  385. }
  386. public function actionCheck() {
  387. $phone = get_params('phone');
  388. if (empty($phone)) {
  389. return $this->asJson([
  390. 'code' => 1,
  391. 'msg' => '参数有误'
  392. ]);
  393. }
  394. $share_user = SaasUser::findOne(['mobile' => $phone]);
  395. if (!$share_user || empty($share_user->platform_open_id)) {
  396. return $this->asJson([
  397. 'code' => 0,
  398. 'msg' => 'success',
  399. 'data' => 0
  400. ]);
  401. }
  402. return $this->asJson([
  403. 'code' => 0,
  404. 'msg' => 'success',
  405. 'data' => 1
  406. ]);
  407. }
  408. public function actionPlatformLogin() {
  409. $form = new PlatformLoginForm();
  410. $form->store_id = get_store_id();
  411. $form->attributes = get_params();
  412. return $this->asJson($form->login());
  413. }
  414. public function actionSearchKeyword()
  415. {
  416. $keyword = Option::get('search_keyword', 0, 'saas', json_encode([]));
  417. return $this->asJson([
  418. 'code' => 0,
  419. 'msg' => 'success',
  420. 'data' => json_decode($keyword['value']),
  421. ]);
  422. }
  423. public function actionAddHistory()
  424. {
  425. $saas_user_id = get_saas_user_id();
  426. if ($saas_user_id > 0) {
  427. $store_id = get_store_id();
  428. $history = SaasHistory::find()->where(['user_id' => $saas_user_id, 'store_id' => $store_id])->one();
  429. if ($history) {
  430. $history->updated_at = time();
  431. $history->save();
  432. } else {
  433. $history = new SaasHistory();
  434. $history->user_id = $saas_user_id;
  435. $history->store_id = $store_id;
  436. $history->updated_at = time();
  437. $history->save();
  438. }
  439. }
  440. return $this->asJson([
  441. 'code' => 0,
  442. 'msg' => '添加成功',
  443. ]);
  444. }
  445. public function actionGetHistory()
  446. {
  447. $page = get_params('page', 1);
  448. $limit = 10;
  449. $query = SaasHistory::find()->alias('sh')
  450. ->leftJoin(['s' => Store::tableName()], 'sh.store_id=s.id')
  451. ->select(['s.id', 's.name', 's.logo']);
  452. $count = $query->count();
  453. $pagination = new Pagination(['totalCount' => $count, 'pageSize' => $limit, 'page' => $page - 1]);
  454. $query->limit($limit)->offset($pagination->offset);
  455. $list = $query->orderBy(['sh.updated_at' => SORT_DESC])->asArray()->all();
  456. return $this->asJson([
  457. 'code' => 0,
  458. 'msg' => 'success',
  459. 'data' => $list,
  460. ]);
  461. }
  462. public function actionOtherInfo() {
  463. $store_apply_banner = Option::get('store_apply_banner', 0, 'saas', '')['value'];
  464. $admin_copyright = Option::get('store_apply_agreement', 0, 'saas', '')['value'];
  465. return $this->asJson([
  466. 'code' => 0,
  467. 'data' => [
  468. 'store_apply_banner' => $store_apply_banner ? Json::decode($store_apply_banner) : [],
  469. 'store_apply_agreement' => $admin_copyright
  470. ]
  471. ]);
  472. }
  473. /**
  474. * 获取信息 与ocr/info接口内容一致
  475. * @return \yii\web\Response
  476. */
  477. public function actionOcrInfo() {
  478. $type = post_params('type');
  479. if (empty($type) || !in_array($type, OcrApi::$validType)) {
  480. return $this->asJson([
  481. 'code' => 1,
  482. 'msg' => '类型参数错误'
  483. ]);
  484. }
  485. $side = post_params('side');
  486. if (empty($side) && $type == OcrApi::TYPE_ID_CARD) {
  487. return $this->asJson([
  488. 'code' => 1,
  489. 'msg' => '身份证参数有误'
  490. ]);
  491. }
  492. $url = post_params('url');
  493. if (empty($url)) {
  494. return $this->asJson([
  495. 'code' => 1,
  496. 'msg' => '图片地址为空'
  497. ]);
  498. }
  499. try {
  500. $ocr = new OcrApi(true);
  501. switch ($type) {
  502. case OcrApi::TYPE_LICENSE:
  503. $res = $ocr->getBusinessLicense($url);
  504. break;
  505. case OcrApi::TYPE_ID_CARD:
  506. $res = $ocr->getIDCard($url, $side);
  507. break;
  508. case OcrApi::TYPE_BANK:
  509. $res = $ocr->getBankCard($url);
  510. break;
  511. case OcrApi::TYPE_TEXT:
  512. $res = $ocr->getTextRecognition($url, 1);
  513. break;
  514. }
  515. if ($res['code'] == 0 && !empty($res['data'])) {
  516. return $this->asJson($res);
  517. }
  518. return $this->asJson([
  519. 'code' => 1,
  520. 'msg' => '获取信息失败'
  521. ]);
  522. } catch (\Exception $e) {
  523. return $this->asJson([
  524. 'code' => 1,
  525. 'msg' => $e->getMessage()
  526. ]);
  527. }
  528. }
  529. }