// +---------------------------------------------------------------------- namespace app\controller\cashier; use app\Request; use app\services\cashier\UserServices; use app\services\store\StoreUserServices; use app\controller\api\v2\activity\UserCode; use app\services\order\{OtherOrderServices, StoreCartServices, StoreDeliveryOrderServices, StoreOrderCartInfoServices, StoreOrderCommentServices, StoreOrderComputedServices, StoreOrderCreateServices, StoreOrderEconomizeServices, StoreOrderRefundServices, StoreOrderServices, StoreOrderStatusServices, StoreOrderSuccessServices, StoreOrderTakeServices, StoreOrderPromotionsServices, StoreOrderWriteOffServices }; use app\services\store\SystemStoreStaffServices; use app\services\user\level\SystemUserLevelServices; use app\services\user\member\MemberCardServices; use app\services\activity\discounts\StoreDiscountsServices; use app\services\activity\collage\UserCollageCodeServices; use app\webscoket\SocketPush; use crmeb\services\CacheService; use think\exception\ValidateException; use think\facade\Log; /** * 收银台用户控制器 */ class User extends AuthController { private $userCode; protected $getChennel = [ 'weixin' => 0, 'routine' => 1, 'weixinh5' => 2, 'pc' => 3, 'app' => 4 ]; protected $addressInfo = [ 'id' => 0, 'real_name' => '', 'phone' => '', 'province' => '', 'city' => '', 'district' => '', 'street' => '', 'detail' => '', 'longitude' => '', 'latitude' => '' ]; /** * 修改收银员信息 * @param Request $request * @param SystemStoreStaffServices $services * @return mixed */ public function __construct(UserCollageCodeServices $services) { // 创建UserCode的实例 $this->userCode = new UserCode($services); } public function updatePwd(Request $request, SystemStoreStaffServices $services) { $data = $request->postMore([ ['real_name', ''], ['pwd', ''], ['new_pwd', ''], ['conf_pwd', ''], ['avatar', ''], ]); if ($data['pwd'] && !preg_match('/^(?![^a-zA-Z]+$)(?!\D+$).{6,}$/', $data['new_pwd'])) { return $this->fail('设置的密码过于简单(不小于六位包含数字字母)'); } if ($services->updateStaffPwd($this->cashierId, $data)) return $this->success('修改成功'); else return $this->fail('修改失败'); } /** * 获取登录店员详情 * @return mixed */ public function getCashierInfo() { return $this->success($this->cashierInfo); } /** * 收银台选择用户列表 * @param Request $request * @param UserServices $services * @return mixed */ public function getUserList(Request $request, StoreUserServices $storeUserservices, \app\services\user\UserServices $services) { $data = $request->getMore([ ['keyword', ''], ['field_key', ''] ]); if ($data['keyword']) { if ($data['field_key'] == 'all') { $data['field_key'] = ''; } if ($data['field_key'] && in_array($data['field_key'], ['uid', 'phone', 'bar_code'])) { $where[$data['field_key']] = trim($data['keyword']); } else { $where['store_like'] = trim($data['keyword']); } $where['is_filter_del'] = 1; $list = $services->getUserList($where); if (isset($list['list']) && $list['list']) { foreach ($list['list'] as &$item) { //用户类型 if ($item['user_type'] == 'routine') { $item['user_type'] = '小程序'; } else if ($item['user_type'] == 'wechat') { $item['user_type'] = '公众号'; } else if ($item['user_type'] == 'h5') { $item['user_type'] = 'H5'; } else if ($item['user_type'] == 'pc') { $item['user_type'] = 'PC'; } else if ($item['user_type'] == 'app') { $item['user_type'] = 'APP'; } else $item['user_type'] = '其他'; } } return $this->success($list); } else { return app('json')->success($storeUserservices->index($data, $this->storeId)); } } /** * 获取当前门店店员列表和店员信息 * @param Request $request * @param SystemStoreStaffServices $services * @return mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getCashierList(Request $request, SystemStoreStaffServices $services) { $where = $request->getMore([ ['keyword', ''] ]); $where['store_id'] = $this->storeId; $where['is_del'] = 0; return $this->success([ 'staffInfo' => $request->cashierInfo(), 'staffList' => $services->getStoreStaff($where), 'count' => $services->count($where) ]); } /** * 游客切换到用户 * @param Request $request * @param StoreCartServices $services * @param $cashierId * @return mixed */ public function switchCartUser(Request $request, StoreCartServices $services, $cashierId) { [$uid, $toUid, $isTourist] = $request->postMore([ ['uid', 0], ['to_uid', 0], ['is_tourist', 0] ], true); if ($isTourist && $uid) { $where = ['tourist_uid' => $uid, 'store_id' => $this->storeId, 'staff_id' => $cashierId]; $touristCart = $services->getCartList($where); if ($touristCart) { $userWhere = ['uid' => $toUid, 'store_id' => $this->storeId, 'staff_id' => $cashierId]; $userCarts = $services->getCartList($userWhere); if ($userCarts) { foreach ($touristCart as $cart) { foreach ($userCarts as $userCart) { //游客商品 存在用户购物车商品中 if ($cart['product_id'] == $userCart['product_id'] && $cart['product_attr_unique'] == $userCart['product_attr_unique']) { //修改用户商品数量 删除游客购物车这条数据 $services->update(['id' => $userCart['id']], ['cart_num' => bcadd((string)$cart['cart_num'], (string)$userCart['cart_num'])]); $services->delete(['id' => $cart['id']]); } } } } //发送消息 try { SocketPush::instance() ->to($this->cashierId) ->setUserType('cashier') ->type('changCart') ->data(['uid' => $uid]) ->push(); } catch (\Throwable $e) { } } $services->update($where, ['uid' => $toUid, 'tourist_uid' => '']); } return $this->success('修改成功'); } /** * 用户信息 * @param Request $request * @param \app\services\user\UserServices $services * @param StoreCartServices $cartServices * @return mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getUserInfo(Request $request, \app\services\user\UserServices $services, StoreCartServices $cartServices) { $code = $request->post('code', ''); $uid = $request->post('uid', ''); if (!$code && !$uid) { return $this->fail('缺少参数'); } $field = ['uid', 'avatar', 'phone', 'nickname', 'now_money', 'integral', 'level', 'is_money_level', 'is_ever_level', 'overdue_time']; $userInfo = []; if ($uid) { $userInfo = $services->getUserInfo($uid, $field); } elseif ($code) { $userInfo = $services->get(['uniqid' => $code], $field); } if ($userInfo) { $userInfo = $userInfo->toArray(); $userInfo['vip_name'] = ''; if ($userInfo['level']) { /** @var SystemUserLevelServices $levelServices */ $levelServices = app()->make(SystemUserLevelServices::class); $levelInfo = $levelServices->getOne(['id' => $userInfo['level']], 'id,name'); $userInfo['vip_name'] = $levelInfo['name'] ?? ''; } $userInfo['overdue_time'] = date('Y-m-d H:i:s', $userInfo['overdue_time']); } $cart = $request->post('cart', []); if ($cart) { $cartServices->batchAddCart($cart, $this->storeId, $userInfo['uid'] ?? 0); } return $this->success($userInfo); } /** * 收银台获取当前用户信息 * @param \app\services\user\UserServices $userServices * @param $uid * @return mixed */ public function getUidInfo(\app\services\user\UserServices $userServices, $uid) { return $this->success($userServices->read((int)$uid)); } /** * 收银台用户记录 * @param Request $request * @param \app\services\user\UserServices $userServices * @param $uid * @return mixed */ public function userRecord(Request $request, \app\services\user\UserServices $userServices, $uid) { $type = $request->get('type', ''); return $this->success($userServices->oneUserInfo((int)$uid, $type)); } /** * 切换用户、用户切换到其他用户、用户切换到游客 * @param Request $request * @return mixed */ public function swithUser(Request $request) { $table_number = $request->post('table_number', 0); if(!empty($table_number)){ //wmc换桌 // 创建UserCode的实例 $h = $this->userCode->userChangingTables2(89,87); var_dump($h);die; } $uid = $request->post('uid', 0); $touristUid = $request->post('tourist_uid', 0); $cashierId = $request->post('cashier_id', 0); $changePrice = $request->post('change_price', 0); $changCartRemove = $request->post('chang_cart_remove', 0); if (!$uid && !$touristUid && !$cashierId && !$changePrice && !$changCartRemove) { return $this->fail('缺少参数'); } $res = CacheService::redisHandler()->get('aux_screen_' . $this->cashierId); if ($uid) { if ($res && is_array($res)) { $res['uid'] = $uid; $res['tourist'] = false; $res['tourist_uid'] = 0; CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId) ->set('aux_screen_' . $this->cashierId, $res); } else { //游客切换到用户。或者用户之间切换 CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId) ->set('aux_screen_' . $this->cashierId, [ 'uid' => $uid, 'cashier_id' => 0, 'tourist_uid' => 0, 'tourist' => false ]); } //发送消息 try { SocketPush::instance()->to($this->cashierId)->setUserType('cashier')->type('changUser')->data(['uid' => $uid])->push(); } catch (\Throwable $e) { } } else if ($touristUid) { if ($res && is_array($res)) { $res['tourist_uid'] = $touristUid; $res['tourist'] = true; $res['uid'] = 0; CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId) ->set('aux_screen_' . $this->cashierId, $res); } else { //用户切换到游客 CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId) ->set('aux_screen_' . $this->cashierId, [ 'uid' => 0, 'cashier_id' => 0, 'tourist_uid' => $touristUid, 'tourist' => true ]); } //发送消息 try { SocketPush::instance()->to($this->cashierId)->setUserType('cashier')->type('changUser')->data(['tourist_uid' => $touristUid])->push(); } catch (\Throwable $e) { } } else if ($cashierId) { //切换店员 if ($res && is_array($res)) { $res['cashier_id'] = $cashierId; CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId) ->set('aux_screen_' . $this->cashierId, $res); } else { CacheService::redisHandler(CacheService::CASHIER_AUX_SCREEN_TAG . '_' . $this->storeId) ->set('aux_screen_' . $this->cashierId, [ 'uid' => 0, 'cashier_id' => $cashierId, 'tourist_uid' => 0, 'tourist' => true ]); } //发送消息 try { SocketPush::instance()->to($this->cashierId)->setUserType('cashier')->type('changUser')->data(['cashier_id' => $cashierId])->push(); } catch (\Throwable $e) { } } else if ($changePrice) { //发送消息 try { SocketPush::instance()->to($this->cashierId)->setUserType('cashier')->type('changUser')->data(['change_price' => $changePrice])->push(); } catch (\Throwable $e) { } } else if ($changCartRemove) { //发送消息 try { SocketPush::instance()->to($this->cashierId)->setUserType('cashier')->type('changCartRemove')->push(); } catch (\Throwable $e) { } } return $this->success(); } /** * 获取副屏用户信息 * @return mixed */ public function getAuxScreenInfo() { $res = CacheService::redisHandler()->get('aux_screen_' . $this->cashierId); $data = []; $key = ['cashier_id' => 0, 'tourist_uid' => 0, 'uid' => 0, 'tourist' => false]; foreach ($key as $k => $v) { $data[$k] = $res[$k] ?? $v; } return $this->success($data); } /** * 获取会员类型 * @param Request $request * @return mixed */ public function getMemberCard(Request $request) { [$is_money_level, $overdue_time] = $request->getMore([ ['is_money_level', 0], ['overdue_time', 0], ], true); /** @var MemberCardServices $memberCardServices */ $memberCardServices = app()->make(MemberCardServices::class); $member_type = $memberCardServices->DoMemberType(0, false); if (!$is_money_level) $overdue_time = time(); foreach ($member_type as $key => &$item) { if (!$overdue_time || $item['type'] == 'ever' && $item['vip_day'] == -1) { $item['overdue_time'] = ''; } else { $item['overdue_time'] = date('Y-m-d H:i:s', $overdue_time + $item['vip_day'] * 86400); } } return $this->success($member_type); } /** * 购买会员 * @param Request $request * @return mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException */ public function payMember(Request $request,\app\services\user\UserServices $services) { [$uid, $price, $memberId, $payType, $authCode,$libao_id,$libao_products] = $request->postMore([ ['uid', 0], ['price', 0], ['merber_id', 0], [['pay_type', 'd'], 2], //2=用户扫码支付,3=付款码扫码支付, 4=现金支付 ['auth_code', ''], ['libao_id', ''], ['libao_products', []], ], true); if (!(int)$memberId) { return $this->fail('缺少购买会员类型ID'); } if (!$authCode && $payType == 3) { return $this->fail('缺少付款码二维码CODE'); } if (!$price || $price <= 0) { return $this->fail('充值金额不能为0元!'); } $storeMinRecharge = sys_config('store_user_min_recharge'); if ($price < $storeMinRecharge) return $this->fail('充值金额不能低于' . $storeMinRecharge); // 创建会员礼包订单 if ($libao_id) { $discountId = $libao_id; //添加购物车 /** @var StoreDiscountsServices $StoreDiscountsServices */ $discountService = app()->make(StoreDiscountsServices::class); /** @var StoreOrderServices $StoreOrderServices */ $StoreOrderServices = app()->make(StoreOrderServices::class); /** @var StoreCartServices $StoreCartServices */ $StoreCartServices = app()->make(StoreCartServices::class); $discounts = $discountService->get((int)$discountId, ['id', 'is_limit', 'limit_num']); if (!$discounts) { return app('json')->fail('套餐商品未找到!'); } //套餐限量 if ($discounts['is_limit']) { if ($discounts['limit_num'] <= 0) { return app('json')->fail('套餐限量不足'); } if (!CacheService::checkStock(md5($discounts['id']), 1, 5)) { return app('json')->fail('套餐限量不足'); } } $cartIds = []; $cartNum = 0; $activityId = (int)$discountId; foreach ($libao_products as $info) { [$cartId, $cartNum] = $StoreCartServices->setCart($uid, (int)$info['product_id'], $info['pnum'], '', 5, 1, $activityId, (int)$info['id']); $cartIds[] = $cartId; } $cartId = implode(',', $cartIds); $user = $services->getUserInfo($uid); $querendingdan = $StoreOrderServices->getOrderConfirmData($user->toArray(), $cartId, 1, 0, 2, 0, 0); $orderarray = array( 'addressId'=> 0, 'bargainId'=> 0, 'collate_code_id'=> 0, 'combinationId'=> 0, 'couponId'=> 0, 'custom_form'=> [], 'discountId'=> $libao_id, 'formId'=> "", 'from'=> "routine", 'invoice_id'=> "", 'mark'=> "", 'new'=> 1, 'payType'=> "weixin", 'phone'=> $user['phone'], 'pinkId'=> 0, 'real_name'=> $user['real_name']??$user['nickname'], 'seckill_id'=> 0, 'shipping_type'=> 2, 'store_id'=> 1, 'useIntegral'=> false, 'uid'=>$uid, 'user' => $user->toArray() ); $order = $this->create($orderarray,$querendingdan['orderKey']); } /** @var OtherOrderServices $OtherOrderServices */ $OtherOrderServices = app()->make(OtherOrderServices::class); $re = $OtherOrderServices->payMember($uid, (int)$memberId, (float)$price, (int)$payType, 'store', $this->cashierInfo, $authCode,$order); if ($re) { $msg = $re['msg']; unset($re['msg']); return $this->success($msg, $re); } return $this->fail('充值失败'); } /** * 订单创建 * @param $key * @return mixed * @throws \Psr\SimpleCache\InvalidArgumentException * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function create($orderinfo, $key) { /** @var StoreOrderServices $StoreOrderServices */ $StoreOrderServices = app()->make(StoreOrderServices::class); /** @var StoreOrderCreateServices $createServices */ $createServices = app()->make(StoreOrderCreateServices::class); if (!$key) return app('json')->fail('参数错误!'); $uid = $orderinfo['uid']; if ($checkOrder = $StoreOrderServices->getOne(['unique' => $key, 'uid' => $orderinfo['uid'], 'is_del' => 0], 'id,order_id')) return app('json')->status('extend_order', '订单已创建,请点击查看完成支付', ['orderId' => $checkOrder['order_id'], 'key' => $key]); $addressId = $orderinfo['addressId']; $bargainId = $orderinfo['bargainId']; $collate_code_id = $orderinfo['collate_code_id']; $combinationId = $orderinfo['combinationId']; $couponId = $orderinfo['couponId']; $customForm = $orderinfo['custom_form']; $discountId = $orderinfo['discountId']; $formId = $orderinfo['formId']; $from = $orderinfo['from']; $invoice_id = $orderinfo['invoice_id']; $mark = $orderinfo['mark']; $news = $orderinfo['new']; $payType = $orderinfo['payType']; $phone = $orderinfo['phone']; $pinkId = $orderinfo['pinkId']; $real_name = $orderinfo['real_name']; $seckill_id = $orderinfo['seckill_id']; $shipping_type = $orderinfo['shipping_type']; $newcomerId = 0; $quitUrl = ''; $storeId = $orderinfo['store_id']; $useIntegral = $orderinfo['useIntegral']; $user = $orderinfo['user']; $cartGroup = $StoreOrderServices->getCacheOrderInfo($uid, $key); if (!$cartGroup) { return app('json')->fail('请勿重复提交或订单已过期 请刷新当前页面!'); } $cartInfo = $cartGroup['cartInfo']; if (!$cartInfo) { return app('json')->fail('订单已过期或提交的商品不在送达区域,请刷新当前页面或重新选择商品下单!123'); } $payType = strtolower($payType); if ($shipping_type == 1) { $cartInfo = $cartGroup['cartInfo']; $product_type = $cartInfo[0]['productInfo']['product_type'] ?? 0; //普通商品 验证地址 if ($product_type == 0 && !$addressId) { return app('json')->fail('请选择收货地址!'); } $addressInfo = ($cartGroup['addr'] ?? []) ?: $this->addressInfo; if ($addressId && (!$addressInfo || !isset($addressInfo['id']) || $addressInfo['id'] != $addressId)) { /** @var UserAddressServices $addressServices */ $addressServices = app()->make(UserAddressServices::class); if (!$addressInfo = $addressServices->getOne(['uid' => $uid, 'id' => $addressId, 'is_del' => 0])) return app('json')->fail('地址选择有误!'); $addressInfo = $addressInfo->toArray(); } } elseif ($shipping_type == 4) { $addressInfo = $this->addressInfo; } else { if (!$real_name || !$phone) { return app('json')->fail('请填写姓名和电话'); } $addressInfo = $this->addressInfo; $addressInfo['real_name'] = $real_name; $addressInfo['phone'] = $phone; } //下单前砍价验证 if ($bargainId) { /** @var StoreBargainServices $bargainServices */ $bargainServices = app()->make(StoreBargainServices::class); $bargainServices->checkBargainUser((int)$bargainId, $uid); } //下单前发票验证 if ($invoice_id) { /** @var UserInvoiceServices $userInvoiceServices */ $userInvoiceServices = app()->make(UserInvoiceServices::class); $userInvoiceServices->checkInvoice((int)$invoice_id, $uid); } if ($pinkId) { $pinkId = (int)$pinkId; /** @var StorePinkServices $pinkServices */ $pinkServices = app()->make(StorePinkServices::class); if ($pinkServices->isPink($pinkId, $uid)) return app('json')->status('ORDER_EXIST', '订单生成失败,你已经在该团内不能再参加了', ['orderId' => $StoreOrderServices->getStoreIdPink($pinkId, $uid)]); if ($StoreOrderServices->getIsOrderPink($pinkId, $uid)) return app('json')->status('ORDER_EXIST', '订单生成失败,你已经参加该团了,请先支付订单', ['orderId' => $StoreOrderServices->getStoreIdPink($pinkId, $uid)]); if (!CacheService::checkStock(md5($pinkId), 1, 3) || !CacheService::popStock(md5($pinkId), 1, 3)) { return app('json')->fail('该团人员已满'); } } if ($from != 'pc') { if (!$StoreOrderServices->checkPaytype($payType)) { return app('json')->fail('暂不支持该支付方式,请刷新页面或者联系管理员'); } } $isChannel = $this->getChennel[$from] ?? 1; if ($seckill_id || $combinationId || $discountId || $bargainId) { //套餐限量库 if ($discountId) { /** @var StoreDiscountsServices $discountService */ $discountService = app()->make(StoreDiscountsServices::class); $discounts = $discountService->get((int)$discountId); if (!$discounts) { return app('json')->fail('套餐商品未找到!'); } //套餐限量 if ($discounts['is_limit'] && !CacheService::popStock(md5($discountId), 1, 5)) { return app('json')->fail('您购买的套餐不足'); } } foreach ($cartInfo as $item) { if (!isset($item['product_attr_unique']) || !$item['product_attr_unique']) continue; $type = $item['type']; if (in_array($type, [1, 2, 3, 4]) && (!CacheService::checkStock($item['product_attr_unique'], (int)$item['cart_num'], $type) || !CacheService::popStock($item['product_attr_unique'], (int)$item['cart_num'], $type))) { return app('json')->fail('您购买的商品库存已不足' . $item['cart_num'] . $item['productInfo']['unit_name']); } } } try { $msg = ''; $order = $createServices->createOrder($uid, $key, $cartGroup, (int)$addressId, $payType, $addressInfo, $user, !!$useIntegral, $couponId, $mark, $pinkId, $isChannel, $shipping_type, $storeId, !!$news, $customForm, (int)$invoice_id, $from, (int)$collate_code_id); } catch (\Throwable $e) { $order = false; $msg = $e->getMessage(); \think\facade\Log::error('订单生成失败,原因:' . $msg . $e->getFile() . $e->getLine()); } if ($order === false) { if ($seckill_id || $combinationId || $discountId || $bargainId) { //回退套餐限量库 if ($discountId) CacheService::setStock(md5($discountId), 1, 5, false); foreach ($cartInfo as $item) { if (!isset($item['product_attr_unique']) || !$item['product_attr_unique']) continue; $type = $item['type']; if (in_array($type, [1, 2, 3, 4])) CacheService::setStock($item['product_attr_unique'], (int)$item['cart_num'], $type, false); } } return app('json')->fail($msg ?: '订单生成失败'); } $orderId = $order['order_id']; return $orderId; } /**显示指定的资源 * @param $id * @param \app\services\user\UserServices $services * @return mixed */ public function read($id, \app\services\user\UserServices $services) { return $this->success($services->read((int)$id)); } /**获取单个用户信息 * @param Request $request * @param $id * @param \app\services\user\UserServices $services * @return mixed */ public function oneUserInfo(Request $request, $id, \app\services\user\UserServices $services) { $data = $request->getMore([ ['type', ''], ]); $id = (int)$id; if ($data['type'] == '') return $this->fail('缺少参数'); return $this->success($services->oneUserInfo($id, $data['type'])); } }