You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
494 lines
19 KiB
494 lines
19 KiB
1 month ago
|
<?php
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||
|
// +----------------------------------------------------------------------
|
||
|
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 DateTimeImmutable;
|
||
|
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\Db;
|
||
|
use think\facade\Log;
|
||
|
|
||
|
/**
|
||
|
* 收银台用户控制器
|
||
|
*/
|
||
|
class User2 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的实例1
|
||
|
$this->userCode = new UserCode($services);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 收银台用户记录
|
||
|
* @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));
|
||
|
}
|
||
|
|
||
|
//台桌预定
|
||
|
public function tableYuDing($wtable_id, $wremark, $wphone, $wyuding_date,$come_date,$store_id)
|
||
|
{
|
||
|
|
||
|
$post['table_id'] = $wtable_id;
|
||
|
$post['phone'] = $wphone;
|
||
|
$post['yuding_date'] = date("Y-m-d", strtotime($wyuding_date));
|
||
|
$post['come_date'] = $come_date;
|
||
|
$post['remark'] = $wremark;
|
||
|
$post['store_id'] = $store_id;
|
||
|
$post['create'] = time();
|
||
|
|
||
|
//校验这个桌子有无在使用
|
||
|
$info = Db::name('table_qrcode')
|
||
|
->where('id', $post['table_id'])
|
||
|
->find();
|
||
|
if (!$info) {
|
||
|
return app('json')->fail('预定失败');
|
||
|
}
|
||
|
|
||
|
if ($info['is_use'] != 0) {
|
||
|
return app('json')->fail('预定失败,台桌正在使用中');
|
||
|
}
|
||
|
|
||
|
//插入预定表
|
||
|
Db::name('table_yuding')->insert($post);
|
||
|
|
||
|
//改桌子状态
|
||
|
$up = Db::name('table_qrcode')->where('id', $post['table_id'])->update(['is_use' => 2]);
|
||
|
if($up){
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 切换用户、用户切换到其他用户、用户切换到游客
|
||
|
* @param Request $request
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public function changeTable(Request $request)
|
||
|
{
|
||
|
//wmc api
|
||
|
$table_number = $request->post('table_number', 0);
|
||
|
$uid = $request->post('uid', 0);
|
||
|
$store_id = $request->post('store_id', 1);
|
||
|
$collage_id = $request->post('collage_id', 0);
|
||
|
|
||
|
if (!empty($table_number)) {
|
||
|
$table = Db::name('table_qrcode')->where('table_number', $table_number)->where('is_use', 0)->find();
|
||
|
if (!$table) {
|
||
|
return $this->fail('桌码输入错误或状态错误');
|
||
|
}
|
||
|
$h = $this->userCode->userChangingTables2($collage_id, $uid, $store_id, $table['id']);
|
||
|
|
||
|
if ($h) {
|
||
|
return $this->success('换桌成功', ['res' => $table['id']]);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return $this->fail('换桌失败');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取副屏用户信息
|
||
|
* @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']));
|
||
|
}
|
||
|
}
|