AreaAgent.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. <?php
  2. namespace addons\Area\common\models;
  3. use addons\Area\common\enums\AreaEnum;
  4. use common\enums\StatusEnum;
  5. use common\enums\UserWalletEnum;
  6. use common\helpers\FormatHelper;
  7. use common\models\base\BaseActiveRecord;
  8. use common\models\common\Addons;
  9. use common\models\common\Region;
  10. use common\models\mall\MallAddons;
  11. use common\models\order\OrderDetail;
  12. use common\models\user\Town;
  13. use common\models\user\User;
  14. use Exception;
  15. use services\common\UserWalletService;
  16. use Yii;
  17. use yii\db\Expression;
  18. /**
  19. * This is the model class for table "qimall_addons_area_agent".
  20. *
  21. * @property int $id
  22. * @property int $mall_id 商城id
  23. * @property int $user_id 会员id
  24. * @property string $realname 代理真实姓名
  25. * @property string $mobile 代理联系方式
  26. * @property float $total_commission 累计佣金
  27. * @property int $level 0普通用户 4、镇代 3、区代 2、市代 1、省代
  28. * @property int $regional_id 大区id
  29. * @property int $province_id 省id
  30. * @property int $city_id 市id
  31. * @property int $district_id 区id
  32. * @property int $town_id 镇id
  33. * @property int $community_id 小区id
  34. * @property string $address 省市区镇地址名称
  35. * @property string|null $remarks 备注
  36. * @property int $status 状态[-1:删除;0:禁用;1启用]
  37. * @property int $created_at 创建时间
  38. * @property int $updated_at 修改时间
  39. * @property int $is_enable_dividend 修改时间
  40. * @property float $total_digital 累计数字币
  41. */
  42. class AreaAgent extends BaseActiveRecord
  43. {
  44. const LEVEL_FIELD_MAP = [
  45. AreaEnum::PROVINCE => 'province_id',
  46. AreaEnum::CITY => 'city_id',
  47. AreaEnum::DISTRICT => 'district_id',
  48. AreaEnum::TOWN => 'town_id',
  49. AreaEnum::COMMUNITY => 'community_id',
  50. AreaEnum::REGIONAL => 'regional_id',
  51. ];
  52. /**
  53. * {@inheritdoc}
  54. */
  55. public static function tableName()
  56. {
  57. return '{{%addons_area_agent}}';
  58. }
  59. /**
  60. * {@inheritdoc}
  61. */
  62. public function rules()
  63. {
  64. return [
  65. [['mall_id', 'user_id', 'level', 'regional_id', 'province_id', 'city_id', 'district_id', 'town_id',
  66. 'status', 'created_at', 'updated_at', 'community_id', 'is_enable_dividend'], 'integer'],
  67. [['total_commission'], 'number'],
  68. [['remarks'], 'string'],
  69. [['address', 'realname', 'mobile'], 'string', 'max' => 255],
  70. [['total_digital'],'number']
  71. ];
  72. }
  73. /**
  74. * {@inheritdoc}
  75. */
  76. public function attributeLabels()
  77. {
  78. return [
  79. 'id' => 'ID',
  80. 'mall_id' => '商城id',
  81. 'user_id' => '会员id',
  82. 'realname' => '代理真实姓名',
  83. 'mobile' => '代理联系方式',
  84. 'total_commission' => '累计佣金',
  85. 'level' => '0普通用户 4、镇代 3、区代 2、市代 1、省代',
  86. 'regional_id' => '大区id',
  87. 'province_id' => '省id',
  88. 'city_id' => '市id',
  89. 'district_id' => '区id',
  90. 'town_id' => '镇id',
  91. 'address' => '省市区镇地址名称',
  92. 'remarks' => '备注',
  93. 'status' => '状态[-1:删除;0:禁用;1启用]',
  94. 'created_at' => '创建时间',
  95. 'updated_at' => '修改时间',
  96. ];
  97. }
  98. /**
  99. * @desc:关联会员信息
  100. * @Author: hua
  101. * @Date: 2022/1/18
  102. * @Time: 17:25
  103. * @Copyright: copyright (c) 2021 广东七件事集团
  104. * @return \yii\db\ActiveQuery
  105. */
  106. public function getUser(): \yii\db\ActiveQuery
  107. {
  108. return $this->hasOne(User::class, ['id' => 'user_id']);
  109. }
  110. public function getGoods()
  111. {
  112. return $this->hasMany(AreaGoods::class, ['agent_id' => 'id'])
  113. ->where(['status' => StatusEnum::ENABLED]);
  114. }
  115. public static function getAreaAgentByLevel($level, $address_id, $mall_id): array
  116. {
  117. $query = self::find()->innerJoinWith(['user'], false)->where(['qimall_addons_area_agent.mall_id' => $mall_id, 'qimall_addons_area_agent.level' => $level, 'qimall_addons_area_agent.status' => StatusEnum::ENABLED]);
  118. switch ($level) {
  119. case AreaEnum::COMMUNITY:
  120. $query->andWhere(['community_id' => $address_id]);
  121. break;
  122. case AreaEnum::TOWN:
  123. $query->andWhere(['town_id' => $address_id]);
  124. break;
  125. case AreaEnum::DISTRICT:
  126. $query->andWhere(['district_id' => $address_id]);
  127. break;
  128. case AreaEnum::CITY:
  129. $query->andWhere(['city_id' => $address_id]);
  130. break;
  131. case AreaEnum::PROVINCE:
  132. $query->andWhere(['province_id' => $address_id]);
  133. break;
  134. case AreaEnum::REGIONAL:
  135. $query->andWhere(['regional_id' => $address_id]);
  136. break;
  137. }
  138. return $query->all();
  139. }
  140. public static function getAreaAgentOneByLevel($user_id,$level, $address_id, $mall_id)
  141. {
  142. $query = self::find()->where(['mall_id' => $mall_id, 'user_id'=>$user_id,'level' => $level, 'status' => StatusEnum::ENABLED]);
  143. switch ($level) {
  144. case AreaEnum::COMMUNITY:
  145. $query->andWhere(['community_id' => $address_id]);
  146. break;
  147. case AreaEnum::TOWN:
  148. $query->andWhere(['town_id' => $address_id]);
  149. break;
  150. case AreaEnum::DISTRICT:
  151. $query->andWhere(['district_id' => $address_id]);
  152. break;
  153. case AreaEnum::CITY:
  154. $query->andWhere(['city_id' => $address_id]);
  155. break;
  156. case AreaEnum::PROVINCE:
  157. $query->andWhere(['province_id' => $address_id]);
  158. break;
  159. case AreaEnum::REGIONAL:
  160. $query->andWhere(['regional_id' => $address_id]);
  161. break;
  162. }
  163. return $query->one();
  164. }
  165. public static function setData(array $params)
  166. {
  167. $t = \Yii::$app->db->beginTransaction();
  168. try {
  169. $is_edit = false;
  170. if (!empty($params['id'])) {
  171. $model = self::findOne(['mall_id' => $params['mall_id'], 'id' => $params['id'], 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]);
  172. if (empty($model)) throw new Exception('服务不存在或已删除');
  173. $is_edit = true;
  174. } else {
  175. $model = new self();
  176. $model->loadDefaultValues();
  177. $params['is_enable_dividend'] = StatusEnum::DISABLED;
  178. }
  179. switch ($params['level']) {
  180. case AreaEnum::PROVINCE:
  181. $field = 'province_id';
  182. $value = $params['province_id'];
  183. break;
  184. case AreaEnum::CITY:
  185. $field = 'city_id';
  186. $value = $params['city_id'];
  187. break;
  188. case AreaEnum::DISTRICT:
  189. $field = 'district_id';
  190. $value = $params['district_id'];
  191. break;
  192. case AreaEnum::TOWN:
  193. $field = 'town_id';
  194. $value = $params['town_id'];
  195. break;
  196. case AreaEnum::COMMUNITY:
  197. $field = 'community_id';
  198. $value = $params['community_id'];
  199. break;
  200. case AreaEnum::REGIONAL:
  201. $field = 'regional_id';
  202. $value = $params['regional_id'];
  203. break;
  204. default:
  205. throw new Exception('请选择区域');
  206. }
  207. if (!$is_edit) {
  208. $area_agent = AreaAgent::findOne([
  209. 'user_id' => $params['user_id'],
  210. 'mall_id' => $params['mall_id'],
  211. $field => $value,
  212. 'level' => $params['level'],
  213. 'status' => StatusEnum::ENABLED,
  214. ]);
  215. if (!empty($area_agent)) throw new Exception('该会员已经是该地区区域代理');
  216. }
  217. $config = \Yii::$app->services->setting->addons->get($params['mall_id'], AreaEnum::ADDONS_NAME, 'basic');
  218. if(empty($params['id'])){
  219. $counts = AreaAgent::find()->where(['user_id' => $params['user_id'], 'mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED])->count();
  220. if (!empty($config['can_apply_area_num']) && $config['can_apply_area_num'] != -1 && $counts >= $config['can_apply_area_num']) throw new Exception('超出可申请最大数量');
  221. }
  222. $region_id_arr = [];
  223. if (!empty($params['province_id'])) $region_id_arr[] = $params['province_id'];
  224. if (!empty($params['city_id'])) $region_id_arr[] = $params['city_id'];
  225. if (!empty($params['district_id'])) $region_id_arr[] = $params['district_id'];
  226. $address = '';
  227. if ($params['level'] == AreaEnum::REGIONAL && !empty($params['regional_id'])) {
  228. $regional_name = AreaRegional::find()->where(['id' => $params['regional_id']])->select('regional_name')->scalar();
  229. !empty($regional_name) && $address .= $regional_name;
  230. }
  231. if (!empty($region_id_arr)) {
  232. $region_list = Region::lists(['where' => [['id' => $region_id_arr]], 'select' => 'id,name', 'order' => 'id asc']);
  233. foreach ($region_list as $item) {
  234. $address .= $item['name'];
  235. }
  236. if (!empty($params['town_id'])) {
  237. $town = Town::getOne([['id' => $params['town_id']]], true, [], false, 'id,name');
  238. if (!empty($town['name'])) $address .= $town['name'];
  239. }
  240. if (!empty($params['community_id'])) {
  241. $community = AreaCommunity::find()->where(['id' => $params['community_id']])->select('community_name')->scalar();
  242. if ($community) $address .= $community;
  243. }
  244. }
  245. if (!empty($address)) $params['address'] = $address;
  246. //对身份为区代的用户修改身份时,查询区代身份是否为购买,是则需要退回金额
  247. if (!empty($params['id']) && $model['level'] == 3) {
  248. $order_data = AreaOrder::getOne([
  249. ['mall_id' => $model['mall_id']],
  250. ['user_id' => $model['user_id']],
  251. ['area_id' => $model['district_id']],
  252. ['status' => StatusEnum::ENABLED],
  253. ['is_pay' => StatusEnum::ENABLED],
  254. ]);
  255. if (!empty($order_data)) {
  256. $insert_wallet[] = [
  257. 'mall_id' => $order_data->mall_id,
  258. 'user_id' => $order_data->user_id,
  259. 'is_frozen' => false,
  260. 'wallet_type' => 'balance',
  261. 'money' => $order_data->price, //转入金额
  262. 'desc' => '代理身份被修改,退回金额',
  263. 'source_table' => 'addons_area_order',
  264. 'source_table_id' => $order_data->id,//结算周期id
  265. 'from_type' => UserWalletEnum::REFUND,
  266. 'capital_type' => UserWalletEnum::AREA_BONUS_REFUND,
  267. // 'not_add_total' => true,
  268. ];
  269. $order_data->status = StatusEnum::DELETE;
  270. }
  271. }
  272. if (!$model->load($params, '')) throw new Exception($model->getErrorMessage());
  273. if (!$model->save()) throw new Exception($model->getErrorMessage());
  274. //维护订单数据,和审核记录
  275. if (!empty($order_data)) {
  276. $order_data->save();
  277. AreaApply::updateAll(['is_refund' => 1, 'refund_time' => time(), 'refund_remark' => '代理身份被删除'], ['mall_id' => $order_data['mall_id'], 'order_id' => $order_data['id']]);
  278. if (!empty($insert_wallet)) {
  279. UserWalletService::batchHandleByQueue($insert_wallet);
  280. }
  281. }
  282. if (!empty($params['goods'])) { // 提交了商品
  283. // 删除之前旧的商品
  284. AreaGoods::batchSave($params['mall_id'], $params['user_id'], $model->id, $params['goods']);
  285. }
  286. $t->commit();
  287. return $model;
  288. } catch (Exception $e) {
  289. $t->rollBack();
  290. self::$static_error = $e->getMessage();
  291. return false;
  292. }
  293. }
  294. public static function getRegionList($parent_id, $mall_id, $level_id_arr)
  295. {
  296. $list = Region::lists(['where' => [['parent_id' => $parent_id]], 'select' => 'id,level,name,parent_id']);
  297. $id_arr = [];
  298. $level = '';
  299. if (!empty($list)) {
  300. foreach ($list as $val) {
  301. $id_arr[] = $val['id'];
  302. $level = $val['level'];
  303. }
  304. $index = $level_id_arr[$level];
  305. $area_agent_list = AreaAgent::lists([
  306. 'where' => [
  307. [$index => $id_arr],
  308. ['level' => $level],
  309. ['mall_id' => $mall_id],
  310. ['status' => StatusEnum::ENABLED]
  311. ],
  312. 'select' => 'id,user_id,' . $index,
  313. 'with' => ['user' => function ($query) {
  314. $query->select('id,nickname,avatar_url');
  315. }],
  316. 'index' => $index
  317. ]);
  318. foreach ($list as &$item) {
  319. $item['agent_list'] = [];
  320. if (isset($area_agent_list[$item['id']])) $item['agent_list'][] = $area_agent_list[$item['id']];
  321. }
  322. }
  323. return $list;
  324. }
  325. public static function getDistrictList($params)
  326. {
  327. $level_arr = [AreaEnum::PROVINCE];
  328. if ($params['level'] == AreaEnum::CITY) $level_arr[] = AreaEnum::CITY;
  329. if (in_array($params['level'], [AreaEnum::DISTRICT, AreaEnum::TOWN])) {
  330. $level_arr[] = AreaEnum::CITY;
  331. $level_arr[] = AreaEnum::DISTRICT;
  332. }
  333. $where[] = ['level' => $level_arr];
  334. $list = Region::getRegionList($where, 'id,name,parent_id,level');
  335. if (in_array($params['level'], [AreaEnum::CITY, AreaEnum::DISTRICT, AreaEnum::TOWN])) {
  336. $tree = [];
  337. $level_arr = [];
  338. foreach ($list as $k => $item) {
  339. if ($item['level'] == AreaEnum::PROVINCE) $tree[] = $item;
  340. if (in_array($item['level'], [AreaEnum::CITY, AreaEnum::DISTRICT])) $level_arr[$item['parent_id']][] = $item;
  341. }
  342. foreach ($tree as &$province) {
  343. if (isset($level_arr[$province['id']])) {
  344. foreach ($level_arr[$province['id']] as &$city) {
  345. if (isset($level_arr[$city['id']])) $city['list'] = $level_arr[$city['id']];
  346. }
  347. $province['list'] = $level_arr[$province['id']];
  348. }
  349. }
  350. return $tree;
  351. } else {
  352. return $list;
  353. }
  354. }
  355. /**
  356. * @desc:推广中心-调用
  357. * @Author: hua
  358. * @Date: 2021/11/12
  359. * @Time: 9:30
  360. * @Copyright: copyright (c) 2021 广东七件事集团
  361. * @param array $params ['user_id' => 1, 'mall_id' => 5, 'addons_name' => 'Agent']
  362. * @return array
  363. */
  364. public static function getIncomeInfo(array $params)
  365. {
  366. $is_install = MallAddons::isInstall($params['mall_id'], $params['addons_name']);
  367. $data['total_commission'] = 0;
  368. $data['is_install'] = 0;
  369. $basic = \Yii::$app->services->setting->addons->get($params['mall_id'], $params['addons_name'], 'basic');
  370. $data['is_show_at_center'] = 1;
  371. if(isset($basic['is_show_at_center'])) $data['is_show_at_center'] = $basic['is_show_at_center'];
  372. if ($is_install) {
  373. $total_commission = self::find()->where(['user_id' => $params['user_id'],'status'=>StatusEnum::ENABLED])->sum('total_commission');
  374. $data['total_commission'] = $total_commission ?? 0;
  375. $data['is_install'] = $is_install;
  376. }
  377. return $data;
  378. }
  379. public static function getLevel($params){
  380. $config = \Yii::$app->services->setting->addons->get($params['mall_id'], AreaEnum::ADDONS_NAME, 'basic');
  381. return [
  382. ['level'=>6,'name'=> $config["level_6"] ?? '大区代'],
  383. ['level'=>1,'name'=> $config["level_1"] ?? '省代'],
  384. ['level'=>2,'name'=> $config["level_2"] ?? '市代'],
  385. ['level'=>3,'name'=> $config["level_3"] ?? '区代'],
  386. ['level'=>4,'name'=> $config["level_4"] ?? '镇代'],
  387. ['level'=>5,'name'=> $config["level_5"] ?? '小区代'],
  388. ];
  389. }
  390. public static function getAddons(array $params){
  391. $is_install = MallAddons::isInstall($params['mall_id'], AreaEnum::ADDONS_NAME);
  392. if($is_install){
  393. $detail = Addons::getOne([['name' => AreaEnum::ADDONS_NAME], ['is_online' => 1]], true);
  394. return [
  395. 'addons_name'=>AreaEnum::ADDONS_NAME,
  396. 'title'=>$detail['title'],
  397. ];
  398. }
  399. return [];
  400. }
  401. /**
  402. * 订单退款维护数据表统计字段(外部开事务)
  403. *
  404. * @param $wallet_type
  405. * @param $order_detail_id
  406. *
  407. * @return bool
  408. */
  409. public static function orderRefundUpdateTotalFields($wallet_type, $order_detail_id): bool
  410. {
  411. if (empty($order_detail_id) || empty($wallet_type)) {
  412. return false;
  413. }
  414. $rewardLogs = AreaCumulativeRewardLog::lists([
  415. 'where' => [
  416. [
  417. 'is_return' => StatusEnum::DISABLED,
  418. 'source_table' => 'order_detail',
  419. 'source_table_id' => $order_detail_id,
  420. 'status' => StatusEnum::ENABLED,
  421. 'wallet_type' => $wallet_type
  422. ]
  423. ],
  424. 'select' => 'agent_id, change_num, id'
  425. ]);
  426. if (empty($rewardLogs)) {
  427. return false;
  428. }
  429. $now = time();
  430. foreach ($rewardLogs as $rewardLog) {
  431. $field = 'total_' . $wallet_type;
  432. self::updateAll(
  433. [
  434. $field => new Expression("`{$field}` - {$rewardLog['change_num']}"),
  435. 'updated_at' => $now,
  436. ],
  437. [
  438. 'id' => $rewardLog['agent_id']
  439. ]
  440. );
  441. }
  442. AreaCumulativeRewardLog::updateAll(
  443. [
  444. 'is_return' => StatusEnum::ENABLED,
  445. 'updated_at' => $now
  446. ],
  447. [
  448. 'id' => array_column($rewardLogs, 'id')
  449. ]
  450. );
  451. return true;
  452. }
  453. /**
  454. * 订单退款维护数据表统计字段(旧方法,为了公用,迁移到这里)
  455. *
  456. * @return bool
  457. */
  458. public static function orderRefundUpdateTotalFieldsOld($commission_list,$wallet_type,$order_detail_id, $order = null)
  459. {
  460. if (empty($order)) {
  461. $orderDetail = OrderDetail::getOne([['id'=>$order_detail_id]],true,['order']);
  462. if(empty($orderDetail['order'])) return false;
  463. $order = $orderDetail['order'];
  464. }
  465. $province_id = $order['province'];
  466. $city_id = $order['city'];
  467. $area_id = $order['area'];
  468. $town_id = $order['town'];
  469. $community_id = $order['community'];
  470. $regional_id = 0; // 大区ID
  471. if (!empty($province_id)) {
  472. $like_conditions = ['%,'. $province_id, '%,'. $province_id. ',%', $province_id. ',%'];
  473. $regional = AreaRegional::getOne([['or like', 'province_ids', $like_conditions, false], ['status' => StatusEnum::ENABLED], ['mall_id' => $order['mall_id']]]);
  474. !empty($regional) && $regional_id = $regional['id'];
  475. }
  476. $user_ids = array_column($commission_list,'user_id');
  477. $area_agent_list = AreaAgent::lists([
  478. 'where'=>[
  479. ['user_id'=>$user_ids],
  480. ['status'=>[StatusEnum::ENABLED,StatusEnum::DISABLED]]
  481. ]],false);
  482. $area_agents = [];
  483. foreach ($area_agent_list as $val){
  484. $area_agents[$val['user_id']][]=$val;
  485. }
  486. foreach ($commission_list as $item) {
  487. if(!isset($area_agents[$item['user_id']])) continue;
  488. $area_agent_arr = $area_agents[$item['user_id']];
  489. foreach ($area_agent_arr as $area_agent){
  490. switch ($area_agent['level']){
  491. case 1:
  492. if($province_id==$area_agent['province_id']){
  493. $field = 'total_' . $wallet_type;
  494. $area_agent->$field += -$item['change_num'];
  495. if($area_agent->$field<0) $area_agent->$field = 0;
  496. $res = $area_agent->save();
  497. }
  498. break;
  499. case 2:
  500. if($city_id==$area_agent['city_id']){
  501. $field = 'total_' . $wallet_type;
  502. $area_agent->$field += -$item['change_num'];
  503. if($area_agent->$field<0) $area_agent->$field = 0;
  504. $res = $area_agent->save();
  505. }
  506. break;
  507. case 3:
  508. if($area_id==$area_agent['district_id']){
  509. $field = 'total_' . $wallet_type;
  510. $area_agent->$field += -$item['change_num'];
  511. if($area_agent->$field<0) $area_agent->$field = 0;
  512. $res = $area_agent->save();
  513. }
  514. break;
  515. case 4:
  516. if($town_id==$area_agent['town_id']){
  517. $field = 'total_' . $wallet_type;
  518. $area_agent->$field += -$item['change_num'];
  519. if($area_agent->$field<0) $area_agent->$field = 0;
  520. $res = $area_agent->save();
  521. }
  522. break;
  523. case 5:
  524. if($community_id==$area_agent['community_id']){
  525. $field = 'total_' . $wallet_type;
  526. $area_agent->$field += -$item['change_num'];
  527. if($area_agent->$field<0) $area_agent->$field = 0;
  528. $res = $area_agent->save();
  529. }
  530. break;
  531. case 6:
  532. if($regional_id == $area_agent['regional_id']){
  533. $field = 'total_' . $wallet_type;
  534. $area_agent->$field += -$item['change_num'];
  535. if($area_agent->$field<0) $area_agent->$field = 0;
  536. $res = $area_agent->save();
  537. }
  538. break;
  539. }
  540. }
  541. }
  542. return true;
  543. }
  544. }