DefaultController.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <?php
  2. namespace addons\WriteOff\api\modules\v1\controllers;
  3. use Yii;
  4. use api\controllers\OnAuthController;
  5. use addons\WriteOff\common\enums\WriteOffEnum;
  6. use addons\WriteOff\common\models\WriteOffUser;
  7. use addons\WriteOff\common\models\WriteOffLevel;
  8. use addons\WriteOff\common\models\WriteOffMember;
  9. use addons\WriteOff\common\models\WriteOffMemberLog;
  10. use addons\WriteOff\common\logic\RewardLogic;
  11. use common\helpers\TaskHelper;
  12. use common\enums\RabbitMqEnum;
  13. use PhpAmqpLib\Message\AMQPMessage;
  14. use common\helpers\LockHelper;
  15. use common\enums\RedisKeyEnum;
  16. use common\enums\StatusEnum;
  17. use common\models\user\User;
  18. use common\models\common\CapitalLog;
  19. use addons\Store\common\models\Store;
  20. use common\models\order\Order;
  21. use common\models\order\OrderDetail;
  22. use common\models\goods\GoodsAttr;
  23. use addons\WriteOff\common\models\WriteOffSetting;
  24. use addons\WriteOff\common\models\WriteOffMemberCode;
  25. use common\enums\ApiStatusEnum;
  26. /**
  27. * 默认控制器
  28. *
  29. * Class DefaultController
  30. * @package addons\WriteOff\api\modules\v1\controllers
  31. */
  32. class DefaultController extends OnAuthController
  33. {
  34. public $modelClass = '';
  35. /**
  36. * 不用进行登录验证的方法
  37. *
  38. * 例如: ['index', 'update', 'create', 'view', 'delete']
  39. * 默认全部需要验证
  40. *
  41. * @var array
  42. */
  43. protected $authOptional = [];
  44. /**
  45. * 首页
  46. */
  47. public function actionIndex()
  48. {
  49. if (!\Yii::$app->request->isGet) {
  50. return $this->error('请求方式错误');
  51. }
  52. // 获取配置
  53. $config = Yii::$app->services->setting->addons->get($this->mall_id, WriteOffEnum::ADDONS_NAME, 'basic');
  54. if(empty($config['is_enable'])){
  55. return $this->error('未开启应用');
  56. }
  57. $writeOffMember = WriteOffMember::findOne(['user_id'=>$this->user_id,'status'=>StatusEnum::ENABLED]);
  58. if(empty($writeOffMember)){
  59. return $this->error('暂无数据');
  60. }
  61. $code = WriteOffMemberCode::find()->where(['user_id'=>$this->user_id,'status'=>StatusEnum::ENABLED,'is_used'=>0])->orderBy('id asc')->select('code')->scalar();
  62. if(!$code){
  63. return $this->error('暂无数据');
  64. }
  65. $data = [
  66. 'background_url' => $config['background_url'],
  67. 'code' => (string)$code,
  68. 'code_url' => $writeOffMember['code_url'],
  69. 'num' => $writeOffMember['num'],
  70. 'used_num' => $writeOffMember['total_num'] - $writeOffMember['num'],
  71. ];
  72. return $this->success('请求成功', $data, ApiStatusEnum::CODE_SUCCESS,JSON_UNESCAPED_UNICODE);
  73. }
  74. /**
  75. * 核销记录
  76. */
  77. public function actionLog(){
  78. if (!\Yii::$app->request->isGet) {
  79. return $this->error('请求方式错误');
  80. }
  81. $page = \Yii::$app->request->get('page', 1);
  82. $limit = \Yii::$app->request->get('limit', $this->pageSize);
  83. $start_time = \Yii::$app->request->get('start_time');
  84. $end_time = \Yii::$app->request->get('end_time');
  85. $keyword = \Yii::$app->request->get('keyword');
  86. $wheres = [];
  87. $wheres[] = ['mall_id' => $this->mall_id];
  88. $wheres[] = ['user_id'=>$this->user_id];
  89. $wheres[] = ['change_type' =>'sub'];
  90. if(!empty($keyword)){
  91. $user_list = User::lists([
  92. 'where'=>[
  93. ['or',
  94. ['=', 'id', $keyword],
  95. ['like', 'nickname', $keyword],
  96. ['like', 'mobile', $keyword]
  97. ]
  98. ],
  99. 'select'=>'id',
  100. ]);
  101. $user_ids = array_column($user_list,'id');
  102. $param_user = [];
  103. if(!empty($user_ids)){
  104. $writeOffUserList = WriteOffUser::find()->where(['user_id' => $user_ids,'status' => StatusEnum::ENABLED])->asArray()->all();
  105. $w_user_ids = array_column($writeOffUserList,'id');
  106. $param_user = ['source_table_id'=>$w_user_ids,'source_table'=>WriteOffUser::tableName()];
  107. }
  108. $store_list = Store::lists([
  109. 'where'=>[
  110. ['or',
  111. ['=', 'id', $keyword],
  112. ['like', 'store_name', $keyword],
  113. ]
  114. ],
  115. 'select'=>'id',
  116. ]);
  117. $store_ids = array_column($store_list,'id');
  118. $param_store = [];
  119. if(!empty($store_ids)){
  120. $param_store = ['store_id'=>$store_ids];
  121. }
  122. $wheres[] = [
  123. 'or',
  124. $param_user,
  125. $param_store,
  126. ['=','order_no',$keyword],
  127. ];
  128. }
  129. if(!empty($start_time)){
  130. $wheres[] = ['>=','created_at',strtotime($start_time)];
  131. }
  132. if(!empty($end_time)){
  133. $wheres[] = ['<=','created_at',strtotime($end_time)];
  134. }
  135. $params = [
  136. 'select' => 'created_at,order_no,source_table_id,store_id',
  137. 'where' =>$wheres,
  138. 'order' => 'id desc',
  139. 'page' => $page,
  140. 'limit' => $limit,
  141. ];
  142. $list = WriteOffMemberLog::listPage($params, false, true);
  143. if(!empty($list['list'])){
  144. foreach($list['list'] as &$item){
  145. $item['created_at'] = date('Y-m-d H:i:s',$item['created_at']);
  146. if(!empty($item['source_table_id'])){
  147. $WriteOffUser = WriteOffUser::findOne($item['source_table_id']);
  148. $w_user = User::findOne($WriteOffUser['user_id']);
  149. $item['write_off_user'] = $w_user['nickname'] ?? '';
  150. }
  151. $item['store_name'] = Store::find()->where(['id'=>$item['store_id']])->select('store_name')->scalar() ?? '';
  152. unset($item['source_table_id'],$item['store_id']);
  153. }
  154. }
  155. return $this->success('success', $list);
  156. }
  157. /**
  158. * 基础设置
  159. */
  160. public function actionSetting(){
  161. if (!\Yii::$app->request->isGet) {
  162. return $this->error('请求方式错误');
  163. }
  164. $attr_ids = \Yii::$app->request->get('attr_ids');
  165. if(empty($attr_ids)) return $this->error('参数异常');
  166. $attr_ids = explode(",",$attr_ids);
  167. $goods_ids = GoodsAttr::find()->where(['id'=>$attr_ids])->select('goods_id')->column();
  168. // 获取配置
  169. $config = Yii::$app->services->setting->addons->get($this->mall_id, WriteOffEnum::ADDONS_NAME, 'basic');
  170. $data['is_enable_promote_reward'] = !empty($config['is_enable']) && !empty($config['is_enable_promote_reward']) ? $config['is_enable_promote_reward'] : 0;
  171. $goods_setting = WriteOffSetting::find()->where(['goods_id' => $goods_ids, 'is_enable_promote_reward' => StatusEnum::ENABLED, 'status' => StatusEnum::ENABLED])->indexBy('goods_id')->one();
  172. if(empty($goods_setting)) $data['is_enable_promote_reward'] = 0;
  173. return $this->success('请求成功', $data);
  174. }
  175. /**
  176. * 核销员搜索
  177. */
  178. public function actionUserInfo()
  179. {
  180. if (!\Yii::$app->request->isGet) {
  181. return $this->error('请求方式错误');
  182. }
  183. $user_keyword = \Yii::$app->request->get('user_keyword');
  184. if (empty($user_keyword)) return $this->error('参数错误');
  185. $write_off_user_ids = WriteOffUser::find()->where(['mall_id'=>$this->mall_id,'status' => StatusEnum::ENABLED])->select('user_id')->column();
  186. $user = User::find()
  187. ->select('id,nickname,avatar_url,mobile')
  188. ->where(['mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'id' => $user_keyword])
  189. ->andWhere(['in','id',$write_off_user_ids])
  190. ->asArray()
  191. ->one();
  192. return $this->success('success', $user);
  193. }
  194. /**
  195. * 核销员首页
  196. */
  197. public function actionUser(){
  198. if (!\Yii::$app->request->isGet) {
  199. return $this->error('请求方式错误');
  200. }
  201. $writeOffUser = WriteOffUser::findOne(['user_id' => $this->user_id,'status' => StatusEnum::ENABLED]);
  202. if (empty($writeOffUser)) {
  203. return $this->error('您还不是核销员');
  204. }
  205. $data['user'] = [
  206. 'nickname' => $this->user['nickname'],
  207. 'id' => $this->user['id'],
  208. 'avatar_url' => $this->user['avatar_url'],
  209. 'level_name' => '',
  210. 'store_name' => '',
  211. ];
  212. $level = WriteOffLevel::findOne(['mall_id'=>$this->mall_id,'level'=>$writeOffUser['level'],'status' => StatusEnum::ENABLED]);
  213. if($level){
  214. $data['user']['level_name'] = $level['name'];
  215. }
  216. $store = Store::findOne($writeOffUser['store_id']);
  217. if($store){
  218. $data['user']['store_name'] = $store['store_name'];
  219. }
  220. $data['total_commission'] = $writeOffUser['total_commission'];
  221. $data['today_commission'] = 0;
  222. $data['yesterday_commission'] = 0;
  223. $data['total_num'] = $writeOffUser['total_num'];
  224. $data['today_num'] = 0;
  225. CapitalLog::$capitalType = 'commission';
  226. $today_start = strtotime(date('Y-m-d 00:00:00',time()));
  227. $yesterday_start = strtotime(date('Y-m-d 00:00:00',strtotime('-1 day')));
  228. $commission_total_today = CapitalLog::find()
  229. ->where(['mall_id' => $this->mall_id, 'from_type' => WriteOffEnum::ADDONS_NAME,'change_type'=>'add','user_id'=>$this->user_id])
  230. ->andWhere(['>=','created_at',$today_start])
  231. ->sum('change_num');
  232. if(!empty($commission_total_today)) $data['today_commission'] = $commission_total_today;
  233. $commission_total_yesterday = CapitalLog::find()
  234. ->where(['mall_id' => $this->mall_id, 'from_type' => WriteOffEnum::ADDONS_NAME,'change_type'=>'add','user_id'=>$this->user_id])
  235. ->andWhere(['>=','created_at',$yesterday_start])
  236. ->andWhere(['<','created_at',$today_start])
  237. ->sum('change_num');
  238. if(!empty($commission_total_yesterday)) $data['yesterday_commission'] = $commission_total_yesterday;
  239. $log_today = WriteOffMemberLog::find()
  240. ->where(['source_table' => WriteOffUser::tableName(),'source_table_id' => $writeOffUser['id'],'change_type' => 'sub'])
  241. ->andWhere(['>=','created_at',$today_start])
  242. ->sum('change_num');
  243. if(!empty($log_today)) $data['today_num'] = $log_today;
  244. $data['list'] = [];
  245. $commission_list = CapitalLog::find()
  246. ->where(['mall_id' => $this->mall_id, 'from_type' => WriteOffEnum::ADDONS_NAME,'change_type'=>'add','user_id'=>$this->user_id])
  247. ->orderBy('created_at desc')
  248. ->select('created_at,order_no,capital_type,change_num,from_type,source_table_id')
  249. ->limit(10)
  250. ->asArray()
  251. ->all();
  252. if(!empty($commission_list)){
  253. foreach($commission_list as &$commission){
  254. $commission['created_at'] = date('Y-m-d H:i:s',$commission['created_at']);
  255. $commission['extra_user'] = '';
  256. $commission['extra_name'] = '';
  257. //核销
  258. if($commission['capital_type'] == WriteOffEnum::WRITE_OFF_PRIZE){
  259. $writeOffMemberLog = WriteOffMemberLog::findOne($commission['source_table_id']);
  260. if($writeOffMemberLog){
  261. $commission['extra_name'] = Store::find()->where(['id'=>$writeOffMemberLog['store_id']])->select('store_name')->scalar() ?? '';
  262. $commission['extra_user'] = User::find()->where(['id'=>$writeOffMemberLog['user_id']])->select('nickname')->scalar() ?? '';
  263. }
  264. }
  265. //促销
  266. if($commission['capital_type'] == WriteOffEnum::PROMOTE_PRIZE){
  267. $order_detail = OrderDetail::find()->where(['id'=>$commission['source_table_id']])->asArray()->one();
  268. if(!empty($order_detail)){
  269. $commission['extra_name'] = $order_detail['goods_name'];
  270. $commission['extra_user'] = User::find()->where(['id'=>$order_detail['user_id']])->select('nickname')->scalar() ?? '';
  271. }
  272. }
  273. $commission['capital_type_text'] = WriteOffEnum::getTypeMap($commission['capital_type']);
  274. unset($commission['from_type'],$commission['source_table_id']);
  275. }
  276. }
  277. $data['list'] = $commission_list;
  278. return $this->success('success', $data);
  279. }
  280. /**
  281. * 核销员奖励列表
  282. */
  283. public function actionUserLog(){
  284. if (!\Yii::$app->request->isGet) {
  285. return $this->error('请求方式错误');
  286. }
  287. $page = \Yii::$app->request->get('page', 1);
  288. $limit = \Yii::$app->request->get('limit', $this->pageSize);
  289. $start_time = \Yii::$app->request->get('start_time');
  290. $end_time = \Yii::$app->request->get('end_time');
  291. $capital_type = \Yii::$app->request->get('type');
  292. $wheres = [];
  293. $wheres[] = ['mall_id' => $this->mall_id,'user_id'=>$this->user_id];
  294. $wheres[] = ['from_type' => WriteOffEnum::ADDONS_NAME];
  295. if(!empty($capital_type)){
  296. $wheres[] = ['capital_type'=>$capital_type];
  297. }
  298. if(!empty($start_time)){
  299. $wheres[] = ['>=','created_at',strtotime($start_time)];
  300. }
  301. if(!empty($end_time)){
  302. $wheres[] = ['<=','created_at',strtotime($end_time)];
  303. }
  304. $params = [
  305. 'select' => 'created_at,order_no,capital_type,change_num,from_type,source_table_id',
  306. 'where' =>$wheres,
  307. 'order' => 'id desc',
  308. 'page' => $page,
  309. 'limit' => $limit,
  310. ];
  311. CapitalLog::$capitalType = 'commission';
  312. $list = CapitalLog::listPage($params, false, true);
  313. if(!empty($list['list'])){
  314. foreach($list['list'] as &$commission){
  315. $commission['created_at'] = date('Y-m-d H:i:s',$commission['created_at']);
  316. $commission['extra_user'] = '';
  317. $commission['extra_name'] = '';
  318. //核销
  319. if($commission['capital_type'] == WriteOffEnum::WRITE_OFF_PRIZE){
  320. $writeOffMemberLog = WriteOffMemberLog::findOne($commission['source_table_id']);
  321. if($writeOffMemberLog){
  322. $commission['extra_name'] = Store::find()->where(['id'=>$writeOffMemberLog['store_id']])->select('store_name')->scalar() ?? '';
  323. $commission['extra_user'] = User::find()->where(['id'=>$writeOffMemberLog['user_id']])->select('nickname')->scalar() ?? '';
  324. }
  325. }
  326. //促销
  327. if($commission['capital_type'] == WriteOffEnum::PROMOTE_PRIZE){
  328. $order_detail = OrderDetail::find()->where(['id'=>$commission['source_table_id']])->asArray()->one();
  329. if(!empty($order_detail)){
  330. $commission['extra_name'] = $order_detail['goods_name'];
  331. $commission['extra_user'] = User::find()->where(['id'=>$order_detail['user_id']])->select('nickname')->scalar() ?? '';
  332. }
  333. }
  334. $commission['capital_type_text'] = WriteOffEnum::getTypeMap($commission['capital_type']);
  335. unset($commission['from_type'],$commission['source_table_id']);
  336. }
  337. }
  338. $list['capital_type_list'] = WriteOffEnum::getTypeMap();
  339. return $this->success('success', $list);
  340. }
  341. /**
  342. * 核销
  343. */
  344. public function actionDoSubmit(){
  345. if (!\Yii::$app->request->isPost) {
  346. return $this->error('请求方式错误');
  347. }
  348. $code = \Yii::$app->request->post('code');
  349. if (empty($code)) {
  350. return $this->error('参数错误');
  351. }
  352. $lock_key = RedisKeyEnum::suffix('lock_write_off_do_submit', $code);
  353. $identification = uniqid();
  354. if (!LockHelper::lock($lock_key, $identification, 100, 100)) {
  355. return $this->error('网络异常,请稍后重试~');
  356. }
  357. $t = \Yii::$app->db->beginTransaction();
  358. try{
  359. $writeOffUser = WriteOffUser::findOne(['user_id' => $this->user_id,'status' => StatusEnum::ENABLED]);
  360. if (empty($writeOffUser)) {
  361. throw new \Exception('您还不是核销员,无权进行核销操作');
  362. }
  363. $level = WriteOffLevel::findOne(['mall_id'=>$this->mall_id,'level'=>$writeOffUser['level'],'status' => StatusEnum::ENABLED]);
  364. if(!empty($level['is_enable_promote_limit'])){
  365. $today_start = strtotime(date('Y-m-d 00:00:00',time()));
  366. $today_end = strtotime(date('Y-m-d 23:59:59',time()));
  367. $log_today = WriteOffMemberLog::find()
  368. ->where(['source_table' => WriteOffUser::tableName(),'source_table_id' => $writeOffUser['id'],'change_type' => 'sub'])
  369. ->andWhere(['>=','created_at',$today_start])
  370. ->andWhere(['<=','created_at',$today_end])
  371. ->sum('change_num') ?? 0;
  372. if($log_today >= $level['promote_time']){
  373. throw new \Exception('您今日核销次数已用完!');
  374. }
  375. }
  376. $writeOffMemberCode = WriteOffMemberCode::findOne(['mall_id' => $this->mall_id, 'code' => $code, 'status' => StatusEnum::ENABLED]);
  377. if (empty($writeOffMemberCode)) {
  378. throw new \Exception('核销数据不存在');
  379. }
  380. if($writeOffMemberCode->is_used == 1){
  381. throw new \Exception('该核销码已被核销!');
  382. }
  383. $writeOffMember = WriteOffMember::findOne(['mall_id' => $this->mall_id, 'user_id' => $writeOffMemberCode['user_id'], 'status' => StatusEnum::ENABLED]);
  384. if (empty($writeOffMember)) {
  385. throw new \Exception('核销用户不存在');
  386. }
  387. if($writeOffMember->num <= 0){
  388. throw new \Exception('该用户核销次数已用完');
  389. }
  390. $writeOffMemberCode->is_used = 1;
  391. if(!$writeOffMemberCode->save()) throw new \Exception(WriteOffMemberCode::getStaticError());
  392. $writeOffMember->num -= 1;
  393. if(!$writeOffMember->save()) throw new \Exception(WriteOffMember::getStaticError());
  394. $writeOffUser->total_num += 1;
  395. if(!$writeOffUser->save()) throw new \Exception(WriteOffUser::getStaticError());
  396. $order_no = WriteOffEnum::generateTradeNo('HX');
  397. $params = [
  398. 'user_id' => $writeOffMember['user_id'],
  399. 'mall_id' => $this->mall_id,
  400. 'change_num' => 1,
  401. 'current_num' => $writeOffMember->num,
  402. 'order_no' => $order_no,
  403. 'source_table' => WriteOffUser::tableName(),
  404. 'source_table_id' => $writeOffUser->id,
  405. 'store_id' => $writeOffUser->store_id,
  406. 'desc' => '线下门店核销',
  407. 'change_type' => 'sub',
  408. 'code' => $code,
  409. ];
  410. $writeOffMemberLog = WriteOffMemberLog::setData($params);
  411. if ($writeOffMemberLog === false) throw new \Exception(WriteOffMemberLog::getStaticError());
  412. $t->commit();
  413. LockHelper::uLock($lock_key, $identification);
  414. //触发核销奖励
  415. $queue_data = [
  416. 'id' => $writeOffMemberLog->id,
  417. ];
  418. TaskHelper::pushTaskQueue(RabbitMqEnum::ORDER_QUEUE, RabbitMqEnum::TASK_QUEUE, $queue_data, RewardLogic::class, 'writeOffReward', function (AMQPMessage $message) {
  419. \Yii::error('核销奖励发放异常'.$code);
  420. });
  421. return $this->success('核销成功');
  422. }catch(\Exception $e){
  423. $t->rollBack();
  424. LockHelper::uLock($lock_key, $identification);
  425. return $this->error('核销失败,'.$e->getMessage());
  426. }
  427. }
  428. }