| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- <?php
- namespace common\models\user;
- use addons\Devote\common\models\DevoteFrozenLog;
- use addons\Devote\common\models\DevoteWallet;
- use common\enums\AddonsEnum;
- use common\enums\StatusEnum;
- use common\helpers\LockHelper;
- use common\models\common\CapitalLog;
- use common\models\common\MallSetting;
- use common\models\mall\MallAddons;
- use Yii;
- use Exception;
- /**
- * This is the model class for table "{{%user_digital}}".
- *
- * @property int $id
- * @property int $mall_id 商城id
- * @property int $user_id 会员id
- * @property float $digital 可用数量
- * @property float $frozen_digital 冻结数量
- * @property int|null $status 状态[-1:删除;0:禁用;1启用]
- * @property int $created_at
- * @property int $updated_at
- */
- class UserDigital extends \common\models\base\BaseActiveRecord
- {
- /**
- * {@inheritdoc}
- */
- public static function tableName()
- {
- return '{{%user_digital}}';
- }
- /**
- * {@inheritdoc}
- */
- public function rules()
- {
- return [
- [['mall_id', 'user_id', 'status', 'created_at', 'updated_at'], 'integer'],
- [['digital', 'frozen_digital'], 'number'],
- ];
- }
- /**
- * {@inheritdoc}
- */
- public function attributeLabels()
- {
- return [
- 'id' => 'ID',
- 'mall_id' => 'Mall ID',
- 'user_id' => 'User ID',
- 'digital' => 'Digital',
- 'frozen_digital' => 'Frozen Digital',
- 'status' => 'Status',
- 'created_at' => 'Created At',
- 'updated_at' => 'Updated At',
- ];
- }
- private static function getKey($user_id)
- {
- return 'lock_user_digital_' . $user_id;
- }
- /**
- * 保存数据
- * @param array $params
- * @return bool|UserExtra
- */
- public static function setData(array $params)
- {
- try {
- if (!empty($params['user_id'])) {
- $model = self::findOne(['user_id' => $params['user_id']]);
- if (empty($model)) {
- $model = new self();
- $model->loadDefaultValues();
- }
- if (!$model->load($params, '') || !$model->save()) throw new Exception($model->getErrorMessage());
- return $model;
- }
- } catch (Exception $e) {
- self::$static_error = $e->getMessage();
- return false;
- }
- }
- /**
- * 操作用户账户
- * @param $mall_id
- * @param $user_id
- * @param $change_num
- * @param bool $is_frozen
- * @param array $params
- * @return bool
- */
- public static function handleUserDigital($mall_id, $user_id, $change_num, $is_frozen = false, $params = [])
- {
- if (bccomp($change_num, 0, 10) == 0) {
- self::$static_error = '操作金额为0';
- return false;
- }
- //获取设置是否启用
- $is_enable = MallSetting::conf($mall_id,'digital.is_enable');
- if(!$is_enable) {
- self::$static_error = '数字币未启用';
- return false;
- }
- $origin_change_num = $change_num;
- $lock_key = self::getKey($user_id);
- $identification = uniqid();
- if (LockHelper::lock($lock_key, $identification, 100, 100)) {
- $t = \Yii::$app->db->beginTransaction();
- try {
- $edit_field = $is_frozen ? 'frozen_digital' : 'digital';
- $user_wallet_model = self::findOne(['mall_id' => $mall_id, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
- if (empty($user_wallet_model)) {
- $user_wallet_model = self::setData([
- 'user_id' => $user_id,
- 'mall_id' => $mall_id,
- 'status' => StatusEnum::ENABLED
- ]);
- if (!$user_wallet_model) throw new Exception(self::getStaticError());
- }
- //扣除对应的贡献值
- $open_deduct_redpack = MallSetting::conf($mall_id,'digital.deduct_redpack');
- $is_installed_devote = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_DEVOTE);
- $from_type = $params['from_type'] ?? '';
- $is_addons = MallAddons::isInstall($mall_id, $from_type);
- $force_deduct_redpack = $params['force_deduct_redpack'] ?? false;
- if(($open_deduct_redpack || $force_deduct_redpack) && $is_installed_devote && $change_num > 0 && $is_addons){
- $deduct_redpack_ratio = MallSetting::conf($mall_id,'digital.deduct_redpack_ratio');
- $deduct_num = bcmul($deduct_redpack_ratio,$change_num,2);
- //发放数字币 需要扣除贡献值
- $params['addons_name'] = $from_type;
- $real_deduct_num = DevoteFrozenLog::deduct_frozen($mall_id,$user_id,$deduct_num,$params);
- if(!$real_deduct_num) throw new Exception('扣除贡献值失败');
- if($real_deduct_num != $deduct_num){
- //实际该发放的数字币
- $change_num = bcdiv($real_deduct_num,$deduct_redpack_ratio,2);
- }
- $desc = $params['desc'] ?? '';
- if($origin_change_num != $change_num && $desc){
- //用户(103939),获得订单(9224)分销商奖励,奖励类型:间推奖励,金额:279.80
- $params['desc'] = str_replace(':'.$origin_change_num,':'.$change_num,$desc);
- }
- }else{
- $is_installed_devote = empty($is_installed_devote) ? 'false' : 'true';
- $is_addons = empty($is_addons) ? 'false' : 'true';
- Yii::error(__CLASS__ . ' handleUserDigital notice : ' . $open_deduct_redpack.$is_installed_devote.$is_addons);
- }
- $current_num = $user_wallet_model->$edit_field;
- $after_num = bcadd($current_num, $change_num, 2);
- if (bccomp($after_num, 0, 10) < 0) {
- $msg = $is_frozen ? '冻结数字币' : '数字币';
- throw new Exception('用户' . $msg . '不足');
- }
- $user_wallet_model->$edit_field = $after_num;
- if (!$user_wallet_model->save()) throw new Exception($user_wallet_model->getErrorMessage());
- $log = [
- 'mall_id' => $mall_id,
- 'user_id' => $user_id,
- 'change_type' => $change_num > 0 ? CapitalLog::CHANGE_TYPE_ADD : CapitalLog::CHANGE_TYPE_SUB,
- 'change_num' => abs($change_num),
- 'current_num' => $current_num,
- 'desc' => $params['desc'] ?? '',
- 'source_table' => $params['source_table'] ?? '',
- 'source_table_id' => $params['source_table_id'] ?? 0,
- 'from_type' => $params['from_type'] ?? '',
- 'capital_type' => $params['capital_type'] ?? '',
- 'order_no' => $params['order_no'] ?? '',
- 'contributor_name' => $params['contributor_name'] ?? '',
- 'contributor_money' => $params['contributor_money'] ?? 0,
- 'contributor_id' => $params['contributor_id'] ?? 0,
- 'send_status' => $is_frozen ? DigitalLog::SEND_STATUS_FROZEN : DigitalLog::SEND_STATUS_NORMAL
- ];
- if (DigitalLog::setData($log) === false) throw new Exception(DigitalLog::getStaticError());
- $t->commit();
- LockHelper::uLock($lock_key, $identification);
- return abs($change_num);
- } catch (Exception $e) {
- Yii::error(__CLASS__ . ' handleUserDigital exception : ' . $e->getMessage() . ',user_id:' . $user_id);
- self::$static_error = $e->getMessage();
- $t->rollBack();
- LockHelper::uLock($lock_key, $identification);
- return false;
- }
- } else {
- //抢不到锁
- Yii::error(__CLASS__ . ' handleUserDigital error : 抢不到锁,user_id:' . $user_id);
- self::$static_error = '操作太频繁';
- return false;
- }
- }
- /**
- * 操作冻结数字币
- * @param $log_id
- * @param bool $is_send true-释放,false-取消
- * @return
- */
- public static function unfrozen($log_id, $is_send = true)
- {
- $t = \Yii::$app->db->beginTransaction();
- try {
- $log = DigitalLog::findOne(['id' => $log_id, 'status' => StatusEnum::ENABLED,'send_status' =>DigitalLog::SEND_STATUS_FROZEN ]);
- if (empty($log)) {
- throw new Exception('操作记录不存在');
- }
- $lock_key = self::getKey($log->user_id);
- $identification = uniqid();
- if (LockHelper::lock($lock_key, $identification, 100, 100)) {
- $user_wallet_model = self::findOne(['mall_id' => $log->mall_id, 'user_id' => $log->user_id, 'status' => StatusEnum::ENABLED]);
- $current_num = $user_wallet_model->frozen_digital;
- $after_num = bcsub($current_num, $log->change_num, 2);
- if (bccomp($after_num, 0, 10) < 0) {
- throw new Exception('用户冻结数字币不足');
- }
- $user_wallet_model->frozen_digital = $after_num;
- if ($is_send) {
- $log->send_status = DigitalLog::SEND_STATUS_NORMAL;
- $user_wallet_model->digital = bcadd($user_wallet_model->digital,$log->change_num,2);
- }else{
- $log->send_status = DigitalLog::SEND_STATUS_INVALID;
- }
- if (!$user_wallet_model->save()) throw new Exception($user_wallet_model->getErrorMessage());
- if (!$log->save()) throw new Exception($log->getErrorMessage());
- }
- $t->commit();
- LockHelper::uLock($lock_key, $identification);
- } catch (Exception $e) {
- $t->rollBack();
- Yii::error(__CLASS__ . ' unfrozen exception : ' . $e->getMessage());
- self::$static_error = $e->getMessage();
- return false;
- }
- }
- }
|