IndexForm.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <?php
  2. namespace app\modules\admin\models\storeDividends;
  3. use app\models\Option;
  4. use app\models\Order;
  5. use app\models\SaasCategory;
  6. use app\models\SaasUser;
  7. use app\models\Store;
  8. use app\models\StoreDividendsCycle;
  9. use app\models\StoreDividendsCycleSub;
  10. use app\models\StoreDividendsCycleUserSub;
  11. use app\models\StoreDividendsUser;
  12. use app\models\StoreDividendsUserIntegralLog;
  13. use app\models\StoreDividendsUserLeagueLog;
  14. use app\models\User;
  15. use yii\base\Model;
  16. class IndexForm extends Model
  17. {
  18. public $user_name;
  19. public $store_name;
  20. public $order_no;
  21. public $start_time;
  22. public $end_time;
  23. public $integral_start;
  24. public $integral_end;
  25. public $price_start;
  26. public $price_end;
  27. public $mobile;
  28. public $status;
  29. public $sort_key;
  30. public $id;
  31. public function rules()
  32. {
  33. return [
  34. [['status', 'id'], 'integer'],
  35. [['integral_start', 'integral_end', 'price_start', 'price_end', 'sort_key'], 'number'],
  36. [['user_name', 'store_name', 'order_no', 'start_time', 'end_time', 'mobile'], 'string'],
  37. [['user_name', 'store_name', 'order_no'], 'trim']
  38. ];
  39. }
  40. public function attributeLabels()
  41. {
  42. return [
  43. 'user_name' => '用户名称',
  44. 'store_name' => '商家名称',
  45. 'order_no' => '订单编号',
  46. 'start_time' => '开始时间',
  47. 'end_time' => '结束时间',
  48. 'integral_start' => '积分开始',
  49. 'integral_end' => '积分结束',
  50. 'price_start' => '金额开始',
  51. 'price_end' => '金额结束',
  52. 'sort_key' => '期数',
  53. 'mobile' => '手机号'
  54. ];
  55. }
  56. /**
  57. * 平台分红池
  58. */
  59. public function storeDividendsPool() {
  60. $user_name = $this->user_name;
  61. $store_name = $this->store_name;
  62. $order_no = $this->order_no;
  63. $start_time = $this->start_time;
  64. $end_time = $this->end_time;
  65. $integral_start = $this->integral_start;
  66. $integral_end = $this->integral_end;
  67. $price_start = $this->price_start;
  68. $price_end = $this->price_end;
  69. $query = StoreDividendsUserIntegralLog::find()->alias('dui')
  70. ->leftJoin(['du' => StoreDividendsUser::tableName()], 'dui.dividends_user_id = du.id')
  71. ->leftJoin(['su' => SaasUser::tableName()], 'du.role_id = su.id AND du.role = ' . StoreDividendsUser::ROLE_USER)
  72. ->leftJoin(['s' => Store::tableName()], 'du.role_id = s.id AND du.role = ' . StoreDividendsUser::ROLE_STORE)
  73. ->leftJoin(['o' => Order::tableName()], 'dui.order_id = o.id AND dui.order_type <> ' . StoreDividendsCycleSub::ORDER_TYPE_FACE)
  74. ->leftJoin(['sco' => \app\plugins\scanCodePay\models\Order::tableName()], 'dui.order_id = sco.id AND dui.order_type = ' . StoreDividendsCycleSub::ORDER_TYPE_FACE)
  75. ->where(['>', 'dui.dividends_integral', 0]);
  76. if ($user_name) {
  77. $query->andWhere(['LIKE', 'su.name', $user_name]);
  78. }
  79. if ($store_name) {
  80. $query->andWhere(['LIKE', 's.name', $store_name]);
  81. }
  82. if ($order_no) {
  83. $query->andWhere(["OR", ['LIKE', 'o.order_no', $order_no], ['LIKE', 'sco.order_no', $order_no]]);
  84. }
  85. if ($start_time) {
  86. $start_time = strtotime($start_time);
  87. $query->andWhere(['>=', 'dui.created_at', $start_time]);
  88. }
  89. if ($end_time) {
  90. $end_time = strtotime($end_time);
  91. $query->andWhere(['<=', 'dui.created_at', $end_time]);
  92. }
  93. if ($integral_start) {
  94. $query->andWhere(['>=', 'dui.dividends_integral', $integral_start]);
  95. }
  96. if ($integral_end) {
  97. $query->andWhere(['<=', 'dui.dividends_integral', $integral_end]);
  98. }
  99. if ($price_start) {
  100. $query->andWhere(['>=', 'o.pay_price', $price_start]);
  101. }
  102. if ($price_end) {
  103. $query->andWhere(['<=', 'o.pay_price', $price_end]);
  104. }
  105. $query->select('dui.id, du.role, du.role_id, o.order_no, o.user_id, o.store_id, o.pay_price,
  106. , dui.order_type, sco.order_no as sc_order_no, sco.user_id as sc_user_id, sco.store_id as sc_store_id,
  107. sco.total_price as sc_total_price, sco.coupon_sub_price,
  108. dui.dividends_integral, dui.created_at')->orderBy('dui.id DESC')->groupBy('dui.id');
  109. $sql = (clone $query)->createCommand()->getRawSql();
  110. $list = pagination_make($query);
  111. foreach ($list['list'] as &$item) {
  112. //如果是当面付
  113. if ($item['order_type'] == StoreDividendsCycleSub::ORDER_TYPE_FACE) {
  114. $item['order_no'] = $item['sc_order_no'];
  115. $item['user_id'] = $item['sc_user_id'];
  116. $item['store_id'] = $item['sc_store_id'];
  117. $item['pay_price'] = bcsub($item['sc_total_price'], $item['coupon_sub_price'], 2);
  118. }
  119. //积分受益人
  120. $item['integral_user_name'] = '';
  121. if (intval($item['role']) === StoreDividendsUser::ROLE_STORE) {
  122. $item['integral_user_name'] = Store::findOne($item['role_id'])->name;
  123. } else {
  124. $item['integral_user_name'] = SaasUser::findOne($item['role_id'])->name;
  125. }
  126. //下单用户
  127. $item['user_name'] = '';
  128. $user = User::findOne($item['user_id']);
  129. if ($user) {
  130. $item['user_name'] = SaasUser::findOne(['mobile' => $user->binding, 'is_delete' => 0])->name ?: ($user->nickname ?: '');
  131. }
  132. //销售店铺
  133. $item['store_name'] = Store::findOne($item['store_id'])->name;
  134. //获取时间
  135. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  136. }
  137. $totalIntegralLogMall = StoreDividendsUserIntegralLog::find()->where(['>', 'dividends_integral', 0])
  138. ->andWhere(['<>', 'order_type', StoreDividendsCycleSub::ORDER_TYPE_FACE])
  139. ->select('order_id, dividends_integral')->asArray()->all();
  140. $total_price = Order::find()->where(['id' => array_column($totalIntegralLogMall, 'order_id')])
  141. ->sum('pay_price') ?: 0;
  142. $total_integral = floor_num(array_sum(array_column($totalIntegralLogMall, 'dividends_integral')), 2);
  143. $totalIntegralLogFace = StoreDividendsUserIntegralLog::find()->where(['>', 'dividends_integral', 0])
  144. ->andWhere(['order_type' => StoreDividendsCycleSub::ORDER_TYPE_FACE])
  145. ->select('order_id, dividends_integral')->asArray()->all();
  146. $face_total_price = \app\plugins\scanCodePay\models\Order::find()->where(['id' => array_column($totalIntegralLogFace, 'order_id')])
  147. ->sum('pay_price') ?: 0;
  148. $total_integral_face = floor_num(array_sum(array_column($totalIntegralLogFace, 'dividends_integral')), 2);
  149. $list['total_info'] = [
  150. 'total_integral' => bcadd($total_integral, $total_integral_face, 2),
  151. 'total_price' => bcadd($total_price, $face_total_price, 2),
  152. ];
  153. return [
  154. 'code' => 0,
  155. 'msg' => '',
  156. 'data' => $list,
  157. 'sql' => $sql
  158. ];
  159. }
  160. /**
  161. * 让利明细
  162. */
  163. public function storeDividendsDetail() {
  164. $order_no = $this->order_no;
  165. $start_time = $this->start_time;
  166. $end_time = $this->end_time;
  167. $query = StoreDividendsCycleSub::find()->alias('dcs')
  168. ->leftJoin(['o' => Order::tableName()], 'dcs.order_id = o.id AND dcs.order_type <> ' . StoreDividendsCycleSub::ORDER_TYPE_FACE)
  169. ->leftJoin(['sco' => \app\plugins\scanCodePay\models\Order::tableName()], 'dcs.order_id = sco.id AND dcs.order_type = ' . StoreDividendsCycleSub::ORDER_TYPE_FACE)
  170. ->where(['>', 'dcs.order_id', 0]);
  171. if ($order_no) {
  172. $query->andWhere(['LIKE', 'dcs.order_no', $order_no]);
  173. }
  174. if ($start_time) {
  175. $start_time = strtotime($start_time);
  176. $query->andWhere(['>=', 'dcs.created_at', $start_time]);
  177. }
  178. if ($end_time) {
  179. $end_time = strtotime($end_time);
  180. $query->andWhere(['<=', 'dcs.created_at', $end_time]);
  181. }
  182. $query->select('dcs.id, dcs.order_no, SUM(dcs.money) as money, o.pay_price, dcs.order_type,
  183. dcs.created_at, sco.total_price as sc_total_price, sco.coupon_sub_price')
  184. ->orderBy('dcs.id DESC')->groupBy('dcs.order_id');
  185. $list = pagination_make($query);
  186. foreach ($list['list'] as &$item) {
  187. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  188. if ($item['order_type'] == StoreDividendsCycleSub::ORDER_TYPE_FACE) {
  189. $item['pay_price'] = bcsub($item['sc_total_price'], $item['coupon_sub_price'], 2);
  190. }
  191. }
  192. $totalIntegral = StoreDividendsCycleSub::find()->where(['>', 'order_id', 0])
  193. ->select('order_id, money')->asArray()->all();
  194. $total_price = Order::find()->where(['id' => array_column($totalIntegral, 'order_id')])
  195. ->sum('pay_price') ?: 0;
  196. $total_money = floor_num(array_sum(array_column($totalIntegral, 'money')), 2);
  197. $list['total_info'] = [
  198. 'total_money' => $total_money,
  199. 'total_price' => $total_price,
  200. ];
  201. return [
  202. 'code' => 0,
  203. 'msg' => '',
  204. 'data' => $list,
  205. ];
  206. }
  207. /**
  208. * 分红记录
  209. */
  210. public function storeDividendsRecord() {
  211. $sort_key = $this->sort_key;
  212. $store_dividends_setting = Option::get('store_dividends_setting', 0, 'store_dividends')['value'];
  213. $store_dividends_setting = json_decode($store_dividends_setting, true);
  214. $single_integral_profit = $store_dividends_setting['store_dividends_single_integral_profit'] ?: 0;
  215. $query = StoreDividendsCycle::find()->alias('dc')
  216. ->leftJoin(['dcs' => StoreDividendsCycleSub::tableName()], 'dcs.dividends_cycle_id = dc.id')
  217. ->where(['>', 'dc.sort_key', 0]);
  218. if ($sort_key > 0) {
  219. $query->andWhere(['dc.sort_key' => $sort_key]);
  220. }
  221. $query->select('dc.id, dc.name, dc.integral_price dividends_integral, dc.dividends_user_num, dc.league_price, dc.is_send,
  222. dc.dividends_trigger_money, dc.dividends_money, dc.sort_key
  223. ')
  224. ->groupBy('dcs.dividends_cycle_id')->orderBy('dc.sort_key DESC');
  225. $list = pagination_make($query);
  226. foreach ($list['list'] as $index => &$item) {
  227. $item['is_send'] = intval($item['is_send']);
  228. if (!$item['is_send']) {
  229. $item['dividends_integral'] = StoreDividendsCycleUserSub::find()->where(['dividends_cycle_id' => $item['id']])
  230. ->sum('dividends_integral') ?: 0;
  231. }
  232. if (!$item['is_send']) {//未发放的话 获取不到发放的联盟券金额
  233. // $user_total_dividends_integral = StoreDividendsCycleUserSub::find()->where(['>', 'dividends_integral', '0'])
  234. // ->andWhere(['dividends_cycle_id' => $item['id']])
  235. $user_total_dividends_integral = StoreDividendsUser::find()->where(['>', 'dividends_integral', '0'])
  236. ->andWhere(['<=', 'join_cycle_key', $item['sort_key']])
  237. ->sum('dividends_integral');
  238. $item['league_price'] = bcdiv(bcmul($user_total_dividends_integral, $single_integral_profit, 2), 100, 2);
  239. }
  240. if ($item['dividends_trigger_money'] > $item['dividends_money']) {
  241. $item['is_send'] = 2;
  242. }
  243. if ($item['is_send'] !== 1) {
  244. // $item['dividends_user_num'] = StoreDividendsCycleUserSub::find()->where(['>', 'dividends_integral', '0'])
  245. // ->andWhere(['dividends_cycle_id' => $item['id']])->count() ?: 0;
  246. $item['dividends_user_num'] = StoreDividendsUser::find()->where(['>', 'dividends_integral', '0'])
  247. ->andWhere(['<=', 'join_cycle_key', $item['sort_key']])->count() ?: 0;
  248. }
  249. // unset($list['list'][$index]['user_integral'], $list['list'][$index]['store_integral'],
  250. // $list['list'][$index]['dividends_trigger_money'], $list['list'][$index]['dividends_money']);
  251. }
  252. $cycle_arr = StoreDividendsCycle::find()->where(['>', 'sort_key', 0])->select('sort_key, name')
  253. ->asArray()->all();
  254. $list['cycle_sort'] = [];
  255. foreach ($cycle_arr as &$cycle_item) {
  256. $list['cycle_sort'][] = [
  257. $cycle_item['sort_key'] => $cycle_item['name'],
  258. ];
  259. }
  260. return [
  261. 'code' => 0,
  262. 'msg' => '',
  263. 'data' => $list,
  264. ];
  265. }
  266. //执行分红
  267. public function storeDividendsSend() {
  268. try {
  269. $id = $this->id;
  270. $cycle = StoreDividendsCycle::findOne($id);
  271. if (!$cycle) {
  272. return [
  273. 'code' => 1,
  274. 'msg' => '参数错误',
  275. ];
  276. }
  277. if (intval($cycle->is_send)) {
  278. return [
  279. 'code' => 1,
  280. 'msg' => '分红已执行发放',
  281. ];
  282. }
  283. if ($cycle->dividends_trigger_money > $cycle->dividends_money) {
  284. throw new \Exception('未满足分红条件 暂不可发放');
  285. }
  286. $num = 0;
  287. $total_league_price = 0;
  288. $order = (object)[
  289. 'id' => 0
  290. ];
  291. $total_integral_price = 0;
  292. $result = StoreDividendsCycle::handleSendLeague($order, $cycle->id, $num, $total_league_price, $total_integral_price);
  293. if ($result['code']) {
  294. throw new \Exception($result['msg']);
  295. }
  296. $cycle->is_send = StoreDividendsCycle::IS_SEND_YES;
  297. $cycle->dividends_user_num = $num;
  298. $cycle->league_price = $total_league_price;
  299. $cycle->integral_price = $total_integral_price;
  300. if (!$cycle->save()) {
  301. throw new \Exception('发放失败【' . $cycle->getErrorSummary(true) . '】');
  302. }
  303. return [
  304. 'code' => 0,
  305. 'msg' => '发放成功',
  306. ];
  307. } catch (\Exception $e) {
  308. return [
  309. 'code' => 1,
  310. 'msg' => $e->getMessage(),
  311. ];
  312. }
  313. }
  314. /**
  315. * 分红明细
  316. */
  317. public function storeDividendsDetailList() {
  318. $store_dividends_setting = Option::get('store_dividends_setting', 0, 'store_dividends')['value'];
  319. $store_dividends_setting = json_decode($store_dividends_setting, true);
  320. $single_integral_profit = $store_dividends_setting['store_dividends_single_integral_profit'];
  321. $store_name = $this->store_name;
  322. $user_name = $this->user_name;
  323. $mobile = $this->mobile;
  324. $id = $this->id;
  325. $cycle = StoreDividendsCycle::findOne($id);
  326. if (!$cycle) {
  327. return [
  328. 'code' => 1,
  329. 'msg' => '参数错误',
  330. ];
  331. }
  332. if (!intval($cycle->is_send)) {
  333. // $query = StoreDividendsCycleUserSub::find()->alias('dcus')
  334. // ->leftJoin(['du' => StoreDividendsUser::tableName()], 'dcus.dividends_user_id = du.id')
  335. // ->leftJoin(['su' => SaasUser::tableName()], 'du.role_id = su.id AND du.role = ' . StoreDividendsUser::ROLE_USER)
  336. // ->leftJoin(['s' => Store::tableName()], 'du.role_id = s.id AND du.role = ' . StoreDividendsUser::ROLE_STORE)
  337. // ->where(['>', 'dcus.dividends_integral', 0])->andWhere(['dcus.dividends_cycle_id' => $cycle->id]);
  338. $query = StoreDividendsUser::find()->alias('du')
  339. ->leftJoin(['su' => SaasUser::tableName()], 'du.role_id = su.id AND du.role = ' . StoreDividendsUser::ROLE_USER)
  340. ->leftJoin(['s' => Store::tableName()], 'du.role_id = s.id AND du.role = ' . StoreDividendsUser::ROLE_STORE)
  341. ->where(['>', 'du.dividends_integral', 0])->andWhere(['<=', 'du.join_cycle_key', $cycle->sort_key]);
  342. if ($store_name) {
  343. $query->andWhere(['like', 's.name', $store_name]);
  344. }
  345. if ($user_name) {
  346. $query->andWhere(['like', 'su.name', $user_name]);
  347. }
  348. if ($mobile) {
  349. $query->andWhere(['like', 'su.mobile', $mobile]);
  350. }
  351. $query->select('du.id, du.role, du.role_id, du.dividends_integral')//$query->select('du.id, du.role, du.role_id, dcus.dividends_integral')
  352. ->orderBy('du.id DESC');
  353. } else {
  354. $query = StoreDividendsUserLeagueLog::find()->alias('dul')
  355. ->leftJoin(['du' => StoreDividendsUser::tableName()], 'dul.dividends_user_id = du.id')
  356. ->leftJoin(['su' => SaasUser::tableName()], 'du.role_id = su.id AND du.role = ' . StoreDividendsUser::ROLE_USER)
  357. ->leftJoin(['s' => Store::tableName()], 'du.role_id = s.id AND du.role = ' . StoreDividendsUser::ROLE_STORE)
  358. ->where(['>', 'dul.dividends_cycle_id', 0]);
  359. if ($store_name) {
  360. $query->andWhere(['like', 's.name', $store_name]);
  361. }
  362. if ($user_name) {
  363. $query->andWhere(['like', 'su.name', $user_name]);
  364. }
  365. if ($mobile) {
  366. $query->andWhere(['like', 'su.mobile', $mobile]);
  367. }
  368. if ($id) {
  369. $query->andWhere(['dul.dividends_cycle_id' => $id]);
  370. }
  371. $query->select('dul.id, du.role, du.role_id, dul.dividends_integral, dul.league_price, dul.created_at')
  372. ->orderBy('dul.id DESC');
  373. }
  374. $list = pagination_make($query);
  375. foreach ($list['list'] as &$item) {
  376. if ($item['role'] == StoreDividendsUser::ROLE_USER) {
  377. $saasInfo = SaasUser::findOne($item['role_id']);
  378. $item['user_info'] = [
  379. 'name' => $saasInfo->name,
  380. 'sub_name' => $saasInfo->mobile,
  381. 'avatar' => $saasInfo->avatar,
  382. ];
  383. } else {
  384. $store = Store::findOne($item['role_id']);
  385. $saasCategory = SaasCategory::findOne($store->category_id);
  386. $item['user_info'] = [
  387. 'name' => $store->name,
  388. 'sub_name' => $saasCategory->name ?: '',
  389. 'avatar' => $store->logo,
  390. ];
  391. }
  392. $item['sort_name'] = $cycle->name;
  393. $item['sort_id'] = $cycle->id;
  394. if (!intval($cycle->is_send)) {
  395. $item['league_price'] = bcdiv(bcmul($item['dividends_integral'], $single_integral_profit, 2), 100, 2);
  396. }
  397. $item['created_at'] = $item['created_at'] ? date('Y-m-d H:i:s', $item['created_at']) : '';
  398. }
  399. return [
  400. 'code' => 0,
  401. 'msg' => '',
  402. 'data' => $list,
  403. ];
  404. }
  405. }