Agent.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. <?php
  2. namespace addons\Agent\common\models;
  3. use addons\Agent\common\enums\AgentEnum;
  4. use common\components\export\CsvTool;
  5. use common\enums\AddonsEnum;
  6. use common\enums\DownloadEnum;
  7. use common\enums\LevelUpgradeLogEnum;
  8. use common\enums\StatusEnum;
  9. use common\helpers\ArrayHelper;
  10. use common\models\base\BaseActiveRecord;
  11. use common\models\common\Addons;
  12. use common\models\common\CommissionLog;
  13. use common\models\common\Download;
  14. use common\models\goods\GoodsAttr;
  15. use common\models\mall\MallAddons;
  16. use common\models\user\User;
  17. use common\models\user\UserAddress;
  18. use common\models\user\UserPartitionRelationship;
  19. use common\models\user\UserTeamStatistics;
  20. use common\helpers\csv\CsvImportForm;
  21. use common\enums\RabbitMqEnum;
  22. use Exception;
  23. use Yii;
  24. /**
  25. * This is the model class for table "{{%addons_agent}}".
  26. * @property int $id
  27. * @property int $mall_id
  28. * @property int $user_id
  29. * @property string|null $remarks 备注
  30. * @property int $status
  31. * @property int $created_at 创建时间
  32. * @property int $updated_at 修改时间
  33. * @property int $level 经销商等级
  34. * @property int $upgrade_level_at 经销商等级升级时间
  35. * @property float $total_commission 佣金
  36. * @property int $total_score 积分
  37. * @property int $province_id 省份ID
  38. * @property User $user
  39. * @property int $upgrade_status
  40. */
  41. class Agent extends BaseActiveRecord
  42. {
  43. public $limit = 10;
  44. public $page = 1;
  45. /**
  46. * {@inheritdoc}
  47. */
  48. public static function tableName()
  49. {
  50. return '{{%addons_agent}}';
  51. }
  52. /**
  53. * {@inheritdoc}
  54. */
  55. public function rules(){
  56. return [
  57. [['mall_id', 'user_id'], 'required'],
  58. [['mall_id', 'user_id', 'status', 'created_at', 'updated_at', 'level', 'upgrade_level_at', 'upgrade_status', 'province_id'], 'integer'],
  59. [['remarks'], 'string'],
  60. [['total_commission','total_score'], 'number'],
  61. ];
  62. }
  63. /**
  64. * {@inheritdoc}
  65. */
  66. public function attributeLabels(){
  67. return [
  68. 'id' => 'ID',
  69. 'mall_id' => 'Mall ID',
  70. 'user_id' => 'User ID',
  71. 'remarks' => '备注',
  72. 'status' => '状态[-1:删除;0:禁用;1启用]',
  73. 'created_at' => '创建时间',
  74. 'updated_at' => '修改时间',
  75. 'level' => '经销商等级',
  76. 'upgrade_level_at' => '经销商等级升级时间',
  77. 'total_commission' => '总佣金',
  78. 'total_score' => '总积分',
  79. 'upgrade_status' => '升级方式,1条件升级 2 购买指定商品升级 3手动升级',
  80. 'province_id' => '省份ID',
  81. ];
  82. }
  83. public static $head_list = [
  84. '0' => [
  85. 'field' => 'serial_number',
  86. 'field_name' => '序号',
  87. ],
  88. '1' => [
  89. 'field' => 'mobile',
  90. 'field_name' => '手机号码',
  91. ],
  92. '2' => [
  93. 'field' => 'level',
  94. 'field_name' => '经销商等级id',
  95. ]
  96. ];
  97. public static $max_count = 5000;
  98. public static $column_num = 3;
  99. /**
  100. * @param bool $insert
  101. * @return bool
  102. */
  103. public function beforeSave($insert)
  104. {
  105. if ($this->isNewRecord && !$this->province_id){
  106. $setting = \Yii::$app->services->setting->addons->get($this->mall_id, AgentEnum::ADDONS_NAME, 'basic');
  107. if($setting['is_enable_province']){
  108. $address = UserAddress::findOne(['user_id' => $this->user_id,'status' => StatusEnum::ENABLED]);
  109. $this->province_id = $address->province_id ?? 0;
  110. }
  111. }
  112. return parent::beforeSave($insert);
  113. }
  114. /**
  115. * @desc:关联会员信息
  116. * @Author: hua
  117. * @Date: 2021/11/5
  118. * @Time: 10:04
  119. * @Copyright: copyright (c) 2021 广东七件事集团
  120. * @return \yii\db\ActiveQuery
  121. */
  122. public function getUser(){
  123. return $this->hasOne(User::class, ['id' => 'user_id']);
  124. }
  125. /**
  126. * @desc:关联经销商等级
  127. * @Author: hua
  128. * @Date: 2021/11/5
  129. * @Time: 10:04
  130. * @Copyright: copyright (c) 2021 广东七件事集团
  131. * @return \yii\db\ActiveQuery
  132. */
  133. public function getAgentLevel(){
  134. return $this->hasOne(AgentLevel::class, ['level' => 'level','mall_id'=>'mall_id'])->andWhere(['<>','status',StatusEnum::DELETE]);
  135. }
  136. public function getUserTeamStatistics(){
  137. return $this->hasOne(UserTeamStatistics::class, ['user_id' => 'user_id']);
  138. }
  139. /**
  140. * @desc:保存数据
  141. * @Author: hua
  142. * @Date: 2021/10/23
  143. * @Time: 17:23
  144. * @Copyright: copyright (c) 2021 广东七件事集团
  145. * @param array $params
  146. * @return Agent|false|null
  147. */
  148. public static function setData(array $params)
  149. {
  150. try {
  151. if(!empty($params['id'])){
  152. $model = self::findOne(['mall_id' => $params['mall_id'], 'id' => $params['id'], 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]);
  153. if (empty($model)) throw new \Exception('服务不存在或已删除');
  154. // 记录升级日志
  155. if (
  156. isset($params['level']) &&
  157. $model->level != $params['level']
  158. ) {
  159. $upgrade_log_obj = new AgentLevelUpgradeLog();
  160. $upgrade_log_obj->before_level = $model->level;
  161. $upgrade_log_obj->upgrade_type = $params['level'] > $model->level ? LevelUpgradeLogEnum::MANUALLY_UPGRADE : LevelUpgradeLogEnum::DOWNGRADE_MANUALLY;
  162. }
  163. }else{
  164. $model = new self();
  165. $model->loadDefaultValues();
  166. // 记录升级日志(如果创建的不是默认等级,则认为手动升级)
  167. if ($params['level'] > 0) {
  168. $upgrade_log_obj = new AgentLevelUpgradeLog();
  169. $upgrade_log_obj->before_level = 0;
  170. $upgrade_log_obj->upgrade_type = LevelUpgradeLogEnum::MANUALLY_UPGRADE;
  171. }
  172. }
  173. if (!$model->load($params, '')) throw new \Exception($model->getErrorMessage());
  174. if (!$model->save()) throw new Exception($model->getErrorMessage());
  175. if (isset($upgrade_log_obj)) {
  176. $upgrade_log_obj->admin_id = $params['admin_id'] ?? 0;
  177. $upgrade_log_obj->mall_id = $params['mall_id'];
  178. $upgrade_log_obj->user_id = $params['user_id'];
  179. $upgrade_log_obj->after_level = $params['level'];
  180. $upgrade_log_obj->save();
  181. }
  182. return $model;
  183. } catch (\Exception $e) {
  184. self::$static_error = $e->getMessage();
  185. return false;
  186. }
  187. }
  188. /**
  189. * @desc:批量修改等级
  190. * @Author: hua
  191. * @Date: 2021/10/23
  192. * @Time: 17:40
  193. * @Copyright: copyright (c) 2021 广东七件事集团
  194. * @param $params
  195. * @return bool
  196. */
  197. public static function batchLevel($params) {
  198. try {
  199. if (isset($params['level']) && !empty($params['level'])) {
  200. $args = [];
  201. $args['where'] = [['mall_id'=>$params['mall_id']],['level'=>$params['level']],['<>','status',StatusEnum::DELETE]];
  202. $args['select'] = 'id,level,name';
  203. $agentList = AgentLevel::lists($args,true);
  204. if (empty($agentList)) {
  205. self::$static_error = '无效的经销商等级';
  206. return false;
  207. }
  208. } else {
  209. $params['level'] = 0;
  210. }
  211. self::updateAll(
  212. ['level' => $params['level'], 'upgrade_level_at' => time(), 'upgrade_status' => AgentEnum::UPGRADE_STATUS_MANUAL, 'updated_at' => time()],
  213. ['id' => $params['batch_ids']]
  214. );
  215. return true;
  216. } catch (\Exception $e) {
  217. self::$static_error = $e->getMessage();
  218. return false;
  219. }
  220. }
  221. /**
  222. * 导出字段
  223. */
  224. public static function exportFieldsList($field = null)
  225. {
  226. $fields = [
  227. 'a.user_id' => '用户ID',
  228. 'u.nickname' => '昵称',
  229. 'u.mobile' => '手机号',
  230. 'a.created_at' => '成为经销商时间',
  231. 'a.upgrade_level_at' => '经销商升级时间',
  232. 'a.total_commission' => '累计佣金',
  233. 'a.level' => '经销商等级',
  234. 'a.level level_id' => '经销商等级id',
  235. 'u.nickname parent_name' => '推荐人',
  236. 'a.remarks' => '备注信息'
  237. ];
  238. $temp = [];
  239. foreach ($fields as $key => $val) {
  240. $showField = explode('.', $key)[1];
  241. if (strstr($showField, ' ')) {
  242. $showField = explode(' ', $showField)[1];
  243. }
  244. if ($field === null) {
  245. $temp[$showField] = $val;
  246. } else if (in_array($showField, $field)) {
  247. $temp[$key] = $val;
  248. }
  249. }
  250. return $temp;
  251. }
  252. /**
  253. * @name:
  254. * @msg: 处理导出数据,这个方法是异步队列处理时使用的,请别修改
  255. * @param {array} $data
  256. * @param {int} $mall_id
  257. * @return array
  258. */
  259. // public static function exportHandle(array $data)
  260. // {
  261. // $download_id = $data['download_id'] ?? 0;
  262. // $download = Download::findOne(['id' => $download_id]);
  263. // if($download){
  264. // try{
  265. // $params = json_decode($download->params,true);
  266. // $exportField = self::exportFieldsList($params['fields']);
  267. // $params = self::getParams($params);
  268. // $params['select'] = array_keys($exportField);
  269. // $filename = $download->name;
  270. // $type = $download->type;
  271. // $model = self::find();
  272. // self::paramPack($params, $model);
  273. // $csv = new CsvTool();
  274. // $csv->filename = $filename;
  275. // $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type);
  276. // $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC;
  277. // $list = [];
  278. // foreach (array_values($exportField) as $val) {
  279. // $list[] = iconv("UTF-8", "gbk//TRANSLIT", $val);
  280. // }
  281. // foreach ($model->batch() as $agents) {
  282. // $agents = ArrayHelper::toArray($agents);
  283. // // $users 是一个包含100条或小于100条用户表数据的数组
  284. // empty($csv->header) && $csv->header = $list;
  285. // $csv->data = array_map(function($agent){
  286. // return array_values($agent);
  287. // },$agents);
  288. // $csv->export();
  289. // }
  290. // $url = $csv->upload($params['mall_id'],$csv->relative_filename);
  291. // $download->url = $url;
  292. // $download->status = 2;
  293. // $download->size = $csv->file_size;
  294. // $download->num = $csv->line_num;
  295. // $download->save();
  296. // return true;
  297. // }catch(Exception $e){
  298. // $download->status = 3;
  299. // self::setStaticError($e->getMessage());
  300. // return false;
  301. // }
  302. // }
  303. // }
  304. public static function fieldsList($field = null){
  305. $fields = [
  306. 'user_id' => '用户ID',
  307. 'nickname' => '昵称',
  308. 'mobile' => '手机号',
  309. 'created_at' => '成为经销商时间',
  310. 'upgrade_level_at' => '经销商升级时间',
  311. 'total_commission' => '累计佣金',
  312. 'level' => '经销商等级',
  313. 'level_id' => '经销商等级id',
  314. 'parent_name' => '推荐人',
  315. 'remarks' => '备注信息',
  316. ];
  317. if ($field === null) return $fields;
  318. $temp = [];
  319. foreach ($field as $val) {
  320. if (isset($fields[$val])) $temp[$val] = $fields[$val];
  321. }
  322. return $temp;
  323. }
  324. /**
  325. * @name:
  326. * @msg: 处理导出数据,这个方法是异步队列处理时使用的,请别修改
  327. * @param {array} $data
  328. * @return bool
  329. */
  330. public static function exportHandle(array $data)
  331. {
  332. $download_id = $data['download_id'] ?? 0;
  333. $download = Download::findOne(['id' => $download_id]);
  334. if($download){
  335. try{
  336. $params = json_decode($download->params,true);
  337. $filename = $download->name;
  338. $type = $download->type;
  339. $fields = $params['fields'];
  340. $fields_arr = self::fieldsList();
  341. $have_select_field_arr = [];
  342. foreach ($fields as $value){
  343. $have_select_field_arr[]=$fields_arr[$value];
  344. }
  345. $csv = new CsvTool();
  346. $csv->filename = $filename;
  347. $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type);
  348. $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC;
  349. $csv->header = $have_select_field_arr;
  350. $model = self::find();
  351. $model->where(['mall_id'=>$params['mall_id']]);
  352. $model->andWhere(['>=','status',StatusEnum::DISABLED]);
  353. $user_id = 0;
  354. $user_id_arr = [];
  355. //拼接查询条件
  356. if(!empty($params['user_id'])) $user_id = $params['user_id'];
  357. if(!empty($params['level'])) $model->andWhere( ['=', 'level', $params['level']]);
  358. if (!empty($params['keyword'])) {
  359. $condition['where'] = [[
  360. 'or',
  361. ['like', 'username', $params['keyword']],
  362. ['like', 'nickname', $params['keyword']],
  363. ['like', 'mobile', $params['keyword']]
  364. ]];
  365. $user_list = User::lists($condition);
  366. $user_id_arr = array_column($user_list,'id');
  367. }
  368. if($user_id&&$user_id_arr){
  369. $user_ids = array_intersect([$user_id],$user_id_arr);
  370. $model->andWhere(['in', 'user_id', $user_ids]);
  371. }else if($user_id){
  372. $model->andWhere(['in', 'user_id', $user_id]);
  373. }elseif($user_id_arr){
  374. $model->andWhere(['in', 'user_id', $user_id_arr]);
  375. }
  376. $model->with(['user','agentLevel'=>function($query){
  377. $query->where(['status'=>StatusEnum::ENABLED]);
  378. }]);
  379. //遍历组装数据
  380. foreach ($model->batch() as $list) {
  381. $parent_id_arr = $parent_arr = [];
  382. //查询上级昵称数组
  383. if(in_array('parent_name',$fields)){
  384. foreach ($list as $item){
  385. $parent_id_arr[] = $item['user']['parent_id'];
  386. }
  387. $parent_arr = UserPartitionRelationship::getParentsNickname($parent_id_arr);
  388. }
  389. $csv->data = array_map(function($agent)use($fields,$parent_arr){
  390. $row = [];
  391. //遍历所选字段
  392. foreach ($fields as $field){
  393. if(in_array($field,['created_at'])){
  394. $row[] = !empty($agent[$field])?date('Y-m-d H:i:s',$agent[$field]):'';
  395. } elseif (in_array($field, ['upgrade_level_at'])) {
  396. $row[] = !empty($agent[$field]) ? date('Y-m-d H:i:s', $agent[$field]) : '';
  397. } elseif(in_array($field,['nickname','mobile'])){
  398. $row[] = !empty($agent['user'][$field])?$agent['user'][$field]:'';
  399. }elseif(in_array($field,['level'])){
  400. $row[] = !empty($agent['agentLevel']['name'])?$agent['agentLevel']['name']:'';
  401. }elseif(in_array($field,['level_id'])){
  402. $row[] = !empty($agent['agentLevel']['level'])?$agent['agentLevel']['level']:'';
  403. }
  404. elseif(in_array($field,['parent_name'])){
  405. $row[] = !empty($parent_arr[$agent['user']['parent_id']])?$parent_arr[$agent['user']['parent_id']]:'平台';
  406. }else{
  407. $row[] = !empty($agent[$field])?$agent[$field]:'';
  408. }
  409. }
  410. return $row;
  411. },$list);
  412. $csv->export();
  413. }
  414. $csv->updateDown($download,$params['mall_id']);
  415. return true;
  416. }catch(Exception $e){
  417. $download->status = 3;
  418. $res = $download->save();
  419. var_dump($e->getMessage());
  420. self::setStaticError($e->getMessage());
  421. return false;
  422. }
  423. }
  424. }
  425. public static function getParams($getData) {
  426. $params = [];
  427. if(isset($getData['user_id']) && !empty($getData['user_id'])) $params['where'][] = ['=', 'u.id', $getData['user_id']];
  428. if(isset($getData['level']) && !empty($getData['level'])) $params['where'][] = ['=', 'a.level', $getData['level']];
  429. if (isset($getData['keyword']) && !empty($getData['keyword'])) {
  430. $params['where'] = [[
  431. 'or',
  432. ['like', 'u.username', $getData['keyword']],
  433. ['like', 'u.nickname', $getData['keyword']],
  434. ['like', 'u.mobile', $getData['keyword']]
  435. ]];
  436. }
  437. $params['where'][] = ['=', 'a.mall_id', $getData['mall_id']];
  438. $params['where'][] = ['in', 'a.status', [StatusEnum::ENABLED,StatusEnum::DISABLED]];
  439. $params['alias'] = 'a';
  440. $params['join'] = [['LEFT JOIN', User::tableName() . ' up', "up.id = u.parent_id"]];
  441. $params['joinWith'] = ['user' => function($query){ $query->from(['u' => User::tableName()]); }];
  442. return $params;
  443. }
  444. /**
  445. * @desc:推广中心-调用
  446. * @Author: hua
  447. * @Date: 2021/11/12
  448. * @Time: 9:31
  449. * @Copyright: copyright (c) 2021 广东七件事集团
  450. * @param array $params ['user_id' => 1, 'mall_id' => 5, 'addons_name' => 'Agent']
  451. * @return array
  452. */
  453. public static function getIncomeInfo(array $params){
  454. $is_install = MallAddons::isInstall($params['mall_id'], $params['addons_name']);
  455. $data['total_commission'] = 0;
  456. $data['is_install'] = 0;
  457. $basic = \Yii::$app->services->setting->addons->get($params['mall_id'], $params['addons_name'], 'basic');
  458. $data['is_show_at_center'] = 1;
  459. if(isset($basic['is_show_at_center'])) $data['is_show_at_center'] = $basic['is_show_at_center'];
  460. if($is_install){
  461. $model = self::findOne(['user_id'=>$params['user_id'],'mall_id'=>$params['mall_id'],'status'=>[StatusEnum::ENABLED,StatusEnum::DISABLED]]);
  462. $data['total_commission'] = $model['total_commission']??0;
  463. $data['is_install'] = $is_install;
  464. }
  465. return $data;
  466. }
  467. public static function getAddons(array $params){
  468. $is_install = MallAddons::isInstall($params['mall_id'], AgentEnum::ADDONS_NAME);
  469. if($is_install){
  470. $detail = Addons::getOne([['name' => AgentEnum::ADDONS_NAME], ['is_online' => 1]], true);
  471. return [
  472. 'addons_name'=>AgentEnum::ADDONS_NAME,
  473. 'title'=>$detail['title'],
  474. ];
  475. }
  476. return [];
  477. }
  478. public static function getDeductMoney($params){
  479. if(empty($params['mall_id'])||empty($params['user_id'])||empty($params['type'])) return $params;
  480. $agent = Agent::findOne(['user_id'=>$params['user_id'],'status'=>StatusEnum::ENABLED]);
  481. $user_id = $params['user_id'];
  482. $mall_id = $params['mall_id'];
  483. $type = $params['type'];
  484. if(empty($agent)){
  485. if(!empty($params['goods_list'])) return $params;
  486. return $params;
  487. }
  488. $setting = \Yii::$app->services->setting->addons->get($mall_id, \common\enums\AddonsEnum::ADDONS_NAME_AGENT, 'basic');
  489. if (empty($setting['is_self_buy']) || empty($setting['enable_goods_deduct'])) {
  490. return $params;
  491. }
  492. switch ($type){
  493. case 'goods':
  494. $goods_ids = array_column( $params['goods_list'],'id');
  495. $item_setting_List = AgentCommissionItemSetting::find()->select('item_id,is_participate')
  496. ->where(['item_id' => $goods_ids, 'status' => StatusEnum::ENABLED])
  497. ->indexBy('item_id')
  498. ->asArray()->all();
  499. foreach ($goods_ids as $k=>$goods_id){
  500. if(isset($item_setting_List[$goods_id])&&empty($item_setting_List[$goods_id]['is_participate'])){
  501. unset($goods_ids[$k]);
  502. }
  503. }
  504. $attr_list = GoodsAttr::lists(['where'=>[['goods_id'=>$goods_ids],['status'=>StatusEnum::ENABLED]],'index'=>'goods_id']);
  505. $goods_attr_id_arr = [];
  506. $goods_attr_id_map = [];
  507. foreach ($attr_list as $value){
  508. $goods_attr_id_arr[$value['id']] = 1;
  509. $goods_attr_id_map[$value['goods_id']] =$value['id'] ;
  510. }
  511. $result = \common\logic\order\marketing\AgentMarketing::getDeductMoney($mall_id,$user_id,$goods_attr_id_arr);
  512. foreach ($params['goods_list'] as &$item){
  513. if(isset($goods_attr_id_map[$item['id']])){
  514. $attr_id =$goods_attr_id_map[$item['id']];
  515. if(isset($result[$attr_id])){
  516. $item['member_price']=bcadd($result[$attr_id],0,2);
  517. }else{
  518. $item['member_price'] = 0;
  519. }
  520. }
  521. }
  522. return $params;
  523. case 'goods_cate':
  524. foreach ($params['goods_list'] as &$item){
  525. if(!is_array($item)) continue;
  526. $goods_ids = array_column($item,'id');
  527. $item_setting_List = AgentCommissionItemSetting::find()->select('item_id,is_participate')
  528. ->where(['item_id' => $goods_ids, 'status' => StatusEnum::ENABLED])
  529. ->indexBy('item_id')
  530. ->asArray()->all();
  531. foreach ($goods_ids as $k=>$goods_id){
  532. if(isset($item_setting_List[$goods_id])&&empty($item_setting_List[$goods_id]['is_participate'])){
  533. unset($goods_ids[$k]);
  534. }
  535. }
  536. $attr_list = GoodsAttr::lists(['where'=>[['goods_id'=>$goods_ids],['status'=>StatusEnum::ENABLED]],'index'=>'goods_id']);
  537. $goods_attr_id_arr = [];
  538. $goods_attr_id_map = [];
  539. foreach ($attr_list as $value){
  540. $goods_attr_id_arr[$value['id']] = 1;
  541. $goods_attr_id_map[$value['goods_id']] =$value['id'] ;
  542. }
  543. $result = \common\logic\order\marketing\AgentMarketing::getDeductMoney($mall_id,$user_id,$goods_attr_id_arr);
  544. foreach ($item as &$val){
  545. if(isset($goods_attr_id_map[$val['id']])){
  546. $attr_id =$goods_attr_id_map[$val['id']];
  547. if(isset($result[$attr_id])){
  548. $val['member_price']=bcadd($result[$attr_id],0,2);
  549. }else{
  550. $val['member_price'] = 0;
  551. }
  552. }
  553. }
  554. }
  555. return $params;
  556. }
  557. }
  558. /**
  559. * 可供导出供应商库存的字段
  560. * @Author:hua
  561. * @Date:2024-02-23 16:37
  562. * @Copyright:copyright(c)2024 广东七件事集团
  563. * @return string[]
  564. */
  565. public static function getSupplierStockExportFieldsList()
  566. {
  567. return [
  568. 'user_id' => '代理ID',
  569. 'nickname' => '昵称',
  570. 'mobile' => '手机号',
  571. 'level' => '身份',
  572. 'stock' => '代理库存',
  573. 'cooperative_shipping_type' => '合作发货类型',
  574. 'counts' => '累计出货',
  575. 'change_num' => '当前收入',
  576. 'total_commission' => '累计收入',
  577. ];
  578. }
  579. /**
  580. * 导出供应商库存
  581. * @Author:hua
  582. * @Date:2024-02-23 16:38
  583. * @Copyright:copyright(c)2024 广东七件事集团
  584. * @param array $data
  585. * @return bool|void
  586. */
  587. public static function exportHandleSupplierStock(array $data)
  588. {
  589. $download_id = $data['download_id'] ?? 0;
  590. $download = Download::findOne(['id' => $download_id]);
  591. if ($download) {
  592. try {
  593. $params = json_decode($download->params, true);
  594. $filename = $download->name;
  595. $type = $download->type;
  596. $fields = $params['fields'];
  597. $fields_arr = self::getSupplierStockExportFieldsList();
  598. $have_select_field_arr = [];
  599. foreach ($fields as $value) {
  600. $have_select_field_arr[] = $fields_arr[$value];
  601. }
  602. $csv = new CsvTool();
  603. $csv->filename = $filename;
  604. $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type);
  605. $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC;
  606. $csv->header = $have_select_field_arr;
  607. $model = self::find();
  608. $model->where(['mall_id' => $params['mall_id']]);
  609. //拼接查询条件
  610. if (!empty($params['level'])) $model->andWhere(['=', 'level', $params['level']]);
  611. if (!empty($params['keyword'])) {
  612. $condition['where'] = [[
  613. 'or',
  614. ['=', 'id', $params['keyword']],
  615. ['like', 'username', $params['keyword']],
  616. ['like', 'nickname', $params['keyword']],
  617. ['like', 'mobile', $params['keyword']]
  618. ]];
  619. $user_list = User::lists($condition);
  620. $user_id_arr = array_column($user_list, 'id');
  621. $model->andWhere(['in', 'user_id', $user_id_arr]);
  622. }
  623. $model->with(['user']);
  624. //遍历组装数据
  625. $args = [];
  626. $args['where'] = [['mall_id' => $params['mall_id']], ['<>', 'status', StatusEnum::DELETE]];
  627. $args['select'] = 'id,level,name';
  628. $args['index'] = 'level';
  629. $level_list = AgentLevel::lists($args, true);
  630. foreach ($model->batch() as $list) {
  631. $user_id_arr = array_column($list,'user_id');
  632. $dsn = Yii::$app->db->dsn;
  633. $commission_log_list = $commission_log_count_list = [];
  634. if(strpos($dsn,'port=8066')===false){
  635. $commission_log_list = CommissionLog::lists([
  636. 'where'=>[
  637. ['user_id'=>$user_id_arr],
  638. ['from_type'=>'Agent']
  639. ],
  640. 'select'=>'sum(change_num) as change_num,user_id',
  641. 'group'=>'user_id',
  642. 'index'=>'user_id'
  643. ]);
  644. $commission_log_count_list = CommissionLog::lists([
  645. 'where'=>[
  646. ['user_id'=>$user_id_arr],
  647. ['from_type'=>'Agent']
  648. ],
  649. 'select'=>'count(*) counts,user_id',
  650. 'group'=>'user_id',
  651. 'index'=>'user_id'
  652. ]);
  653. }
  654. $csv->data = array_map(function ($agent) use ($fields, $level_list,$dsn,$commission_log_list,$commission_log_count_list) {
  655. $row = [];
  656. //遍历所选字段
  657. foreach ($fields as $field) {
  658. if (in_array($field, ['pay_time'])) {
  659. $row[] = !empty($agent[$field]) ? date('Y-m-d H:i:s', $agent[$field]) : '';
  660. } elseif (in_array($field, ['nickname'])) {
  661. $row[] = !empty($agent['user']['nickname']) ? $agent['user']['nickname'] : '';
  662. } elseif (in_array($field, ['mobile'])) {
  663. $row[] = !empty($agent['user']['mobile']) ? $agent['user']['mobile'] : '';
  664. } elseif (in_array($field, ['level'])) {
  665. if (isset($level_list[$agent['level']])) {
  666. $row[] = $level_list[$agent['level']]['name'];
  667. } else {
  668. $row[] = '普通会员';
  669. }
  670. } elseif (in_array($field, ['stock'])) {
  671. $row[] = '0件';
  672. } elseif (in_array($field, ['cooperative_shipping_type'])) {
  673. $row[] = '平台代发';
  674. } elseif (in_array($field, ['counts'])) {
  675. if(strpos($dsn,'port=8066')===false){
  676. if (isset($commission_log_count_list[$v['user_id']])) {
  677. $row[] = '¥'.$commission_log_count_list[$agent['user_id']]['counts'];
  678. } else {
  679. $row[] = '¥0';
  680. }
  681. }else{
  682. $counts = CommissionLog::find()->where(['user_id'=>$agent['user_id'],'from_type'=>'Agent'])->count();
  683. if(!empty($counts)) {
  684. $row[] = $counts;
  685. } else {
  686. $row[] = '¥0';
  687. }
  688. }
  689. } elseif (in_array($field, ['change_num'])) {
  690. if(strpos($dsn,'port=8066')===false) {
  691. if (isset($commission_log_list[$v['user_id']])) {
  692. $row[] = '¥'.$commission_log_list[$agent['user_id']]['change_num'];
  693. }else{
  694. $row[] = '¥0';
  695. }
  696. }else{
  697. $change_num = CommissionLog::find()->where(['user_id'=>$agent['user_id'],'from_type'=>'Agent'])->sum('change_num');
  698. if(!empty($change_num)) {
  699. $row[] = '¥'.$change_num;
  700. } else {
  701. $row[] = '¥0';
  702. }
  703. }
  704. } elseif (in_array($field, ['total_commission'])) {
  705. if(!empty($agent[$field])&&$agent[$field]!='0.00') {
  706. $row[] = '¥'.$agent[$field];
  707. }else{
  708. $row[] = '¥0';
  709. }
  710. } else {
  711. $row[] = !empty($agent[$field]) ? $agent[$field] : '';
  712. }
  713. }
  714. return $row;
  715. }, $list);
  716. $csv->export();
  717. }
  718. $csv->updateDown($download, $params['mall_id']);
  719. return true;
  720. } catch (\Exception $e) {
  721. $download->status = 3;
  722. $res = $download->save();
  723. self::setStaticError($e->getMessage());
  724. return false;
  725. }
  726. }
  727. }
  728. /**
  729. * 获取升级条件包含自身
  730. * @param $mall_id
  731. * @param $user_id
  732. * @return bool
  733. */
  734. public static function getUpgradeContainSelf($mall_id,$user_id)
  735. {
  736. $contain_self = true;
  737. $more_setting = \Yii::$app->services->setting->addons->get($mall_id, AddonsEnum::ADDONS_NAME_AGENT, 'more');
  738. $is_apply = $more_setting['is_apply'] ?? 0;
  739. if($is_apply){
  740. $agent_user = Agent::findOne(['user_id' => $user_id,'status' => StatusEnum::ENABLED]);
  741. $apply = AgentApply::findOne(['user_id' => $user_id,'status' => StatusEnum::ENABLED,'check_status' => AgentApply::CHECK_STATUS_SUCCESS]);
  742. if(!$agent_user && !$apply){
  743. $contain_self = false;
  744. }
  745. }
  746. return $contain_self;
  747. }
  748. /**
  749. * 批量更新代理等级
  750. * @param $params
  751. * @return array|bool
  752. */
  753. public static function importLevel($params)
  754. {
  755. $t = \Yii::$app->db->beginTransaction();
  756. try {
  757. self::isCanImport($params['mall_id']);
  758. $csvImport = new CsvImportForm();
  759. $data = $csvImport->setDataForm($params)
  760. ->setMaxCount(self::$max_count)
  761. ->setImportFieldConfig(self::$head_list)
  762. ->setColumnNum(self::$column_num)
  763. ->readCsvData();
  764. if (!$data) throw new \Exception(CsvImportForm::getStaticError());
  765. $success_counts = $fail_counts = 0;
  766. $counts = count($data);
  767. $fail_arr = [];
  768. $success_user_id_arr = [];
  769. $merge_arr = [];
  770. foreach ($data as $item) {
  771. $param = $item;
  772. $merge_arr[] = $param;
  773. }
  774. self::batchUpdateLevel($params['mall_id'], $merge_arr, $success_counts, $fail_arr, $fail_counts, $success_user_id_arr);
  775. $param['counts'] = $counts;
  776. $param['success_counts'] = $success_counts;
  777. $param['fail_counts'] = $fail_counts;
  778. $param['status'] = 1;
  779. $param['mall_id']=$params['mall_id'];
  780. $import_log_model = AgentImportLevelLog::setData($param);
  781. if (!$import_log_model) throw new \Exception(AgentImportLevelLog::getStaticError());
  782. if (!empty($fail_arr)) {
  783. $res = AgentImportLevelFailLog::setData($fail_arr, $import_log_model->id);
  784. if (!$res) throw new \Exception(AgentImportLevelFailLog::getStaticError());
  785. }
  786. $t->commit();
  787. return ['counts' => $counts, 'success_counts' => $success_counts, 'fail_counts' => $fail_counts];
  788. } catch (\Exception $e) {
  789. var_dump($e->getMessage().$e->getFile());
  790. self::$static_error = $e->getMessage();
  791. $t->rollBack();
  792. return false;
  793. }
  794. }
  795. public static function importLevelSync($params)
  796. {
  797. $t = \Yii::$app->db->beginTransaction();
  798. try {
  799. self::isCanImport($params['mall_id']);
  800. $basePath = \Yii::$app->basePath;
  801. if (empty($_FILES) || !isset($_FILES['file'])) throw new \Exception('请上传csv文件');
  802. $fileName = $_FILES['file']['name'];
  803. $tmpName = $_FILES['file']['tmp_name'];
  804. $basePath = $basePath . '/web/uploads/';
  805. if (!is_dir($basePath))mkdir($basePath, 0775, true);
  806. $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
  807. if ($ext != 'csv') throw new \Exception('请上传csv文件');
  808. $uploadFile = $basePath . 'ADMIN-' . date('Y-m-d His') . '.' . $ext;
  809. //上传
  810. move_uploaded_file($tmpName, $uploadFile);
  811. $success_counts = $fail_counts = 0;
  812. $counts = 0;
  813. $param['counts'] = $counts;
  814. $param['success_counts'] = $success_counts;
  815. $param['fail_counts'] = $fail_counts;
  816. $param['upload_file'] = $uploadFile;
  817. $param['mall_id'] = $params['mall_id'];
  818. $user_import_log_model = AgentImportLevelLog::setData($param);
  819. if (!$user_import_log_model) throw new \Exception(AgentImportLevelLog::getStaticError());
  820. $t->commit();
  821. $params = ['id'=>$user_import_log_model['id']];
  822. \Yii::$app->services->rabbitMq->push(RabbitMqEnum::TASK_QUEUE, RabbitMqEnum::TASK_QUEUE, $params, self::class, 'syncImportLevel');
  823. return ['counts' => $counts, 'success_counts' => $success_counts, 'fail_counts' => $fail_counts];
  824. } catch (\Exception $e) {
  825. self::$static_error = $e->getMessage();
  826. var_dump($e->getMessage());
  827. $t->rollBack();
  828. return false;
  829. }
  830. }
  831. public static function isCanImport($mall_id){
  832. $time = strtotime('2024-04-28 23:59:59');
  833. $res = AgentImportLevelLog::find()->where(['mall_id'=>$mall_id,'status'=>3])->andWhere(['>=','created_at',$time])->one();
  834. if(!empty($res)) throw new \Exception('等上一次导入执行完再导入');
  835. }
  836. //异步执行
  837. public static function syncImportLevel($params){
  838. if(empty($params['id'])) return false;
  839. $model = AgentImportLevelLog::findOne(['id' => $params['id']]);
  840. if (!empty($model['upload_file'])) {
  841. $upload_file = $model['upload_file'];
  842. $mall_id = $model['mall_id'];
  843. $cvsFile = fopen($upload_file, 'r'); //开始读取csv文件数据
  844. $fail_arr = [];
  845. $success_counts = $fail_counts =$counts = $i = 0;
  846. $counts = 0;
  847. $success_user_id_arr = [];
  848. $data = [];// 初始化数据
  849. while ($fileData = fgetcsv($cvsFile)) {
  850. $i++;
  851. if ($i == 1) continue;//过滤表头
  852. $counts++;
  853. $mobile=0;
  854. $level_id=0;
  855. foreach ($fileData as $k => &$val) {
  856. $val = mb_convert_encoding(trim($val), "UTF-8", "GBK");
  857. switch ($k) {
  858. case 1:
  859. $mobile = !empty($val)?$val:'';
  860. break;
  861. case 2:
  862. $level_id = !empty($val)?trim($val):0;
  863. break;
  864. }
  865. }
  866. $param['mobile'] = $mobile;
  867. $param['level'] = $level_id;
  868. $data[] = $param;
  869. }
  870. self::batchUpdateLevel($mall_id, $data, $success_counts, $fail_arr, $fail_counts);
  871. $model->counts = $counts;
  872. $model->success_counts = $success_counts;
  873. $model->fail_counts = $fail_counts;
  874. $model->status = 1;
  875. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  876. if (!empty($fail_arr)) {
  877. $res = AgentImportLevelFailLog::setData($fail_arr, $model->id);
  878. if (!$res) throw new \Exception(AgentImportLevelFailLog::getStaticError());
  879. }
  880. }
  881. }
  882. /**
  883. * 批量更新等级
  884. * @Author: zfh
  885. * @DateTime: 2024/4/28 0003 15:16
  886. * @Copyright: copyright (c) 2021 广东七件事集团
  887. * @param $mall_id
  888. * @param $data
  889. * @param int $success_counts
  890. * @param array $fail_arr
  891. * @param int $fail_counts
  892. * @throws Exception
  893. */
  894. public static function batchUpdateLevel($mall_id, $data, &$success_counts = 0, &$fail_arr = [], &$fail_counts = 0, &$success_user_id_arr = [])
  895. {
  896. foreach ($data as $item) {
  897. $fail_params = $item;
  898. $fail_params['maill_id']=$mall_id;
  899. $where = [];
  900. $where[] = ['mall_id' => $mall_id];
  901. $where[] = ['mobile' => $item['mobile']];
  902. $user = User::getUser($where,'id,mobile');
  903. if (empty($user)) {
  904. $fail_params['reason'] = '用户不存在';
  905. list($fail_arr, $fail_counts) = AgentImportLevelFailLog::packFailArr($fail_params, $fail_arr, $fail_counts);
  906. } else if (empty(AgentLevel::getOne([['level' => $item['level'],'status'=>1,'mall_id'=>$mall_id]]))) {
  907. $fail_params['reason'] = '经销商等级id不存在';
  908. list($fail_arr, $fail_counts) = AgentImportLevelFailLog::packFailArr($fail_params, $fail_arr, $fail_counts);
  909. } else {
  910. $agent = Agent::getOne([['user_id' => $user['id'], 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]]); //加上条件:状态= 1[启用] && 0[禁用]
  911. if ($agent) {
  912. $item['id'] = $agent['id'];
  913. }
  914. $item['mall_id']=$mall_id;
  915. $item['user_id']=$user['id'];
  916. $item['upgrade_level_at']=time();
  917. $item['upgrade_status']=AgentEnum::UPGRADE_STATUS_MANUAL;
  918. $res = Agent::setData($item);
  919. if ($res) {
  920. $success_user_id_arr[] = $res['id'];
  921. $success_counts++;
  922. } else {
  923. $fail_params['reason'] = Agent::getStaticError();
  924. list($fail_arr, $fail_counts) = AgentImportLevelFailLog::packFailArr($fail_params, $fail_arr, $fail_counts);
  925. }
  926. }
  927. }
  928. }
  929. }