| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- <?php
- namespace addons\Bargain\common\models;
- use addons\Bargain\common\enums\BargainEnum;
- use addons\Bargain\common\models\BargainOrder;
- use common\enums\RedisKeyEnum;
- use common\enums\StatusEnum;
- use common\helpers\LockHelper;
- use common\models\base\BaseActiveRecord;
- use common\models\goods\Goods;
- use common\models\user\User;
- use common\models\user\UserLevel;
- use Yii;
- /**
- * This is the model class for table "qimall_addons_bargain_user_order".
- *
- * @property int $id
- * @property int $mall_id
- * @property int $user_id
- * @property int $bargain_order_id 砍价订单ID
- * @property float $price 砍价的金额
- * @property string $token
- * @property int $status 状态[-1:删除;0:禁用;1启用]
- * @property int $created_at
- * @property int $updated_at
- */
- class BargainUserOrder extends BaseActiveRecord
- {
- /**
- * {@inheritdoc}
- */
- public static function tableName()
- {
- return '{{%addons_bargain_user_order}}';
- }
- /**
- * {@inheritdoc}
- */
- public function rules()
- {
- return [
- [['mall_id', 'user_id', 'bargain_order_id', 'status', 'created_at', 'updated_at'], 'integer'],
- [['price'], 'number'],
- [['token'], 'string', 'max' => 255],
- ];
- }
- /**
- * {@inheritdoc}
- */
- public function attributeLabels()
- {
- return [
- 'id' => 'ID',
- 'mall_id' => 'Mall ID',
- 'user_id' => 'User ID',
- 'bargain_order_id' => '砍价订单ID',
- 'price' => '砍价的金额',
- 'token' => 'Token',
- 'status' => '状态[-1:删除;0:禁用;1启用]',
- 'created_at' => 'Created At',
- 'updated_at' => 'Updated At',
- ];
- }
- // 关联模型
- public function getUser()
- {
- return $this->hasOne(User::class, ['id' => 'user_id']);
- }
- public function getOrder()
- {
- return $this->hasOne(BargainOrder::class, ['id' => 'bargain_order_id']);
- }
- public static function userJoinBargain($params)
- {
- $stock_locks = [];
- $t = Yii::$app->db->beginTransaction();
- try {
- $lock_key = RedisKeyEnum::LOCK_BARGAIN_ORDER . $params['bargain_order_id'];
- $identification = uniqid();
- if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new \Exception('当前访问人数过多');
- $stock_locks[$lock_key] = $identification;
- $user_join_order_list = self::findAll(['mall_id' => $params['mall_id'], 'bargain_order_id' => $params['bargain_order_id'], 'status' => StatusEnum::ENABLED]);
- foreach ($user_join_order_list as $val) {
- if ($val['user_id'] == $params['user_id']) throw new \Exception('您已参与过本次砍价');
- }
- $bargain_order = BargainOrder::findOne(['mall_id' => $params['mall_id'], 'id' => $params['bargain_order_id']]);
- if (empty($bargain_order)) throw new \Exception('砍价活动已关闭');
- if ($bargain_order->order_status == BargainEnum::ORDER_SUCCESS) throw new \Exception('砍价已完成');
- if ($bargain_order->order_status == BargainEnum::ORDER_FAILURE) throw new \Exception('砍价失败');
- $active = BargainActive::findOne(['mall_id' => $params['mall_id'], 'id' => $bargain_order->bargain_active_id]);
- if (($bargain_order->created_at + $active['time'] * 3600) <= time()) throw new \Exception('砍价已结束');
- $bargain_goods_data = json_decode($bargain_order->bargain_goods_data,true);
- if ($active->stock <= 0 && $bargain_goods_data['type'] == 1) throw new \Exception('商品已售罄,暂时无法砍价哦~');
- if ($bargain_order->user_id != $params['user_id'] ||
- ($bargain_order->user_id == $params['user_id'] && $active->is_creator_exempt == 0)) {
- //判断用户等级能否参与砍价
- self::checkUserBargain($params, $active);
- //判断用户能否参与砍价
- self::checkUserBargainTime($params, $active, $bargain_order);
- }
- // 已砍价金额
- $total_price = array_sum(array_column($user_join_order_list, 'price'));
- // 参与砍价人数
- $total_people = count($user_join_order_list);
- // 剩余可砍价金额
- $reset_price = floatval($bargain_order->price) - floatval($bargain_order->min_price) - $total_price;
- $reset_price = $reset_price <= 0 ? 0 : $reset_price;
- if ($reset_price <= 0){
- //todo
- //推送一条信息给发布砍价的用户
- throw new \Exception('已砍至最低价');
- }
- $price = self::intToFloat(self::getPrice($reset_price, $total_people, $bargain_order->bargain_goods_data));
- $model = new self();
- $model->user_id = $params['user_id'];
- $model->mall_id = $params['mall_id'];
- $model->price = $price;
- $model->token = \Yii::$app->security->generateRandomString();
- $model->bargain_order_id = $params['bargain_order_id'];
- $res = $model->save();
- if ($res == false) throw new \Exception(self::getStaticError());
- $active->participant += 1;
- if ($price == $reset_price) $active->min_price_goods += 1;
- $res = $active->save();
- if ($res == false) throw new \Exception(BargainActive::getStaticError());
- $bargain_order->reduce_price+=$price;
- if($bargain_order->reduce_price==$bargain_order->min_price) $bargain_order->order_status = BargainEnum::ORDER_SUCCESS;
- $res = $bargain_order->save();
- if ($res == false) throw new \Exception($bargain_order->getErrorMessage());
- $t->commit();
- LockHelper::batchUlock($stock_locks);
- $info = [
- 'nickname' => $model->user->nickname ?? '',
- 'price' => $model->price,
- 'user_id' => $model->user_id,
- ];
- $start = substr($bargain_order->user->mobile,0,3);
- $end = substr($bargain_order->user->mobile,-4,4);
- $mobile = $start.'****'.$end;
- $bargain = [
- 'nickname' => $bargain_order->user->nickname ?? '',
- 'mobile' => $mobile,
- 'avatar_url' => $bargain_order->user->avatar_url ?? '',
- 'user_id' => $bargain_order->user_id,
- ];
- return ['info' => $info, 'bargain' => $bargain];
- } catch (\Exception $e) {
- LockHelper::batchUlock($stock_locks);
- $t->rollback();
- self::$static_error = $e->getMessage();
- return false;
- }
- }
- /**
- * @desc:砍价算法
- * @Author: hua
- * @Date: 2022/1/3
- * @Time: 15:46
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $reset_price
- * @param $people
- * @param $bargain_goods_data
- * @return float|int
- */
- private static function getPrice($reset_price, $people, $bargain_goods_data)
- {
- $data = json_decode($bargain_goods_data);
- if (isset($data->bargain_people)) {
- $dataPeople = intval($data->bargain_people);
- if ($dataPeople != 0) {
- if ($people == $dataPeople - 1) {
- return $reset_price * 100;
- }
- if ($people >= $dataPeople) return 0;
- }
- }
- if ($people < intval($data->bargain_human)) {
- $min = $data->bargain_first_min_price > $data->bargain_first_max_price ? $data->bargain_first_max_price : $data->bargain_first_min_price;
- $max = $data->bargain_first_min_price > $data->bargain_first_max_price ? $data->bargain_first_min_price : $data->bargain_first_max_price;
- } else {
- $min = min($data->bargain_second_min_price, $data->bargain_second_max_price);
- $max = max($data->bargain_second_min_price, $data->bargain_second_max_price);
- }
- $money = mt_rand($min * 100, $max * 100);
- if ($money > $reset_price * 100) $money = (round($reset_price, 2)) * 100;
- return intval($money);
- }
- // int转float
- private static function intToFloat($int)
- {
- // 去除原来计算保留两个小数点
- return bcdiv($int, 100, 2);
- }
- /**
- * 指定位置插入字符串
- * @param $str string 原字符串
- * @param $i integer 插入位置
- * @param $substr string 插入字符串
- * @return string 处理后的字符串
- */
- private static function insertToStr($str, $i, $substr)
- {
- //指定插入位置前的字符串
- $startStr = substr($str, 0, $i);
- //指定插入位置后的字符串
- $lastStr = substr($str, -2);
- //将插入位置前,要插入的,插入位置后三个字符串拼接起来
- $str = $startStr . $substr . $lastStr;
- //返回结果
- return $str;
- }
- public function sendMessage($mall_id,$open_id,$total_price,$min_price,$temp_id){
- $notice_wechat = \Yii::$app->services->setting->mall->get(5, 'notice_wechat');
- if(!empty($notice_wechat['is_miniapp_priority'])){
- $mini_program = \Yii::$app->services->setting->mall->get($mall_id, 'mini_program');
- if (!empty($mini_program)) {
- \Yii::$app->params['wechatMiniProgramConfig'] = [
- 'app_id' => $mini_program['app_id'],
- 'secret' => $mini_program['secret'],
- 'key' => $mini_program['pay_secret'] ?? '',
- 'cert_path' => $mini_program['cert_pem_path'] ?? '',
- 'key_path' => $mini_program['key_pem_path'] ?? '',
- 'notify_url' => ''//回调地址
- ];
- }
- $app = \Yii::$app->wechat->miniProgram;
- }else{
- $wechat = \Yii::$app->services->setting->mall->get($mall_id, 'wechat');
- if ($wechat) {
- \Yii::$app->params['wechatConfig'] = [
- 'app_id' => $wechat['app_id'] ?? '',
- 'secret' => $wechat['secret'] ?? '',
- 'token' => $wechat['token'] ?? '',
- 'aes_key' => $wechat['aes_key'] ?? '',
- ];
- }
- $app = \Yii::$app->wechat->app;
- }
- $send_data = [
- 'first' => '你发布的商品已经砍价成功',
- 'keyword1' => '砍掉'.$total_price."元",
- 'keyword2' => date("Y-m-d H:i:s"),
- 'keyword3' => $min_price,
- 'remark' => '已砍至最低价,快来买我吧!!'
- ];
- $pageUrl = '/plugins2/bargain/joinBargain?id=' . '1';
- $h5_url = 'https://h5.qijianshirjcs.com' . "/h5/#" . $pageUrl;
- $app->template_message->send([
- 'touser' => $open_id,
- 'template_id' => $temp_id,
- 'url' => $h5_url,
- 'data' => $send_data,
- ]);
- }
- public static function checkUserBargain($params, $active)
- {
- $bargain_limit_user_level = empty($active->bargain_limit_user_level) ? [] : $active->bargain_limit_user_level;
- if (empty($bargain_limit_user_level)) {
- return true;
- }
- $user = User::find()
- ->where(['id' => $params['user_id'], 'status' => StatusEnum::ENABLED])
- ->select('id,level')
- ->asArray()
- ->one();
- if (empty($user)) {
- throw new \Exception('用户信息不存在');
- }
- $mall_level_info = UserLevel::find()
- ->where([
- 'mall_id' => $params['mall_id'],
- 'status' => StatusEnum::ENABLED
- ])
- ->andWhere(['in', 'id', $bargain_limit_user_level])
- ->select('id,level')
- ->asArray()
- ->all();
- $join_level = $mall_level_info ? array_column($mall_level_info, 'level') : [];
- if (in_array(0, $bargain_limit_user_level)) {
- $join_level[] = 0;
- }
- if (!in_array($user['level'], $join_level)) {
- throw new \Exception('很抱歉!您暂时无法帮砍~');
- }
- }
- public static function checkUserBargainTime($params, $active, $bargain_order)
- {
- //统计用户参与该活动的次数
- $model = (new \yii\db\Query())
- ->from('qimall_addons_bargain_order o')
- ->innerJoin('qimall_addons_bargain_user_order u', 'o.id = u.bargain_order_id')
- ->where([
- 'o.bargain_active_id' => $active->id,
- 'u.user_id' => $params['user_id'],
- 'o.status' => StatusEnum::ENABLED,
- 'u.status' => StatusEnum::ENABLED
- ]);
- if ($active['is_creator_exempt']) {
- $model->andWhere(['<>', 'o.user_id', $params['user_id']]);
- }
- $records = $model->select('o.user_id,u.bargain_order_id,u.user_id as bargain_user_id')
- ->all();
- $count = count($records);
- if (!empty($active->bargain_time)) {
- if ($count >= $active->bargain_time) {
- throw new \Exception('您的帮砍次数不足,去看看其它活动吧~');
- }
- }
- if ($count > 0 && empty($active->is_repeat_bargain)) {
- //不允许帮同个用户但不同砍价订单重复帮砍
- foreach ($records as $record) {
- if ($record['user_id'] == $bargain_order->user->id) {
- throw new \Exception('您已经帮ta砍过一次啦,不可以重复帮砍哦~');
- }
- }
- }
- }
- }
|