UserForm.php 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models;
  8. use app\constants\OptionSetting;
  9. use app\models\Address;
  10. use app\models\Cash;
  11. use app\models\common\InviteCode;
  12. use app\models\District;
  13. use app\models\Level;
  14. use app\models\Mch;
  15. use app\models\Option;
  16. use app\models\Order;
  17. use app\models\SaasUser;
  18. use app\models\ShareDetail;
  19. use app\models\Shop;
  20. use app\models\User;
  21. use app\models\UserCard;
  22. use app\models\UserLabel;
  23. use app\models\UserShareMoney;
  24. use app\utils\Export;
  25. use app\utils\ExportList;
  26. use Spatie\SimpleExcel\SimpleExcelWriter;
  27. use Yii;
  28. use yii\base\Model;
  29. use app\models\PospalUser;
  30. use app\models\Share;
  31. use app\models\ShareHolderParentOutLog;
  32. class UserForm extends Model
  33. {
  34. public $store_id;
  35. public $md_id;
  36. public $ids;
  37. public $price;
  38. public $contact_way;
  39. public $comments;
  40. public $blacklist;
  41. public $level;
  42. public $id;
  43. public $parent_id;
  44. public $old_parent_id;
  45. public $init_parent_id;
  46. public $is_saas_clerk;
  47. public $type;
  48. public $name;
  49. public $phone;
  50. public $dateStart;
  51. public $dateEnd;
  52. public $flag;
  53. public $fields;
  54. public $is_admin = -1;
  55. public $is_yinbao = 0;
  56. public $user_remark;
  57. public $payment;
  58. public $binding;
  59. public $user_id;
  60. public $mobile;
  61. public $detail;
  62. public $province_id;
  63. public $city_id;
  64. public $district_id;
  65. public $is_default;
  66. public $latitude;
  67. public $longitude;
  68. public $is_export;
  69. public $remark_name;
  70. public $money_month_min;
  71. public $password;
  72. public $nickname;
  73. //订单数量
  74. public $orderCountStart;
  75. public $orderCountEnd;
  76. //订单金额
  77. public $priceTotalStart;
  78. public $priceTotalEnd;
  79. //余额
  80. public $moneyStart;
  81. public $moneyEnd;
  82. //积分
  83. public $integralStart;
  84. public $integralEnd;
  85. public $user_label_id;
  86. public $user_label_name;
  87. /**
  88. * @return array the validation rules.
  89. */
  90. public function rules()
  91. {
  92. return [
  93. [['comments', 'name', 'dateStart', 'dateEnd', 'phone', 'flag', 'type', 'ids', 'user_remark', 'mobile', 'detail', 'password', 'user_label_name', 'nickname'], 'string'],
  94. [['name', 'dateStart', 'dateEnd', 'phone', 'flag', 'remark_name', 'password', 'nickname'], 'trim'],
  95. [['id', 'blacklist', 'level', 'parent_id', 'is_saas_clerk', 'is_admin', 'is_yinbao', 'old_parent_id', 'is_export', 'user_id', 'province_id', 'city_id', 'district_id', 'store_id', 'md_id'], 'integer'],
  96. [['price', 'latitude', 'longitude', 'orderCountStart', 'orderCountEnd', 'priceTotalStart', 'priceTotalEnd', 'moneyStart', 'moneyEnd', 'integralStart', 'integralEnd'], 'number'],
  97. [['fields', 'payment', 'is_default', 'money_month_min', 'init_parent_id','user_label_id'], 'safe'],
  98. [['contact_way', 'binding'], 'match', 'pattern' => '/^1[3456789]\d{9}$/', 'message' => '手机号码格式不正确。'],
  99. ];
  100. }
  101. public function getUserList()
  102. {
  103. $query = User::find()->alias('u')->where([
  104. 'u.type' => User::USER_TYPE_NORMAL,
  105. 'u.store_id' => $this->store_id,
  106. 'u.is_delete' => User::USER_NOT_DELETE,
  107. ])->andWhere(['<>', 'u.binding' , ''])
  108. ->leftJoin(SaasUser::tableName() . ' su', 'su.mobile=u.binding');
  109. if($this->is_yinbao){
  110. $query->leftJoin(['pu' => PospalUser::tableName()], 'pu.user_id = u.id')->leftJoin(['o' => \app\models\OrderPospal::find()
  111. ->where(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])
  112. ->andWhere(['is_delete' => 0])
  113. ->andWhere(['is_pay' => Order::IS_PAY_TRUE, 'store_id' => $this->store_id])->select('user_id,
  114. count( id ) AS order_count,
  115. sum( pay_price ) AS pay_price_sum')->groupBy('user_id')], 'o.user_id = u.id')
  116. ->andWhere(['>', 'pu.id', 0]);
  117. } else {
  118. $query->leftJoin(['o' => Order::find()
  119. ->where(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])
  120. ->andWhere(['is_delete' => 0])
  121. ->andWhere(['is_pay' => Order::IS_PAY_TRUE, 'store_id' => $this->store_id, 'is_recycle' => 0])->select('user_id,
  122. count( id ) AS order_count,
  123. sum( pay_price ) AS pay_price_sum')->groupBy('user_id')], 'o.user_id = u.id');
  124. }
  125. // 手机号 TODO:这是啥东西判断???看不懂,先注释了
  126. // if ($this->type == 'mobile') {
  127. // if ($this->name) {
  128. // $query->andWhere(['or', ['like', 'u.contact_way', $this->name], ['like', 'u.binding', $this->name]]);
  129. // }
  130. // }
  131. // //名称或者昵称
  132. // if ($this->type == 'type') {
  133. // if ($this->name) {
  134. // $query->andWhere(['or', ['like', 'u.nickname', $this->name], ['like', 'su.name', $this->name]]);
  135. // }
  136. // }
  137. if (intval($this->orderCountStart) > 0) {
  138. $query->andWhere(['>=', 'o.order_count', $this->orderCountStart]);
  139. }
  140. if (intval($this->orderCountEnd) > 0) {
  141. $query->andWhere(['<=', 'o.order_count', $this->orderCountEnd]);
  142. }
  143. if (intval($this->priceTotalStart) > 0) {
  144. $query->andWhere(['>=', 'o.pay_price_sum', $this->priceTotalStart]);
  145. }
  146. if (intval($this->priceTotalEnd) > 0) {
  147. $query->andWhere(['<=', 'o.pay_price_sum', $this->priceTotalEnd]);
  148. }
  149. if (floatval($this->moneyStart) > 0) {
  150. $query->andWhere(['>=', 'u.money', $this->moneyStart]);
  151. }
  152. if (floatval($this->moneyEnd) > 0) {
  153. $query->andWhere(['<=', 'u.money', $this->moneyEnd]);
  154. }
  155. if (floatval($this->integralStart) > 0) {
  156. $query->andWhere(['>=', 'u.integral', $this->integralStart]);
  157. }
  158. if (floatval($this->integralEnd) > 0) {
  159. $query->andWhere(['<=', 'u.integral', $this->integralEnd]);
  160. }
  161. if (isset($this->money_month_min)) {
  162. $query->andWhere(['>', 'u.money_month', $this->money_month_min]);
  163. }
  164. if ($this->user_id) {
  165. $query->andWhere(['u.id' => $this->user_id]);
  166. }
  167. if ($this->phone) {
  168. $query->andWhere(['like', 'u.binding', $this->phone]);
  169. }
  170. if ($this->user_remark) {
  171. $query->andWhere(['like', 'u.user_remark', $this->user_remark]);
  172. }
  173. if ($this->name) {
  174. $query->andWhere(['OR', ['like', 'su.name', $this->name], ['like', 'u.nickname', $this->name]]);
  175. }
  176. // 日期
  177. if ($this->dateStart) {
  178. $query->andWhere(['>=', 'u.created_at', strtotime($this->dateStart)]);
  179. }
  180. if ($this->dateEnd) {
  181. $query->andWhere(['<=', 'u.created_at', strtotime($this->dateEnd)]);
  182. }
  183. if ($this->is_admin == 1) {
  184. $query->andWhere(['u.is_admin' => 1]);
  185. } elseif ($this->is_admin == 0) {
  186. $query->andWhere(['u.is_admin' => 0]);
  187. }
  188. if (!empty($this->user_label_id)) {
  189. $query->andWhere(['like','user_label_id' , ','.$this->user_label_id.',']);
  190. }
  191. // $orderQuery = Order::find()->where([
  192. // 'store_id' => $this->store_id, 'is_delete' => 0,
  193. // 'mch_id' => 0
  194. // ])->andWhere('user_id = u.id')->andWhere(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])->select('count(1)');
  195. // $cardQuery = UserCard::find()->where(['store_id' => $this->store_id, 'is_delete' => 0])
  196. // ->andWhere('user_id = u.id')->select('count(1)');
  197. // 等级
  198. if ($this->level || $this->level === '0' || $this->level === 0) {
  199. $query->andWhere(['u.level' => $this->level]);
  200. }
  201. // if ($this->flag === Export::EXPORT) {
  202. // $orderConsumeQuery = Order::find()->where(['store_id' => $this->store_id, 'is_delete' => 0])->andWhere(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])->andWhere('user_id = u.id')->select('sum(pay_price)');
  203. // $list = $query->select([
  204. // 'u.*', 's.name shop_name', 'l.name l_name', 'card_count' => $cardQuery, 'order_count' => $orderQuery,
  205. // 'orderConsume' => $orderConsumeQuery,
  206. // ])->orderBy('u.created_at DESC')->asArray()->all();
  207. // $export = new ExportList();
  208. // $export->fields = $this->fields;
  209. // $export->UserExportData($list);
  210. // }
  211. $slectExt = [];
  212. if($this->is_yinbao){
  213. $slectExt = ['pu.json pu_json'];
  214. }
  215. $query->groupBy('u.id')->orderBy('u.id DESC');
  216. if (intval($this->is_export) === 1) {
  217. return $this->exportUserInfo($query);
  218. }
  219. $query->select(array_merge(['u.*', 'o.order_count', 'o.pay_price_sum'], $slectExt));
  220. $pagination = pagination_make($query);
  221. $list = $pagination['list'];
  222. // 会员列表
  223. $level = Level::find()->select('level, name')->where([
  224. 'store_id' => $this->store_id,
  225. 'is_delete' => Level::NOT_DELETE,
  226. 'status' => Level::STATUS_TRUE
  227. ])->asArray()->all();
  228. $level[] = ['level' => '-1', 'name' => '普通用户'];
  229. foreach ($list as $key => &$value) {
  230. //id转化成邀请码
  231. $list[$key]['invite_code'] = InviteCode::id2Code($value['id']);
  232. $level_ = Level::findOne(['level' => $value['level'], 'is_delete' => 0, 'store_id' => $this->store_id]);
  233. if ($level_) {
  234. $value['l_name'] = $level_->name;
  235. }
  236. if(!empty($value['user_label_id'])){
  237. $userLabelRes = UserLabel::getLabelNames($this->store_id, trim($value['user_label_id'],','));
  238. $value['user_label_name'] = $userLabelRes ?: [];
  239. $value['user_label_id'] = explode(',',trim($value['user_label_id'],','));
  240. }else{
  241. $value['user_label_name'] = [];
  242. }
  243. if (empty($value['l_name'])) {
  244. $list[$key]['l_name'] = '普通用户';
  245. }
  246. // 25-4-23分支要求秀嘎 这里不管就显示商城的头像和昵称
  247. $value['saas_name'] = $value['nickname'];
  248. $value['saas_avatar'] = $value['avatar_url'];
  249. // if (empty($value['binding'])) {
  250. // $value['saas_name'] = $value['nickname'];
  251. // $value['saas_avatar'] = $value['avatar_url'];
  252. // } else {
  253. $sass_user = SaasUser::findOne(['mobile' => $value['binding']]);
  254. if ($sass_user) {
  255. $value['saas_id'] = $sass_user->id;
  256. }
  257. // }
  258. $user = User::find()->where(['store_id' => $this->store_id, 'id' => $value['parent_id']])
  259. ->select('nickname')->asArray()->One();
  260. // 成交订单数
  261. // $list[$key]['orderCount'] = Order::find()
  262. // ->where(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])
  263. // ->andWhere(['is_delete' => 0])
  264. // ->andWhere(['is_pay' => Order::IS_PAY_TRUE, 'store_id' => $this->store_id, 'user_id' => $value['id']])
  265. // ->count();
  266. //
  267. // // 成交金额
  268. // $list[$key]['priceTotal'] = sprintf('%.2f', Order::find()->where(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])
  269. // ->andWhere(['is_pay' => Order::IS_PAY_TRUE, 'store_id' => $this->store_id, 'user_id' => $value['id']])
  270. // ->sum('pay_price'));
  271. $list[$key]['orderCount'] = $list[$key]['order_count'] ?: 0;
  272. $list[$key]['priceTotal'] = $list[$key]['pay_price_sum'] ?: '0.00';
  273. unset($list[$key]['order_count'], $list[$key]['pay_price_sum']);
  274. $list[$key]['parent_name'] = !empty($user['nickname']) ? $user['nickname'] : '总店';
  275. $list[$key]['nickname'] = $value['nickname'] ?: $value['saas_name'];
  276. $list[$key]['avatar_url'] = !empty($value['saas_avatar']) ? $value['saas_avatar'] : $value['avatar_url'];
  277. $list[$key]['create_at_text'] = date('Y-m-d H:i:s', $value['created_at']);
  278. if (strpos($value['binding'], 'X')) {
  279. $value['binding'] = '';
  280. }
  281. //门店增加收银台 查询商品列表逻辑
  282. if (!empty($this->md_id) && $this->md_id > 0) {
  283. $list[$key]['binding'] = substr_replace($value['binding'], '****', 3, 4);
  284. }
  285. // TODO: 其他数据
  286. }
  287. return [
  288. 'code' => 0,
  289. 'msg' => 'success',
  290. 'data' => [
  291. 'level' => $level,
  292. 'data' => $list,
  293. 'pageNo' => $pagination['pageNo'],
  294. 'totalCount' => $pagination['totalCount'],
  295. ],
  296. ];
  297. }
  298. /**
  299. * 查看用户详情列表(积分、余额、会员记录)
  300. * @return array
  301. */
  302. public function getUserIntegralRechargeList()
  303. {
  304. $query = User::find()->orderBy('created_at DESC');
  305. $pagination = pagination_make($query);
  306. $list = $pagination['list'];
  307. foreach ($list as $key => $value) {
  308. }
  309. return [
  310. 'code' => 0,
  311. 'msg' => 'success',
  312. 'data' => [
  313. 'data' => $list,
  314. 'pageNo' => $pagination['pageNo'],
  315. 'totalCount' => $pagination['totalCount'],
  316. ],
  317. ];
  318. }
  319. /**
  320. * 更新用户信息
  321. * @return array
  322. * @throws \yii\base\Exception
  323. */
  324. public function updateUserInfo()
  325. {
  326. try {
  327. if ($this->validate()) {
  328. if ($this->id == $this->parent_id || $this->id == $this->old_parent_id || $this->id == $this->init_parent_id) {
  329. return [
  330. 'code' => 1,
  331. 'msg' => '不能添加自己为上级'
  332. ];
  333. }
  334. $user = User::findOne(['id' => $this->id, 'is_delete' => User::USER_NOT_DELETE]);
  335. if ($user->binding != $this->binding) {
  336. $t = \Yii::$app->db->beginTransaction();
  337. try {
  338. $is = User::findOne(['binding' => $this->binding, 'is_delete' => 0]);
  339. if ($is) {
  340. throw new \Exception('该手机号已被使用');
  341. }
  342. $users = User::find()->where(['binding' => $user->binding, 'is_delete' => 0])->all();
  343. foreach ($users as $userItem) {
  344. $userItem->binding = $this->binding;
  345. $userItem->save();
  346. }
  347. $saasUser = SaasUser::findOne(['mobile' => $user->binding, 'is_delete' => 0]);
  348. if ($saasUser) {
  349. $saasUser->mobile = $this->binding;
  350. $saasUser->save();
  351. }
  352. $t->commit();
  353. } catch (\Exception $ex) {
  354. $t->rollBack();
  355. return [
  356. 'code' => 1,
  357. 'msg' => $ex->getMessage(),
  358. ];
  359. }
  360. }
  361. $oldParentChange = 0;
  362. $parentChange = 0;
  363. $beforeOldParentId = $user->old_parent_id;
  364. $beforeParentId = $user->parent_id;
  365. if($user->old_parent_id != $this->old_parent_id){
  366. $oldParentChange = 1;
  367. }
  368. if($user->parent_id != $this->parent_id){
  369. $parentChange = 1;
  370. }
  371. debug_log('parentChange => ' . $parentChange, 'aaaa.log');
  372. debug_log('oldParentChange => ' . $oldParentChange, 'aaaa.log');
  373. $diff_price = bcsub($this->price, $user->price, 2);
  374. if ($diff_price > 0) {
  375. $user->total_price = bcadd($user->total_price, $diff_price, 2);
  376. }
  377. if (!empty($this->password)) {
  378. $user->password = \Yii::$app->security->generatePasswordHash($this->password);
  379. }
  380. if (!empty($this->nickname)) {
  381. $user->nickname = $this->nickname;
  382. }
  383. $user->level = $this->level;
  384. $user->price = $this->price;
  385. $user->parent_id = $this->parent_id;
  386. $user->old_parent_id = $this->old_parent_id;
  387. $user->init_parent_id = $this->init_parent_id;
  388. $user->contact_way = $this->contact_way;
  389. $user->remark_name = $this->remark_name;
  390. $user->comments = $this->comments;
  391. $user->blacklist = $this->blacklist;
  392. $user->is_saas_clerk = $this->is_saas_clerk;
  393. if ($this->user_label_id) {
  394. $user->user_label_id = ','.implode(',',$this->user_label_id).',';
  395. }
  396. $group_setting = OptionSetting::getOptionSetting();
  397. $group_arr = $group_setting['pay']['list'] ?: [];
  398. foreach ($group_arr as $val) {
  399. if ($val['name'] == 'payment') {
  400. $group_data = Option::findOne(['store_id' => $this->store_id, 'group' => 'user', 'name' => $val['name'].'_'.$user->id]);
  401. $payment[] = [
  402. 'name' => $group_data ? $group_data->name : $val['name'].'_'.$user->id,
  403. 'text' => $val['text'],
  404. 'group' => $group_data ? $group_data->group : 'user',
  405. 'type' => $val['type'],
  406. 'value' => $this->payment,
  407. 'updated_at' => $group_data ? $group_data->updated_at : 0,
  408. ];
  409. $empty = 1;
  410. foreach($this->payment as $item){
  411. if($item['value']){
  412. $empty = 0;
  413. break;
  414. }
  415. }
  416. if($empty){
  417. if($group_data){
  418. Option::deleteAll(['store_id' => $this->store_id, 'group' => $payment[0]['group'], 'name' => $payment[0]['name']]);
  419. }
  420. }else{
  421. $res = Option::setGroup('user',$payment, $user->store_id);
  422. }
  423. }
  424. }
  425. $levelData = Level::findOne(['level' => $this->level, 'promotion_status' => 1, 'store_id' => $this->store_id, 'is_delete' => Level::NOT_DELETE]);
  426. if (!empty($levelData) && $user->is_distributor != 1) {
  427. $user->is_distributor = 1;
  428. $share = Share::findOne(['user_id' => $user->id, 'store_id' => $user->store_id, 'is_delete' => 0]);
  429. if (!$share) {
  430. $share = new Share();
  431. $share->user_id = $user->id;
  432. $share->mobile = $user->binding;
  433. $share->name = $user->nickname;
  434. $share->is_delete = 0;
  435. $share->store_id = $user->store_id;
  436. $share->status = 1;
  437. $share->created_at = time();
  438. if (!$share->save()) {
  439. throw new \Exception('添加用户分销商信息失败' . $share->getErrors());
  440. }
  441. }
  442. }
  443. if ($user->save()) {
  444. $oldParentChange && \app\utils\Share\BonusPool::addShareHolderParentOutLog($user, $beforeOldParentId, ShareHolderParentOutLog::getConditionName(11), 1);
  445. $parentChange && \app\utils\Share\BonusPool::addShareHolderParentOutLog($user, $beforeParentId, ShareHolderParentOutLog::getConditionName(11), 0);
  446. if ($diff_price != 0) {
  447. if ($diff_price > 0) {
  448. $str = '后台修改佣金-增加';
  449. $type = 0;
  450. } else {
  451. $str = '后台修改佣金-减少';
  452. $type = 1;
  453. }
  454. $diff_price = abs($diff_price);
  455. UserShareMoney::set($diff_price, $user->id, 0, $type, 10, $user->store_id, 0, $str);
  456. }
  457. return [
  458. 'code' => 0,
  459. 'msg' => '更新成功'
  460. ];
  461. }
  462. return [
  463. 'code' => 1,
  464. 'msg' => $this->getErrorSummary(false)[0],
  465. ];
  466. }
  467. return [
  468. 'code' => 1,
  469. 'msg' => $this->getErrorSummary(false)[0],
  470. ];
  471. } catch (\Exception $e) {
  472. return [
  473. 'code' => 1,
  474. 'msg' => '更新失败'.$e->getMessage(),
  475. ];
  476. }
  477. }
  478. /**
  479. * 删除管理员
  480. * @return array|bool
  481. */
  482. public function delAdmin()
  483. {
  484. $id = $this->id;
  485. $user = User::findOne($id);
  486. if (empty($user)) {
  487. return [
  488. 'code' => 1,
  489. 'msg' => '未选择任何数据'
  490. ];
  491. }
  492. $user->is_admin = 0;
  493. if (!$user->save()) {
  494. return [
  495. 'code' => 1,
  496. 'msg' => '删除失败' . $user->errors
  497. ];
  498. }
  499. return [
  500. 'code' => 0,
  501. 'msg' => '删除成功'
  502. ];
  503. }
  504. /**
  505. * 导出用户数据
  506. */
  507. public function exportUserInfo($query) {
  508. $query->select('u.id, su.id saas_id, su.name saas_name, u.binding, u.level l_name, u.created_at, u.price, u.total_price, u.integral, u.total_integral, u.money, u.nickname');
  509. $list = $query->asArray()->all();
  510. foreach ($list as $key => &$value) {
  511. $level = Level::findOne(['level' => $value['l_name'], 'is_delete' => 0, 'store_id' => $this->store_id]);
  512. $value['l_name'] = $level->name ?: '普通用户';
  513. if (empty($value['binding'])) {
  514. $value['saas_name'] = $value['nickname'];
  515. }
  516. // 成交订单数
  517. $value['orderCount'] = count(Order::find()
  518. ->where(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])
  519. ->andWhere(['is_pay' => Order::IS_PAY_TRUE, 'store_id' => $this->store_id, 'user_id' => $value['id']])
  520. ->asArray()->all());
  521. // 成交金额
  522. $value['priceTotal'] = sprintf('%.2f', Order::find()->where(['<>', 'trade_status', Order::ORDER_FLOW_CANCEL])
  523. ->andWhere(['is_pay' => Order::IS_PAY_TRUE, 'store_id' => $this->store_id, 'user_id' => $value['id']])
  524. ->sum('pay_price'));
  525. // $list[$key]['parent_name'] = !empty($user['nickname']) ? $user['nickname'] : '总店';
  526. // $list[$key]['nickname'] = $value['nickname'] ?: $value['saas_name'];
  527. $value['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
  528. if (strpos($value['binding'], 'X')) {
  529. $value['binding'] = '';
  530. }
  531. unset($list[$key]['nickname']);
  532. // TODO: 其他数据
  533. }
  534. $list = array_values($list);
  535. $list = array_merge([
  536. [
  537. 'id' => "主键",
  538. 'saas_id' => '联盟用户主键',
  539. 'saas_name' => '用户昵称',
  540. 'binding' => "手机号",
  541. 'l_name' => "用户等级",
  542. 'created_at' => "创建时间",
  543. 'price' => "可提现佣金",
  544. 'total_price' => "总佣金",
  545. 'integral' => "积分",
  546. 'total_integral' => "总积分",
  547. 'money' => "钱包余额",
  548. 'orderCount' => "订单总数量",
  549. 'priceTotal' => "订单总金额",
  550. ]
  551. ], $list);
  552. $writer = SimpleExcelWriter::streamDownload('store_user_' . time() . '.xlsx')->noHeaderRow()
  553. ->addRows($list)->toBrowser();
  554. }
  555. public function addAddress() {
  556. try {
  557. $user_id = $this->user_id;
  558. $name = $this->name;
  559. $mobile = $this->mobile;
  560. $detail = $this->detail;
  561. $province_id = $this->province_id;
  562. $city_id = $this->city_id;
  563. $district_id = $this->district_id;
  564. $is_default = $this->is_default;
  565. $store_id = $this->store_id;
  566. $id = $this->id;
  567. $latitude = $this->latitude;
  568. $longitude = $this->longitude;
  569. $user = User::findOne($user_id);
  570. $saas_user = SaasUser::findOne(['mobile' => $user->binding]);
  571. $address = Address::findOne($id) ?: new Address();
  572. $address->store_id = $store_id;
  573. $address->user_id = $saas_user->id;
  574. $address->is_delete = Address::DELETE_STATUS_FALSE;
  575. $address->addtime = time();
  576. $address->name = trim($name);
  577. $address->mobile = $mobile;
  578. $address->detail = trim($detail);
  579. $province = District::findOne($province_id);
  580. if (!$province) {
  581. throw new \Exception('省份数据错误,请重新选择');
  582. }
  583. $address->province_id = $province->id;
  584. $address->province = $province->name;
  585. if ($this->longitude) {
  586. $address->longitude = $this->longitude;
  587. }
  588. if ($this->latitude) {
  589. $address->latitude = $this->latitude;
  590. }
  591. $city = District::findOne($city_id);
  592. if (!$city) {
  593. throw new \Exception('城市数据错误,请重新选择');
  594. }
  595. $address->city_id = $city->id;
  596. $address->city = $city->name;
  597. $district = District::findOne($district_id);
  598. if (!$district) {
  599. throw new \Exception('地区数据错误,请重新选择');
  600. }
  601. $address->district_id = $district->id;
  602. $address->district = $district->name;
  603. $address->is_default = $is_default ?: 0;
  604. $address->latitude = $latitude ?: '0.00';
  605. $address->longitude = $longitude ?: '0.00';
  606. if (!$address->save()) {
  607. throw new \Exception(json_encode($address->errors, JSON_UNESCAPED_UNICODE));
  608. }
  609. if (intval($is_default)) {
  610. $this->id = $address->id;
  611. $result = $this->setUserAddressStatus();
  612. if ($result['code'] !== 0) {
  613. return $result;
  614. }
  615. }
  616. $address = Address::find()->where([
  617. 'user_id' => $saas_user->id,
  618. 'is_delete' => 0,
  619. ])->asArray()->all();
  620. return [
  621. 'code' => 0,
  622. 'msg' => "设置成功",
  623. 'data' => $address
  624. ];
  625. } catch (\Exception $e) {
  626. return [
  627. 'code' => 1,
  628. 'msg' => $e->getMessage(),
  629. ];
  630. }
  631. }
  632. public function setUserAddressStatus() {
  633. try {
  634. $type = intval($this->type);
  635. $id = $this->id;
  636. $address = Address::findOne(['is_delete' => 0, 'id' => $id]);
  637. if (empty($address)) {
  638. throw new \Exception('查询失败');
  639. }
  640. if ($type) {
  641. //删除
  642. $address->is_delete = 1;
  643. } else {
  644. //设置为默认
  645. $user_id = $address->user_id;
  646. Address::updateAll(['is_default' => 0], ['user_id' => $user_id, 'is_delete' => 0]);
  647. $address = Address::findOne($id);
  648. $address->is_default = 1;
  649. }
  650. if (!$address->save()) {
  651. throw new \Exception(json_encode($address->errors, JSON_UNESCAPED_UNICODE));
  652. }
  653. return [
  654. 'code' => 0,
  655. 'msg' => '设置成功'
  656. ];
  657. } catch (\Exception $e) {
  658. return [
  659. 'code' => 1,
  660. 'msg' => $e->getMessage(),
  661. ];
  662. }
  663. }
  664. public function getUserAddress() {
  665. try {
  666. $user_id = $this->user_id;
  667. $user = User::findOne($user_id);
  668. if (empty($user)) {
  669. throw new \Exception('用户查询失败');
  670. }
  671. if($user->binding){
  672. $saas_user = SaasUser::findOne(['mobile' => $user->binding]);
  673. }else{
  674. if($user->alipay_open_id){
  675. $saas_user = SaasUser::findOne(['ali_user_id' => $user->alipay_open_id]);
  676. }
  677. }
  678. if(empty($saas_user)) {
  679. throw new \Exception('用户查询失败');
  680. }
  681. $address_list = Address::find()->where(['user_id' => $saas_user->id, 'is_delete' => 0])->select('name, mobile, province, city, district, town, village, detail, is_default, id, latitude, longitude, province_id, city_id, district_id, town_id, village_id')->orderBy('addtime desc')->asArray()->all();
  682. foreach ($address_list as &$item) {
  683. $item['is_default'] = (int)$item['is_default'];
  684. }
  685. return [
  686. 'code' => 0,
  687. 'msg' => '获取成功',
  688. 'data' => [
  689. 'address_list' => $address_list
  690. ]
  691. ];
  692. } catch (\Exception $e) {
  693. return [
  694. 'code' => 1,
  695. 'msg' => $e->getMessage()
  696. ];
  697. }
  698. }
  699. public function userPriceTotal($params) {
  700. $store_id = $this->store_id;
  701. $user_id = $this->user_id;
  702. if($params['user_id']){
  703. $user_id = $params['user_id'];
  704. }
  705. $query = User::find()->where(['store_id' => $store_id, 'is_delete' => 0]);
  706. if ($user_id) {
  707. $query->andWhere(['id' => $user_id]);
  708. }
  709. if ($params['mobile']) {
  710. $query->andWhere(['like', 'binding', $params['mobile']]);
  711. }
  712. if ($params['name']) {
  713. $query->andWhere(['!=', 'binding', ''])->andWhere(['binding' => SaasUser::find()->select('mobile')->where(['like', 'name', $params['name']])]);
  714. }
  715. $sum = (clone $query)->select('SUM(price) sum_price, SUM(total_price) sum_total_price')->asArray()->one();
  716. $query->orderBy('id DESC');
  717. $list = pagination_make($query);
  718. foreach($list['list'] as &$item){
  719. $item['saasUser'] = $item['binding'] ? SaasUser::findOne(['mobile' => $item['binding']]) : null;
  720. $item['sum']['sumUserShareMoney'] = (float)\app\models\UserShareMoney::find()->where(['user_id' => $item['id'], 'is_delete' => 0, 'type' => 0])->sum('money');
  721. $item['sum']['sumShareHold'] = (float)\app\models\ShareDetail::find()->where(['user_id' => $item['id'], 'is_send' => 1, 'is_delete' => 0, 'type' => [
  722. \app\models\ShareDetail::TYPE_HOLDER_PROFIT,
  723. \app\models\ShareDetail::TYPE_RANGE_PROFIT,
  724. \app\models\ShareDetail::TYPE_SHARE_PROFIT,
  725. \app\models\ShareDetail::TYPE_RANGE_PROFIT_OLD,
  726. \app\models\ShareDetail::TYPE_RANGE_PROFIT_OLD_USER_LEVEL,
  727. ]])->sum('money');
  728. $item['sum']['sumTwoPlusOne'] = (float)\app\models\ShareDetail::find()->where(['user_id' => $item['id'], 'is_send' => 1, 'is_delete' => 0, 'type' => [
  729. \app\models\ShareDetail::TYPE_TWO_PLUS_ONE_SHARE_PROFIT,
  730. \app\models\ShareDetail::TYPE_TWO_PLUS_ONE_SHARE_TEAM_PROFIT,
  731. \app\models\ShareDetail::TYPE_TWO_PLUS_ONE_SHARE_TEAM_PROFIT_OLD,
  732. ]])->sum('money');
  733. $item['sum']['sumAreaProfit'] = (float)\app\models\ShareDetail::find()->where(['user_id' => $item['id'], 'is_send' => 1, 'type' => \app\models\ShareDetail::TYPE_AREA_PROFIT, 'is_delete' => 0])->sum('money');
  734. $item['sum']['sumActivityRebateOrderN'] = (float)\app\models\ActivityRebateOrderNLog::find()->where(['user_id' => $item['id'], 'status' => 1, 'is_delete' => 0, 'finished' => 1])->sum('price');
  735. $item['sum']['sumFreeQueue'] = (float)\app\models\QueueLog::find()->where(['user_id' => $item['id']])->sum('returned_money');
  736. $item['sum']['sumActivityOrderRebateSelf'] = (float)\app\models\ActivityOrderRebateSelfLog::find()->where(['user_id' => $item['id'], 'send_type' => 1, 'is_send' => 1])->sum('price_send');
  737. $item['sum']['sumReportPoolLevel'] = (float)\app\models\ReportPoolLevel::find()->where(['user_id'=>$item['id'], 'is_send'=>1, 'is_delete'=>0])->sum('dividend_money');
  738. $item['sum']['sumVideoGoodsShare'] = (float)\app\models\VideoGoodsShare::find()->where(['author_user_id' => $item['id'], 'is_send' => 1])->sum('proportion');
  739. $item['sum']['sumWorker'] = (float)\app\models\WorkerOrderExt::find()->where(['worker_id' => \app\models\Worker::find()->select('id')->where(['user_id' => $item['id']]), 'worker_is_price' => 1])->sum('worker_price');
  740. $item['sum']['sumBalanceToCommission'] = (float)\app\models\AccountLog::find()->where([
  741. 'user_id'=>$item['id'], 'order_type'=>\app\models\AccountLog::TYPE_BALANCE_TO_COMMISSION,
  742. 'type'=>\app\models\AccountLog::TYPE_BALANCE, 'log_type'=>\app\models\AccountLog::LOG_TYPE_EXPEND,
  743. ])->sum('amount');
  744. $item['sum']['sumTeamBonus'] = (float)\app\models\ShareDetail::find()->where(['user_id' => $item['id'], 'is_send' => 1, 'is_delete' => 0, 'type' => [
  745. \app\models\ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT,
  746. \app\models\ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL,
  747. \app\models\ShareDetail::TYPE_TEAM_BONUS_PARENT,
  748. \app\models\ShareDetail::TYPE_TEAM_BONUS_THANKS,
  749. ]])->sum('money');
  750. $item['_sum_sum'] = round(array_sum($item['sum']), 2);
  751. }
  752. return [
  753. 'list' => $list,
  754. 'sum' => $sum,
  755. ];
  756. }
  757. /**
  758. * 获取用户佣金列表
  759. */
  760. public function getUserPrice() {
  761. try {
  762. $user_id = $this->user_id;
  763. $store_id = $this->store_id;
  764. $pageNo = get_params('pageNo', 1);
  765. $pageSize = get_params('pageSize', \Yii::$app->params['pageSize']);
  766. $cashTable = Cash::tableName();
  767. $userShareMoneyTable = UserShareMoney::tableName();
  768. $shareDetailTable = ShareDetail::tableName();
  769. // price_type = 0 收入类型 1支出类型
  770. // status 如果是支出类型 0--申请中 1--确认申请 2--已打款 3--驳回 4--手动打款 5--余额通过 收入类型 则一直为2已打款
  771. // table_type
  772. $sql = "select * from (SELECT 0 AS table_type, money, `desc`, 0 AS `price_type`, 2 AS `status`, 0 AS type, source, created_at FROM {$userShareMoneyTable} WHERE store_id = {$store_id} AND user_id = {$user_id}
  773. UNION ALL SELECT 1 AS table_type, money, `desc`, 0 AS `price_type`, 2 AS `status`, type, 0 AS source, send_time AS created_at FROM {$shareDetailTable} WHERE store_id = {$store_id} AND user_id = {$user_id} AND is_send = 1
  774. UNION ALL SELECT 2 AS table_type, price AS money, '提现申请' AS `desc`, 1 AS `price_type`, `status`, 0 AS type, 0 as source, created_at FROM {$cashTable} WHERE store_id = {$store_id} AND user_id = {$user_id} AND status != 3) AS o ORDER BY o.created_at DESC";
  775. $pageInitNum = ($pageNo - 1) * $pageSize;
  776. $count = \Yii::$app->db->createCommand($sql)->query()->count();
  777. $sql .= " LIMIT {$pageSize} OFFSET {$pageInitNum}";
  778. $list = \Yii::$app->db->createCommand($sql)->queryAll();
  779. foreach ($list as &$item) {
  780. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  781. $item['status'] = intval($item['status']);
  782. $item['price_type'] = intval($item['price_type']);
  783. $item['status_name'] = "已打款";
  784. if ($item['price_type']) {
  785. $item['status_name'] = Cash::getStatusName($item['status']);
  786. }
  787. if (!intval($item['table_type'])) {
  788. if (empty($item['desc'])) {
  789. $item['desc'] = UserShareMoney::getSourceName($item['source'], $store_id);
  790. }
  791. }
  792. if (intval($item['table_type']) === 1) {
  793. if (empty($item['desc'])) {
  794. $item['desc'] = ShareDetail::typeName($item['type']);
  795. }
  796. }
  797. }
  798. return [
  799. 'code' => 0,
  800. 'msg' => 'success',
  801. 'data' => [
  802. 'data' => $list,
  803. 'pageNo' => $pageNo,
  804. 'totalCount' => $count,
  805. ],
  806. ];
  807. } catch (\Exception $e) {
  808. return [
  809. 'code' => 1,
  810. 'msg' => $e->getMessage()
  811. ];
  812. }
  813. }
  814. }