UserController.php 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528
  1. <?php
  2. namespace backend\modules\mall\controllers;
  3. use addons\Coupon\common\enums\AddonsCouponEnum;
  4. use addons\Coupon\common\models\AddonsCoupon;
  5. use addons\Coupon\common\models\AddonsCouponUserRelate;
  6. use addons\Redpack\common\enums\RedpackEnum;
  7. use addons\Redpack\common\models\RedpackWallet;
  8. use addons\Store\common\models\StoreCouponUserRelate;
  9. use addons\Store\common\services\StoreAssociatedUserService;
  10. use addons\UserSync\common\models\UserSync;
  11. use common\enums\AddonsEnum;
  12. use common\enums\DownloadEnum;
  13. use common\enums\LevelUpgradeLogEnum;
  14. use common\enums\MemberLabelEnum;
  15. use common\enums\RabbitMqEnum;
  16. use common\enums\UserWalletEnum;
  17. use common\events\census\UserUpgradeAfterEvent;
  18. use common\events\user\UserCancellationEvent;
  19. use common\events\user\UserModifyPayPwdEvent;
  20. use common\events\user\UserModifyPwdEvent;
  21. use common\events\user\UserUpdateEvent;
  22. use common\helpers\ArrayHelper;
  23. use common\helpers\csv\CsvExportHelper;
  24. use common\helpers\RegularHelper;
  25. use common\logic\memberLabel\MemberLabelLogic;
  26. use common\models\census\CensusMallSingleMonth;
  27. use common\models\common\Addons;
  28. use common\models\common\ChangeMobileLog;
  29. use common\models\elasticsearch\user\LoginLog;
  30. use common\models\mall\MallAddons;
  31. use common\models\user\MemberLabel;
  32. use common\models\user\UserActionRecord;
  33. use common\models\user\UserDigital;
  34. use common\models\user\UserImportFailLog;
  35. use backend\controllers\MallController;
  36. use common\components\CsvExport;
  37. use common\enums\StatusEnum;
  38. use common\models\user\Tag;
  39. use common\models\user\User;
  40. use common\models\user\UserExtra;
  41. use common\models\user\UserImportLog;
  42. use common\models\user\UserInfo;
  43. use common\models\user\UserLabel;
  44. use common\models\user\UserLabelRelationship;
  45. use common\models\user\UserLevel;
  46. use common\models\user\UserLevelExpired;
  47. use common\models\user\UserLevelUpgradeLog;
  48. use common\models\user\UserMemberLabel;
  49. use common\models\user\UserPartitionRelationship;
  50. use common\models\user\UserRelationshipLog;
  51. use common\models\user\UserTagRelate;
  52. use common\models\user\UserTeamStatistics;
  53. use common\models\user\UserWallet;
  54. use common\services\mall\user\UserBehaviorLogsService;
  55. use services\common\UserWalletService;
  56. use Yii;
  57. use yii\db\Exception;
  58. use yii\helpers\Json;
  59. use common\models\statistics\UserStatisticsTotal;
  60. use common\models\common\CapitalLog;
  61. use common\enums\EventNameEnum;
  62. use common\events\user\UserRegisterEvent;
  63. use common\logic\statistics\StatisticsHandle;
  64. use common\models\common\MallSetting;
  65. use common\models\user\UserFreezeCommission;
  66. /**
  67. * 会员控制器
  68. *
  69. * Class IdentityController
  70. * @package backend\modules\mall\controllers
  71. */
  72. class UserController extends MallController
  73. {
  74. /**
  75. * 会员首页
  76. * @return mixed|string|void
  77. */
  78. public function actionIndex()
  79. {
  80. if (\Yii::$app->request->isAjax) {
  81. if (\Yii::$app->request->isPost) {
  82. if (\Yii::$app->request->post('flag') == 'EXPORT') {
  83. $post = \Yii::$app->request->post();
  84. $type_arr = DownloadEnum::getTypeMap();
  85. $post['mall_id'] = $this->mall_id;
  86. $post['type'] = DownloadEnum::TYPE_MEMBER;
  87. $post['status'] = DownloadEnum::STATUS_DOWNING;
  88. $post['name'] = $type_arr[DownloadEnum::TYPE_MEMBER] . '列表' . date('YmdHis');
  89. $filename = '会员列表-' . date('YmdHis') . '_' . rand(10000, 99999);
  90. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id, $filename, DownloadEnum::TYPE_MEMBER, User::class, 'exportHandle', $post);
  91. if ($res === false) return $this->error('加入导出任务失败' . CsvExportHelper::getStaticError());
  92. return $this->success('添加导出任务成功,任务完成后请在下载中心进行下载!');
  93. }
  94. }
  95. if (Yii::$app->request->isGet) {
  96. $search = \Yii::$app->request->get('search');
  97. $isChanjetAddons = \Yii::$app->request->get('is_chanjet_addons');
  98. !empty($search) && $params = Json::decode($search, true);
  99. $sort = \Yii::$app->request->get('sort', 'user_id desc');
  100. // 查询参数
  101. $where = [];
  102. $where[] = ['=', 'u.mall_id', $this->mall_id];
  103. $where[] = ['in', 'u.status', [StatusEnum::ENABLED,StatusEnum::DISABLED]];
  104. $week_time = strtotime('-7 day');// 七天前
  105. $month_time = strtotime('-30 day');// 一个月前
  106. // 初始化数据
  107. $data = [
  108. 'channel' => [],
  109. 'tag_list' => [],
  110. 'member_label_List' => [],
  111. 'currency_list' => [],
  112. 'mall_data' => [
  113. 'user_total' => 0,
  114. 'new_user_total' => 0,
  115. 'active_user_total' => 0,
  116. 'loss_user_total' => 0,
  117. 'no_pay_user_total' => 0,
  118. 'o2o_user_total' => 0,
  119. 'updated_at' => '该商城暂未更新',
  120. ],
  121. 'user_list' => [],
  122. 'is_freeze_commission' => UserFreezeCommission::getSwitchStatus($this->mall_id),
  123. ];
  124. if (!empty($params['user_type'])) {
  125. switch ($params['user_type']) {
  126. case 1:// 新增会员
  127. $where[] = ['>=', 'u.created_at', $week_time];
  128. break;
  129. case 2:// 活跃会员
  130. $where[] = ['>=', 'u.last_login_at', $week_time];
  131. break;
  132. case 3:// 近7天有购买行为,但没有成功付款的客户
  133. // $where[] = ['>=', 'ua.last_no_pay_at', $week_time];
  134. break;
  135. case 4:// 流失会员
  136. $where[] = ['<', 'u.last_login_at', $month_time];
  137. break;
  138. case 5:// 线下会员
  139. $where[] = ['=', 'u.source', User::SOURCE_SHARE_O2O];
  140. break;
  141. }
  142. }
  143. if (\Yii::$app->request->get('page') == 1) {
  144. // 判断用户插件是否开启
  145. // 获取标签列表
  146. $tag_list = UserLabel::getUserLabel([['mall_id' => $this->mall_id,'status' => StatusEnum::ENABLED]], [], true, 'id tag_id,name');
  147. if ($tag_list) $data['tag_list'] = $tag_list;
  148. $data['channel'] = array_merge(['all' => '全部'], User::TYPE_NAME_LIST);
  149. $memberLabelList = MemberLabel::lists(['where'=>[
  150. ['mall_id'=>$this->mall_id],
  151. ['status'=>[StatusEnum::ENABLED,StatusEnum::DISABLED]
  152. ]
  153. ],'order'=>'cate_id asc','select'=>'id,name,cate_id']);
  154. if (!empty($memberLabelList)){
  155. $cateMap = MemberLabelEnum::getMap();
  156. foreach ($memberLabelList as &$val){
  157. if(isset($cateMap[$val['cate_id']]))$val['name'] = $cateMap[$val['cate_id']].' : '. $val['name'];
  158. }
  159. $data['member_label_List'] = $memberLabelList;
  160. }
  161. }
  162. // 用户条件筛选搜索
  163. // 根据用户id精准查找
  164. if (!empty($params['user_id'])) $where[] = ['=', 'u.id', $params['user_id']];
  165. // 根据用户团队查找
  166. if (isset($params['channel']) && $params['channel'] != 'all') $where[] = ['u.platform' => $params['channel']];
  167. // 根据用户昵称或手机号码查找
  168. if (!empty($params['nickname_or_mobile'])) $where[] = [
  169. 'OR',
  170. ['like', 'u.nickname', $params['nickname_or_mobile']],
  171. ['like', 'u.mobile', $params['nickname_or_mobile']],
  172. ];
  173. //根据智能标签进行搜索
  174. if (!empty($params['lableValue'])){
  175. $user_label_where = ['mall_id' =>$this->mall_id,'status' => StatusEnum::ENABLED,'label_id' => $params['lableValue']];
  176. $user_ids = UserLabelRelationship::find()->select("user_id")->where($user_label_where)->asArray()->column();
  177. $where[] = ['u.id'=>$user_ids ];
  178. }
  179. // 查找上级推荐人手机号
  180. if (isset($params['p_mobile']) && $params['p_mobile'] !== '') {
  181. $where[] = [
  182. 'in',
  183. 'u.parent_id',
  184. User::find()
  185. ->where([
  186. 'mall_id' => $this->mall_id,
  187. 'status' => [StatusEnum::ENABLED,StatusEnum::DISABLED]
  188. ])
  189. ->andWhere(['like', 'mobile', $params['p_mobile']])
  190. ->select('id')
  191. ->column()
  192. ];
  193. }
  194. // 查找上级推荐人
  195. if (!empty($params['parent_id'])) $where[] = ['=', 'u.parent_id', $params['parent_id']];
  196. // 查找注册来源团队
  197. if (!empty($params['source']) && $params['source'] != 'all') $where[] = ['=', 'u.platform', $params['source']];
  198. //添加等级查询
  199. $levels = UserLevel::getListIndexByLevelColumn($this->mall_id, [StatusEnum::ENABLED, StatusEnum::DISABLED]);
  200. $default_level_name = Yii::$app->services->setting->mall->get($this->mall_id,'user.default_level_name','basic',true);
  201. if (empty($default_level_name)) $default_level_name = '普通会员';
  202. $levels[0] = $default_level_name;
  203. $data['levels'] = $levels;
  204. if (isset($params['level']) && $params['level'] !== '') $where[] = ['=', 'u.level', $params['level']];
  205. // if (!empty($params['level'])) $where[] = ['=', 'u.level', $params['level']];
  206. // 查找会员标签
  207. // if (!empty($params['tag_id'])) {
  208. //
  209. // }
  210. // 查找注册时间
  211. if (!empty($params['register_start']) && !empty($params['register_end'])) $where[] = ['between', 'u.created_at', strtotime($params['register_start']), strtotime($params['register_end'])];
  212. // 最后更新时间
  213. if (!empty($params['update_start']) && !empty($params['update_end'])) $where[] = ['between', 'u.updated_at', strtotime($params['update_start']), strtotime($params['update_end'])];
  214. // 查找上次消费时间
  215. // if (!empty($params['pay_start']) && !empty($params['pay_end'])) $where[] = ['between', 'ua.last_pay_at', strtotime($params['pay_start']), strtotime($params['pay_end'])];
  216. // 查找余额范围
  217. if (!empty($params['balance_start']) && !empty($params['balance_end'])) $where[] = ['between', 'uw.balance', $params['balance_start'], $params['balance_end']];
  218. if (!empty($params['balance_start']) && empty($params['balance_end']) ) $where[] = ['>', 'uw.balance', $params['balance_start']];
  219. if (!empty($params['balance_end']) && empty($params['balance_start'])) $where[] = ['<', 'uw.balance', $params['balance_end']];
  220. // 查找积分范围
  221. if (!empty($params['score_start']) && !empty($params['score_end'])) $where[] = ['between', 'uw.score', $params['score_start'], $params['score_end']];
  222. if (!empty($params['score_start']) && empty($params['score_end'])) $where[] = ['>', 'uw.score', $params['score_start']];
  223. if (empty($params['score_start']) && !empty($params['score_end'])) $where[] = ['<', 'uw.score', $params['score_end']];
  224. // 查找佣金范围
  225. if (!empty($params['commission_start']) && !empty($params['commission_end'])) $where[] = ['between', 'uw.commission', $params['commission_start'], $params['commission_end']];
  226. if (!empty($params['commission_start']) && empty($params['commission_end'])) $where[] = ['>', 'uw.commission', $params['commission_start']];
  227. if (empty($params['commission_start']) && !empty($params['commission_end'])) $where[] = ['<', 'uw.commission', $params['commission_end']];
  228. // 查找累计消费金额范围
  229. // if (!empty($params['price_total_start']) && !empty($params['price_total_end'])) $where[] = ['between', 'us.pay_order_price_total', $params['price_total_start'], $params['price_total_end']];
  230. // 查找购买次数范围
  231. // if (!empty($params['order_total_start']) && !empty($params['order_total_end'])) $where[] = ['between', 'us.pay_order_total', $params['order_total_start'], $params['order_total_end']];
  232. //根据会员标签进行搜索
  233. if (!empty($params['memberLabelIds'])){
  234. $cateIdArr = [];
  235. foreach ($params['memberLabelIds'] as $value){
  236. $temp_arr = explode('_', $value);
  237. $cateIdArr[$temp_arr[0]][] = $temp_arr[1];
  238. }
  239. foreach ($cateIdArr as $cate_id => $memberLabelIds) {
  240. $where[] = ['uml.'.'cate_id' . $cate_id=>$memberLabelIds];
  241. }
  242. }
  243. // 黑名单
  244. if (!empty($params['black'])) {
  245. $where[] = ['=', 'u.status', $params['black'] == 2 ? 1 : 0];
  246. }
  247. // 联表查询
  248. $joins = [
  249. ['LEFT JOIN', UserWallet::tableName() . 'uw', 'uw.user_id = u.id'],
  250. ];
  251. if (!empty($params['memberLabelIds'])){
  252. $joins[] = [
  253. 'LEFT JOIN', UserMemberLabel::tableName() . 'uml', 'uml.user_id = u.id'
  254. ];
  255. }
  256. $select = 'u.id,u.id as user_id,nickname,avatar_url,mobile,level,u.status,platform,u.is_inviter,
  257. balance,commission as income,u.source,score,u.created_at,u.parent_id';
  258. if (Addons::isInstall(AddonsEnum::ADDONS_NAME_CHANJET)) {
  259. $select .= ',frozen_commission,total_commission';
  260. }
  261. $order = $sort;
  262. $with = ['userLabel', 'userFreezeCommission', 'userLevelExpired'];
  263. // 畅捷通
  264. if ($isChanjetAddons) {
  265. $with[] = 'addonsChanjetRequest';
  266. $select .= ',u.updated_at';
  267. $exportList = User::chanjetFieldsList();
  268. }
  269. $params = array('alias' => 'u', 'select' => $select, 'where' => $where, 'with' => $with, 'join' => $joins, 'order' => $order, 'limit' => 10);
  270. $user_data = User::listPage($params, false, true);
  271. if (empty($user_data)) return $this->success('操作成功', $data);
  272. $default_parent = ['id' => 0, 'nickname' => '平台', 'avatar_url' => ''];
  273. // 获取用户user_id
  274. $user_ids = array_column($user_data['list'], 'user_id');
  275. // 获取用户推荐人
  276. $parent_ids = array_column($user_data['list'], 'parent_id');
  277. $parent_list = User::getUserList([['in', 'id', $parent_ids]], 'id,nickname,avatar_url', [], 1);
  278. $parent = [];
  279. foreach ($parent_list as $v) {
  280. $parent[$v['id']] = $v;
  281. }
  282. $user_action_arr = UserActionRecord::find()->where(['user_id'=>$user_ids,'mall_id'=>$this->mall_id])->indexBy('user_id')->all();
  283. // 获取用户标签
  284. // $user_tag_list = UserTagRelate::getUserTagList($this->mall_id, $user_ids);
  285. $user_tag_list = UserLabel::getUserLabel([['mall_id' => $this->mall_id,'status' => StatusEnum::ENABLED]], [], true, 'id,name');
  286. $user_tag_arr = [];
  287. foreach ($user_tag_list as $v) {
  288. $user_tag_arr[$v['id']][] = ['tag_id' => $v['id'], 'name' => $v['name']];
  289. }
  290. $item['tag_name'] = empty($user_tag) ? [] : $user_tag;
  291. $user_level_arr = UserLevel::getUserLevelArr($this->mall_id);
  292. foreach ($user_data['list'] as &$item) {
  293. $item['last_pay_at'] =!empty($user_action_arr[$item['id']]['last_pay_at'])? date('Y-m-d H:i:s',$user_action_arr[$item['id']]['last_pay_at']):'暂无消费';
  294. $item['nickname'] = empty($item['nickname']) ? '--' : $item['nickname'];
  295. $item['level_name'] = empty($user_level_arr[$item['level']]) ? MallSetting::getDefaultLevelName($this->mall_id) : $user_level_arr[$item['level']];// 会员等级名称
  296. $item['source'] = empty(User::$sources[$item['source']]) ? '' : User::$sources[$item['source']];// 来源
  297. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);// 注册时间
  298. // $item['average_price'] = $item['pay_order_total'] == 0 ? 0 : bcdiv($item['pay_order_price_total'], $item['pay_order_total'], 2);// 平均客单价
  299. $item['average_price'] = 0;// 平均客单价
  300. $item['parent'] = (!empty($direct_id_arr[$item['user_id']]) && $parent[$direct_id_arr[$item['user_id']]]) ? $parent[$direct_id_arr[$item['user_id']]] : $default_parent;
  301. $item['parent'] = !empty($parent[$item['parent_id']])? $parent[$item['parent_id']] : $default_parent;
  302. $item['platform'] = empty($item['platform']) ? '其他' : (User::TYPE_NAME_LIST)[$item['platform']];
  303. $item['tag_name'] = empty($user_tag_arr[$item['user_id']]) ? [] : $user_tag_arr[$item['user_id']];
  304. if(empty($item['userFreezeCommission'])){
  305. $item['userFreezeCommission'] = ['user_id' => $item['id'], 'freeze_scale' => 0, 'freeze_cap' => 0, 'freeze_amount' => 0,'not_freeze_amount' => 0];
  306. }else{
  307. $item['userFreezeCommission']['not_freeze_amount'] = bcsub($item['income'], $item['userFreezeCommission']['freeze_amount'],2);
  308. $item['userFreezeCommission']['not_freeze_amount'] = max($item['userFreezeCommission']['not_freeze_amount'], 0);
  309. }
  310. $userLevelExpired = array_column($item['userLevelExpired'], 'expired_at', 'level');
  311. $item['expired_at_text'] = !empty($userLevelExpired[$item['level']]) ? date('Y-m-d H:i:s', $userLevelExpired[$item['level']]) : '--';
  312. }
  313. $data['user_list'] = $user_data;
  314. $data['export_list'] = $exportList ?? User::fieldsList();
  315. // 获取已安装的插件
  316. $data['install_addons'] = MallAddons::getValidAddons($this->mall_id);
  317. return $this->success('操作成功', $data);
  318. }
  319. }
  320. return $this->render($this->action->id);
  321. }
  322. /**
  323. * 会员详情
  324. * @return mixed|string|void
  325. */
  326. public function actionUserDetail()
  327. {
  328. if (\Yii::$app->request->isAjax) {
  329. $user_id = Yii::$app->request->get('id', '');
  330. if (empty($user_id)) return $this->error('会员id不能为空');
  331. $is_show_user_relationship_log = 0;
  332. if(!isset(Yii::$app->params['is_show_user_relationship_log'])||Yii::$app->params['is_show_user_relationship_log']==1) {
  333. $is_show_user_relationship_log = 1;
  334. }
  335. return $this->successStr('操作成功', [
  336. 'detail' => User::getUserDetail($this->mall_id, $user_id),
  337. 'default_level_name' => MallSetting::getDefaultLevelName($this->mall_id),
  338. 'is_show_user_relationship_log'=>$is_show_user_relationship_log,
  339. ]);
  340. }
  341. return $this->render($this->action->id);
  342. }
  343. /**
  344. * 关系设置
  345. * @return mixed|string|void
  346. */
  347. public function actionRelationEdit()
  348. {
  349. try {
  350. $request = Yii::$app->request;
  351. if ($request->isAjax) {
  352. if ($request->isGet) {
  353. $relation_setting = \Yii::$app->services->setting->mall->get($this->mall_id, 'user_relation_setting.relation_setting');
  354. $data = [];
  355. if (!empty($relation_setting)) $data = json_decode($relation_setting, true);
  356. return $this->success('ok', $data);
  357. }
  358. }
  359. } catch (\Exception $e) {
  360. return $this->error($e->getMessage(), []);
  361. }
  362. try {
  363. if (\Yii::$app->request->isAjax) {
  364. if (\Yii::$app->request->isPost) {
  365. $params = Yii::$app->request->post();
  366. $res = Yii::$app->services->validate->validate($params, [
  367. [['get_power_way', 'buy_num_selected', 'buy_num', 'buy_price_selected',
  368. 'buy_goods_selected', 'buy_goods_way', 'buy_compute_way', 'become_child_way', 'status',
  369. 'goods_ids', 'cat_ids', 'cat_list', 'goods_list', 'notice', 'protocol','buy_price'
  370. ], 'safe'],
  371. ]);
  372. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  373. $params['mall_id'] = $this->mall_id;
  374. $data['user_relation_setting'] = ['relation_setting' => json_encode($params)];
  375. \Yii::$app->services->setting->mall->set($this->mall_id, $data);
  376. if ($res === false) return $this->error('设置失败');
  377. return $this->success('操作成功');
  378. }
  379. }
  380. } catch (\Exception $e) {
  381. return $this->error($e->getMessage(), []);
  382. }
  383. return $this->render($this->action->id);
  384. }
  385. /**
  386. * 后台添加会员
  387. * @return mixed|string|void
  388. */
  389. public function actionAdd()
  390. {
  391. try {
  392. $request = Yii::$app->request;
  393. if ($request->isAjax) {
  394. if ($request->isGet) {
  395. $list = UserLevel::getUserLevel([['mall_id' => $this->mall_id]], [], 1);
  396. return $this->success('ok', $list);
  397. }
  398. }
  399. } catch (\Exception $e) {
  400. return $this->error($e->getMessage(), []);
  401. }
  402. try {
  403. if (\Yii::$app->request->isAjax) {
  404. if (\Yii::$app->request->isPost) {
  405. $mall_id= $this->mall_id;
  406. $params = Yii::$app->request->post();
  407. $res = Yii::$app->services->validate->validate($params, [
  408. [['nickname', 'mobile', 'level',], 'required'],
  409. [['parent_id','username'], 'safe'],
  410. [['mobile'], 'match', 'pattern' => RegularHelper::mobile(), 'message' => '请输入正确的手机号码'],
  411. ['mobile', function ($attribute) use ($mall_id) {
  412. $where[] = ['mall_id' => $mall_id];
  413. $where[] = ['mobile' => trim($this->$attribute)];
  414. if (User::getUser($where)) $this->addError($attribute, '手机号码已存在');
  415. }],
  416. ]);
  417. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  418. $password = substr($params['mobile'],-6,6);
  419. $params['mall_id'] = $this->mall_id;
  420. if(empty($params['username'])){
  421. $params['username'] = $params['mobile'];
  422. }
  423. $params['source'] = User::SOURCE_ADD_PLATFORM;
  424. $params['platform'] = User::TYPE_MANUAL;
  425. $params['password'] = Yii::$app->getSecurity()->generatePasswordHash($password);
  426. $model = User::setData($params);
  427. if (empty($model)) throw new Exception(User::$static_error);
  428. !empty($model->id) && $this->memberExpired(['mall_id' => $mall_id, 'user_id' => $model->id, 'after_level' => $params['level']]);
  429. // 记录升级日志(如果创建的不是默认等级,则认为手动升级)
  430. if ($model && $model->level > 0) {
  431. $upgrade_log_obj = new UserLevelUpgradeLog();
  432. $upgrade_log_obj->admin_id = $this->admin->id;
  433. $upgrade_log_obj->mall_id = $this->mall_id;
  434. $upgrade_log_obj->user_id = $model->id;
  435. $upgrade_log_obj->before_level = 0;
  436. $upgrade_log_obj->after_level = $model->level;
  437. $upgrade_log_obj->upgrade_type = LevelUpgradeLogEnum::MANUALLY_UPGRADE;
  438. $upgrade_log_obj->save();
  439. }
  440. //添加用户数量统计
  441. $event = new UserRegisterEvent($this->mall_id);
  442. $data = ['user_id' => $model->id, 'platform' => User::TYPE_MANUAL];
  443. Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  444. return $this->success('操作成功');
  445. }
  446. }
  447. } catch (\Exception $e) {
  448. return $this->error($e->getMessage(), []);
  449. }
  450. return $this->render($this->action->id);
  451. }
  452. /**
  453. * 修改密码
  454. * @return mixed|void
  455. * @throws \yii\base\Exception
  456. */
  457. public function actionUpdatePassword()
  458. {
  459. $params = Yii::$app->request->post();
  460. $res = User::updateAll(['password' => Yii::$app->getSecurity()->generatePasswordHash($params['password'])], ['id' => $params['user_id']]);
  461. if ($res === false) return $this->error(User::getStaticError());
  462. // 修改密码事件
  463. $event = new UserModifyPwdEvent($this->mall_id);
  464. Yii::$app->services->events->dispatch($event, [
  465. 'operator_user_id' => $this->admin->id,
  466. 'new_pwd' => trim($params['password']),
  467. 'is_admin' => 1,
  468. 'user_id' => $params['user_id'],
  469. 'mall_id' => $this->mall_id
  470. ], $event->listeners);
  471. return $this->success('操作成功');
  472. }
  473. /**
  474. * 黑白名单
  475. * @return mixed|void
  476. */
  477. public function actionAddBlacklist()
  478. {
  479. $params = Yii::$app->request->post();
  480. // $res = User::updateAll(['status' => $params['status']], ['in', 'id', explode(',', $params['user_id'])]);
  481. // if ($res === false) return $this->error(User::getStaticError());
  482. // return $this->success('操作成功');
  483. try {
  484. $params['mall_id'] = $this->mall_id;
  485. User::addBlacklist($params);
  486. if(empty($params['status'])){
  487. $event = new UserCancellationEvent($this->mall_id);
  488. \Yii::$app->services->events->dispatch($event, [
  489. 'mall_id' => $this->mall_id,
  490. 'user_id' => $params['user_id'],
  491. 'is_admin' => 1,
  492. 'operator_user_id' => $this->admin->id
  493. ], $event->listeners);
  494. }
  495. return $this->success('操作成功');
  496. }catch (\Exception $e){
  497. return $this->error($e->getMessage());
  498. }
  499. }
  500. /**
  501. * 积分充值
  502. * @return mixed|void
  503. * @throws \yii\db\Exception
  504. */
  505. public function actionScore()
  506. {
  507. $admin = Yii::$app->getUser()->identity;
  508. $params = Yii::$app->request->post();
  509. $where[] = ['mall_id' => $this->mall_id];
  510. $where[] = ['in', 'id', explode(',', $params['user_id'])];
  511. $user_list = User::getUserList($where);
  512. $score_name = \Yii::$app->services->setting->mall->get($this->mall_id, UserWalletService::WALLET_TYPE_SCORE.'.score_name');
  513. $score_name =$score_name?? '积分';
  514. $remark = $params['remark'] ? ',备注信息['. $params['remark'] .']' : '';
  515. $pre = $params['num'] > 0 ? '充值' : '扣减';
  516. foreach ($user_list as $user) {
  517. $desc = '管理员'.$admin->username.' 后台' . $pre .$params['num'].$score_name.$remark;
  518. if($params['type']==3){
  519. $params['num'] = -$user['userWallet']['score'];
  520. $desc = '管理员'.$admin->username.' 后台清空'.$params['num'].$score_name.$remark;
  521. }
  522. $insert_wallet [] = [
  523. 'mall_id' => $this->mall_id,
  524. 'user_id' => $user->id,
  525. 'is_frozen' => false,
  526. 'wallet_type' =>UserWalletService::WALLET_TYPE_SCORE,
  527. 'money' => $params['num'],
  528. 'desc' => $desc,
  529. 'source_table' => 'admin',
  530. 'source_table_id' => $admin->id,
  531. 'from_type' => $params['num'] > 0 ? UserWalletEnum::RECHARGE : UserWalletEnum::DEDUCT,
  532. 'capital_type' => $params['num'] > 0 ? UserWalletEnum::RECHARGE_PLATFORM : UserWalletEnum::BACKEND_DEDUCT,
  533. ];
  534. }
  535. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  536. if ($res === false) return $this->error(UserWalletService::getStaticError());
  537. return $this->success('操作成功');
  538. }
  539. /**
  540. * 后台余额充值
  541. * @return mixed|void
  542. * @throws \yii\db\Exception
  543. */
  544. public function actionBalance()
  545. {
  546. $admin = Yii::$app->getUser()->identity;
  547. $params = Yii::$app->request->post();
  548. $where[] = ['mall_id' => $this->mall_id];
  549. $where[] = ['in', 'id', explode(',', $params['user_id'])];
  550. $user_list = User::getUserList($where);
  551. $balance_name = \Yii::$app->services->setting->mall->get($this->mall_id, UserWalletService::WALLET_TYPE_BALANCE.'.balance_name');
  552. $balance_name = $balance_name?? '余额';
  553. $remark = $params['remark'] ? ',备注信息['. $params['remark'] .']' : '';
  554. $pre = $params['price'] > 0 ? '充值' : '扣减';
  555. foreach ($user_list as $user) {
  556. $desc = '管理员'.$admin->username.' 后台' . $pre .$params['price'].$balance_name.$remark;
  557. if($params['type']==3){
  558. $params['price'] = -$user['userWallet']['balance'];
  559. $desc = '管理员'.$admin->username.' 后台清空'.$params['num'].$balance_name.$remark;
  560. }
  561. $insert_wallet [] = [
  562. 'mall_id' => $this->mall_id,
  563. 'user_id' => $user->id,
  564. 'is_frozen' => false,
  565. 'wallet_type' =>UserWalletService::WALLET_TYPE_BALANCE,
  566. 'money' => $params['price'],
  567. 'desc' =>$desc,
  568. 'source_table' => 'admin',
  569. 'source_table_id' => $admin->id,
  570. 'from_type' => $params['price'] > 0 ? UserWalletEnum::RECHARGE : UserWalletEnum::DEDUCT,
  571. 'capital_type' => $params['price'] > 0 ? UserWalletEnum::RECHARGE_PLATFORM : UserWalletEnum::BACKEND_DEDUCT,
  572. ];
  573. }
  574. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  575. if ($res === false) return $this->error(UserWallet::getStaticError());
  576. if ($params['price'] > 0) {
  577. $user_ids = explode(',', $params['user_id']);
  578. foreach ($user_ids as $user_id) {
  579. Yii::$app->services->statistics->user->set($this->mall_id, $user_id, ['recharge_money' => $params['price']]);
  580. UserStatisticsTotal::setUserStatisticsTotal($this->mall_id, $user_id, ['recharge_money' => $params['price']]);
  581. }
  582. $data = ['total_recharge_money' => $params['price'] * count($user_ids)];
  583. CensusMallSingleMonth::setSingleMonthCache($this->mall_id, 'total_recharge_money', $data, 'total_recharge_money');
  584. }
  585. return $this->success('操作成功');
  586. }
  587. /**
  588. * 后台佣金充值
  589. * @return mixed|void
  590. * @throws \yii\db\Exception
  591. */
  592. public function actionCommission()
  593. {
  594. $admin = Yii::$app->getUser()->identity;
  595. $params = Yii::$app->request->post();
  596. $where[] = ['mall_id' => $this->mall_id];
  597. $where[] = ['in', 'id', explode(',', $params['user_id'])];
  598. $user_list = User::getUserList($where);
  599. $commission_name = '佣金';
  600. $remark = $params['remark'] ? ',备注信息['. $params['remark'] .']' : '';
  601. $pre = $params['price'] > 0 ? '充值' : '扣减';
  602. foreach ($user_list as $user) {
  603. $desc = '管理员'.$admin->username.' 后台'. $pre .$params['price'].$commission_name.$remark;
  604. if($params['type']==3){
  605. $params['price'] = -$user['userWallet']['commission'];
  606. $desc = '管理员'.$admin->username.' 后台清空'.$params['num'].$commission_name.$remark;
  607. }
  608. $insert_wallet [] = [
  609. 'mall_id' => $this->mall_id,
  610. 'user_id' => $user->id,
  611. 'is_frozen' => false,
  612. 'wallet_type' =>UserWalletService::WALLET_TYPE_COMMISSION,
  613. 'money' => $params['price'],
  614. 'desc' =>$desc,
  615. 'source_table' => 'admin',
  616. 'source_table_id' => $admin->id,
  617. 'from_type' => $params['price'] > 0 ? UserWalletEnum::RECHARGE : UserWalletEnum::DEDUCT,
  618. 'capital_type' => $params['price'] > 0 ? UserWalletEnum::RECHARGE_PLATFORM : UserWalletEnum::BACKEND_DEDUCT,
  619. ];
  620. }
  621. $res = UserWalletService::batchHandleByQueue($insert_wallet);
  622. if ($res === false) return $this->error(UserWallet::getStaticError());
  623. return $this->success('操作成功');
  624. }
  625. /**
  626. * 红包充值
  627. * @Author: ltm
  628. * @DateTime: 2022/3/23 0023 17:38
  629. * @Copyright: copyright (c) 2021 广东七件事集团
  630. * @param $data
  631. * @return string
  632. */
  633. public function actionRedpack(){
  634. if (Yii::$app->request->isPost) {
  635. $params = Yii::$app->request->post();
  636. // 验证
  637. $res = Yii::$app->services->validate->validate($params, [
  638. [['user_id', 'money','type'], 'required'],
  639. [['money'], 'number'],
  640. [['type','desc'], 'string'],
  641. ]);
  642. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  643. if($params['type'] == RedpackEnum::WALLET_REDPACK_FROZEN) {
  644. $is_frozen = true;
  645. }else{
  646. $is_frozen = false;
  647. }
  648. //接收红包者
  649. $wallet = RedpackWallet::setData([
  650. 'mall_id' => $this->mall_id,
  651. 'user_id' => $params['user_id'],
  652. 'is_frozen' => $is_frozen,
  653. 'is_deduct' => true,
  654. 'money' => $params['money'],
  655. 'from_type' => RedpackEnum::FROM_RECHARGE,
  656. 'desc' => $params['desc'] ?? "手动充值",
  657. ]);
  658. if ($wallet == false) throw new Exception(RedpackWallet::getStaticError());
  659. return $this->success('操作成功');
  660. }
  661. return $this->success('操作成功');
  662. }
  663. /**
  664. * 批量加标签
  665. * @return mixed|void
  666. * @throws \yii\db\Exception
  667. */
  668. public function actionAddTagUser()
  669. {
  670. $params = Yii::$app->request->post();
  671. $res = Yii::$app->services->validate->validate($params, [
  672. [['user_id', 'tag_ids'], 'required'],
  673. ]);
  674. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  675. $user_id_arr = json_decode($params['user_id'], true);
  676. $tag_id_arr = json_decode($params['tag_ids'], true);
  677. foreach ($user_id_arr as $user_id) {
  678. $res = UserTagRelate::setData($user_id, $tag_id_arr);
  679. if ($res === false) return $this->error(User::getStaticError());
  680. }
  681. return $this->success('操作成功');
  682. }
  683. /**
  684. * 单个用户加标签-已废除
  685. * @return mixed|void
  686. * @throws \yii\db\Exception
  687. */
  688. public function actionEditUserTag()
  689. {
  690. $params = Yii::$app->request->post();
  691. $res = Yii::$app->services->validate->validate($params, [
  692. [['user_id', 'tag_id'], 'required'],
  693. ]);
  694. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  695. $tag_id_arr = json_decode($params['tag_id'], true);
  696. $res = UserTagRelate::setData($params['user_id'], $tag_id_arr);
  697. if ($res === false) return $this->error(UserTagRelate::getStaticError());
  698. return $this->success('操作成功');
  699. }
  700. /**
  701. * 编辑会员标签
  702. * user_label_arr[user_id] = [1,2,3,4,5]
  703. * @Author: lun
  704. * @DateTime: 2022/3/14 0014 10:52
  705. * @Copyright: copyright (c) 2021 广东七件事集团
  706. * @return mixed|void
  707. * @throws \yii\db\Exception
  708. */
  709. public function actionAddUserLabel()
  710. {
  711. $params = Yii::$app->request->post();
  712. $res = Yii::$app->services->validate->validate($params, [
  713. [['user_label_arr', 'is_batch'], 'required'],
  714. ]);
  715. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  716. $res = UserLabelRelationship::batchSetData($this->mall_id, $params['user_label_arr'], $params['is_batch']);
  717. if ($res === false) return $this->error(UserTagRelate::getStaticError());
  718. return $this->success('操作成功');
  719. }
  720. /**
  721. * 编辑备注
  722. * @return mixed|void
  723. */
  724. public function actionEditRemark()
  725. {
  726. $params = \Yii::$app->request->post();
  727. $res = Yii::$app->services->validate->validate($params, [
  728. [['user_id', 'remark'], 'required'],
  729. ]);
  730. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  731. $res = UserExtra::setData($params);
  732. if ($res === false) return $this->error(UserExtra::getStaticError());
  733. return $this->success('操作成功');
  734. }
  735. public function actionEditUsername()
  736. {
  737. $params = \Yii::$app->request->post();
  738. $res = Yii::$app->services->validate->validate($params, [
  739. [['user_id', 'username'], 'required'],
  740. ]);
  741. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  742. $res = User::updateAll(['username'=>$params['username']],['id'=>$params['user_id'],'mall_id'=>$this->mall_id]);
  743. if ($res === false) return $this->error(User::getStaticError());
  744. // 触发用户信息修改事件
  745. $event = new UserUpdateEvent($this->mall_id);
  746. Yii::$app->services->events->dispatch($event, ['user_id'=>$params['user_id'], 'mall_id' => $this->mall_id], $event->listeners);
  747. return $this->success('操作成功');
  748. }
  749. /**
  750. * 编辑会员资料
  751. * @return \yii\web\Response
  752. */
  753. public function actionUserExtraEdit()
  754. {
  755. $params = \Yii::$app->request->post();
  756. $res = UserExtra::setData($params);
  757. if ($res === false) return $this->error(UserExtra::getStaticError());
  758. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE, [
  759. 'user_id'=>$params['user_id'],
  760. 'mall_id'=>$this->mall_id,
  761. 'cate_ids'=>[MemberLabelEnum::USER_AGE]
  762. ], MemberLabelLogic::class, 'executeSyncCateId11');
  763. return $this->success('操作成功');
  764. }
  765. /**
  766. * 修改推广资格
  767. * @return mixed|void
  768. */
  769. public function actionChangeInviter()
  770. {
  771. $postData = \Yii::$app->request->post();
  772. $res = User::updateAll(['is_inviter' => $postData['is_inviter']], ['id' => $postData['user_id']]);
  773. if ($res) return $this->success('修改成功');
  774. return $this->error('修改失败');
  775. }
  776. /**
  777. * 获取可以绑定的推荐人
  778. * @return \yii\web\Response
  779. */
  780. public function actionGetCanBindInviter()
  781. {
  782. if (\Yii::$app->request->isAjax) {
  783. $params = \Yii::$app->request->get();
  784. $params['mall_id'] = $this->mall_id;
  785. $list = User::getCanBindInviter($params);
  786. return $this->success('操作成功', ['list' => $list]);
  787. }
  788. }
  789. /**
  790. * 修改推荐人
  791. * @return mixed|void
  792. */
  793. public function actionUpdateParent()
  794. {
  795. if (\Yii::$app->request->isAjax) {
  796. $params = \Yii::$app->request->post();
  797. $params['mall_id'] = $this->mall_id;
  798. // $res = User::updateParent($params);
  799. //会员同步插件
  800. if(MallAddons::isInstall($this->mall_id,'UserSync')){
  801. $configs = \Yii::$app->services->setting->addons->get($this->mall_id, 'UserSync', 'basic');
  802. if(!empty($configs['is_enable'])){
  803. $insert = [
  804. 'mall_id'=>$this->mall_id,
  805. 'user_id'=>$params['user_id'],
  806. 'type'=>2,
  807. ];
  808. UserSync::setData($insert);
  809. }
  810. }
  811. try {
  812. $params['is_admin'] = 1;
  813. $params['ip'] = ArrayHelper::get_client_ip();
  814. $params['operator_user_id'] = $this->admin->id;
  815. $res = User::updateParentByLock($params);
  816. if (\common\models\mall\MallAddons::isInstall($this->mall_id, \common\enums\AddonsEnum::ADDONS_NAME_STORE)) {
  817. //安装了o2o,获取关联门店数据
  818. $store_associated_user_service = new StoreAssociatedUserService();
  819. $store_associated_user_service->getStoreAssociated([
  820. 'user_id' => $params['user_id'],
  821. 'mall_id' => $this->mall_id,
  822. ]);
  823. }
  824. if ($res) return $this->success('修改成功');
  825. }catch (\Exception $e){
  826. return $this->error($e->getMessage());
  827. }
  828. return $this->error(user::getStaticError());
  829. }
  830. }
  831. /**
  832. * 修改推荐人记录
  833. * @return mixed|void
  834. */
  835. public function actionUserChangeParentLog()
  836. {
  837. $params = \Yii::$app->request->get();
  838. $where[] = ['user_id' => $params['user_id']];
  839. $with = ['beforeParent', 'afterParent'];
  840. $params['where'] = $where;
  841. $params['with'] = $with;
  842. $params['order'] = 'id desc';
  843. $list = UserRelationshipLog::listPage($params);
  844. if (!empty($list['list'])) {
  845. foreach ($list['list'] as $k => &$item) {
  846. if ($k == 0) {
  847. $list['parent_id'] = $item['after_id'];
  848. $list['parent_nickname'] = $item['afterParent']['nickname'];
  849. }
  850. $item['before_name'] = $item['beforeParent']['nickname'];
  851. $item['after_name'] = $item['afterParent']['nickname'];
  852. $item['updated_at'] = date('Y-m-d H:i:s', $item['created_at']);
  853. }
  854. }
  855. return $this->success('操作成功', $list);
  856. }
  857. /**
  858. * 批量导入会员
  859. * @return mixed|string|void
  860. */
  861. public function actionImportUsers()
  862. {
  863. set_time_limit(0);
  864. if (\Yii::$app->request->isAjax) {
  865. $params = \Yii::$app->request->post();
  866. $res = Yii::$app->services->validate->validate($params, [
  867. [['current_num'], 'required'],
  868. [['file'], 'file', 'extensions' => ['csv']],
  869. [['file_path'], 'string'],
  870. [['sync'], 'safe'],
  871. ]);
  872. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  873. $params['mall_id'] = $this->mall_id;
  874. if(!empty($params['sync'])){
  875. $res = User::importUsersSync($params);
  876. }else{
  877. $res = User::importUsers($params);
  878. }
  879. if($res==false){
  880. return $this->error(user::getStaticError());
  881. }
  882. if (empty($res['fail_counts'])) return $this->success('操作成功', $res);
  883. if (!empty($res['fail_counts'])) return $this->error('导入失败'.$res['fail_counts'].'条');
  884. return $this->error(user::getStaticError());
  885. } else {
  886. return $this->render($this->action->id);
  887. }
  888. }
  889. /**
  890. * 会员批量导入模板下载
  891. */
  892. public function actionUserBatchSendModel()
  893. {
  894. $csv = new CsvExport();
  895. $file_name = '会员批量导入模板-' . date('YmdHis', time());
  896. $head_list = array_column(User::$head_list, 'field_name');
  897. return $csv->export([], $head_list, $file_name);
  898. }
  899. /**
  900. * 导入日志记录
  901. * @return mixed|void
  902. */
  903. public function actionGetUserImportLog()
  904. {
  905. $params = \Yii::$app->request->get();
  906. $params['where'] = [
  907. ['mall_id'=>$this->mall_id]
  908. ];
  909. $params['order'] = 'id desc';
  910. $data = UserImportLog::listPage($params, false, true);
  911. if (!empty($data['list'])) {
  912. foreach ($data['list'] as &$v) {
  913. $v['url'] = '';
  914. if ($v['fail_counts']) $v['url'] = \Yii::$app->urlManager->createUrl(['mall/user/export-fail', 'user_import_log_id' => $v['id']]);
  915. }
  916. }
  917. return $this->success('操作成功', $data);
  918. }
  919. /**
  920. * 导出失败日志
  921. */
  922. public function actionExportFail()
  923. {
  924. UserImportFailLog::exportFailLog(\Yii::$app->request->get());
  925. }
  926. /**
  927. * 登录日志
  928. * @return mixed|string|void
  929. */
  930. public function actionLoginLog(){
  931. try {
  932. $request = Yii::$app->request;
  933. if ($request->isAjax) {
  934. if ($request->isGet) {
  935. $params = \Yii::$app->request->get();
  936. $params['where'] = [['mall_id'=>$this->mall_id]];
  937. $params['order'] = 'created_at desc';
  938. $list = LoginLog::getLoginLogList($params);
  939. return $this->success('ok', $list);
  940. }
  941. }
  942. } catch (\Exception $e) {
  943. return $this->error($e->getMessage(), []);
  944. }
  945. return $this->render($this->action->id);
  946. }
  947. public function actionEditUserLevel(){
  948. $params = \Yii::$app->request->post();
  949. $params['id'] = $params['user_id'];
  950. $params['mall_id'] = $this->mall_id;
  951. //查询修改前用户信息
  952. $user = User::getUser([['id' => $params['user_id'],'mall_id' => $params['mall_id']]],'*',[],1);
  953. $res = User::change($params);
  954. if($res){
  955. if ($params['level'] != $user['level']) {
  956. // 记录升级日志
  957. $upgrade_log_obj = new UserLevelUpgradeLog();
  958. $upgrade_log_obj->admin_id = $this->admin->id;
  959. $upgrade_log_obj->mall_id = $this->mall_id;
  960. $upgrade_log_obj->user_id = $params['user_id'];
  961. $upgrade_log_obj->before_level = $user['level'];
  962. $upgrade_log_obj->after_level = $params['level'];
  963. $upgrade_log_obj->upgrade_type = $params['level'] > $user['level'] ? LevelUpgradeLogEnum::MANUALLY_UPGRADE : LevelUpgradeLogEnum::DOWNGRADE_MANUALLY;
  964. $upgrade_log_obj->save();
  965. }
  966. //触发事件
  967. $event = new UserUpgradeAfterEvent($this->mall_id);
  968. $data = ['after_level' => $params['level'], 'before_level' => $user['level'],'mall_id'=>$this->mall_id,
  969. 'user_id' => $params['user_id'], 'is_admin' => 1, 'operator_user_id' => $this->admin->id];
  970. \Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  971. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE, [
  972. 'user_id'=>$params['user_id'],
  973. 'mall_id'=>$this->mall_id,
  974. 'cate_ids'=>[MemberLabelEnum::USER_LEVEL]
  975. ], MemberLabelLogic::class, 'executeSyncCateId2Or3');
  976. }
  977. if ($res) return $this->success('修改成功');
  978. return $this->error(user::getStaticError());
  979. }
  980. //批量修改用户等级
  981. public function actionBatchEditUserLevel(){
  982. $params = \Yii::$app->request->post();
  983. $params['id'] = explode(',', $params['user_id']);
  984. $params['mall_id'] = $this->mall_id;
  985. // print_r($params);exit;
  986. $list = User::lists(['where'=>[['in','id',$params['id']]]],false);
  987. $num = 0;
  988. $event = new UserUpgradeAfterEvent($this->mall_id);
  989. foreach($list as $user){
  990. $data = [
  991. 'id' => $user['id'],
  992. 'level' => $params['level'],
  993. 'mall_id' => $params['mall_id'],
  994. ];
  995. //修改用户等级数据
  996. $res = User::change($data);
  997. //触发异步事件
  998. if($res){
  999. // //触发事件
  1000. $event = new UserUpgradeAfterEvent($this->mall_id);
  1001. $data = ['after_level' => $params['level'], 'before_level' => $user['level'],'mall_id'=>$this->mall_id,
  1002. 'user_id' => $user['id'], 'is_admin' => 1, 'operator_user_id' => $this->admin->id];
  1003. \Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  1004. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE, [
  1005. 'user_id' => $user['id'],
  1006. 'mall_id' => $this->mall_id,
  1007. 'cate_ids' => [MemberLabelEnum::USER_LEVEL]
  1008. ], MemberLabelLogic::class, 'executeSyncCateId2Or3');
  1009. $num ++;
  1010. }else{
  1011. return $this->error(user::getStaticError());
  1012. }
  1013. }
  1014. if ($num > 0) return $this->success('批量修改成功'.$num.'条用户数据');
  1015. return $this->error('批量修改失败');
  1016. }
  1017. /**
  1018. * 查询会员的优惠卷
  1019. *
  1020. * @return mixed
  1021. */
  1022. public function actionGetUserCoupon()
  1023. {
  1024. $params = Yii::$app->request->get();
  1025. if ($params['coupon_list_type'] == 2) { // 判断是否为门店
  1026. if (!MallAddons::isInstall($this->mall_id, 'Store')) {
  1027. return $this->success('操作成功', []);
  1028. }
  1029. $userRelate = StoreCouponUserRelate::tableName();
  1030. $params['where'][] = ['acu.from_type' => 1];
  1031. } else {
  1032. $userRelate = AddonsCouponUserRelate::tableName();
  1033. }
  1034. $params['join'] = [['left join', $userRelate . ' as acu', 'ac.id = acu.coupon_id']];
  1035. if (isset($params['type'])) {
  1036. if ($params['type'] == 2) {
  1037. // 未使用
  1038. $params['where'][] = ['ac.status' => StatusEnum::ENABLED];
  1039. $params['where'][] = ['acu.is_use' => 0];
  1040. $params['where'][] = ['>','acu.end_time', time()];
  1041. $params['where'][] = ['=','acu.coupon_status', 2];
  1042. }
  1043. if ($params['type'] == 1) {
  1044. // 不可用
  1045. $params['where'][] = ['=', 'acu.is_use', 1];
  1046. }
  1047. if ($params['type'] == 3) {
  1048. // 已过期
  1049. $params['where'][] = ['=', 'acu.coupon_status', AddonsCouponEnum::STATUS_EXPIRED];
  1050. }
  1051. if ($params['type'] == 4) {
  1052. // 已失效
  1053. $params['where'][] = ['=', 'acu.coupon_status', AddonsCouponEnum::STATUS_FAILURE];
  1054. }
  1055. }
  1056. $params['where'][] = ['acu.user_id' => $params['user_id']];
  1057. $params['where'][] = ['acu.status' => StatusEnum::ENABLED];
  1058. if (!empty($params['keyword'])) $params['where'][] = ['like', 'name', $params['keyword']];
  1059. $params['order'] = 'sort asc,id desc';
  1060. $params['alias'] = 'ac';
  1061. $params['select'] = 'ac.id as coupon_id,ac.name,acu.created_at as get_time,acu.end_time';
  1062. $params['order'] = 'acu.created_at desc';
  1063. //dd($params);
  1064. $list = AddonsCoupon::listPage($params);
  1065. $data['list'] = $list;
  1066. return $this->success('操作成功', $data);
  1067. }
  1068. /**
  1069. * 团队数据
  1070. *
  1071. * @param int $user_id
  1072. * @param int $status 1:直推客户-下级 2:间推客户-下级的下级 3:我的团队-全部下级 4:推荐人-全部上级
  1073. * @param string $keyword 关键字
  1074. * @param int $search_type 1:会员ID 2:会员昵称 3:手机号码
  1075. * @param int $page
  1076. * @return mixed|array|void
  1077. */
  1078. public function actionMyCustomer() {
  1079. if (!Yii::$app->request->isAjax) {
  1080. $user_id = Yii::$app->request->get('user_id');
  1081. if (!$user_id) throw new \Exception('用户不存在');
  1082. $where[] = ['=', 'u.id', $user_id];
  1083. $join = [['LEFT JOIN', User::tableName() . ' as p', 'u.parent_id = p.id']];
  1084. $select = ['u.id', 'u.nickname', 'u.mobile', 'u.parent_id','u.avatar_url', 'u.created_at', 'p.nickname p_nickname'];
  1085. $params = [
  1086. 'where' => $where,
  1087. 'alias' => 'u',
  1088. 'select' => $select,
  1089. 'join' => $join
  1090. ];
  1091. $model = User::find();
  1092. User::paramPack($params, $model);
  1093. $user_info = $model->asArray()->one();
  1094. if (empty($user_info)) throw new \Exception('用户不存在');
  1095. // 团队用户数据统计
  1096. $statistics = UserTeamStatistics::find()->select('user_team_total,user_direct_total,user_indirect_total')->where(['user_id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->one();
  1097. $user_info['team_num'] = $statistics['user_team_total'] ?: 0;
  1098. $user_info['first_num'] = $statistics['user_direct_total'] ?: 0;
  1099. $user_info['second_num'] = $statistics['user_indirect_total'] ?: 0;
  1100. //累计消费
  1101. $user_info['pay_money'] = UserStatisticsTotal::find()->where(['user_id' => $user_id])->sum('pay_money');
  1102. CapitalLog::$capitalType = 'commission_frozen';
  1103. //累计佣金
  1104. $user_info['commission'] = CapitalLog::find()->where(['user_id' => $user_id, 'change_type' => CapitalLog::CHANGE_TYPE_ADD])->sum('change_num');
  1105. //未结算
  1106. $user_info['not_income'] = CapitalLog::find()->where(['user_id' => $user_id, 'change_type' => CapitalLog::CHANGE_TYPE_ADD, 'status' => CapitalLog::STATUS_WAIT_SEND])->sum('change_num');
  1107. return $this->render('my-customer', ['user_info' => json_encode($user_info)]);
  1108. }
  1109. $get = Yii::$app->request->get();
  1110. $res = Yii::$app->services->validate->validate($get, [
  1111. [['user_id'], 'required'],
  1112. [['user_id', 'status', 'page'], 'integer'],
  1113. [['keyword', 'search_type'],'safe']
  1114. ]);
  1115. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  1116. $user_id = $get['user_id'];
  1117. $status = $get['status'] ?? 1;
  1118. $keyword = $get['keyword'] ?? '';
  1119. $search_type = $get['search_type'] ?? 1;
  1120. $page = $get['page'] ?? 1;
  1121. switch ($status) {
  1122. case '1':
  1123. $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 1, 1);
  1124. break;
  1125. case '2':
  1126. $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 1, 2);
  1127. break;
  1128. case '3':
  1129. $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 1);
  1130. break;
  1131. case '4':
  1132. $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 2,1);
  1133. break;
  1134. }
  1135. if (empty($user_relations)) return $this->success('操作成功', ['list' => [], 'page_count' => 0]);
  1136. $user_list = $user_relations['list'];
  1137. $user_ids = array_keys($user_list);
  1138. $where[] = ['in', 'u.id', $user_ids];
  1139. $select = ['u.id', 'u.nickname', 'u.mobile', 'u.avatar_url', 'ust.user_id', 'ust.pay_money', 'ust.pay_num'];
  1140. $join = [['LEFT JOIN', UserStatisticsTotal::tableName() . ' as ust', 'u.id=ust.user_id']];
  1141. //需要查询父级
  1142. if (in_array($status, [2,3])) {
  1143. array_push($select, 'p.id p_id', 'p.avatar_url p_avatar_url', 'p.nickname p_nickname');
  1144. array_push($join, ['LEFT JOIN', USER::tableName() . ' as p', 'p.id=u.parent_id']);
  1145. }
  1146. $params = [
  1147. 'alias' => 'u',
  1148. 'where' => $where,
  1149. 'select' => $select,
  1150. 'join' => $join
  1151. ];
  1152. $model = User::find();
  1153. User::paramPack($params, $model);
  1154. $list = $model->asArray()->all();
  1155. foreach ($list as &$val) {
  1156. $val['pay_money'] = $val['pay_money'] ?? 0;
  1157. $val['pay_num'] = $val['pay_num'] ?? 0;
  1158. $val['bind_time'] = isset($user_list[$val['id']]) ? $user_list[$val['id']] : '暂无';
  1159. }
  1160. $data = ['list' => $list, 'page_count' => ceil($user_relations['count'] / 10)];
  1161. return $this->success('操作成功', $data);
  1162. }
  1163. /**
  1164. * 我的收益
  1165. *
  1166. * @param int user_id
  1167. */
  1168. public function actionMyCommission() {
  1169. $user_id = Yii::$app->request->get('user_id');
  1170. if (!$user_id) return [];
  1171. $params = Yii::$app->request->get();
  1172. CapitalLog::$capitalType = 'commission';
  1173. $where[] = ['user_id'=>$user_id];
  1174. $where[] = ['mall_id'=>$this->mall_id];
  1175. if (Yii::$app->request->get('id')) $where[] = ['>','id'=>Yii::$app->request->get('id')];
  1176. if (Yii::$app->request->get('id')) $where[] = ['=','capital_type'=>Yii::$app->request->get('capital_type')];
  1177. $capital_type = UserWalletEnum::getCapitalTypeMapByCommission();
  1178. $params['where'] = $where;
  1179. $params['select'] = 'change_type,change_num,current_num,created_at,from_type,capital_type,id,desc';
  1180. $params['order'] = 'id desc';
  1181. $params['limit'] = 10;
  1182. $list = CapitalLog::listPage($params);
  1183. $list['capital_type'] = $capital_type;
  1184. return $this->success('操作成功', $list);
  1185. }
  1186. /**
  1187. * @notes:用户树状关系图
  1188. * @return mixed|string|null
  1189. * @author: lun
  1190. * @Time: 2022/12/13 17:20
  1191. */
  1192. public function actionRelationTree()
  1193. {
  1194. $request = Yii::$app->request;
  1195. if ($request->isPost) {
  1196. try {
  1197. // 提交内容
  1198. $params = Yii::$app->request->post();
  1199. $res = Yii::$app->services->validate->validate($params, [
  1200. [['type','tree_type'], 'required'],
  1201. [['keyword',], 'integer'],
  1202. ]);
  1203. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  1204. $field = $params['type'] == 1 ? 'id' : 'mobile';
  1205. $select = 'id,mobile,nickname,level,parent_id,created_at';
  1206. $user = User::find()->select($select)->where(['mall_id' => $this->mall_id, $field => $params['keyword']])->asArray()->one();
  1207. if(empty($user)) return $this->error("查询的会员不存在");
  1208. // 获取5层用户
  1209. if ($params['tree_type'] == 'under') {// 查询下级
  1210. $data = UserPartitionRelationship::getChildIdMake($user['id'], 10, 200, 1);
  1211. $list = $data['list'];
  1212. $child_uids = array_column($list, 'user_id');
  1213. if (count($list) <= 1) return $this->error('此用户暂无下级数据');
  1214. } else {// 查询上级
  1215. $parent_ids = UserPartitionRelationship::getParentIdArr($user['id']);
  1216. array_push($parent_ids, $user['id']);
  1217. $child_uids = $list = $parent_ids;
  1218. if (count($list) <= 1) return $this->error('此用户暂无上级数据');
  1219. }
  1220. $where[] = ['in', 'id', $child_uids];
  1221. $index = "id";
  1222. $param = compact('where','select', 'index');
  1223. $child_arr = User::lists($param);
  1224. // 等级
  1225. $level_arr = UserLevel::getUserLevelArr($this->mall_id);
  1226. $new_list = [];
  1227. foreach($list as $key => $item) {
  1228. if ($params['tree_type'] == 'under') {
  1229. $user_id = $item['user_id'];
  1230. $pid = $child_arr[$user_id]['parent_id'];
  1231. } else {
  1232. $user_id = $item;
  1233. $pid = $list[$key - 1];
  1234. }
  1235. $new_list[] = [
  1236. 'id' => $user_id,
  1237. 'user_id' => $user_id,
  1238. 'name' => $user_id,
  1239. 'level_name' => $level_arr[$child_arr[$user_id]['level']] ?? MallSetting::getDefaultLevelName($this->mall_id),
  1240. 'pid' => $user_id == $user['id'] && $params['tree_type'] == 'under' ? 0 : $pid,
  1241. 'nickname' => $child_arr[$user_id]['nickname'],
  1242. 'mobile' => $child_arr[$user_id]['mobile'],
  1243. 'created_at' => date('Y-m-d H:i:s', $child_arr[$user_id]['created_at']),
  1244. ];
  1245. }
  1246. // 组合成树形结构返回
  1247. $tree_arr = UserPartitionRelationship::listToTree($new_list, 0);
  1248. return $this->success('获取成功', $tree_arr);
  1249. } catch (\Exception $e) {
  1250. return $this->error('获取失败:' . $e->getMessage());
  1251. }
  1252. } else {
  1253. return $this->render($this->action->id);
  1254. }
  1255. }
  1256. //修改手机号码
  1257. public function actionUpdateMobile(){
  1258. try {
  1259. $params = Yii::$app->request->post();
  1260. $res = Yii::$app->services->validate->validate($params, [
  1261. [['mobile', 'user_id'], 'required'],
  1262. ['mobile', 'match', 'pattern' => '/^1\d{10}$/', 'message' => '请输入正确的手机号码'],
  1263. ]);
  1264. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  1265. $params['mall_id'] = $this->mall_id;
  1266. $params['operator'] = $this->admin->username??'';
  1267. $params['operator_user_id'] = $this->admin->id;
  1268. User::updateMobile($params);
  1269. return $this->success('操作成功');
  1270. }catch (\Exception $e){
  1271. return $this->error($e->getMessage());
  1272. }
  1273. }
  1274. public function actionGetChangeMobileLog(){
  1275. $params = \Yii::$app->request->get();
  1276. $where[] = ['user_id' => $params['user_id']];
  1277. $where[] = ['type' => 1];
  1278. $params['where'] = $where;
  1279. $params['order'] = 'id desc';
  1280. $params['select'] = 'user_id,operator,old_mobile,new_mobile,created_at';
  1281. $list = ChangeMobileLog::listPage($params);
  1282. if (!empty($list['list'])) {
  1283. foreach ($list['list'] as &$item) {
  1284. $item['created_at'] = date('Y-m-d H:i:s',$item['created_at']);
  1285. if($item['user_id']==$item['operator']){
  1286. $item['operator'] = '会员自己';
  1287. }
  1288. }
  1289. }
  1290. return $this->success('操作成功', $list);
  1291. }
  1292. public function actionHandleFreezeCommission()
  1293. {
  1294. try {
  1295. $params = Yii::$app->request->post();
  1296. $res = Yii::$app->services->validate->validate($params, [
  1297. [['freeze_cap', 'freeze_scale', 'user_id'], 'required'],
  1298. [['freeze_amount'], 'number'],
  1299. [['freeze_scale'], 'number', 'min' => 0, 'max' => 100],
  1300. [['freeze_cap'], 'number', 'min' => 0],
  1301. ]);
  1302. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  1303. $params['mall_id'] = $this->mall_id;
  1304. if(UserFreezeCommission::setData($params) === false){
  1305. throw new \Exception(UserFreezeCommission::getStaticError());
  1306. }
  1307. return $this->success('操作成功');
  1308. }catch (\Exception $e){
  1309. return $this->error($e->getMessage());
  1310. }
  1311. }
  1312. public function actionHandleClearFreezeCommission()
  1313. {
  1314. try {
  1315. $params = Yii::$app->request->post();
  1316. $res = Yii::$app->services->validate->validate($params, [
  1317. [['id'], 'required'],
  1318. [['id'], 'number'],
  1319. ]);
  1320. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  1321. $params['mall_id'] = $this->mall_id;
  1322. if(!empty(UserFreezeCommission::getSwitchStatus($this->mall_id))){
  1323. if(UserFreezeCommission::clearUserData($this->mall_id, $params['id']) === false){
  1324. throw new \Exception(UserFreezeCommission::getStaticError());
  1325. }
  1326. }
  1327. return $this->success('操作成功');
  1328. }catch (\Exception $e){
  1329. return $this->error($e->getMessage());
  1330. }
  1331. }
  1332. /**
  1333. * 清除用户授权,传user_id则代表清单用户,不传则删除某平台
  1334. *
  1335. * @return mixed|null
  1336. */
  1337. public function actionClearAuth()
  1338. {
  1339. $userId = Yii::$app->request->post('user_id', 0);
  1340. $platform = Yii::$app->request->post('platform', '');
  1341. if (!$userId && !$platform) {
  1342. return $this->error('参数错误');
  1343. }
  1344. if ($platform && !in_array($platform, ['wechat', 'mp-wx'])) {
  1345. return $this->error('参数错误');
  1346. }
  1347. UserInfo::clearAuth($this->mall_id, $userId, $platform);
  1348. return $this->success();
  1349. }
  1350. /**
  1351. * 重置用户支付密码
  1352. * @params user_id 用户id
  1353. * @params password 支付密码
  1354. * @return mixed|null
  1355. * @throws \yii\base\Exception
  1356. */
  1357. public function actionResetPaymentPassword()
  1358. {
  1359. $userId = Yii::$app->request->post('user_id', 0);
  1360. $password = Yii::$app->request->post('password', '');
  1361. if (!$userId && !$password) {
  1362. return $this->error('参数错误');
  1363. }
  1364. $res = User::updateAll(['transaction_password' => Yii::$app->getSecurity()->generatePasswordHash($password)], ['id' => $userId]);
  1365. if ($res === false) return $this->error(User::getStaticError());
  1366. $event = new UserModifyPayPwdEvent($this->mall_id);
  1367. Yii::$app->services->events->dispatch($event, [
  1368. 'operator_user_id' => $this->admin->id,
  1369. 'new_pwd' => trim($password),
  1370. 'is_admin' => 1,
  1371. 'user_id' => $userId,
  1372. 'mall_id' => $this->mall_id
  1373. ], $event->listeners);
  1374. return $this->success('操作成功');
  1375. }
  1376. /**
  1377. * 会员过期
  1378. *
  1379. * @param $data
  1380. *
  1381. * @return true|void
  1382. */
  1383. public function memberExpired($data){
  1384. $user_level = UserLevel::findOne(['mall_id'=>$data['mall_id'],'status'=>StatusEnum::ENABLED,'level'=>$data['after_level']]);
  1385. if(!$user_level) return true;
  1386. if(isset($user_level['is_open_expired']) && $user_level['is_open_expired']){
  1387. $expire_at = strtotime("+".$user_level['expired_day']." day");
  1388. $user_level_expired = UserLevelExpired::findOne(['user_id'=> $data['user_id'],'level'=>$data['after_level'],'status'=>StatusEnum::ENABLED]);
  1389. if(!$user_level_expired){
  1390. $user_level_expired = new UserLevelExpired();
  1391. $user_level_expired->mall_id = $data['mall_id'];
  1392. $user_level_expired->user_id = $data['user_id'];
  1393. $user_level_expired->level = $data['after_level'];
  1394. }
  1395. $user_level_expired->expired_at = $expire_at;
  1396. $user_level_expired->save();
  1397. }
  1398. }
  1399. //后台数字币充值
  1400. public function actionAddDigital()
  1401. {
  1402. try {
  1403. $admin = Yii::$app->getUser()->identity;
  1404. $params = Yii::$app->request->post();
  1405. $user = User::getOne([['mall_id' => $this->mall_id, 'id' => $params['user_id'], 'status' => StatusEnum::ENABLED]], true);
  1406. if (!$user) throw new \Exception('用户不存在');
  1407. $desc = '管理员' . $admin->username .' 后台充值' . $params['price'] . '数字币';
  1408. $res = UserDigital::handleUserDigital($user['mall_id'], $user['id'], $params['price'], false, [
  1409. 'from_type' => UserWalletEnum::RECHARGE,
  1410. 'capital_type' => UserWalletEnum::RECHARGE_PLATFORM,
  1411. 'desc' => $desc
  1412. ]);
  1413. if (!$res) {
  1414. throw new \Exception(UserDigital::getStaticError());
  1415. }
  1416. return $this->success('操作成功');
  1417. } catch (\Exception $e) {
  1418. return $this->error($e->getMessage());
  1419. }
  1420. }
  1421. }