PurchaseGoods.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <?php
  2. namespace addons\Purchase\common\models;
  3. use addons\Purchase\common\enums\PurchaseEnum;
  4. use common\enums\StatusEnum;
  5. use common\models\goods\Goods;
  6. use common\models\goods\GoodsAttr;
  7. use common\models\goods\GoodsMarketing;
  8. use common\models\user\UserWallet;
  9. use Yii;
  10. use yii\db\Exception;
  11. /**
  12. * This is the model class for table "{{%addons_purchase_goods}}".
  13. *
  14. * @property int $id
  15. * @property int $mall_id
  16. * @property int $goods_id 商品ID
  17. * @property string $exchange_price 兑换价说明
  18. * @property int $exchange_num 已兑换数量
  19. * @property int $status 状态[-1:删除;0:禁用;1启用]
  20. * @property int $created_at 创建时间
  21. * @property int $updated_at 更新时间
  22. */
  23. class PurchaseGoods extends \common\models\base\BaseActiveRecord
  24. {
  25. /**
  26. * {@inheritdoc}
  27. */
  28. public static function tableName()
  29. {
  30. return '{{%addons_purchase_goods}}';
  31. }
  32. /**
  33. * {@inheritdoc}
  34. */
  35. public function rules()
  36. {
  37. return [
  38. [['mall_id', 'goods_id', 'exchange_num', 'status', 'created_at', 'updated_at'], 'integer'],
  39. [['exchange_price'], 'string'],
  40. ];
  41. }
  42. /**
  43. * {@inheritdoc}
  44. */
  45. public function attributeLabels()
  46. {
  47. return [
  48. 'id' => 'ID',
  49. 'mall_id' => 'Mall ID',
  50. 'goods_id' => '商品ID',
  51. 'exchange_price' => '兑换价说明',
  52. 'exchange_num' => '已兑换数量',
  53. 'status' => '状态[-1:删除;0:禁用;1启用]',
  54. 'created_at' => '创建时间',
  55. 'updated_at' => '更新时间',
  56. ];
  57. }
  58. /**
  59. * @notes:管理主商城商品
  60. * @return \yii\db\ActiveQuery
  61. * @author: lun
  62. * @Time: 2022/10/22 10:31
  63. */
  64. public function getGoods()
  65. {
  66. return $this->hasOne(Goods::class, ['id' => 'goods_id'])->select('id,goods_name,cover_pic,price,is_on_sale,status');
  67. }
  68. /**
  69. * @notes:关联规格
  70. * @return \yii\db\ActiveQuery
  71. * @author: lun
  72. * @Time: 2022/10/22 11:05
  73. */
  74. public function getAttr()
  75. {
  76. return $this->hasMany(PurchaseGoodsAttr::class, ['goods_id' => 'goods_id'])->where(['status' => StatusEnum::ENABLED]);
  77. }
  78. /**
  79. * @notes:关联分类
  80. * @return \yii\db\ActiveQuery
  81. * @author: lun
  82. * @Time: 2022/10/22 13:52
  83. */
  84. public function getCats()
  85. {
  86. return $this->hasMany(PurchaseCate::class, ['id' => 'cate_id'])
  87. ->via('purchaseGoodsCateRelate');
  88. }
  89. /**
  90. * @notes:关联分类
  91. * @return \yii\db\ActiveQuery
  92. * @author: lun
  93. * @Time: 2022/10/22 16:25
  94. */
  95. public function getPurchaseGoodsCateRelate()
  96. {
  97. return $this->hasMany(PurchaseGoodsCateRelate::class, ['goods_id' => 'goods_id']);
  98. }
  99. /**
  100. * @notes:数据保存
  101. * @param $mall_id
  102. * @param $params
  103. * @return bool
  104. * @author: lun
  105. * @Time: 2022/10/22 16:00
  106. */
  107. public static function setData($mall_id, $params)
  108. {
  109. $trans = Yii::$app->db->beginTransaction();
  110. try {
  111. // 查询是否已存在该商品
  112. $goods = self::find()->where(['mall_id' => $mall_id, 'goods_id' => $params['goods_id'], 'status' => StatusEnum::ENABLED])->asArray()->one();
  113. if (!empty($params['id'])) {
  114. $model = self::findOne(['mall_id' => $mall_id, 'id' => $params['id']]);
  115. if (empty($model)) throw new \Exception('查无此商品');
  116. if ($model->id != $goods['id'] && $goods['goods_id'] == $model->goods_id) throw new \Exception('已存在该商品,请另选商品');
  117. } else {
  118. $model = new self();
  119. $model->mall_id = $mall_id;
  120. $model->loadDefaultValues();
  121. }
  122. $model->goods_id = $params['goods_id'];
  123. $params['goods_id'] != $model->goods_id && $model->exchange_num = 0;
  124. // 获取商品兑换价
  125. $exchange = $params['attr'][0] ?? [];
  126. $model->exchange_price = '最低抵扣:'.($exchange['min_limit'] === 'false' ? $exchange['min_score'] : '无限制').',最高抵扣:'.($exchange['max_limit'] === 'false' ? $exchange['max_score'] : '无限制');
  127. if (!$model->save()) throw new Exception($model->getErrorMessage());
  128. // 保存商品分类
  129. if (!empty($params['cats'])) {
  130. $res = PurchaseGoodsCateRelate::setData($model->goods_id, $params['cats']);
  131. if ($res === false) throw new \Exception(PurchaseGoodsCateRelate::getStaticError());
  132. }
  133. // 保存商品规格
  134. if (!empty($params['attr'])) {
  135. $res = PurchaseGoodsAttr::setData($params['attr']);
  136. if ($res === false) throw new \Exception(PurchaseGoodsAttr::getStaticError());
  137. }
  138. // 保存商品无法编辑设置
  139. $installData = [
  140. 'mall_id' => $mall_id,
  141. 'goods_id' => $model->goods_id,
  142. 'marketing_id' => $model->id,
  143. 'status' => StatusEnum::ENABLED,
  144. 'marketing_type' => PurchaseEnum::ADDONS_NAME
  145. ];
  146. $res = GoodsMarketing::setData($installData);
  147. if ($res === false) throw new \Exception(GoodsMarketing::getStaticError());
  148. // 商品无法搜索设置
  149. $trans->commit();
  150. return true;
  151. } catch (\Exception $e) {
  152. $trans->rollBack();
  153. self::setStaticError($e->getMessage());
  154. return false;
  155. }
  156. }
  157. /**
  158. * @notes:商品删除
  159. * @param $mall_id
  160. * @param $id
  161. * @return bool
  162. * @author: lun
  163. * @Time: 2022/10/22 16:58
  164. */
  165. public static function del($mall_id, $id)
  166. {
  167. $trans = Yii::$app->db->beginTransaction();
  168. try {
  169. $model = self::findOne(['mall_id' => $mall_id, 'id' => $id, 'status' => StatusEnum::ENABLED]);
  170. if (empty($model)) throw new \Exception('该商品已被删除');
  171. // 删除商品
  172. $model->status = StatusEnum::DELETE;
  173. if (!$model->save()) throw new Exception($model->getErrorMessage());
  174. // 删除分类
  175. PurchaseGoodsCateRelate::deleteAll(['goods_id' => $model->goods_id]);
  176. // 删除规格
  177. PurchaseGoodsAttr::updateAll(['status' => StatusEnum::DELETE, 'updated_at' => time()], ['goods_id' => $model->goods_id]);
  178. // 删除商品无法编辑
  179. $installData = [
  180. 'mall_id' => $mall_id,
  181. 'goods_id' => $model->goods_id,
  182. 'marketing_id' => $model->id,
  183. 'status' => StatusEnum::DELETE,
  184. 'marketing_type' => PurchaseEnum::ADDONS_NAME
  185. ];
  186. $res = GoodsMarketing::setData($installData);
  187. if ($res === false) throw new \Exception(GoodsMarketing::getStaticError());
  188. // 删除商品无法搜索
  189. $trans->commit();
  190. return true;
  191. } catch (\Exception $e) {
  192. $trans->rollBack();
  193. self::setStaticError($e->getMessage());
  194. return false;
  195. }
  196. }
  197. /**
  198. * @notes:获取兑换价格
  199. * @param $goods
  200. * @param $score_config
  201. * @param $num
  202. * @param $user_id
  203. * @return array
  204. * @author: lun
  205. * @Time: 2022/10/25 18:36
  206. */
  207. public static function getExchangePrice($goods, $score_config, $num = 1, $user_id = 0)
  208. {
  209. $data = ['status' => 1, 'deduct_score' => 0, 'deduct_money' => 0, 'score_name' => $score_config['score_name']];// 初始化
  210. // 获取属性设置
  211. $attr = PurchaseGoodsAttr::find()->where(['goods_id' => $goods['goods_id'], 'goods_attr_id' => $goods['goods_attr_id'], 'status' => StatusEnum::ENABLED])->asArray()->one();
  212. if (empty($attr)) throw new \Exception('该商品的积分抵扣设置不存在');
  213. $data['goods_id'] = $attr['goods_id'];
  214. $deduct_ratio = $score_config['score_deduct_ratio'];
  215. $min_limit = $attr['min_limit'];
  216. $min_score = $attr['min_score'];
  217. $max_limit = $attr['max_limit'];
  218. $max_score = $attr['max_score'];
  219. // 最低抵扣不做限制,则最低零点抵扣
  220. $low_score = empty($min_limit) ? $min_score * $num : 0;// 最低积分
  221. // 最高抵扣不做限制,则最高抵扣为商品原价
  222. if ($max_limit == 0) {
  223. $high_price = ceil($max_score / $deduct_ratio) * $num;// 最高价
  224. if ($high_price >= $goods['price'] * $num) {// 设置的最高价若大于等级商品售价则显示商品售价
  225. $high_score = ceil($goods['price'] * $deduct_ratio * $num);// 最高积分
  226. } else {
  227. $high_score = $max_score * $num;// 最高积分
  228. }
  229. } else {
  230. $high_score = ceil($goods['price'] * $deduct_ratio * $num);// 最高积分
  231. }
  232. // 获取用户的现有积分
  233. if ($score_config['score'] < $low_score) {// 不够积分情况
  234. $data['deduct_score'] = $low_score;// 支付的积分
  235. $data['deduct_money'] = ceil($low_score / $deduct_ratio);// 支付的金额
  236. $min_limit == 0 && $data['status'] = 0;// 设置了最低积分,若不够积分则不能下单
  237. } elseif ($score_config['score'] >= $low_score && $score_config['score'] < $high_score) {// 积分足够情况
  238. $data['deduct_score'] = $score_config['score'];// 支付的积分
  239. $data['deduct_money'] = ceil($score_config['score'] / $deduct_ratio);// 支付的金额
  240. } else {// 积分足够并且超出最大设置
  241. $data['deduct_score'] = $high_score;// 支付的积分
  242. $data['deduct_money'] = ceil($high_score / $deduct_ratio);// 支付的金额
  243. }
  244. return $data;
  245. }
  246. /**
  247. * @notes:批量添加商品
  248. * @param $mall_id
  249. * @param $params
  250. * @return bool
  251. * @author: lun
  252. * @Time: 2022/11/15 14:45
  253. */
  254. public static function batchSetData($mall_id, $params)
  255. {
  256. $trans = Yii::$app->db->beginTransaction();
  257. try {
  258. $attr_setting = $params['attr'];
  259. $score_deduct_ratio = Yii::$app->services->setting->mall->get($mall_id, 'score.score_deduct_ratio');
  260. foreach ($params['goods'] as $item) {
  261. // 查询是否已存在该商品
  262. $check = self::find()->where(['mall_id' => $mall_id, 'goods_id' => $item['id'], 'status' => StatusEnum::ENABLED])->asArray()->one();
  263. if (!empty($check)) throw new \Exception('商品ID=' . $item['id'] . '的商品已存在,请勿重复添加');
  264. // 获取该商品的所有规格
  265. $where = [];
  266. $where[] = ['=', 'goods_id', $item['id']];
  267. $where[] = ['=', 'status', StatusEnum::ENABLED];
  268. $attrs = GoodsAttr::getGoodsAttrs($where, [], true, ['id as goods_attr_id', 'goods_id', 'name', 'price','pic_url']);
  269. if (empty($attrs)) throw new \Exception('商品ID=' . $item['id'] . '的商品商品规格不存在,请检查主商城商品信息');
  270. $attr_setting['min_limit'] === 'false' && $min_score = ceil($attr_setting['min_score'] * $score_deduct_ratio * $attrs[0]['price']) / 100;
  271. $attr_setting['max_limit'] === 'false' && $max_score = ceil($attr_setting['max_score'] * $score_deduct_ratio * $attrs[0]['price']) / 100;
  272. // 新增数据
  273. $model = new self();
  274. $model->mall_id = $mall_id;
  275. $model->goods_id = $item['id'];
  276. $model->exchange_price = '最低抵扣:'.($attr_setting['min_limit'] === 'true' ? '无限制' : $min_score).',最高抵扣:'.($attr_setting['max_limit'] === 'true' ? '无限制' : $max_score);
  277. $model->loadDefaultValues();
  278. if (!$model->save()) throw new Exception($model->getErrorMessage());
  279. // 保存商品分类
  280. if (!empty($params['cats'])) {
  281. $res = PurchaseGoodsCateRelate::setData($model->goods_id, $params['cats'], 'batch');
  282. if ($res === false) throw new \Exception(PurchaseGoodsCateRelate::getStaticError());
  283. }
  284. // 保存商品规格
  285. $res = PurchaseGoodsAttr::percentSetData($attrs, $attr_setting, $score_deduct_ratio);
  286. if ($res === false) throw new \Exception(PurchaseGoodsAttr::getStaticError());
  287. // 保存商品无法编辑设置
  288. $installData = [
  289. 'mall_id' => $mall_id,
  290. 'goods_id' => $model->goods_id,
  291. 'marketing_id' => $model->id,
  292. 'status' => StatusEnum::ENABLED,
  293. 'marketing_type' => PurchaseEnum::ADDONS_NAME
  294. ];
  295. $res = GoodsMarketing::setData($installData);
  296. if ($res === false) throw new \Exception(GoodsMarketing::getStaticError());
  297. }
  298. $trans->commit();
  299. return true;
  300. } catch (\Exception $e) {
  301. $trans->rollBack();
  302. self::setStaticError($e->getMessage());
  303. return false;
  304. }
  305. }
  306. }