AddonsCourse.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. <?php
  2. namespace addons\Course\common\models;
  3. use addons\Agent\common\models\AgentCommissionItemSetting;
  4. use addons\Agent\common\models\AgentCommissionItemSettingDetail;
  5. use addons\Agent\common\models\AgentLevel;
  6. use addons\Course\common\enums\CourseEnum;
  7. use addons\Distribution\common\models\DistributionCommissionItemSetting;
  8. use addons\Distribution\common\models\DistributionCommissionItemSettingDetail;
  9. use addons\Distribution\common\models\DistributionLevel;
  10. use common\enums\AddonsEnum;
  11. use common\enums\RedisKeyEnum;
  12. use common\enums\StatusEnum;
  13. use common\helpers\ArrayHelper;
  14. use common\helpers\LockHelper;
  15. use common\models\mall\MallAddons;
  16. use common\models\user\UserLevel;
  17. use Exception;
  18. use Yii;
  19. /**
  20. * This is the model class for table "{{%addons_course}}".
  21. *
  22. * @property int $id
  23. * @property int $mall_id 商城id
  24. * @property string $name 课程名称
  25. * @property int $cat_id 课程分类id
  26. * @property float $price 课程价格
  27. * @property float $line_off_price 划线价格
  28. * @property float $member_price 会员价格
  29. * @property string $logo 课程封面logo图片保存地址
  30. * @property string $allow_member_levels 指定会员观看,会员等级之间用逗号连接
  31. * @property int $can_download 是否允许下载 默认允许下载 1:是 0:否
  32. * @property int $can_comment 是否允许评论 默认允许评论 1:是 0:否
  33. * @property string $introduce 课程介绍
  34. * @property string $detail 课程详情
  35. * @property int $sales 课程销量
  36. * @property int $is_open_vm 是否开启虚拟数据 默认开启 1:开启 0:不开启
  37. * @property int $vm_likes 课程虚拟点赞数
  38. * @property int $vm_shares 课程虚拟分享数
  39. * @property int $vm_downloads 课程虚拟下载数
  40. * @property int $vm_views 课程虚拟播放次数
  41. * @property int $likes 课程实际点赞数
  42. * @property int $shares 课程实际分享数
  43. * @property int $downloads 课程实际下载数
  44. * @property int $views 课程实际播放次数
  45. * @property int $comments 课程实际评论数
  46. * @property int $sell_type 课程售卖方式,1:按照课程设置的售价付费观看,2:指定会员观看,3:免费,4:转发一定次数免费观看
  47. * @property int $relays 预设置转发次数,达到转发次数后可以免费观看
  48. * @property string $relay_customize_text 转发按钮自定义文字
  49. * @property int $relay_times 课程被所有的会员转发的总次数,在此做冗余
  50. * @property int $status 课程状态 默认是1(上架) 1:上架 0:下架,-1是删除
  51. * @property int $created_at 创建时间
  52. * @property int $updated_at 修改时间
  53. * @property int $sort 排序值,数值越大排的越前
  54. */
  55. class AddonsCourse extends \common\models\base\BaseActiveRecord
  56. {
  57. /**
  58. * {@inheritdoc}
  59. */
  60. public static function tableName()
  61. {
  62. return '{{%addons_course}}';
  63. }
  64. /**
  65. * {@inheritdoc}
  66. */
  67. public function rules()
  68. {
  69. return [
  70. [['mall_id', 'cat_id', 'sales', 'can_download', 'can_comment', 'is_open_vm', 'vm_likes', 'vm_shares', 'vm_downloads', 'vm_views', 'likes', 'shares', 'downloads', 'views', 'comments', 'sell_type', 'relays', 'relay_times', 'status', 'created_at', 'updated_at','sort'], 'integer'],
  71. [['price', 'line_off_price', 'member_price'], 'number'],
  72. [['detail'], 'string'],
  73. [['name'], 'string', 'max' => 50],
  74. [['logo'], 'string', 'max' => 255],
  75. [['allow_member_levels', 'introduce'], 'string', 'max' => 1000],
  76. [['relay_customize_text'], 'string', 'max' => 20],
  77. ];
  78. }
  79. /**
  80. * {@inheritdoc}
  81. */
  82. public function attributeLabels()
  83. {
  84. return [
  85. 'id' => 'ID',
  86. 'mall_id' => '商城id',
  87. 'name' => '课程名称',
  88. 'cat_id' => '课程分类id',
  89. 'price' => '课程价格',
  90. 'line_off_price' => '划线价格',
  91. 'member_price' => '会员价格',
  92. 'logo' => '课程封面logo图片保存地址',
  93. 'allow_member_levels' => '指定会员观看,会员等级之间用逗号连接',
  94. 'can_download' => '是否允许下载 默认允许下载 1:是 0:否',
  95. 'can_comment' => '是否允许评论 默认允许评论 1:是 0:否',
  96. 'introduce' => '课程介绍',
  97. 'detail' => '课程详情',
  98. 'sales' => '课程销量',
  99. 'is_open_vm' => '是否开启虚拟数据 默认开启 1:开启 0:不开启',
  100. 'vm_likes' => '课程虚拟点赞数',
  101. 'vm_shares' => '课程虚拟分享数',
  102. 'vm_downloads' => '课程虚拟下载数',
  103. 'vm_views' => '课程虚拟播放次数',
  104. 'likes' => '课程实际点赞数',
  105. 'shares' => '课程实际分享数',
  106. 'downloads' => '课程实际下载数',
  107. 'views' => '课程实际播放次数',
  108. 'comments' => '课程实际评论数',
  109. 'sell_type' => '课程售卖方式,1:按照课程设置的售价付费观看,2:指定会员观看,3:免费,4:转发一定次数免费观看',
  110. 'relays' => '预设置转发次数,达到转发次数后可以免费观看',
  111. 'relay_customize_text' => '转发按钮自定义文字',
  112. 'relay_times' => '课程被所有的会员转发的总次数,在此做冗余',
  113. 'status' => '课程状态 默认是1(上架) 1:上架 0:下架,-1是删除',
  114. 'created_at' => '创建时间',
  115. 'updated_at' => '修改时间',
  116. 'sort' => '排序值,数值越大排的越前',
  117. ];
  118. }
  119. public static function getCourseListWithMemberPrice($user, int $mall_id, $course_ids = null, array $andWhere = [], string $field = '', $limit = null, $order = null)
  120. {
  121. try {
  122. $where[] = ['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED];
  123. $select = 'id,name as course_name,logo,introduce,vm_views,views,vm_likes,likes,vm_shares,shares,vm_downloads,downloads,price,line_off_price,is_open_vm,can_download,can_comment';
  124. if (!empty($course_ids)) {
  125. $where[] = ['id' => $course_ids];
  126. }
  127. if (!empty($andWhere)) {
  128. $where[] = $andWhere;
  129. }
  130. if (!empty($field)) {
  131. if ('*' == $field) {
  132. $select = '*';
  133. } else {
  134. $select .= ',' . $field;
  135. }
  136. }
  137. $params = [
  138. 'select' => $select,
  139. 'order' => $order ?? 'sort desc,created_at desc',
  140. 'where' => $where,
  141. ];
  142. if (!empty($limit)) {
  143. $params['limit'] = $limit;
  144. }
  145. $list = self::listPage($params, false, true);
  146. if (empty($user)) {
  147. $discount = 1;
  148. } else {
  149. $discount = self::getCurrMemberDiscount($user, $mall_id);
  150. }
  151. if (!empty($list['list'])) {
  152. foreach ($list['list'] as $lk => &$lv) {
  153. if (isset($lv['is_open_vm']) && !empty($lv['is_open_vm'])) {
  154. $lv['likes'] += $lv['vm_likes'];
  155. $lv['shares'] += $lv['vm_shares'];
  156. $lv['downloads'] += $lv['vm_downloads'];
  157. $lv['views'] += $lv['vm_views'];
  158. }
  159. $list['list'][$lk]['member_price'] = bcmul($lv['price'], $discount, 2);
  160. $list['list'][$lk]['allow_member_levels'] = trim($lv['allow_member_levels'], ',');
  161. // $list['list'][$lk]['views'] = self::numberFormat($lv['views']);
  162. }
  163. }
  164. return $list;
  165. } catch (\Exception $e) {
  166. self::$static_error = $e->getMessage();
  167. return false;
  168. }
  169. }
  170. /**
  171. * @name:
  172. * @msg: 获取当前会员折扣
  173. * @param {*}
  174. * @return {*}
  175. */
  176. public static function getCurrMemberDiscount($user, $mall_id)
  177. {
  178. if ($user->level == 0) {
  179. $discount = 10;
  180. } else {
  181. $where[] = ['mall_id' => $mall_id];
  182. $where[] = ['level' => $user->level];
  183. $member_level_info = UserLevel::getUserLevelOne($where, [], 1);
  184. // 当前会员折扣
  185. $discount = $member_level_info['discount'];
  186. }
  187. $discount = $discount * 10 / 100;
  188. return $discount;
  189. }
  190. public static function setData(int $mall_id, array $data)
  191. {
  192. if (!empty($data['allow_member_levels']) && is_array($data['allow_member_levels'])) {
  193. $data['allow_member_levels'] = implode(',', array_keys(array_flip(array_filter($data['allow_member_levels']))));
  194. }
  195. if (!empty($data['id'])) {
  196. $model = self::findOne(['mall_id' => $mall_id, 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED], 'id' => $data['id']]);
  197. if (empty($model)) {
  198. self::$static_error = '数据异常';
  199. return false;
  200. }
  201. } else {
  202. $model = new self();
  203. $model->loadDefaultValues();
  204. $model->mall_id = $mall_id;
  205. $model->status = StatusEnum::ENABLED;
  206. }
  207. foreach ($data as $key => $val) {
  208. $model->$key = $val;
  209. }
  210. if (!$model->save()) {
  211. self::$static_error = '保存数据失败:' . $model->getErrorMessage();
  212. return false;
  213. }
  214. return $model;
  215. }
  216. /**
  217. * 获取课程详情
  218. *
  219. * @param int $id 课程ID
  220. * @return mixed | Yii\web\response
  221. */
  222. public static function getDetail(int $id, int $mall_id, string $field = '*', bool $as_array = false, $status = [StatusEnum::ENABLED])
  223. {
  224. $result = self::find()
  225. ->select($field)
  226. ->where(['id' => $id, 'status' => $status, 'mall_id' => $mall_id])
  227. ->asArray($as_array)
  228. ->one();
  229. if (empty($result)) {
  230. self::$static_error = '课程不存在';
  231. return false;
  232. }
  233. if (!empty($result) && !empty($result['is_open_vm'])) {
  234. $result['views'] = $result['views'] + $result['vm_views'];
  235. $result['downloads'] = $result['downloads'] + $result['vm_downloads'];
  236. $result['likes'] = $result['likes'] + $result['vm_likes'];
  237. $result['shares'] = $result['shares'] + $result['vm_shares'];
  238. }
  239. if (!empty($result['allow_member_levels'])) {
  240. $result['allow_member_levels'] = explode(',', $result['allow_member_levels']);
  241. } elseif ($result['allow_member_levels'] == 0) {
  242. $result['allow_member_levels'] = [0];
  243. }
  244. return $result;
  245. }
  246. /**
  247. * @name:
  248. * @msg: 检查某个用户是否可以播放课程
  249. * @param {int} $course_id 课程 id
  250. * @param {int} $mall_id 商城 id
  251. * @param {int} $user_id 用户 id
  252. * @return {array} is_can_play 1:可以播放,2:用户未购买课程,3:用户不在课程指定的会员等级内, 4:转发次数不够;
  253. */
  254. public static function courseCanPlay(int $course_id, int $mall_id, $user): array
  255. {
  256. $course = self::find()
  257. ->select('id,sell_type,allow_member_levels,relays')
  258. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $course_id])
  259. ->asArray()
  260. ->one();
  261. //后台发放课程(任何类型课程)后,用户可直接播放视频
  262. if (!empty($user)) {
  263. if (self::courseIsBought($course_id, $mall_id, $user['id'])) {
  264. $is_can_play = 1;
  265. $is_can_play = ['is_can_play' => 1, 'need_relays' => 0, 'current_user_relayed_times' => 0];
  266. return $is_can_play;
  267. }
  268. }
  269. switch ($course['sell_type']) {
  270. case CourseEnum::COURSE_SELL_TYPE_1:
  271. // 当前会员是否购买改课程
  272. if (empty($user)) {
  273. $is_can_play = 2;
  274. } else {
  275. if (self::courseIsBought($course_id, $mall_id, $user['id'])) {
  276. $is_can_play = 1;
  277. } else {
  278. $is_can_play = 2;
  279. }
  280. }
  281. $is_can_play = ['is_can_play' => $is_can_play];
  282. break;
  283. case CourseEnum::COURSE_SELL_TYPE_2:
  284. $level_arr = explode(',', $course['allow_member_levels']);
  285. if ($course['allow_member_levels'] == 0 && is_numeric($course['allow_member_levels'])) {
  286. // 全部会员可以看
  287. $is_can_play = 1;
  288. } elseif (!empty($level_arr[0]) && in_array($user['level'], $level_arr)) {
  289. // 当前会员在课程指定的会员等级内
  290. $is_can_play = 1;
  291. } else {
  292. // 课程未选择可以看的会员等级,所有会员不可以看;或者当前会员等级不在课程指定的会员等级内
  293. $is_can_play = 3;
  294. }
  295. $is_can_play = ['is_can_play' => $is_can_play];
  296. break;
  297. case CourseEnum::COURSE_SELL_TYPE_3:
  298. // 课程免费
  299. // $is_can_play = 1;
  300. $is_can_play = ['is_can_play' => 1];
  301. break;
  302. case CourseEnum::COURSE_SELL_TYPE_4:
  303. if (!empty($user)) {
  304. $current_user_relayed_times = AddonsCourseRelays::find()
  305. ->where(['mall_id' => $mall_id, 'user_id' => $user['id'], 'course_id' => $course_id])
  306. ->count();
  307. } else {
  308. $current_user_relayed_times = 0;
  309. }
  310. if ($current_user_relayed_times >= $course['relays']) {
  311. $is_can_play = 1;
  312. } else {
  313. $is_can_play = 4;
  314. }
  315. // 当前还需要转发的次数
  316. $need_relays = $course['relays'] - $current_user_relayed_times >= 0 ? $course['relays'] - $current_user_relayed_times : 0;
  317. $is_can_play = ['is_can_play' => $is_can_play, 'need_relays' => $need_relays, 'current_user_relayed_times' => $current_user_relayed_times];
  318. break;
  319. default:
  320. $is_can_play = ['is_can_play' => 2];
  321. break;
  322. }
  323. return $is_can_play;
  324. }
  325. /**
  326. * @name:
  327. * @msg: 检查某一个会员是否购买某一个课程
  328. * @param {int} $course_id 课程 id
  329. * @param {int} $user_id 用户 id
  330. * @param {int} $mall_id 商城 id
  331. * @return {int} $is_bought 1:用户已购买该课程,0: 用户未购买该课程
  332. */
  333. public static function courseIsBought(int $course_id, int $mall_id, int $user_id): int
  334. {
  335. $bought_info = AddonsCourseBought::findOne(['mall_id' => $mall_id, 'course_id' => $course_id, 'user_id' => $user_id, 'is_pay' => CourseEnum::IS_PAY_YES, 'status' => StatusEnum::ENABLED]);
  336. $is_bought = empty($bought_info) ? 0 : 1;
  337. return $is_bought;
  338. }
  339. /**
  340. * @name:
  341. * @msg: 获取课程列表,不获取课程的会员价信息
  342. * @param {int} $mall_id
  343. * @param {*} $ids
  344. * @param {string} $field
  345. * @return {*}
  346. */
  347. public static function getList(int $mall_id, $ids = null, string $field = 'id,name')
  348. {
  349. if (!empty($ids)) {
  350. $where = ['status' => StatusEnum::ENABLED, 'mall_id' => $mall_id, 'id' => $ids];
  351. } else {
  352. $where = ['status' => StatusEnum::ENABLED, 'mall_id' => $mall_id];
  353. }
  354. $list = self::find()
  355. ->select($field)
  356. ->where($where)
  357. ->asArray()
  358. ->all();
  359. return $list;
  360. }
  361. /**
  362. * 获取会员价
  363. *
  364. * @param array $user 会员信息
  365. * @param int $use_discount 使用折扣
  366. * @return float
  367. */
  368. public function getMemberPrice($user, &$use_discount = false)
  369. {
  370. $discount = self::getCurrMemberDiscount($user, $user['mall_id']);
  371. if ($discount == 1) {
  372. $use_discount = false;
  373. }
  374. return (float)$discount * $this->price;
  375. }
  376. /** Undocumented function
  377. * 维护课程销量
  378. * @param [type] $course_id
  379. * @param [type] $sales
  380. * @return bool
  381. */
  382. public static function updateSales($course_id, $sales)
  383. {
  384. $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_COURSE, $course_id);
  385. $identification = uniqid();
  386. try {
  387. if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new Exception('当前访问人数过多');
  388. $course = AddonsCourse::findOne(['id' => $course_id]);
  389. $course->sales += $sales;
  390. $course->save();
  391. LockHelper::uLock($lock_key, $identification);
  392. return true;
  393. } catch (Exception $e) {
  394. LockHelper::uLock($lock_key, $identification);
  395. if (isset($trans)) $trans->rollback();
  396. self::$static_error = $e->getMessage();
  397. return false;
  398. }
  399. }
  400. /**
  401. * @name:
  402. * @msg: 获取经销设置
  403. * @param {int} $mall_id
  404. * @param {int} $course_id
  405. * @return {*}
  406. */
  407. public static function getAgentConfig(int $mall_id, int $course_id) : array
  408. {
  409. $addons_name = AddonsEnum::ADDONS_NAME_AGENT;
  410. $is_install = MallAddons::isInstall($mall_id, $addons_name);
  411. if (!$is_install) {
  412. $agent_enable = 0;
  413. $item_setting = [];
  414. $agent_levels = [];
  415. $agent_details = [];
  416. $agent_config = compact('agent_enable', 'item_setting', 'agent_levels', 'agent_details');
  417. } else {
  418. $agent_enable = 1;
  419. $item_setting = AgentCommissionItemSetting::find()
  420. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $course_id, 'item_type' => CourseEnum::ADDONS_NAME, 'commission_type' => 'commission'])
  421. ->one();
  422. if (!empty($item_setting)) {
  423. $agent_details = array_values(ArrayHelper::toArray($item_setting->detail));
  424. $item_setting = ArrayHelper::toArray($item_setting);
  425. } else {
  426. $item_setting = [];
  427. $agent_details = [];
  428. }
  429. $agent_levels = AgentLevel::find()
  430. ->select('id,name,level')
  431. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])
  432. ->orderBy('level asc')
  433. ->asArray()
  434. ->all();
  435. $agent_config = compact('agent_enable', 'item_setting', 'agent_levels', 'agent_details');
  436. }
  437. return $agent_config;
  438. }
  439. /**
  440. * @name:
  441. * @msg: 获取分销设置
  442. * @param {int} $mall_id
  443. * @param {int} $course_id
  444. * @return {*}
  445. */
  446. public static function getDistributionConfig(int $mall_id, int $course_id) : array
  447. {
  448. $addons_name = AddonsEnum::ADDONS_NAME_DISTRIBUTION ?? '';
  449. $is_install = MallAddons::isInstall($mall_id, $addons_name);
  450. if (!$is_install) {
  451. $item_setting = [];
  452. $level_names = [];
  453. $distribution_levels = [];
  454. $distribution_details = [];
  455. $distribution_enable = 0;
  456. } else {
  457. $distribution_enable = 1;
  458. $level_names = [
  459. [
  460. 'name' => '一级分销',
  461. 'value' => 'commission_first',
  462. ],
  463. [
  464. 'name' => '二级分销',
  465. 'value' => 'commission_second',
  466. ],
  467. // [
  468. // 'name' => '三级分销',
  469. // 'value' => 'commission_third',
  470. // ],
  471. ];
  472. $distribution_levels = DistributionLevel::find()
  473. ->select('id,level,name')
  474. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])
  475. ->orderBy('level asc')
  476. ->asArray()
  477. ->all();
  478. $item_setting = DistributionCommissionItemSetting::find()
  479. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $course_id])
  480. ->asArray()
  481. ->one();
  482. if (empty($item_setting)) {
  483. $distribution_details = [];
  484. } else {
  485. $distribution_details = DistributionCommissionItemSettingDetail::find()
  486. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'distribution_commission_item_setting_id' => $item_setting['id']])
  487. ->asArray()
  488. ->all();
  489. }
  490. }
  491. $distribution_config = compact('item_setting', 'level_names', 'distribution_levels', 'distribution_details', 'distribution_enable');
  492. return $distribution_config;
  493. }
  494. /**
  495. * @name:
  496. * @msg: 保存经销设置
  497. * @param {int} $mall_id
  498. * @param {array} $data
  499. * @return {*}
  500. */
  501. public static function AgentSetting(int $mall_id, array $data) : bool
  502. {
  503. $transaction = \Yii::$app->db->beginTransaction();
  504. $item_setting = $data['item_setting'];
  505. $item_setting['item_id'] = $data['course_id'];
  506. $item_setting['commission_type'] = 'commission';
  507. $item_setting['item_type'] = CourseEnum::ADDONS_NAME;
  508. if (!empty($item_setting['id'])) {
  509. $item_settting_model = AgentCommissionItemSetting::find()
  510. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $item_setting['id']])
  511. ->one();
  512. } else {
  513. $item_settting_model = AgentCommissionItemSetting::find()
  514. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $data['course_id'], 'item_type' => CourseEnum::ADDONS_NAME])
  515. ->one();
  516. if (empty($item_settting_model)) {
  517. $item_settting_model = new AgentCommissionItemSetting();
  518. $item_settting_model->loadDefaultValues();
  519. $item_settting_model->mall_id = $mall_id;
  520. }
  521. unset($item_setting['id']);
  522. }
  523. foreach ($item_setting as $key => $val) {
  524. $item_settting_model->$key = $val;
  525. }
  526. $res_agent_item_setting = $item_settting_model->save();
  527. if (false === $res_agent_item_setting) {
  528. $transaction->rollBack();
  529. self::$static_error = $item_settting_model->getErrorMessage();
  530. return false;
  531. }
  532. $detail_settings = [];
  533. unset($data['item_setting'], $data['_csrf'], $data['course_id']);
  534. // 团队奖
  535. foreach ($data['team_prize_info'] as $key => $setting) {
  536. // dd($key, $settings);
  537. $prize_info = [
  538. 'mall_id' => $mall_id,
  539. 'agent_commission_item_setting_id' => $item_settting_model->id,
  540. 'level' => $setting['level'],
  541. 'agent_team_prize' => $setting['agent_team_prize'] ?? 0,
  542. 'status' => StatusEnum::ENABLED,
  543. ];
  544. $detail_settings[$setting['level']] = $prize_info;
  545. }
  546. // 平级将
  547. foreach ($data['equal_prize_info'] as $key => $setting) {
  548. // dd($key, $settings);
  549. $prize_info = [
  550. 'mall_id' => $mall_id,
  551. 'agent_commission_item_setting_id' => $item_settting_model->id,
  552. 'level' => $setting['level'],
  553. 'agent_equal_prize' => $setting['agent_equal_prize'] ?? 0,
  554. 'status' => StatusEnum::ENABLED,
  555. ];
  556. $detail_settings[$setting['level']] = array_merge($detail_settings[$setting['level']], $prize_info);
  557. }
  558. // 越级奖
  559. foreach ($data['over_prize_info'] as $key => $setting) {
  560. // dd($key, $settings);
  561. $prize_info = [
  562. 'mall_id' => $mall_id,
  563. 'agent_commission_item_setting_id' => $item_settting_model->id,
  564. 'level' => $setting['level'],
  565. 'agent_over_prize' => $setting['agent_over_prize'] ?? 0,
  566. 'status' => StatusEnum::ENABLED,
  567. ];
  568. $detail_settings[$setting['level']] = array_merge($detail_settings[$setting['level']], $prize_info);
  569. }
  570. // 额外奖
  571. foreach ($data['extra_prize_info'] as $key => $setting) {
  572. // dd($key, $settings);
  573. $prize_info = [
  574. 'mall_id' => $mall_id,
  575. 'agent_commission_item_setting_id' => $item_settting_model->id,
  576. 'level' => $setting['level'],
  577. 'agent_extra_prize' => $setting['agent_extra_prize'] ?? 0,
  578. 'status' => StatusEnum::ENABLED,
  579. ];
  580. $detail_settings[$setting['level']] = array_merge($detail_settings[$setting['level']], $prize_info);
  581. }
  582. // dd($detail_settings);
  583. $insert_data = [];
  584. $time = time();
  585. foreach ($detail_settings as $setting) {
  586. $insert_data[] = [
  587. $setting['mall_id'],
  588. $setting['agent_commission_item_setting_id'],
  589. $setting['level'],
  590. $setting['agent_team_prize'],
  591. $setting['agent_equal_prize'],
  592. $setting['agent_over_prize'],
  593. $setting['agent_extra_prize'],
  594. $setting['status'],
  595. $time,
  596. $time,
  597. ];
  598. }
  599. if (!empty($insert_data)) {
  600. $res_delete = AgentCommissionItemSettingDetail::deleteAll(['mall_id' => $mall_id, 'agent_commission_item_setting_id' => $item_settting_model->id]);
  601. if (false === $res_delete) {
  602. $transaction->rollBack();
  603. self::$static_error = '清理原有的设置数据失败:' . $item_settting_model->getErrorMessage();
  604. return false;
  605. }
  606. $fields = ['mall_id', 'agent_commission_item_setting_id', 'level', 'agent_team_prize', 'agent_equal_prize', 'agent_over_prize', 'agent_extra_prize', 'status', 'created_at', 'updated_at'];
  607. $res = \Yii::$app->db->createCommand()->batchInsert(AgentCommissionItemSettingDetail::tableName(), $fields, $insert_data)->execute();
  608. if (false === $res) {
  609. $transaction->rollBack();
  610. self::$static_error = '保存设置详情失败';
  611. return false;
  612. }
  613. }
  614. $transaction->commit();
  615. return true;
  616. }
  617. /**
  618. * @name:
  619. * @msg: 保存分销设置
  620. * @param {int} $mall_id
  621. * @param {array} $data
  622. * @return {*}
  623. */
  624. public static function distributionSetting(int $mall_id, array $data) : bool
  625. {
  626. $transaction = \Yii::$app->db->beginTransaction();
  627. $item_setting = $data['item_setting'];
  628. $item_setting['item_id'] = $data['course_id'];
  629. $item_setting['item_type'] = CourseEnum::ADDONS_NAME;
  630. $item_setting['settings'] = 0;
  631. $item_setting['commission_type'] = 'commission';
  632. $item_setting['status'] = StatusEnum::ENABLED;
  633. if (!empty($item_setting['id'])) {
  634. $item_settting_model = DistributionCommissionItemSetting::find()
  635. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $item_setting['id']])
  636. ->one();
  637. } else {
  638. $item_settting_model = DistributionCommissionItemSetting::find()
  639. ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $data['course_id'], 'item_type' => CourseEnum::ADDONS_NAME])
  640. ->one();
  641. if (empty($item_settting_model)) {
  642. $item_settting_model = new DistributionCommissionItemSetting();
  643. $item_settting_model->loadDefaultValues();
  644. $item_settting_model->mall_id = $mall_id;
  645. }
  646. unset($item_setting['id']);
  647. }
  648. foreach ($item_setting as $key => $val) {
  649. $item_settting_model->$key = $val;
  650. }
  651. $res_distribution_item_setting = $item_settting_model->save();
  652. if (false === $res_distribution_item_setting) {
  653. $transaction->rollBack();
  654. self::$static_error = $item_settting_model->getErrorMessage();
  655. return false;
  656. }
  657. $details = $data['distribution_level_list'];
  658. // dd($details);
  659. $insert_data = [];
  660. $time = time();
  661. if (!empty($details)) {
  662. foreach ($details as $detail) {
  663. $insert_data[] = [
  664. $mall_id,
  665. $item_settting_model->id,
  666. $detail['level'],
  667. $detail['value'][0] ?? 0,
  668. $detail['value'][1] ?? 0,
  669. $detail['value'][2] ?? 0,
  670. StatusEnum::ENABLED,
  671. $time,
  672. $time,
  673. ];
  674. }
  675. }
  676. if (!empty($insert_data)) {
  677. $res_delete = DistributionCommissionItemSettingDetail::deleteAll(['mall_id' => $mall_id, 'distribution_commission_item_setting_id' => $item_settting_model->id]);
  678. if (false === $res_delete) {
  679. $transaction->rollBack();
  680. self::$static_error = '清理原有的设置数据失败:' . $item_settting_model->getErrorMessage();
  681. return false;
  682. }
  683. $fields = ['mall_id', 'distribution_commission_item_setting_id', 'level', 'first_prize', 'second_prize', 'third_prize','status', 'created_at', 'updated_at'];
  684. $res = \Yii::$app->db->createCommand()->batchInsert(DistributionCommissionItemSettingDetail::tableName(), $fields, $insert_data)->execute();
  685. if (false === $res) {
  686. $transaction->rollBack();
  687. self::$static_error = '保存设置详情失败';
  688. return false;
  689. }
  690. }
  691. $transaction->commit();
  692. return true;
  693. }
  694. //供公共调用
  695. public static function getCapitalLogList($params){
  696. if (!isset($params['list']) || !is_array($params['list'])) return [];
  697. $source_table_id_arr_by_course_orders = [];
  698. foreach ($params['list'] as $item) {
  699. if (strpos($item['source_table'],'{{%addons_course_orders}}')!==false) {
  700. $source_table_id_arr_by_course_orders[] = $item['source_table_id'];
  701. }
  702. }
  703. if(!empty($source_table_id_arr_by_course_orders)){
  704. $order_detail_arr = [];
  705. $cond = [];
  706. $cond['where'] = [['id' => $source_table_id_arr_by_course_orders]];
  707. $cond['with'] = [
  708. 'user' => function ($query) {
  709. $query->select('id,nickname,avatar_url');
  710. },
  711. 'course' => function ($query) {
  712. $query->select('id,name,price');
  713. }
  714. ];
  715. $course_order_list = AddonsCourseOrders::lists($cond);
  716. foreach ($course_order_list as $value) {
  717. $order_detail_arr[$value['id']] = [
  718. 'goods_name' => $value['course']['name'],
  719. 'goods_price' => $value['course']['price'],
  720. 'created_at' => date('Y-m-d H:i:s', $value['created_at']),
  721. 'order_no' => $value['order_no'],
  722. 'user_id' => $value['user']['id'],
  723. 'nickname' => $value['user']['nickname'],
  724. 'avatar_url' => $value['user']['avatar_url'],
  725. ];
  726. }
  727. foreach ($params['list'] as &$item) {
  728. if (strpos($item['source_table'],'{{%addons_course_orders}}')!==false) {
  729. $item['user_id'] = '';
  730. $item['nickname'] = '';
  731. $item['avatar_url'] = '';
  732. $item['order_no'] = '';
  733. $item['created_at'] = '';
  734. $item['goods_price'] = '';
  735. $item['goods_name'] = '';
  736. if (!empty($order_detail_arr[$item['source_table_id']])) {
  737. $item['user_id'] = $order_detail_arr[$item['source_table_id']]['user_id'];
  738. $item['nickname'] = $order_detail_arr[$item['source_table_id']]['nickname'];
  739. $item['avatar_url'] = $order_detail_arr[$item['source_table_id']]['avatar_url'];
  740. $item['order_no'] = $order_detail_arr[$item['source_table_id']]['order_no'];
  741. $item['created_at'] = $order_detail_arr[$item['source_table_id']]['created_at'];
  742. $item['goods_price'] = $order_detail_arr[$item['source_table_id']]['goods_price'];
  743. $item['goods_name'] = $order_detail_arr[$item['source_table_id']]['goods_name'];
  744. }
  745. }
  746. }
  747. }
  748. return $params['list'];
  749. }
  750. }