'订单', self::REFLUX_TYPE_WITHDRAW => '提现', ]; const IS_SEND_TRUE = 1; const IS_SEND_FALSE = 0; /** * {@inheritdoc} */ public static function tableName() { return '{{%integral_appreciation_pool_sub}}'; } public function behaviors() { return [ [ 'class' => TimestampBehavior::class ] ]; } /** * {@inheritdoc} */ public function rules() { return [ [['id', 'store_id', 'user_id', 'order_id', 'reflux_type', 'is_send_integral'], 'integer'], [['amount', 'integral_price', 'integral', 'after_integral_price', 'created_at', 'updated_at'], 'number'] ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => '', 'store_id' => '店铺ID', 'user_id' => '用户ID', 'order_id' => '用户订单ID/提现ID', 'amount' => '贡献底池金额', 'integral_price' => '当前积分价格', 'after_integral_price' => '当前积分价格', 'integral' => '可得的积分数量', 'is_send_integral' => '订单回流类型下是否给用户发放完积分', 'reflux_type' => '回流类型:0=订单;1=提现', 'created_at' => '', 'updated_at' => '', ]; } //计算积分金额 积分价格 添加奖金池 /** * 设置发放活动积分 * 订单情况流程:假设A在商城中下单购买商品 该商品中设置的活动金额为30元 将30元根据后台设置的奖金池铸造积分百分比拿出来铸造积分 假设设置的70% * 那可铸造出21积分 再获取奖金池中的积分价格(没有的话 就获取后台设置的初始积分价格)假设价格是1 那么 获取到用户实际可得的积分数量为21 / 1 = 21 * 此时积分价格就变成了30 / 21 = 1.43元/积分 * 假设有用户下单也是30元商品 那就还是铸造出21积分 积分价格为1.43元/积分 那么当前用户可获得的积分数量为21 / 1.43 = 14.68个积分数量 * 此时积分价格就变成了(30 + 30) / (21 + 14.68) = 1.68元/积分 * ... **/ public static function setPool($order_id, $store_id, $reflux_type = self::REFLUX_TYPE_ORDER) { $transaction = \Yii::$app->db->beginTransaction(); try { $integral_appreciation_setting = Option::get('integral_appreciation_setting', $store_id, 'integral_appreciation')['value']; $integral_appreciation_setting = json_decode($integral_appreciation_setting ?? '', true); //如果是订单 if (intval($reflux_type) === self::REFLUX_TYPE_ORDER) { $order = Order::findOne($order_id); if (!$order) { throw new \Exception('订单不存在'); } if (!intval($order->is_sale)) { throw new \Exception('订单未过售后期'); } $is_repeat = self::findOne(['order_id' => $order_id, 'reflux_type' => self::REFLUX_TYPE_ORDER]); if ($is_repeat) { throw new \Exception('订单已参与过'); } $order_goods = OrderDetail::find()->where(['order_id' => $order_id])->select('goods_id, num') ->asArray()->all(); $integral_goods_amount = 0; foreach ($order_goods as $order_goods_item) { //计算订单中可为奖金池底池增加多少金额 $integral_goods_amount += IntegralAppreciationGoods::find()->where(['store_id' => $order->store_id, 'is_delete' => 0]) ->andWhere(['goods_id' => $order_goods_item['goods_id']])->sum('reflux_amount') ?: 0; $integral_goods_amount = bcmul($integral_goods_amount, $order_goods_item['num'], 2); } if ($integral_goods_amount <= 0) { throw new \Exception('当前订单未产生奖金池金额order_no=' . $order->order_no); } //计算当前订单可铸造多少积分 $integral_amount_to_integral_profit = $integral_appreciation_setting['integral_amount_to_integral_profit'] ?: 0; //计算出积分数量 $integral_num = round(($integral_goods_amount * $integral_amount_to_integral_profit) / 100, 2); //获取当前奖金池中的积分价格 $integral_price = 0; $pool = IntegralAppreciationPool::findOne(['store_id' => $order->store_id]); if ($pool) { $integral_price = $pool->integral_price; } else { $pool = new IntegralAppreciationPool(); $pool->store_id = $store_id; //方便计算积分价格趋势 给个默认值 $model = new self(); $model->store_id = $store_id; $model->user_id = 0; $model->order_id = 0; $model->amount = 0; $model->integral_price = 0; $model->integral = 0; $model->is_send_integral = self::IS_SEND_TRUE; $model->reflux_type = self::REFLUX_TYPE_ORDER; $model->after_integral_price = $integral_appreciation_setting['integral_init_price'] ?: 0; if (!$model->save()) { throw new \Exception(json_encode($model->errors, JSON_UNESCAPED_UNICODE)); } } //如果没有获取到积分价格 就使用设置项中的积分初始价格 if ($integral_price <= 0) { $integral_price = $integral_appreciation_setting['integral_init_price'] ?: 0; } if ($integral_price <= 0) { throw new \Exception('当前活动未设置积分初始价格' ); } //计算用户可获得的积分数量 $user_integral_num = round($integral_num / $integral_price, 2); //写入数据 //..... //计算积分价格 写入到奖金池表 //积分价格计算方式:奖金池总额 / 所有用户当前拥有的积分数量 (todo 修改积分价格计算方式:奖金池总额/积分池总积分) $user_total_integral = IntegralAppreciationUser::find()->where(['store_id' => $store_id])->sum('integral') ?: 0; $user_total_integral = bcadd($user_total_integral, $user_integral_num, 2); $amount = $pool->amount ?: 0; $pool->amount = bcadd($amount, $integral_goods_amount, 2); $pool->total_integral = bcadd($pool->total_integral, $user_integral_num, 2); $pool->integral_price = $pool->total_integral > 0 ? round($pool->amount / $pool->total_integral, 2) : 0; $pool->total_user_integral = $user_total_integral; $pool->save(); $model = new self(); $model->store_id = $store_id; $model->user_id = $order->user_id; $model->order_id = $order->id; $model->amount = $integral_goods_amount; $model->integral_price = $integral_price; $model->integral = $user_integral_num; $model->is_send_integral = self::IS_SEND_TRUE; $model->reflux_type = self::REFLUX_TYPE_ORDER; $model->after_integral_price = $pool->integral_price; if (!$model->save()) { throw new \Exception(json_encode($model->errors, JSON_UNESCAPED_UNICODE)); } //发放积分 $integral_appreciation_user = IntegralAppreciationUser::findOne(['user_id' => $order->user_id]); if (!$integral_appreciation_user) { $integral_appreciation_user = new IntegralAppreciationUser(); $integral_appreciation_user->user_id = $order->user_id; $integral_appreciation_user->store_id = $store_id; } $integral_appreciation_user->total_integral = bcadd($integral_appreciation_user->total_integral, $user_integral_num, 2); $integral_appreciation_user->integral = bcadd($integral_appreciation_user->integral, $user_integral_num, 2); if (!$integral_appreciation_user->save()) { throw new \Exception(json_encode($integral_appreciation_user->errors, JSON_UNESCAPED_UNICODE)); }; $result = IntegralAppreciationUserIntegralLog::saveIntegralLog( $integral_appreciation_user->id, $user_integral_num, IntegralAppreciationUserIntegralLog::TYPE_INCOME, IntegralAppreciationUserIntegralLog::SOURCE_TYPE_CAST_INTEGRAL, "订单{$order->order_no}过售后期铸造积分", $order_id ); if ($result['code']) { throw new \Exception('操作失败'); } } else { $cash = Cash::findOne(['id' => $order_id, 'store_id' => $store_id]); if (!$cash) { throw new \Exception('提现记录不存在'); } if (intval($cash->cash_type) !== Cash::IS_CASH_TYPE_INTEGRAL_APPRECIATION) { throw new \Exception('非增值积分提现'); } if (!in_array(intval($cash->status), [$cash::STATUS_GIVEN, $cash::STATUS_HAND])) { throw new \Exception('提现未通过'); } $integral_cash_log = IntegralAppreciationCashLog::findOne(['cash_id' => $cash->id]); if (!$integral_cash_log) { throw new \Exception('未找到增值积分提现'); } $integral_price = 0; $pool = IntegralAppreciationPool::findOne(['store_id' => $store_id]); if ($pool) { $integral_price = $pool->integral_price; } else { $pool = new IntegralAppreciationPool(); $pool->store_id = $store_id; //方便计算积分价格趋势 给个默认值 $model = new self(); $model->store_id = $store_id; $model->user_id = 0; $model->order_id = 0; $model->amount = 0; $model->integral_price = 0; $model->integral = 0; $model->is_send_integral = self::IS_SEND_TRUE; $model->reflux_type = self::REFLUX_TYPE_WITHDRAW; $model->after_integral_price = $integral_appreciation_setting['integral_init_price'] ?: 0; if (!$model->save()) { throw new \Exception(json_encode($model->errors, JSON_UNESCAPED_UNICODE)); } } //如果没有获取到积分价格 就使用设置项中的积分初始价格 if ($integral_price <= 0) { $integral_price = $integral_appreciation_setting['integral_init_price'] ?: 0; } //积分价格计算方式:奖金池总额 / 所有用户当前拥有的积分数量 // $user_total_integral = IntegralAppreciationUser::find()->where(['store_id' => $store_id])->sum('integral') ?: 0; $amount = $pool->amount ?: 0; $pool->amount = bcadd($amount, $integral_cash_log->reflux_price, 2); $pool->total_integral = bcadd($pool->total_integral, 0, 2); $pool->total_user_integral = bcadd($pool->total_user_integral, 0, 2); $pool->integral_price = $pool->total_integral > 0 ? round($pool->amount / $pool->total_integral, 2) : 0; if (!$pool->save()) { throw new \Exception(json_encode($pool->errors, JSON_UNESCAPED_UNICODE)); }; $model = new self(); $model->store_id = $store_id; $model->user_id = $cash->user_id; $model->order_id = $cash->id; $model->amount = $integral_cash_log->reflux_price; $model->integral_price = $integral_price; $model->integral = 0; $model->is_send_integral = self::IS_SEND_TRUE; $model->reflux_type = self::REFLUX_TYPE_WITHDRAW; $model->after_integral_price = $pool->integral_price; if (!$model->save()) { throw new \Exception(json_encode($model->errors, JSON_UNESCAPED_UNICODE)); } } $transaction->commit(); return [ 'code' => 0, 'msg' => '操作成功' ]; } catch (\Exception $e) { $transaction->rollBack(); return [ 'code' => 1, 'msg' => $e->getMessage() ]; } } }