| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- <?php
- namespace api\modules\v1\controllers\user;
- use api\controllers\OnAuthController;
- use common\enums\StatusEnum;
- use common\enums\UserWalletEnum;
- use common\helpers\ApiCode;
- use common\helpers\LockHelper;
- use common\models\common\GlobalVarMap;
- use common\models\common\MallSetting;
- use common\models\user\DigitalLog;
- use common\models\user\User;
- use common\models\user\UserDigital;
- use services\common\UserWalletService;
- use Yii;
- use yii\db\Exception;
- class DigitalController extends OnAuthController
- {
- public $modelClass = '';
- public function beforeAction($action)
- {
- parent::beforeAction($action);
- $setting = MallSetting::conf($this->mall_id, 'digital');
- if (!$setting || !$setting['is_enable']) return $this->error('系统未开启');
- return $action;
- }
- /**
- *
- * 不用进行登录验证的方法
- *
- * 例如: ['index', 'update', 'create', 'view', 'delete']
- * 默认全部需要验证
- *
- * @var array
- */
- protected $authOptional = [];
- /**
- * 获取用户基本信息
- * @return array|mixed
- */
- public function actionUserInfo()
- {
- try {
- $setting = MallSetting::conf($this->mall_id, 'digital');
- $user_digital = UserDigital::findOne(['mall_id' => $this->mall_id, 'user_id' => $this->user_id, 'status' => StatusEnum::ENABLED]);
- $return['digital'] = $user_digital->digital ?? 0;
- //获取设置
- $return['enable_transfer'] = $setting['is_transfer'] ?? 0;
- $return['enable_to_balance'] = $setting['enable_to_balance'] ?? 0;
- $return['enable_to_score'] = $setting['enable_to_score'] ?? 0;
- $return['name'] = $setting['name'] ?? '数字币';
- $return['forwarding_charge'] = $setting['forwarding_charge'] ?? 0; //转送手续费
- $return['forwarding_charge'] = $return['forwarding_charge'] . '%';
- $return['to_balance_ratio'] = $setting['to_balance_ratio'] ?? 0; //数字币转余额比例
- $return['to_score_ratio'] = $setting['to_score_ratio'] ?? 0; //数字币转余额比例
- return $this->success(ApiCode::CODE_SUCCESS_TITLE, $return);
- } catch (\Exception $e) {
- return $this->error($e->getMessage());
- }
- }
- /**
- * 数字币列表
- */
- public function actionUserList()
- {
- try {
- $params = Yii::$app->request->get();
- $res = Yii::$app->services->validate->validate($params, [
- [['status'], 'safe'],
- ]);
- if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
- $status = $params['status'] == 1 ? DigitalLog::SEND_STATUS_NORMAL : DigitalLog::SEND_STATUS_FROZEN;
- $where[] = ['in', 'status', [StatusEnum::DISABLED, StatusEnum::ENABLED]];
- $where[] = ['mall_id' => $this->mall_id];
- $where[] = ['user_id' => $this->user_id];
- $where[] = ['send_status' => $status];
- $params['select'] = 'id,change_type,change_num,desc,from_type,capital_type,created_at,order_no';
- $params['order'] = 'id desc';
- $params['where'] = $where;
- $page_data = DigitalLog::listPage($params, false);
- $commission_map = GlobalVarMap::getEnumMapByType('FromTypeMap');
- $capital_type_map = GlobalVarMap::getEnumMapByType('CapitalTypeMap');
- foreach ($page_data['list'] as $key => $val) {
- $val['source_text'] = ($commission_map[$val['from_type']] ?? '') . ($capital_type_map[$val['capital_type']] ? '-' . $capital_type_map[$val['capital_type']] : '');
- $val['created_at'] = date('Y-m-d H:i:s', $val['created_at']);
- $page_data['list'][$key] = $val;
- }
- return $this->success(ApiCode::CODE_SUCCESS_TITLE, $page_data);
- } catch (\Exception $e) {
- return $this->error($e->getMessage());
- }
- }
- /**
- * 转送
- */
- public function actionTransfer()
- {
- if (Yii::$app->request->isPost) {
- $lock_key = 'digital_transfer_' . $this->user_id;
- $identification = uniqid();
- $t = \Yii::$app->db->beginTransaction();
- if (!LockHelper::lock($lock_key, $identification, 30, 5)) return $this->error('操作太频繁');
- try {
- $params = Yii::$app->request->post();
- $res = Yii::$app->services->validate->validate($params, [
- [['num', 'user_id'], 'required'],
- [['num', 'user_id'], 'integer'],
- [['num'], 'compare', 'compareValue' => 0, 'operator' => '>']
- ]);
- if ($res === false) throw new \Exception(Yii::$app->services->validate->getErrorMessage());
- $setting = MallSetting::conf($this->mall_id, 'digital');
- if (!$setting['is_transfer']) throw new \Exception('系统未开启转送功能');
- if ($params['user_id'] == $this->user_id) throw new Exception('赠送的用户不能是本人哦');
- $user_digital = UserDigital::findOne(['mall_id' => $this->mall_id, 'user_id' => $this->user_id, 'status' => StatusEnum::ENABLED]);
- if (!$user_digital || $user_digital->digital < $params['num']) throw new \Exception('超出可转数量');
- $forwarding_charge_radio = $setting['forwarding_charge'] ?? 0;
- $forwarding_charge = bcmul($params['num'], $forwarding_charge_radio / 100, 2);
- $need_deduct_digital = bcadd($params['num'], $forwarding_charge, 2);
- if ($user_digital->digital < $need_deduct_digital) throw new \Exception('超出可转数量');
- // 检查用户是否存在
- $receive_user = User::getUser([['id' => $params['user_id'], 'mall_id' => $this->mall_id]], 'id');
- if (empty($receive_user)) throw new Exception('赠送的用户不存在');
- //开启事务
- $setting = MallSetting::conf($this->mall_id, 'digital');
- $digital_name = $setting['name'] ?? '数字币';
- $send_data = [
- 'desc' => '用户id: ' . $user_digital['user_id'] . '向用户id: ' . $params['user_id'] . '转送' . $params['num'] . $digital_name,
- 'source_table' => User::tableName(),
- 'source_table_id' => $params['user_id'],
- 'from_type' => UserWalletEnum::TRANSFER,
- 'capital_type' => UserWalletEnum::TRANSFER_GIVE,
- 'contributor_id' => $user_digital['user_id'],
- 'contributor_money' => $forwarding_charge, //手续费
- 'contributor_name' => '转送'
- ];
- $res = UserDigital::handleUserDigital($this->mall_id, $user_digital['user_id'], $need_deduct_digital * -1, false, $send_data);
- if ($res === false) throw new \Exception(UserDigital::getStaticError());
- $receive_data = [
- 'desc' => '用户id: ' . $user_digital['user_id'] . '向用户id: ' . $params['user_id'] . '转送' . $params['num'] . $digital_name,
- 'source_table' => User::tableName(),
- 'source_table_id' => $user_digital['user_id'],
- 'from_type' => UserWalletEnum::TRANSFER,
- 'capital_type' => UserWalletEnum::TRANSFER_GIVE,
- 'contributor_id' => $user_digital['user_id'],
- 'contributor_name' => '转送'
- ];
- $res = UserDigital::handleUserDigital($this->mall_id, $params['user_id'], $params['num'], false, $receive_data);
- if ($res === false) throw new \Exception(UserDigital::getStaticError());
- $t->commit();
- LockHelper::uLock($lock_key, $identification);
- return $this->success('转送成功');
- } catch (\Exception $e) {
- $t->rollBack();
- LockHelper::uLock($lock_key, $identification);
- return $this->error($e->getMessage());
- }
- }
- }
- public function actionPreviewConvert()
- {
- try {
- if (!Yii::$app->request->isGet) throw new \Exception('this request method is not supported');
- $params = Yii::$app->request->get();
- $res = Yii::$app->services->validate->validate($params, [
- [['from', 'to'], 'required'],
- [['from', 'to'], 'string'],
- ]);
- if ($res === false) throw new \Exception(Yii::$app->services->validate->getErrorMessage());
- $setting = MallSetting::conf($this->mall_id, 'digital');
- $is_open_switch = 0;
- $from_text = $setting['name'];
- $to_text = '';
- $from_ratio = 1;
- $to_ratio = 0;
- if ($params['from'] == 'digital' && $params['to'] == 'balance') {
- $is_open_switch = $setting['enable_to_balance'] ?? 0;
- $to_text = Yii::$app->services->setting->mall->get($this->mall_id, 'balance.balance_name') ?? '余额';
- $to_ratio = $setting['to_balance_ratio'] ?? 0;
- } elseif ($params['from'] == 'digital' && $params['to'] == 'score') {
- $is_open_switch = $setting['enable_to_score'] ?? 0;
- $to_text = \Yii::$app->services->setting->mall->get($this->mall_id, 'score.score_name') ?? '积分';
- $to_ratio = $setting['to_score_ratio'] ?? 0;
- }
- if (empty($is_open_switch)) throw new \Exception('system is not allowed to this action');
- if (empty($to_ratio)) throw new \Exception('system is not corrected to set setting');
- $user_digital = UserDigital::findOne(['mall_id' => $this->mall_id, 'user_id' => $this->user_id, 'status' => StatusEnum::ENABLED]);
- $currency = $user_digital->digital ?? 0;
- return $this->success('数据请求成功', compact('currency', 'from_text', 'to_text', 'from_ratio', 'to_ratio'));
- } catch (\Exception $e) {
- return $this->error($e->getMessage());
- }
- }
- public function actionConvert()
- {
- if (Yii::$app->request->isPost) {
- $lock_key = 'digital_convert_' . $this->user_id;
- $identification = uniqid();
- $t = \Yii::$app->db->beginTransaction();
- if (!LockHelper::lock($lock_key, $identification, 30, 5)) return $this->error('操作太频繁');
- try {
- $params = Yii::$app->request->post();
- $res = Yii::$app->services->validate->validate($params, [
- [['num', 'from', 'to'], 'required'],
- [['num',], 'integer'],
- [['from', 'to'], 'string'],
- [['num'], 'compare', 'compareValue' => 0, 'operator' => '>']
- ]);
- if ($res === false) throw new \Exception(Yii::$app->services->validate->getErrorMessage());
- $setting = MallSetting::conf($this->mall_id, 'digital');
- $is_open_switch = 0;
- $from_text = $setting['name'] ?? '数字币';
- $to_text = '';
- $from_ratio = 1;
- $to_ratio = 0;
- if ($params['from'] == 'digital' && $params['to'] == 'balance') {
- $is_open_switch = $setting['enable_to_balance'] ?? 0;
- $to_text = Yii::$app->services->setting->mall->get($this->mall_id, 'balance.balance_name') ?? '余额';
- $to_ratio = $setting['to_balance_ratio'] ?? 0;
- } elseif ($params['from'] == 'digital' && $params['to'] == 'score') {
- $is_open_switch = $setting['enable_to_score'] ?? 0;
- $to_text = \Yii::$app->services->setting->mall->get($this->mall_id, 'score.score_name') ?? '积分';
- $to_ratio = $setting['to_score_ratio'] ?? 0;
- }
- if (empty($is_open_switch)) throw new \Exception('system is not allowed to this action');
- if (empty($to_ratio)) throw new \Exception('system is not corrected to set setting');
- $user_digital = UserDigital::findOne(['mall_id' => $this->mall_id, 'user_id' => $this->user_id, 'status' => StatusEnum::ENABLED]);
- if (!$user_digital || $user_digital->digital < $params['num']) throw new \Exception("当前{$from_text}不足");
- $get_num = bcdiv(bcmul($to_ratio, $params['num'], 2), $from_ratio, 2);
- $desc = $params['num'] . $from_text . '转为' . $get_num . $to_text;
- $send_data = [
- 'desc' => $desc,
- 'source_table' => UserDigital::tableName(),
- 'source_table_id' => $user_digital['id'],
- 'from_type' => UserWalletEnum::TRANSFER,
- 'capital_type' => UserWalletEnum::TRANSFER_GIVE
- ];
- $res = UserDigital::handleUserDigital($this->mall_id, $user_digital['user_id'], $params['num'] * -1, false, $send_data);
- if ($res === false) throw new \Exception(UserDigital::getStaticError());
- $handle_wallet = [
- 'mall_id' => $this->mall_id,
- 'user_id' => $this->user_id,
- 'is_frozen' => false,
- 'wallet_type' => $params['to'] == 'balance' ? UserWalletService::WALLET_TYPE_BALANCE : UserWalletService::WALLET_TYPE_SCORE,
- 'money' => $get_num,
- 'desc' => $desc,
- 'source_table' => UserDigital::tableName(),
- 'source_table_id' => $user_digital['id'],
- 'from_type' => UserWalletEnum::TRANSFER,
- 'capital_type' => UserWalletEnum::TRANSFER_GIVE
- ];
- $res = UserWalletService::handle(0, $handle_wallet);
- if (!$res) {
- $error_msg = UserWalletService::$static_error ?? $to_text . '转换失败';
- throw new \Exception($error_msg);
- }
- $t->commit();
- LockHelper::uLock($lock_key, $identification);
- return $this->success('转换成功');
- } catch (\Exception $e) {
- $t->rollBack();
- LockHelper::uLock($lock_key, $identification);
- return $this->error($e->getMessage());
- }
- }
- }
- }
|