// +---------------------------------------------------------------------- declare (strict_types=1); namespace app\store\controller; use app\common\service\Order as OrderService; use app\common\service\SybOil; use app\store\model\Merchant as MerchantModel; use app\store\model\Company as CompanyModel; use app\store\model\company\BalanceLog as CompanyBalanceLogModel; use app\store\model\User as UserModel; use app\store\model\user\BalanceLog as BalanceLogModel; use app\store\model\Order as OrderModel; use app\store\model\Goods as GoodsModel; use think\response\Json; use think\Exception; use app\common\enum\merchant\balanceLog\Scene as SceneEnum; use app\common\lock\RedisLock; use think\facade\Db; use app\console\service\Order as OrderServiceNew; /** * 用户管理 * Class User * @package app\store\controller */ class User extends Controller { /** * 用户列表 * @return array * @throws \think\db\exception\DbException */ public function list() { /* $service = new OrderServiceNew; $service->deliveryEvent($this->storeId); print_r('111');*/ // 用户列表 $model = new UserModel; $list = $model->getList($this->request->param(), $this->store['user']); return $this->renderSuccess(compact('list')); } /** * 添加用户 * @return array|mixed * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function add() { $model = new UserModel; $data = $this->postForm(); if (empty($data['company_id'])) { return $this->renderError('请填写分油公司'); } if (empty($data['merchant_id'])) { return $this->renderError('请填写商户'); } if (empty($data['userType'])) { return $this->renderError('请填写用户角色'); } if (empty($data['userName'])) { return $this->renderError('请填写用户姓名'); } if (empty($data['mobile'])) { return $this->renderError('请填写用户手机号'); } if (empty($data['userIdCard'])) { return $this->renderError('请填写用户身份证号'); } $company = CompanyModel::detail($data['company_id']); // 对接平台接口 $res = $this->userOptAdd(['mobile'=>$data['mobile'],'userName'=>$data['userName'],'userIdCard'=>$data['userIdCard'],'userType'=>$data['userType']], $company); if($res['code'] == '00' && isset($res['data']['userNo'])){ $data['userNo'] = $res['data']['userNo']; }else{ return $this->renderError('平台创建用户失败【'.($res['errMessage'] ?? $res['message']).'】'); } // 新增记录 if ($model->add($data,$this->store['user'])) { return $this->renderSuccess('添加成功'); } return $this->renderError($model->getError() ?: '添加失败'); } /** * 用户详情 * @param int $userId * @return Json * @throws BaseException * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @throws \cores\exception\BaseException */ public function detail(int $userId): Json { $userInfo = UserModel::detail($userId); return $this->renderSuccess(compact('userInfo')); } /** * 编辑用户 * @param int $userId * @return Json * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @throws \cores\exception\BaseException */ public function edit(int $userId): Json { $model = UserModel::detail($userId); $data = $this->postForm(); // 更新记录 if ($model->edit($data)) { return $this->renderSuccess('更新成功'); } return $this->renderError($model->getError() ?: '更新失败'); } /** * 删除用户 * @param int $userId * @return array */ public function delete(int $userId) { // 用户详情 $model = UserModel::detail($userId); if ($model->setDelete()) { return $this->renderSuccess('删除成功'); } return $this->renderError($model->getError() ?: '删除失败'); } public function processUserOrders() { $redisLock = new RedisLock('user_order_lock'); $maxAttempts = 10; // 最大尝试次数 $attempt = 0; $sleepTime = 500000; // 每次尝试失败后的等待时间(微秒),500000微秒 = 0.5秒 while ($attempt < $maxAttempts) { $lockAcquired = $redisLock->acquireLock(); if ($lockAcquired) { break; } $attempt++; usleep($sleepTime); // 等待一段时间再尝试 } if (!$lockAcquired) { throw new Exception("网络繁忙请稍后"); } //$todayStart = strtotime(date('Y-m-d 00:00:00')); // 查找一个未被调用的用户 $account = Db::name('account') ->alias('a') ->join('company c', 'a.company_id = c.company_id') ->where('a.last_called_at', '=', 0) ->where('c.status', '=', 10) ->field('a.*') ->limit(1) ->find(); if (!$account) { throw new Exception("没有可用的用户"); } // 更新用户的 `last_called_at` Db::name('account') ->where('account_id', $account['account_id']) ->update(['last_called_at' => time()]); $redisLock->releaseLock(); return $account; } /** * 用户分油 * @param int $userId * @param string $target * @return array|mixed */ public function oil(int $userId, string $target) { $data = $this->postForm(); $user = UserModel::detail($userId); $data['amount'] = $data['amount']??0; $data['goodsNo'] = $data['goodsNo']??''; // 用户详情 $model = new OrderModel(); if (empty($data['oilCardType'])) { return $this->renderError('请填写卡券类型'); } if ($data['oilCardType'] == 'card' && empty($data['amount'])) { return $this->renderError('请填写分油金额'); } if ($data['oilCardType'] != 'card' && empty($data['goods_id'])) { return $this->renderError('请选择油券'); } if($data['goods_id']) { $goods = GoodsModel::detail($data['goods_id']); $data['goodsNo'] = $goods['goods_no']; $data['amount'] = $goods['goods_price_max']; // 金额 } // 查询用户余额 if($data['amount'] > $user['balance']){ return $this->renderError('用户余额不足'); } $saleOrderNo = OrderService::createOrderNo(); try { // 查找一个未被调用的用户 $account = $this->processUserOrders(); } catch (Exception $e) { return $this->renderError($e->getMessage()); } $company = CompanyModel::detail($account['company_id']); // 查询公司余额 if($data['amount'] > $company['balance']){ return $this->renderError('公司余额不足'); } $SybOil = new SybOil(); // 对接平台接口 $res = $SybOil->oilOilCardShare(['goodsNo'=>$data['goodsNo'],'amount'=>$data['amount'],'userNo'=>$account['userNo'],'mobile'=>$account['mobile'],'saleOrderNo'=>$saleOrderNo,'oilCardType'=>$data['oilCardType']], $company); //$res = json_decode('{"code":"00","message":"请求成功","errCode":null,"errMessage":null,"data":{"oilCardNo":null,"amount":100,"balance":null,"shareNo":"CDV2407271355570001"}}',true); if($res['code'] == '00'){ $data['saleOrderNo'] = $saleOrderNo; $data['oilCardNo'] = $data['oilCardType'] == 'zsy_ticket' ? $res['data']['shareNo'] : $res['data']['oilCardNo']; $data['amount'] = $res['data']['amount']; $data['shareNo'] = $res['data']['shareNo'] ?? ''; $data['company_id'] = $account['company_id']; $data['account_id'] = $account['account_id']; $data['userNo'] = $account['userNo']; $data['mobile'] = $account['mobile']; }else{ return $this->renderError('平台分油失败【'.($res['errMessage'] ?? $res['message']).'】'); } $data['user_id'] = $user['user_id']; $data['store_id'] = $user['store_id']; $data['payType'] = 10; if ($model->addOil($data)) { // 更新用户余额 UserModel::setDecBalance((int)$user['user_id'], (float)$data['amount']); BalanceLogModel::add(SceneEnum::CONSUME, [ 'user_id' => (int)$user['user_id'], 'money' => -(float)$data['amount'], ], ['saleOrderNo' => $saleOrderNo]); // 累积用户总消费金额 UserModel::setIncPayMoney($user['user_id'], (float)$data['amount']); // 更新公司余额 CompanyModel::setDecBalance((int)$user['company_id'], (float)$data['amount']); CompanyBalanceLogModel::add(SceneEnum::CONSUME, [ 'company_id' => (int)$user['company_id'], 'money' => -(float)$data['amount'], ], ['saleOrderNo' => $saleOrderNo]); return $this->renderSuccess('操作成功'); } return $this->renderError($model->getError() ?: '操作失败'); } /** * 用户充值 * @param int $userId * @param string $target * @return array */ public function recharge(int $userId, string $target) { // 用户详情 $model = UserModel::detail($userId); if ($model->recharge($target, $this->postForm())) { return $this->renderSuccess('操作成功'); } return $this->renderError($model->getError() ?: '操作失败'); } /** * 修改会员等级 * @param int $userId * @return array */ public function grade(int $userId) { // 用户详情 $model = UserModel::detail($userId); if ($model->updateGrade($this->postForm())) { return $this->renderSuccess('操作成功'); } return $this->renderError($model->getError() ?: '操作失败'); } /** * 获取所有商户 * @return mixed * @throws \think\exception\DbException */ public function merchant(): Json { $user = $this->store['user']; $list = MerchantModel::getAll($user); return $this->renderSuccess(compact('list','user')); } }