548 lines
22 KiB
PHP
548 lines
22 KiB
PHP
<?php
|
||
|
||
namespace app\controller\api\user;
|
||
|
||
|
||
use app\common\model\user\ExchangeIntegralRecord;
|
||
use app\common\model\user\ExchangePickupRecord;
|
||
use app\common\model\user\ExchangeQuota;
|
||
use app\common\model\user\ExchangeQuotaRecord;
|
||
use app\common\model\user\User;
|
||
use app\common\repositories\store\order\StoreOrderCreateRepository;
|
||
use app\common\repositories\store\order\StoreOrderRepository;
|
||
use app\common\repositories\store\service\StoreServiceRepository;
|
||
use app\common\repositories\system\merchant\MerchantRepository;
|
||
use app\common\repositories\user\ExchangeIntegralRecordRepository;
|
||
use app\common\repositories\user\ExchangePickupPointRepository;
|
||
use app\common\repositories\user\ExchangePickupRecordRepository;
|
||
use app\common\repositories\user\ExchangeQuotaRecordRepository;
|
||
use app\common\repositories\user\ExchangeQuotaRepository;
|
||
use app\common\repositories\user\UserRepository;
|
||
use crmeb\basic\BaseController;
|
||
use crmeb\services\LockService;
|
||
use crmeb\services\QrcodeService;
|
||
use think\App;
|
||
use think\facade\Db;
|
||
|
||
class Exchange extends BaseController{
|
||
protected $user;
|
||
|
||
public function __construct(App $app){
|
||
parent::__construct($app);
|
||
}
|
||
/**
|
||
* Common: 获取用户持有信息
|
||
* Author: wu-hui
|
||
* Time: 2024/01/14 16:53
|
||
* @return mixed
|
||
*/
|
||
public function getUserHold(){
|
||
$params = $this->request->params(['consume_uid','quota_type']);
|
||
$uid = $this->request->uid();
|
||
// 判断:是否存在指定消费者,不存在则使用当前登录用户
|
||
$uid = (int)$params['consume_uid'] > 0 ? (int)$params['consume_uid'] : $uid;
|
||
$params['uid'] = $uid;
|
||
// 获取额度
|
||
$info = app()->make(ExchangeQuotaRepository::class)
|
||
->searchModel($params)
|
||
->field([
|
||
'*',
|
||
// 可用额度=剩余额度-冻结额度
|
||
'(surplus_quota - freeze_quota) as available'
|
||
])
|
||
->findOrEmpty();
|
||
$user = app()->make(UserRepository::class)->getSearch([])->where('uid',$uid)->findOrEmpty();
|
||
$info->available = (float)$info->available;
|
||
$info->available_integral = (float)$user->exchange_integral;
|
||
$info->diff_rate = 30;// 差价 应补金额,默认为30%
|
||
$info->transfer_rate = 0;// 转赠手续费比例 0-100
|
||
|
||
return app('json')->success($info);
|
||
}
|
||
/**
|
||
* Common: 获取提货点列表
|
||
* Author: wu-hui
|
||
* Time: 2024/01/14 16:06
|
||
* @return mixed
|
||
*/
|
||
public function getPointList(){
|
||
$search = $this->request->params(['uid', 'address', 'default_point_id','lng','lat']);
|
||
$search['is_show'] = 1;
|
||
$make = app()->make(ExchangePickupPointRepository::class);
|
||
[$page, $limit] = $this->getPage();
|
||
$data = $make->getList($search, $page, $limit);
|
||
$list = $data['list'];
|
||
|
||
return app('json')->success($list);
|
||
}
|
||
/**
|
||
* Common: 兑换处理
|
||
* Author: wu-hui
|
||
* Time: 2024/01/14 18:02
|
||
* @return mixed
|
||
*/
|
||
public function exchangeHandle(StoreOrderCreateRepository $orderCreateRepository){
|
||
// 参数获取
|
||
$data = $this->request->params([
|
||
'total_money',
|
||
'use_integral',
|
||
'diff_money',
|
||
'diff_money_pay',
|
||
'point_id',
|
||
'staff_uid',
|
||
'consume_uid',
|
||
'service_id',
|
||
'quota_type'
|
||
]);
|
||
$quotaType = $data['quota_type'] ?? 1;// 存在指定类型则使用指定类型,否则使用默认类型(默认酒卡)
|
||
$data['quota_type'] = in_array((int)$quotaType,[1,2]) ? $quotaType : 1;// 类型非法,使用默认类型
|
||
|
||
|
||
if($data['quota_type'] == 2) return $this->createOrderTwo($data, $orderCreateRepository);
|
||
else return $this->createOrder($data, $orderCreateRepository);
|
||
}
|
||
/**
|
||
* Common: 酒卡兑换下单
|
||
* Author: wu-hui
|
||
* Time: 2024/02/03 17:16
|
||
* @param $data
|
||
* @param $orderCreateRepository
|
||
* @return mixed
|
||
*/
|
||
private function createOrder($data, $orderCreateRepository){
|
||
$uid = $this->request->uid();
|
||
if ((float)$data['total_money'] <= 0) return app('json')->fail('价值必须大于0!');
|
||
if ((float)$data['point_id'] <= 0) return app('json')->fail('请选择提货点!');
|
||
if ((float)$data['staff_uid'] <= 0) return app('json')->fail('请选择操作员!');
|
||
// 判断:是否存在指定消费者,不存在则使用当前登录用户
|
||
$uid = (int)$data['consume_uid'] > 0 ? (int)$data['consume_uid'] : $uid;
|
||
if ($data['staff_uid'] == $uid) return app('json')->fail('操作员和消费用户不能是同一人!');
|
||
// 支付信息
|
||
$payInfo = $this->request->params(['pay_type', 'return_url']);
|
||
$payInfo['money'] = (float)$data['diff_money_pay'];
|
||
if((float)$payInfo['money'] > 0){
|
||
if (!in_array($payInfo['pay_type'], StoreOrderRepository::PAY_TYPE, true)) return app('json')->fail('请选择正确的支付方式');
|
||
}
|
||
// 添加兑换记录
|
||
try{
|
||
return Db::transaction(function () use ($data, $uid, $payInfo, $orderCreateRepository) {
|
||
// 添加兑换记录
|
||
$pickupRecordId = ExchangePickupRecord::insertGetId([
|
||
'uid' => $uid,
|
||
'point_id' => $data['point_id'],
|
||
'staff_uid' => $data['staff_uid'],
|
||
'total_money' => $data['total_money'],
|
||
'use_integral' => $data['use_integral'],
|
||
'diff_money' => $data['diff_money'],
|
||
'diff_money_pay' => $data['diff_money_pay'],
|
||
]);
|
||
// 判断:如果【差价应支付金额】大于0 生成支付订单
|
||
if((float)$payInfo['money'] > 0){
|
||
$userInfo = User::where('uid',$uid)->findOrEmpty();
|
||
$payInfo['pickup_record_id'] = $pickupRecordId;
|
||
// 发起支付
|
||
$groupOrder = app()->make(LockService::class)
|
||
->exec('online_order.create',function() use ($payInfo,$orderCreateRepository, $userInfo){
|
||
$payType = array_search($payInfo['pay_type'],StoreOrderRepository::PAY_TYPE);
|
||
|
||
return $orderCreateRepository->exchangeGoods($payType,$payInfo,$userInfo);
|
||
});
|
||
|
||
if ($groupOrder['pay_price'] == 0) {
|
||
app()->make(StoreOrderRepository::class)->paySuccess($groupOrder);
|
||
return app('json')->status('success', '支付成功', ['order_id' => $groupOrder['group_order_id']]);
|
||
}
|
||
try {
|
||
|
||
return app()->make(StoreOrderRepository::class)
|
||
->pay($payInfo['pay_type'], $userInfo, $groupOrder, $payInfo['return_url'], $this->request->isApp());
|
||
} catch (\Exception $e) {
|
||
|
||
return app('json')->status('error', $e->getMessage(), ['order_id' => $groupOrder->group_order_id]);
|
||
}
|
||
}
|
||
else{
|
||
app()->make(ExchangePickupPointRepository::class)->exchangeSuccessHandle($pickupRecordId);
|
||
|
||
return app('json')->success('success');
|
||
}
|
||
});
|
||
}catch(\Exception $e){
|
||
|
||
return app('json')->fail($e->getMessage());
|
||
}
|
||
}
|
||
/**
|
||
* Common: 菜卡兑换下单
|
||
* Author: wu-hui
|
||
* Time: 2024/02/03 17:16
|
||
* @param $data
|
||
* @param $orderCreateRepository
|
||
* @return mixed
|
||
*/
|
||
private function createOrderTwo($data, $orderCreateRepository){
|
||
$uid = $this->request->uid();
|
||
if ((float)$data['total_money'] <= 0) return app('json')->fail('价值必须大于0!');
|
||
if ((float)$data['service_id'] <= 0) return app('json')->fail('兑换信息不存在!');
|
||
$service = app()->make(StoreServiceRepository::class)
|
||
->getSearch([])
|
||
->where('service_id',$data['service_id'])
|
||
->findOrEmpty()
|
||
->toArray();
|
||
// 判断:是否存在指定消费者,不存在则使用当前登录用户
|
||
// if ($service['uid'] == $uid) return app('json')->fail('操作员和消费用户不能是同一人!');
|
||
// 支付信息
|
||
$payInfo = $this->request->params(['pay_type', 'return_url']);
|
||
$payInfo['money'] = (float)$data['diff_money_pay'];
|
||
if((float)$payInfo['money'] > 0) if (!in_array($payInfo['pay_type'], StoreOrderRepository::PAY_TYPE, true)) return app('json')->fail('请选择正确的支付方式');
|
||
// 添加兑换记录
|
||
try{
|
||
return Db::transaction(function () use ($data, $uid, $payInfo, $orderCreateRepository, $service) {
|
||
// 商户类别:0=普通商户,1=酒道馆,2=供应商
|
||
$merchantType = (int)app()->make(MerchantRepository::class)->getSearch(['mer_id'=>$service['mer_id']])->value('merchant_type');
|
||
// 添加兑换记录 额度类型:1=酒卡额度,2=菜卡额度
|
||
$pickupRecordId = ExchangePickupRecord::insertGetId([
|
||
'uid' => $uid,
|
||
'point_id' => $service['mer_id'],
|
||
'staff_uid' => $service['uid'],
|
||
'total_money' => $data['total_money'],
|
||
'use_integral' => $data['use_integral'],
|
||
'diff_money' => $data['diff_money'],
|
||
'diff_money_pay' => $data['diff_money_pay'],
|
||
'quota_type' => $merchantType == 1 ? 1 : 2,// 酒道馆核销酒卡额度,普通商户核销菜卡额度
|
||
]);
|
||
// 判断:如果【差价应支付金额】大于0 生成支付订单
|
||
if((float)$payInfo['money'] > 0){
|
||
$userInfo = User::where('uid',$uid)->findOrEmpty();
|
||
$payInfo['pickup_record_id'] = $pickupRecordId;
|
||
// 发起支付
|
||
$groupOrder = app()->make(LockService::class)
|
||
->exec('online_order.create',function() use ($payInfo,$orderCreateRepository, $userInfo){
|
||
$payType = array_search($payInfo['pay_type'],StoreOrderRepository::PAY_TYPE);
|
||
|
||
return $orderCreateRepository->exchangeGoods($payType,$payInfo,$userInfo);
|
||
});
|
||
|
||
if ($groupOrder['pay_price'] == 0) {
|
||
app()->make(StoreOrderRepository::class)->paySuccess($groupOrder);
|
||
return app('json')->status('success', '支付成功', ['order_id' => $groupOrder['group_order_id']]);
|
||
}
|
||
try {
|
||
|
||
return app()->make(StoreOrderRepository::class)
|
||
->pay($payInfo['pay_type'], $userInfo, $groupOrder, $payInfo['return_url'], $this->request->isApp());
|
||
} catch (\Exception $e) {
|
||
|
||
return app('json')->status('error', $e->getMessage(), ['order_id' => $groupOrder->group_order_id]);
|
||
}
|
||
}
|
||
else{
|
||
app()->make(ExchangePickupPointRepository::class)->exchangeSuccessHandle($pickupRecordId);
|
||
|
||
return app('json')->success('success');
|
||
}
|
||
});
|
||
}catch(\Exception $e){
|
||
|
||
return app('json')->fail($e->getMessage());
|
||
}
|
||
}
|
||
/**
|
||
* Common: 取货记录
|
||
* Author: wu-hui
|
||
* Time: 2024/01/14 18:44
|
||
* @return mixed
|
||
*/
|
||
public function exchangeRecord(){
|
||
$params = $this->request->params(['staff_uid','address']);
|
||
$params['uid'] = $this->request->uid();
|
||
[$page, $limit] = $this->getPage();
|
||
|
||
$data = app()->make(ExchangePickupRecordRepository::class)->getList((array)$params,(int)$page,(int)$limit);
|
||
|
||
return app('json')->success($data);
|
||
}
|
||
/**
|
||
* Common: 获取消费者列表
|
||
* Author: wu-hui
|
||
* Time: 2024/01/16 11:16
|
||
* @return mixed
|
||
*/
|
||
public function getConsumeList(){
|
||
$search = $this->request->params(['search_text', 'default_consume_id','search_id_and_phone']);
|
||
$list = app()->make(UserRepository::class)
|
||
->getSearch([])
|
||
->field(['uid','real_name','nickname','avatar','phone'])
|
||
->when(!empty($search['search_text']),function($query) use ($search){
|
||
$query->where(function($query) use ($search){
|
||
// 用户ID/用户昵称/真实姓名/联系电话
|
||
$query->where('uid',$search['search_text'])
|
||
->whereOr('nickname','like',"%{$search['search_text']}%")
|
||
->whereOr('real_name','like',"%{$search['search_text']}%")
|
||
->whereOr('phone','like',"%{$search['search_text']}%");
|
||
});
|
||
})
|
||
->when(!empty($search['search_id_and_phone']),function($query) use ($search){
|
||
$query->where(function($query) use ($search){
|
||
// 用户ID/联系电话
|
||
$query->where('uid',$search['search_id_and_phone'])
|
||
->whereOr('phone',$search['search_id_and_phone']);
|
||
});
|
||
})
|
||
->when(isset($search['default_consume_id']) && $search['default_consume_id'] > 0,function($query) use ($search){
|
||
$query->where('uid',$search['default_consume_id']);
|
||
})
|
||
->page(1, 30)
|
||
->select()
|
||
->toArray();
|
||
|
||
return app('json')->success($list);
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 获取当前用户身为管理员时 参与管理的站点
|
||
* Author: wu-hui
|
||
* Time: 2024/01/15 11:22
|
||
* @return mixed
|
||
*/
|
||
public function siteList(){
|
||
$search = $this->request->params(['uid','address']);
|
||
$search['uid'] = $this->request->uid();
|
||
[$page, $limit] = $this->getPage();
|
||
$data = app()->make(ExchangePickupPointRepository::class)->getList($search, $page, $limit);
|
||
|
||
return app('json')->success($data);
|
||
}
|
||
/**
|
||
* Common: 获取当前用户身为管理员时 操作的兑换记录
|
||
* Author: wu-hui
|
||
* Time: 2024/01/15 11:20
|
||
* @return mixed
|
||
*/
|
||
public function siteExchangeRecord(){
|
||
$params = $this->request->params(['staff_uid','address','uid']);
|
||
$params['staff_uid'] = $this->request->uid();
|
||
[$page, $limit] = $this->getPage();
|
||
|
||
$data = app()->make(ExchangePickupRecordRepository::class)->getList((array)$params,(int)$page,(int)$limit);
|
||
|
||
return app('json')->success($data);
|
||
}
|
||
/**
|
||
* Common: 获取兑换二维码显示(操作员二维码)
|
||
* Author: wu-hui
|
||
* Time: 2024/01/15 14:37
|
||
* @return mixed
|
||
*/
|
||
public function siteQrCode(){
|
||
// 参数获取
|
||
$uid = $this->request->uid();
|
||
$params = $this->request->params(['point_id','mer_id','quota_type',['total_money',0]]);
|
||
$quotaType = $params['quota_type'] ?? 1;// 存在指定类型则使用指定类型,否则使用默认类型(默认酒卡)
|
||
$quotaType = in_array((int)$quotaType,[1,2]) ? $quotaType : 1;// 类型非法,使用默认类型
|
||
// 参数验证
|
||
if((int)$params['point_id'] <= 0 && $quotaType == 1) return app('json')->fail('小程序码生成失败,不存在的酒道馆!');
|
||
if((int)$params['mer_id'] <= 0 && $quotaType == 2) return app('json')->fail('小程序码生成失败,不存在的商户!');
|
||
// 二维码生成
|
||
try{
|
||
if($quotaType == 1){
|
||
// 酒卡兑换 由于微信长度限制问题 suid=staff_id;pid=point_id;tmy=total_money
|
||
$valueData = 'suid=' . $uid . '&pid=' . $params['point_id'] . '&tmy=' . $params['total_money'];
|
||
$name = md5($valueData) . '.jpg';
|
||
$path = 'pages/users/online_payment/exchange/index';
|
||
}else if($quotaType == 2){
|
||
// 菜卡兑换 由于微信长度限制问题 sid=service_id;tmy=total_money
|
||
$service = app()->make(StoreServiceRepository::class)
|
||
->getSearch([])
|
||
->where('mer_id',$params['mer_id'])
|
||
->where('uid',$uid)
|
||
->findOrEmpty()
|
||
->toArray();
|
||
$valueData = 'sid=' . $service['service_id'] . '&tmy=' . $params['total_money'];
|
||
$name = md5($valueData) . '.jpg';
|
||
$path = 'pages/users/online_payment/exchange/vegetable';
|
||
}else{
|
||
throw new \Exception('二维码生成失败,类型不明确!');
|
||
}
|
||
// 生成二维码
|
||
$qrcode = app()->make(QrcodeService::class)->getRoutineQrcodePath($name, $path, $valueData);
|
||
if (!$qrcode) throw new \Exception('二维码生成失败');
|
||
|
||
return app('json')->success([
|
||
'qr_code' => $qrcode
|
||
]);
|
||
}catch(\Exception $e){
|
||
return app('json')->fail($e->getMessage());
|
||
}catch(\Throwable $e){
|
||
return app('json')->fail($e->getMessage());
|
||
}
|
||
}
|
||
/**
|
||
* Common: 获取兑换二维码(用户二维码)
|
||
* Author: wu-hui
|
||
* Time: 2024/01/16 10:17
|
||
* @return mixed
|
||
*/
|
||
public function userQrCode(){
|
||
// 参数获取
|
||
$uid = $this->request->uid();
|
||
if((int)$uid > 0){
|
||
try{
|
||
$valueData = 'consume_uid=' . $uid;
|
||
$name = md5('consume_qrcode_'.$valueData) . '.jpg';
|
||
$qrcode = app()->make(QrcodeService::class)->getRoutineQrcodePath($name, 'pages/users/online_payment/exchange/index', $valueData);
|
||
if (!$qrcode) throw new \Exception('二维码生成失败');
|
||
|
||
return app('json')->success([
|
||
'qr_code' => $qrcode
|
||
]);
|
||
}catch(\Exception $e){
|
||
return app('json')->fail($e->getMessage());
|
||
}catch(\Throwable $e){
|
||
return app('json')->fail($e->getMessage());
|
||
}
|
||
}
|
||
|
||
return app('json')->fail('小程序码生成失败!');
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 额度记录 - 统计
|
||
* Author: wu-hui
|
||
* Time: 2024/01/17 17:00
|
||
* @return mixed
|
||
*/
|
||
public function recordQuota(){
|
||
$params = $this->request->params(['quota_type', ['mer_id', 0]]);
|
||
$params['uid'] =$this->request->uid();
|
||
|
||
$statistics = app()->make(ExchangeQuotaRepository::class)
|
||
->searchModel($params)
|
||
->field([
|
||
'*',
|
||
// 可用额度=剩余额度-冻结额度
|
||
'(surplus_quota - freeze_quota) as available'
|
||
])
|
||
->findOrEmpty()
|
||
->toArray();
|
||
|
||
$statisticsList = [
|
||
['title' => '总额度','value' => $statistics['total_quota'] ?? 0],
|
||
['title' => '已使用额度','value' => $statistics['use_quota'] ?? 0],
|
||
// ['title' => '剩余额度','value' => $statistics['surplus_quota']],
|
||
// ['title' => '冻结额度','value' => $statistics['freeze_quota']],
|
||
['title' => '可用额度','value' => $statistics['available'] ?? 0],
|
||
];
|
||
|
||
return app('json')->success($statisticsList);
|
||
}
|
||
/**
|
||
* Common: 额度记录 - 记录列表
|
||
* Author: wu-hui
|
||
* Time: 2024/01/17 17:01
|
||
* @return mixed
|
||
*/
|
||
public function recordQuotaList(){
|
||
[$page, $limit] = $this->getPage();
|
||
$params = $this->request->params(['quota_type',['mer_id', 0]]);
|
||
$params['uid'] = $this->request->uid();
|
||
$data = app()->make(ExchangeQuotaRecordRepository::class)->getList((array)$params,(int)$page,(int)$limit);
|
||
|
||
return app('json')->success($data);
|
||
}
|
||
/**
|
||
* Common: 积分记录 - 记录列表
|
||
* Author: wu-hui
|
||
* Time: 2024/01/17 17:02
|
||
* @return mixed
|
||
*/
|
||
public function recordIntegralList(){
|
||
[$page, $limit] = $this->getPage();
|
||
$params = $this->request->params(['uid']);
|
||
$params['uid'] = $this->request->uid();
|
||
$data = app()->make(ExchangeIntegralRecordRepository::class)->getList((array)$params,(int)$page,(int)$limit);
|
||
|
||
return app('json')->success($data);
|
||
}
|
||
/**
|
||
* Common: 额度转赠
|
||
* Author: wu-hui
|
||
* Time: 2024/01/18 16:04
|
||
* @return mixed
|
||
*/
|
||
public function quotaTransfer(){
|
||
// 参数
|
||
$params = $this->request->params([
|
||
['transfer_num', 0],
|
||
['receipt_num', 0],
|
||
['service_charge', 0],
|
||
['transfer_uid', 0],
|
||
'quota_type'
|
||
]);
|
||
$uid = $this->request->uid();
|
||
// 判断:信息是否符合要求
|
||
if($params['transfer_uid'] <= 0) return app('json')->fail("请选择接收用户!");
|
||
if($params['transfer_num'] <= 0) return app('json')->fail("转赠金额必须大于0!");
|
||
if($uid == $params['transfer_uid']) return app('json')->fail("接收用户不能是本人!");
|
||
// 转赠操作
|
||
try{
|
||
app()->make(ExchangeQuotaRepository::class)->transfer($uid,$params);
|
||
|
||
return app('json')->success('操作成功');
|
||
}catch(\Exception $e){
|
||
return app('json')->fail($e->getMessage());
|
||
}catch(\Throwable $e){
|
||
return app('json')->fail($e->getMessage());
|
||
}
|
||
}
|
||
/**
|
||
* Common: 根据商户id 获取绑定的酒道馆
|
||
* Author: wu-hui
|
||
* Time: 2024/02/05 9:36
|
||
* @param $merId
|
||
* @return mixed
|
||
*/
|
||
public function merBindShop($merId){
|
||
$bindShop = app()->make(MerchantRepository::class)->getSearch([])
|
||
->where('shop_mer_id', $merId)
|
||
->where('is_del', 0)
|
||
->findOrEmpty()
|
||
->toArray();
|
||
|
||
|
||
return app('json')->success($bindShop);
|
||
}
|
||
/**
|
||
* Common: 惠民积分 - 统计
|
||
* Author: wu-hui
|
||
* Time: 2024/07/03 15:18
|
||
* @return mixed
|
||
*/
|
||
public function quotaIntegralStatistics(){
|
||
$uid = $this->request->uid();
|
||
$info = app()->make(ExchangeQuotaRepository::class)->getIntegralAll((int)$uid);
|
||
|
||
return app('json')->success($info);
|
||
}
|
||
/**
|
||
* Common: 惠民积分 - 各商户持有信息列表
|
||
* Author: wu-hui
|
||
* Time: 2024/07/03 15:40
|
||
* @return mixed
|
||
*/
|
||
public function quotaIntegralHoldList(){
|
||
[$page, $limit] = $this->getPage();
|
||
$params = $this->request->params(['quota_type']);
|
||
$params['uid'] = $this->request->uid();
|
||
$data = app()->make(ExchangeQuotaRepository::class)->getList((array)$params,(int)$page,(int)$limit);
|
||
|
||
return app('json')->success($data);
|
||
}
|
||
|
||
|
||
|
||
|
||
}
|