AddonsOperatingNoteContent.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <?php
  2. namespace addons\OperatingNote\common\models;
  3. use addons\Coupon\common\enums\AddonsCouponEnum;
  4. use addons\Coupon\common\models\AddonsCouponCatRelate;
  5. use addons\Coupon\common\models\AddonsCouponGoodsRelate;
  6. use addons\Coupon\common\models\AddonsCouponMemberRelate;
  7. use addons\Coupon\common\models\AddonsCouponReward;
  8. use addons\OperatingNote\common\enums\NoteEnum;
  9. use addons\Redpack\common\enums\RedpackEnum;
  10. use addons\Redpack\common\models\RedpackWallet;
  11. use common\enums\AssetsType;
  12. use common\enums\PaymentTradeOrderEnum;
  13. use common\enums\StatusEnum;
  14. use common\enums\UserWalletEnum;
  15. use common\models\goods\Goods;
  16. use common\models\user\User;
  17. use common\models\user\UserFollow;
  18. use services\common\UserWalletService;
  19. use Yii;
  20. use yii\db\Exception;
  21. /**
  22. * This is the model class for table "{{%addons_operating_note_content}}".
  23. *
  24. * @property int $id
  25. * @property int $mall_id 商城id
  26. * @property int $user_id 发布者id(后台发布为0)
  27. * @property int $goods_id 关联商品id
  28. * @property int $cate_id 分类id
  29. * @property int $sort 排序(数字越大排在前面)
  30. * @property int $note_type 笔记类型(1文章/2视频/3广告)
  31. * @property string $cover_img 封面/数组
  32. * @property int $cover_type 封面类型:1小单图2大单图3二图4三图5竖屏6横屏
  33. * @property string $title 笔记标题
  34. * @property string $content 笔记内容
  35. * @property string $content_href 笔记为视频/广告使用
  36. * @property int $hidden_comment 是否显示评价 1/是 0/否
  37. * @property string $show_type 展示内容(阅读数/点赞数/发布时间/发布者)
  38. * @property int $views_people_num 浏览人数
  39. * @property int $views_num 实际阅读数量
  40. * @property int $likes_num 实际点赞数量
  41. * @property int $share_num 分享次数
  42. * @property int $virtual_views_num 虚拟阅读数量
  43. * @property int $virtual_likes_num 虚拟点赞数量
  44. * @property int $is_top 是否置顶 1/是 0/否
  45. * @property int $is_top_updated_at 置顶时间
  46. * @property string $share_title 分享标题类型 1/文章标题 2/自定义
  47. * @property int $share_title_type 分享标题
  48. * @property int $view_limit 浏览限制类型
  49. * @property string $view_limit_content 浏览限制类容
  50. * @property int $pay_people_num 付费观看人数
  51. * @property float $pay_amount 付费总额
  52. * @property int $share_reward 分享奖励是否开启1/是 0/否
  53. * @property int $share_reward_type 分享奖励类型 0/积分 1/余额 2/红包
  54. * @property int $share_reward_max_time 分享最多奖励次数
  55. * @property string $share_reward_content 分享奖励内容
  56. * @property int $view_reward 浏览奖励是否开启1/是 0/否
  57. * @property int $view_reward_type 浏览奖励类型
  58. * @property int $view_reward_max_time 浏览最多奖励次数
  59. * @property string $view_reward_content 浏览奖励内容
  60. * @property int $is_release 是否发布 1/是 0/否
  61. * @property int $status 状态,-1是删除,0是禁用,1是启用
  62. * @property int $check_status 审核状态:0:未审核 1:审核通过 2:审核不通过
  63. * @property string|null $check_remark 审核原因
  64. * @property int $check_time 审核时间
  65. * @property int $created_at
  66. * @property int $updated_at
  67. */
  68. class AddonsOperatingNoteContent extends \common\models\base\BaseActiveRecord
  69. {
  70. /**
  71. * {@inheritdoc}
  72. */
  73. public static function tableName()
  74. {
  75. return '{{%addons_operating_note_content}}';
  76. }
  77. /**
  78. * {@inheritdoc}
  79. */
  80. public function rules()
  81. {
  82. return [
  83. [['mall_id', 'user_id', 'cate_id', 'note_type', 'view_limit', 'share_reward', 'share_reward_max_time', 'view_reward', 'view_reward_max_time'], 'required'],
  84. [['mall_id', 'user_id', 'goods_id', 'cate_id', 'sort', 'note_type', 'hidden_comment', 'views_people_num', 'views_num', 'likes_num', 'share_num', 'virtual_views_num', 'virtual_likes_num', 'is_top', 'is_top_updated_at', 'share_title_type', 'view_limit', 'pay_people_num', 'share_reward', 'share_reward_type', 'share_reward_max_time', 'view_reward', 'view_reward_type', 'view_reward_max_time', 'is_release', 'status', 'check_status', 'check_time', 'created_at', 'updated_at', 'cover_type'], 'integer'],
  85. [['content', 'cover_img', 'content_href'], 'string'],
  86. [['pay_amount'], 'number'],
  87. [['share_title', 'view_limit_content', 'check_remark'], 'string', 'max' => 255],
  88. [['title', 'show_type', 'share_reward_content', 'view_reward_content'], 'string', 'max' => 100],
  89. ];
  90. }
  91. /**
  92. * {@inheritdoc}
  93. */
  94. public function attributeLabels()
  95. {
  96. return [
  97. 'id' => 'ID',
  98. 'mall_id' => '商城id',
  99. 'user_id' => '发布者id(后台发布为0)',
  100. 'goods_id' => '关联商品id',
  101. 'cate_id' => '分类id',
  102. 'sort' => '排序(数字越大排在前面)',
  103. 'note_type' => '笔记类型(1文章/2视频/3广告)',
  104. 'cover_img' => '封面/数组',
  105. 'cover_type' => '封面类型', // 封面类型:1小单图2大单图3二图4三图5竖屏6横屏
  106. 'title' => '笔记标题',
  107. 'content' => '笔记内容',
  108. 'content_href' => '笔记为视频/广告使用',
  109. 'hidden_comment' => '是否显示评价 1/是 0/否',
  110. 'show_type' => '展示内容(阅读数/点赞数/发布时间/发布者)',
  111. 'views_people_num' => '浏览人数',
  112. 'views_num' => '实际阅读数量',
  113. 'likes_num' => '实际点赞数量',
  114. 'share_num' => '分享次数',
  115. 'virtual_views_num' => '虚拟阅读数量',
  116. 'virtual_likes_num' => '虚拟点赞数量',
  117. 'is_top' => '是否置顶 1/是 0/否',
  118. 'is_top_updated_at' => '置顶时间',
  119. 'share_title' => '分享标题类型 1/文章标题 2/自定义',
  120. 'share_title_type' => '分享标题',
  121. 'view_limit' => '浏览限制类型',
  122. 'view_limit_content' => '浏览限制类容',
  123. 'pay_people_num' => '付费观看人数',
  124. 'pay_amount' => '付费总额',
  125. 'share_reward' => '分享奖励是否开启1/是 0/否',
  126. 'share_reward_max_time' => '分享最多奖励次数',
  127. 'share_reward_content' => '分享奖励内容',
  128. 'view_reward' => '浏览奖励是否开启',
  129. 'view_reward_max_time' => '浏览最多奖励次数',
  130. 'view_reward_content' => '浏览奖励内容',
  131. 'is_release' => '是否发布 1/是 0/否',
  132. 'status' => '状态,-1是删除,0是禁用,1是启用',
  133. 'check_status' => '审核状态:0:未审核 1:审核通过 2:审核不通过',
  134. 'check_remark' => '审核原因',
  135. 'check_time' => '审核时间',
  136. 'created_at' => 'Created At',
  137. 'updated_at' => 'Updated At',
  138. ];
  139. }
  140. // public function scenarios()
  141. // {
  142. // return [
  143. // 'create' => [],
  144. // 'update' => ['goods_id','cate_id','sort','note_type','cover_img','title','content','content_href','hidden_comment','show_type','virtual_views_num','virtual_likes_num','is_top','is_top_updated_at','share_title','share_title_type','view_limit','view_limit_content','share_reward','share_reward_max_time','share_reward_content','view_reward','view_reward_max_time','view_reward_content','is_release','status','check_status','check_remark','check_time'],
  145. // 'default' => [],
  146. // ];
  147. // }
  148. public function getUser()
  149. {
  150. // return $this->hasOne(User::class, ['id' => 'user_id'])->select('id,mobile,nickname,avatar_url,parent_id,username,user_id');
  151. return $this->hasOne(User::class, ['id' => 'user_id']);
  152. }
  153. public function getGoods()
  154. {
  155. // return $this->hasOne(Goods::class, ['id' => 'goods_id'])->select('id,goods_name,price,cover_pic,sales_num,virtual_sales');
  156. return $this->hasOne(Goods::class, ['id' => 'goods_id']);
  157. }
  158. /**
  159. * @throws \yii\db\Exception
  160. */
  161. public static function setData(array $params, string $scenarios = 'create', $is_admin = true)
  162. {
  163. if (isset($params['content_href']) && !is_string($params['content_href'])) {
  164. $params['content_href'] = json_encode($params['content_href'], JSON_UNESCAPED_UNICODE);
  165. }
  166. $transaction = \Yii::$app->db->beginTransaction();
  167. try {
  168. if ($scenarios == 'update') {
  169. $model = self::findOne(['id' => $params['id']]);
  170. if (!$is_admin && $model->user_id != $params['user_id']) {
  171. return false;
  172. }
  173. if (!$is_admin && isset($params['cover_img'])) { // 用户重新编辑验证封面图
  174. $cover_count = NoteEnum::getCoverTypeCount($model->cover_type);
  175. if (is_array($params['cover_img']) && count($params['cover_img']) != $cover_count) {
  176. throw new Exception('请上传'. $cover_count . '张封面图');
  177. }
  178. }
  179. } else {
  180. $model = new self();
  181. }
  182. if (isset($params['cover_img'])) {
  183. $params['cover_img'] = is_array($params['cover_img']) ? json_encode($params['cover_img']) : $params['cover_img'];
  184. }
  185. if (empty($params['goods_id'])) {
  186. unset($params['goods_id']);
  187. }
  188. if (!$model->load($params, '') || false === $model->validate()) {
  189. $errors = $model->errors;
  190. $error_str = '';
  191. foreach ($errors as $error) {
  192. $error_str .= implode(',', $error) . ',';
  193. }
  194. $error_str = trim($error_str, ',');
  195. throw new \Exception($error_str);
  196. }
  197. if (!$model->save()) throw new Exception($model->getErrorMessage());
  198. $transaction->commit();
  199. return true;
  200. } catch (Exception $e) {
  201. $transaction->rollBack();
  202. self::setStaticError($e->getMessage());
  203. //var_dump($e->getMessage());
  204. //throw new Exception($e->getMessage());
  205. }
  206. }
  207. public static function getDetail($id, $user)
  208. {
  209. $is_like = false;
  210. $is_follow = StatusEnum::DISABLED;
  211. $view_record_count = 0;
  212. $share_record_count = 0;
  213. $detail = AddonsOperatingNoteContent::getOne([['id' => $id]], true, ['user', 'goods']);
  214. if ($detail['status'] == StatusEnum::DELETE) {
  215. self::$static_error = '文章已删除';
  216. return false;
  217. }
  218. $can_ready = true;
  219. if ($detail['note_type'] != NoteEnum::STATUS_THREE) {
  220. if ($user['id'] == $detail['user_id']) {
  221. $can_ready = true;
  222. } else {
  223. if ($detail['view_limit'] == NoteEnum::STATUS_ZERO) {
  224. if ($detail['view_limit_content'] == 'all') {
  225. $can_ready = true;
  226. } else {
  227. $view_limit_content = \Qiniu\json_decode($detail['view_limit_content']);
  228. if (!in_array($user['level'], $view_limit_content)) {
  229. $can_ready = false;
  230. }
  231. }
  232. } else {
  233. //获取是否购买
  234. $can_ready = AddonsOperatingNoteBuy::count(['where' => [['=', 'user_id', $user->id], ['=', 'note_id', $id], ['=', 'is_pay', NoteEnum::STATUS_ONE]]]) ? true : false;
  235. }
  236. }
  237. }
  238. if (!$can_ready) {
  239. $view_limit_content = $detail['view_limit_content'];
  240. $view_limit = $detail['view_limit'];
  241. $detail = [
  242. 'view_limit_content' => $view_limit_content,
  243. 'view_limit' => $view_limit,
  244. 'title' => $detail['title'],
  245. 'created_at' => $detail['created_at'],
  246. ];
  247. } else {
  248. $view_record_count = AddonsOperatingNoteRewardRecord::count(['where' => [['=', 'user_id', $user['id']], ['=', 'reward_source', NoteEnum::STATUS_ONE], ['=', 'note_content_id', $id]]]);
  249. $share_record_count = AddonsOperatingNoteShareRecord::count(['where' => [['=', 'user_id', $user['id']], ['=', 'note_id', $id], ['=', 'has_gift', 1]]]);
  250. $like = AddonsOperatingNoteUserLike::getOne([['user_id' => $user->id, 'note_content_id' => $id, 'is_like' => 1]]);
  251. if ($like) {
  252. $is_like = true;
  253. }
  254. $follow = UserFollow::getOne([['follow_id' => $detail['user_id']], ['user_id' => $user['id']]]);
  255. if ($follow && $follow['status'] == StatusEnum::ENABLED) {
  256. $is_follow = StatusEnum::ENABLED;
  257. }
  258. $model = AddonsOperatingNoteContent::getOne([['id' => $id]]);
  259. $model->updateCounters(['views_num' => 1]);
  260. //todo 浏览量新增
  261. }
  262. return ['can_ready' => $can_ready, 'detail' => $detail, 'is_like' => $is_like, 'is_follow' => $is_follow, 'share_record_count' => $share_record_count, 'view_record_count' => $view_record_count];
  263. }
  264. public static function viewReward($id, $user)
  265. {
  266. $state = false;
  267. $num = 0;
  268. $content = '';
  269. $transaction = \Yii::$app->db->beginTransaction();
  270. try {
  271. $note = AddonsOperatingNoteContent::getOne([['id' => $id]], false, [], false);
  272. if ($note->note_type == NoteEnum::STATUS_TWO) {
  273. $note->updateCounters(['views_num' => 1]);
  274. }
  275. if ($note->view_reward == 1) {
  276. $can_ready = true;
  277. if ($note->note_type != NoteEnum::STATUS_THREE) {
  278. if ($user['id'] == $note->user_id) {
  279. $can_ready = true;
  280. } else {
  281. if ($note->view_limit == NoteEnum::STATUS_ZERO) {
  282. if ($note->view_limit_content == 'all') {
  283. $can_ready = true;
  284. } else {
  285. $view_limit_content = \Qiniu\json_decode($note->view_limit_content);
  286. if (!in_array($user['level'], $view_limit_content)) {
  287. $can_ready = false;
  288. }
  289. }
  290. } else {
  291. //获取是否购买
  292. $can_ready = AddonsOperatingNoteBuy::count(['where' => [['=', 'user_id', $user['id']], ['=', 'note_id', $id], ['=', 'is_pay', NoteEnum::STATUS_ONE]]]) ? true : false;
  293. }
  294. }
  295. }
  296. if ($can_ready) {
  297. $record_count = AddonsOperatingNoteRewardRecord::count(['where' => [['=', 'user_id', $user['id']], ['=', 'reward_source', NoteEnum::STATUS_ONE], ['=', 'note_content_id', $id]]]);
  298. if ($record_count < $note->view_reward_max_time) {
  299. // 积分 余额
  300. if (in_array($note->view_reward_type, [NoteEnum::STATUS_ZERO, NoteEnum::STATUS_ONE])) {
  301. if ($note->view_reward_type == NoteEnum::STATUS_ZERO) {
  302. $content = '积分';
  303. $wallet_type = UserWalletService::WALLET_TYPE_SCORE;
  304. }
  305. if ($note->view_reward_type == NoteEnum::STATUS_ONE) {
  306. $wallet_type = UserWalletService::WALLET_TYPE_BALANCE;
  307. $content = '余额';
  308. }
  309. $handle_wallet = [
  310. 'message_id' => 0,
  311. 'mall_id' => $note->mall_id,
  312. 'user_id' => $user['id'],
  313. 'wallet_type' => $wallet_type,
  314. 'money' => $note->view_reward_content,
  315. 'desc' => '浏览文章奖励',
  316. 'source_table' => AssetsType::OPERATING_NOTE,
  317. 'source_table_id' => $note->id,
  318. 'from_type' => UserWalletEnum::REWARD,
  319. 'capital_type' => UserWalletEnum::OPERATING_NOTE_VIEW,
  320. ];
  321. $state = UserWalletService::handle(0, $handle_wallet);
  322. } else {
  323. // 红包
  324. $state = RedpackWallet::setData([
  325. 'mall_id' => $note->mall_id,
  326. 'user_id' => $user['id'],
  327. 'is_frozen' => false,
  328. 'money' => $note->share_reward_content,
  329. 'source_table' => static::tableName(),
  330. 'source_table_id' => $note->id,
  331. 'from_type' => RedpackEnum::FROM_RECEIVE,
  332. 'desc' => "运营笔记ID: {$id}阅读奖励",
  333. ]);
  334. }
  335. if ($state) {
  336. $model = new AddonsOperatingNoteRewardRecord();
  337. $model->mall_id = $note->mall_id;
  338. $model->user_id = $user['id'];
  339. $model->note_content_id = $id;
  340. $model->note_cate_id = $note->cate_id;
  341. $model->note_type = $note->note_type;
  342. $model->reward_type = $note->view_reward_type;
  343. $model->reward_source = NoteEnum::STATUS_ONE;
  344. $model->reward_content = $note->view_reward_content;
  345. $model->save();
  346. $num = $note->view_reward_content;
  347. }
  348. }
  349. }
  350. }
  351. $transaction->commit();
  352. } catch (Exception $e) {
  353. $transaction->rollBack();
  354. }
  355. return ['state' => $state, 'content' => $content, 'num' => $num];
  356. }
  357. public static function getUrlContent($url)
  358. {
  359. //设置 header
  360. header("Content-type:application/json");
  361. //初始化 CURL
  362. $ch = curl_init();
  363. //目标服务器地址
  364. curl_setopt($ch, CURLOPT_URL, $url);
  365. // 对认证证书来源的检查
  366. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
  367. // 从证书中检查SSL加密算法是否存在
  368. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  369. //获取的信息以文件流的形式返回,而不是直接输出
  370. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  371. // 添加浏览器用户代理和其他必要的头信息
  372. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  373. 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
  374. 'Referer: https://mp.weixin.qq.com/'
  375. ]);
  376. //发起请求
  377. $result = curl_exec($ch);
  378. $str_7 = substr($result, strripos($result, "twitter:title") + 24);
  379. $str_8 = substr($str_7, 0, strrpos($str_7, "twitter:creator") - 23); //公众号文章标题
  380. $str_16 = substr($result, strripos($result, "div class=\"rich_media_content") + 76);
  381. $str_17 = substr($str_16, 0, strrpos($str_16, "first_sceen__time") - 83); //公众号文章正文
  382. //关闭请求
  383. curl_close($ch);
  384. return ['title' => $str_8, 'content' => trim($str_17)];
  385. }
  386. }