ScoreMallGoods.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <?php
  2. namespace addons\ScoreMall\common\models;
  3. use addons\ScoreMall\common\enums\ScoreMallEnum;
  4. use common\enums\AddonsEnum;
  5. use common\enums\StatusEnum;
  6. use common\models\base\BaseActiveRecord;
  7. use common\models\common\AddonsMarketingSetting;
  8. use common\models\goods\Goods;
  9. use common\models\goods\GoodsExtra;
  10. use common\models\user\UserWallet;
  11. use common\models\goods\GoodsMarketing;
  12. use Exception;
  13. use Yii;
  14. use yii\helpers\Json;
  15. /**
  16. * This is the model class for table "{{%addons_score_mall_goods}}".
  17. * @property int $id
  18. * @property int $mall_id
  19. * @property int $goods_id 商品ID
  20. * @property int $goods_attr_id 属性ID
  21. * @property int $num 已兑换数量
  22. * @property int $type 类型
  23. * @property int $use_coupon 是否使用
  24. * @property int $status
  25. * @property int $created_at 创建时间
  26. * @property int $updated_at 修改时间
  27. */
  28. class ScoreMallGoods extends BaseActiveRecord
  29. {
  30. /**
  31. * {@inheritdoc}
  32. */
  33. public static function tableName()
  34. {
  35. return '{{%addons_score_mall_goods}}';
  36. }
  37. /**
  38. * {@inheritdoc}
  39. */
  40. public function rules()
  41. {
  42. return [
  43. [['mall_id'], 'required'],
  44. [['mall_id', 'status', 'created_at', 'updated_at', 'goods_id', 'type', 'num', 'use_coupon', 'cate_id'], 'integer'],
  45. [['money', 'price', 'score'], 'number'],
  46. ];
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public function attributeLabels()
  52. {
  53. return [
  54. 'id' => 'ID',
  55. 'mall_id' => 'Mall ID',
  56. 'goods_id' => '商品ID',
  57. 'cate_id' => '分类ID',
  58. 'num' => '已兑换数量',
  59. 'money' => '商品最低价',
  60. 'price' => '商品售价',
  61. 'score' => '积分',
  62. 'type' => '兑换类型',
  63. 'use_coupon' => '是否不参加优惠券抵扣',
  64. 'status' => '状态[-1:删除;0:禁用;1启用]',
  65. 'created_at' => '创建时间',
  66. 'updated_at' => '修改时间'
  67. ];
  68. }
  69. /**
  70. * 关联积分商品规格表
  71. * @Author: lun
  72. * @DateTime: 2022/1/7 0007 14:40
  73. * @Copyright: copyright (c) 2021 广东七件事集团
  74. * @return \yii\db\ActiveQuery
  75. */
  76. public function getAttr()
  77. {
  78. return $this->hasMany(ScoreMallGoodsAttr::class, ['goods_id' => 'goods_id'])->where(['status' => StatusEnum::ENABLED]);
  79. }
  80. /**
  81. * 关联商品表
  82. * @Author: lun
  83. * @DateTime: 2022/1/7 0007 16:28
  84. * @Copyright: copyright (c) 2021 广东七件事集团
  85. * @return \yii\db\ActiveQuery
  86. */
  87. public function getGoods()
  88. {
  89. return $this->hasOne(Goods::class, ['id' => 'goods_id']);
  90. }
  91. /**
  92. * 获取积分商品兑换价
  93. * @Author: lun
  94. * @DateTime: 2022/1/7 0007 16:24
  95. * @Copyright: copyright (c) 2021 广东七件事集团
  96. * @param $type
  97. * @param $attr
  98. * @param $score_config
  99. * @param $num
  100. * @param $user_id
  101. * @return array
  102. */
  103. public static function getExchangePrice($type, $attr, $score_config, $num = 1, $user_id = 0)
  104. {
  105. $data = [
  106. 'exchange_price' => '',
  107. 'pay_money' => 0,
  108. 'pay_score' => 0,
  109. 'deduct_money' => 0,
  110. ];
  111. $score_name = $score_config['score_name'] ?? '积分';
  112. $price = $total_price = 0;
  113. switch ($type) {
  114. case ScoreMallEnum::TYPE_SCORE:
  115. $data['exchange_price'] = $total_price = ($attr['score'] * $num) . $score_name;
  116. $price = $attr['score'] . $score_name;
  117. $data['pay_score'] = $attr['score'] * $num;
  118. $data['deduct_money'] = ($attr['price'] ?? 0) * $num;
  119. break;
  120. case ScoreMallEnum::TYPE_SCORE_MONEY:
  121. $data['exchange_price'] = $total_price = ($attr['score'] * $num) . $score_name . '+¥' . ($attr['money'] * $num);
  122. $price = '¥' . $attr['money'] . '+' . $attr['score'] . $score_name;
  123. $data['pay_money'] = $attr['money'] * $num;
  124. $data['pay_score'] = $attr['score'] * $num;
  125. $data['deduct_money'] = ($attr['price'] ?? 0) * $num - $data['pay_money'];
  126. break;
  127. case ScoreMallEnum::TYPE_LIMIT:
  128. $deduct_ratio = empty((float)$score_config['score_deduct_ratio']) ? 1 : $score_config['score_deduct_ratio'];
  129. $deduct_limit = Json::decode($attr['deduction_limit'], true);
  130. $low = $deduct_limit[0];
  131. $high = $deduct_limit[1];
  132. $data['exchange_price'] = '¥' . ($attr['price'] ?? 0); // 默认售价
  133. // 最低抵扣不做限制,则最低零点抵扣
  134. if ($low['limit'] == 0) {
  135. $low_score = 0; // 最低积分
  136. } else {
  137. $low_score = $low['score'] * $num; // 最低积分
  138. }
  139. // 最高抵扣不做限制,则最高抵扣为商品原价
  140. if ($high['limit'] == 0) {
  141. $high_score = ceil($attr['price'] * $deduct_ratio * $num); // 最高积分
  142. } else {
  143. $high_price = ceil($high['score'] / $deduct_ratio) * $num; // 最高价
  144. if ($high_price >= $attr['price'] * $num) { // 设置的最高价若大于等级商品售价则显示商品售价
  145. $high_score = ceil($attr['price'] * $deduct_ratio * $num); // 最高积分
  146. } else {
  147. $high_score = $high['score'] * $num; // 最高积分
  148. }
  149. }
  150. // 获取用户的现有积分
  151. if ($user_id) {
  152. $score = UserWallet::find()->select("score")->where(['user_id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->scalar() ?? 0;
  153. $score = floatval($score);
  154. if ($score < $low_score) { // 不够积分情况
  155. $data['pay_score'] = $low_score; // 支付的积分
  156. $data['pay_money'] = ceil(($attr['price'] * $num) - ($low_score / $deduct_ratio)); // 支付的金额
  157. $data['exchange_price'] = $low_score . $score_name . '+¥' . $data['pay_money'];
  158. } elseif ($score >= $low_score && $score < $high_score) { // 积分足够情况
  159. $data['pay_score'] = $score; // 支付的积分
  160. $data['pay_money'] = ceil(($attr['price'] * $num) - ($score / $deduct_ratio)); // 支付的金额
  161. $data['exchange_price'] = empty($data['pay_money']) ? $score . $score_name : $score . $score_name . '+¥' . $data['pay_money'];
  162. } else { // 积分足够并且超出最大设置
  163. $data['pay_score'] = $high_score; // 支付的积分
  164. $data['pay_money'] = ceil(($attr['price'] * $num) - ($high_score / $deduct_ratio)); // 支付的金额
  165. $data['exchange_price'] = $data['pay_score'] . $score_name;
  166. !empty($data['pay_money']) && $data['exchange_price'] .= '+¥' . $data['pay_money'];
  167. }
  168. $price_arr = []; // 单价
  169. !empty($data['pay_money']) && $price_arr[] = '¥' . bcdiv($data['pay_money'], $num, 2);
  170. !empty($data['pay_score']) && $price_arr[] = bcdiv($data['pay_score'], $num, 2) . $score_name;
  171. $price = implode('+', $price_arr);
  172. $exchange_price = [];
  173. !empty($data['pay_money']) && $exchange_price[] = '¥' . $data['pay_money'];
  174. !empty($data['pay_score']) && $exchange_price[] = $data['pay_score'] . $score_name;
  175. $total_price = implode('+', $exchange_price); // 总价
  176. }
  177. $data['deduct_money'] = $attr['price'] * $num - $data['pay_money'];
  178. break;
  179. }
  180. $data['extra_info'] = ['price' => $price, 'total_price' => $total_price];
  181. return $data;
  182. }
  183. /**
  184. * 装修选择链接获取积分商品
  185. * @Author: lun
  186. * @DateTime: 2022/1/10 0010 19:13
  187. * @Copyright: copyright (c) 2021 广东七件事集团
  188. * @param $mall_id
  189. * @param $post
  190. * @return array|bool|mixed|void
  191. */
  192. public static function getGoodsListByDiy($mall_id, $post)
  193. {
  194. $where[] = ['mall_id' => $mall_id];
  195. $where[] = ['status' => StatusEnum::ENABLED];
  196. if (!empty($post['keyword'])) {
  197. $goods_list = Goods::lists(['where' => [['mall_id' => $mall_id], ['like', 'goods_name', trim($post['keyword']) . '%', false], ['status' => StatusEnum::ENABLED]], 'select' => 'id']);
  198. $goods_id_arr = array_column($goods_list, 'id');
  199. $where[] = ['goods_id' => $goods_id_arr];
  200. }
  201. $order = 'id desc';
  202. $select = "id,goods_id,cate_id,score,money,type,created_at";
  203. $with = [
  204. 'goods' => function ($query) {
  205. $query->select("id,goods_name,price,cover_pic,subtitle");
  206. },
  207. 'attr' => function ($query) {
  208. $query->select("goods_id,goods_attr_id,score,money,deduction_limit,price");
  209. }
  210. ];
  211. $params = compact('where', 'order', 'select', 'with');
  212. $list = self::listPage($params, false, true);
  213. if (!empty($list['list'])) {
  214. $addons_fields = [];
  215. if (isset($post['parameter']) && isset($post['parameter']['addonsFields'])) {
  216. $addons_fields = $post['parameter']['addonsFields'];
  217. }
  218. if ($addons_fields) {
  219. $goods_list_info = [];
  220. foreach ($list['list'] as $value) {
  221. $value['goods']['id'] = $value['goods_id'];
  222. $goods_list_info[$value['goods_id']] = $value['goods'];
  223. }
  224. $goods_list_info = Goods::getAddonsGoodsSetting($mall_id, $addons_fields, $goods_list_info, 'list');
  225. foreach ($list['list'] as &$v) {
  226. if (!isset($goods_list_info[$v['goods_id']])) continue;
  227. $v = array_merge($goods_list_info[$v['goods_id']], $v);
  228. }
  229. unset($v);
  230. }
  231. // 获取积分配置
  232. $score_config = Yii::$app->services->setting->mall->get($mall_id, 'score');
  233. foreach ($list['list'] as &$item) {
  234. $item['id'] = $item['goods_id'];
  235. $item['img'] = $item['goods']['cover_pic'];
  236. $item['title'] = $item['goods']['goods_name'];
  237. $item['subtitle'] = $item['goods']['subtitle'];
  238. $item['price'] = $item['goods']['price'];
  239. $exchange_price = ScoreMallGoods::getExchangePrice($item['type'], $item['attr'][0], $score_config, 1, 0);
  240. $item['exchange_price'] = $exchange_price['exchange_price'];
  241. unset($item['goods']);
  242. unset($item['goods_id']);
  243. }
  244. }
  245. return $list;
  246. }
  247. /**
  248. * 获取分类
  249. * @Author: lun
  250. * @DateTime: 2022/1/10 0010 19:16
  251. * @Copyright: copyright (c) 2021 广东七件事集团
  252. * @param $mall_id
  253. * @param $post
  254. * @return array|bool|mixed|void
  255. */
  256. public static function getCateListByDiy($mall_id, $post)
  257. {
  258. $res = Yii::$app->services->setting->addons->get($mall_id, AddonsEnum::ADDONS_NAME_SCORE_MALL, 'basic');
  259. $list = !empty($res) && isset($res['classification']) ? json_decode($res['classification'], true) : [];
  260. if ($list) {
  261. foreach ($list as $key => &$item) {
  262. if ($item['status'] == 0) unset($list[$key]);
  263. if ($post['keyword'] && stristr($item['name'], $post['keyword']) == false) unset($list[$key]);
  264. $item['title'] = $item['name'];
  265. $item['created_at'] = strtotime($item['created_at']);
  266. }
  267. }
  268. return ['list' => array_values($list)];
  269. }
  270. /**
  271. * 保存数据
  272. * @param int $goods_id
  273. * @param int $cate_id
  274. * @param int $score
  275. * @param int $money type=2时 商品价格
  276. * @param int $price 对应商品表price
  277. * @param int $type 1:全积分兑换,2:积分加金额,3:积分抵扣
  278. * @param int $num 已兑换数量
  279. * @param int $use_coupon 0:参数优惠券抵扣,1:不参加优惠券抵扣
  280. * @param string action edit时不允许变更goods_id
  281. * @author hpei
  282. * @return array
  283. */
  284. public static function setData($params)
  285. {
  286. $goods_id = $params['goods_id'];
  287. try {
  288. $scoreMdl = self::findOne(['goods_id' => $goods_id]);
  289. if ($scoreMdl && isset($params['action']) && $params['action'] == 'add' && $scoreMdl->status != StatusEnum::DELETE) {
  290. self::$static_error = '该商品已存在';
  291. return false;
  292. }
  293. if (empty($scoreMdl)) {
  294. if (isset($params['action']) && $params['action'] == 'edit') {
  295. self::$static_error = '该商品不存在';
  296. return false;
  297. }
  298. $scoreMdl = new self();
  299. $scoreMdl->loadDefaultValues();
  300. }
  301. if (!$scoreMdl->load($params, '') || !$scoreMdl->save()) {
  302. self::$static_error = $scoreMdl->getErrorMessage();
  303. return false;
  304. }
  305. if ($params['action'] != 'edit') {
  306. $installData = [
  307. 'mall_id' => $scoreMdl->mall_id,
  308. 'goods_id' => $scoreMdl->goods_id,
  309. 'marketing_id' => $scoreMdl->id,
  310. 'status' => StatusEnum::ENABLED,
  311. 'marketing_type' => ScoreMallEnum::ADDONS_NAME
  312. ];
  313. GoodsMarketing::setData($installData);
  314. }
  315. return $scoreMdl->toArray();
  316. } catch (Exception $e) {
  317. self::$static_error = $e->getMessage();
  318. return false;
  319. }
  320. }
  321. /**
  322. * 积分商品海报分享内容
  323. * @Author: lun
  324. * @DateTime: 2022/1/17 0017 15:20
  325. * @Copyright: copyright (c) 2021 广东七件事集团
  326. * @param $mall_id
  327. * @param $goods_id
  328. * @return array|bool
  329. */
  330. public static function getPosterScoreGoods($mall_id, $goods_id)
  331. {
  332. $score_goods = ScoreMallGoods::getOne([['goods_id' => $goods_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]], true, ['goods' => function ($query) {
  333. $query->select("id,goods_name,price,original_price,cover_pic");
  334. }, 'attr' => function ($query) {
  335. $query->select("goods_id,score,money,price,deduction_limit");
  336. }], false, 'goods_id,score,money,type,price');
  337. if (empty($score_goods)) return false;
  338. $score_config = Yii::$app->services->setting->mall->get($mall_id, 'score');
  339. $exchange = self::getExchangePrice($score_goods['type'], $score_goods['attr'][0], $score_config);
  340. return [
  341. 'item_id' => $goods_id,
  342. 'share_title' => $score_goods['goods']['goods_name'],
  343. 'price' => ltrim($exchange['exchange_price'], '¥'),
  344. 'original_price' => $score_goods['price'],
  345. 'share_img' => $score_goods['goods']['cover_pic'],
  346. ];
  347. }
  348. public static function getScoreMallExtraFields($mall_id, $list){
  349. if (!empty($list['list'])) {
  350. $data = AddonsMarketingSetting::getOne([['mall_id' => $mall_id], ['addons_name' => ScoreMallEnum::ADDONS_NAME], ['status' => StatusEnum::ENABLED]]);
  351. $content = json_decode($data['content'], true);
  352. // 勾选的字段
  353. $selected_fields = [];
  354. if(isset($content[3]['data']['showContent'])&&is_array($content[3]['data']['showContent'])){
  355. $show_content = $content[3]['data']['showContent'];
  356. $selected_fields = array_column($show_content, 'field');
  357. }
  358. $exclude_fields = ['goods_name', 'price', 'original_price'];
  359. $need_fields = [];
  360. foreach($selected_fields as $field) {
  361. !in_array($field, $exclude_fields) && $need_fields[] = $field;
  362. }
  363. if ($need_fields) {
  364. $goods_list_info = [];
  365. foreach ($list['list'] as $value) {
  366. $value['goods']['id'] = $value['goods_id'];
  367. $goods_list_info[$value['goods_id']] = $value['goods'];
  368. }
  369. $goods_list_info = Goods::getAddonsGoodsSetting($mall_id, $need_fields, $goods_list_info, 'list');
  370. foreach ($list['list'] as &$v) {
  371. if (!isset($goods_list_info[$v['goods_id']])) continue;
  372. $v['goods'] = array_merge($goods_list_info[$v['goods_id']], $v['goods']);
  373. }
  374. unset($v);
  375. }
  376. }
  377. return $list;
  378. }
  379. }