coupon-admin/app/controller/api/Coupon.php

502 lines
19 KiB
PHP

<?php
namespace app\controller\api;
use app\exception\RepositoryException;
use app\model\Account;
use app\model\CouponMain;
use app\model\Score;
use app\repository\AccountRepository;
use app\repository\CouponRepository;
use app\validate\CouponRelease;
use app\validate\CouponUsingRule;
use think\Exception;
use think\facade\Config;
use think\facade\Db;
use think\facade\Log;
/**
* 优惠卷相关
* Class Coupon
* @package app\controller\api
*/
class Coupon extends Base
{
protected $noNeedLogin = [];
/**
* 我的优惠卷列表
*
* type in ['', 'notUsed', 'normal', 'used']
*/
public function getCouponList()
{
$page = $this->request->param('page/d', 1);
$size = $this->request->param('size/d', 10);
$type = $this->request->param('type', '');
$page = $page < 1 ? 1 : $page;
$size = $size < 1 ? 10 : $size;
$accountCode = $this->request->user['user_code'] ?? '';
try {
$whereMap = [];
$sortOrder = ['received_time' => 'desc'];
$fields = [
'id',
'is_verificated as isVerificated',
'money',
'name as couponName',
'business_code as businessCode',
'end_time as endTime',
'consumer_name as consumerName',
'verificate_time as verificateTime',
'(end_time > NOW()) as sort_weight'];
$whereMap[] = ['consumer_code', '=', $accountCode];
switch ($type) {
case 'all':
// 全部持有优惠券
$sortOrder = ['sort_weight' => 'desc', 'end_time' => 'asc'];
break;
case 'notUsed':
// 未使用(包含已过期)
$whereMap[] = ['is_verificated', '=', self::BOOL_FALSE];
$sortOrder = ['sort_weight' => 'desc', 'end_time' => 'asc'];
break;
case 'normal':
// 未使用且未过期
$whereMap[] = ['is_verificated', '=', self::BOOL_FALSE];
$whereMap[] = ['end_time', '< TIME', date('Y-m-d H:i:s')];
break;
case 'used':
// 已使用
$whereMap[] = ['is_verificated', '=', self::BOOL_TRUE];
$sortOrder = ['verificate_time' => 'desc'];
break;
}
$res = CouponRepository::getInstance()->findList($whereMap, $fields, $page, $size,function ($q){
return $q->with(["couponMain","scoreModel"]);
}, $sortOrder);
$res['list'] ->each(function ($item){
//重置优惠券名称
if(isset($item->couponMain) && $item->couponMain){
$item->couponName = $item->couponMain->name;
}
//是否已经打分过了
if(isset($item->scoreModel) && $item->scoreModel){
$item->scored = true;
$item->score = $item->scoreModel->score;
}else{
$item->scored = false;
$item->score = Score::COMMON_OFF;
}
});
$res['list'] = multiTwoArrayKeysExcludeFilter($res['list']->toArray(), ['sort_weight']);
return $this->json(0, 'success', $res);
} catch (RepositoryException | \Exception $e) {
return $this->json(5001, '优惠卷查询失败!');
}
}
/**
* 领取优惠券
* */
public function receiveCoupon()
{
$accountId = $this->request->user['user_id'] ?? 0;
$lat = input("lat/f",0);
$lng = input("lng/f",0);
$account = AccountRepository::getInstance()->findById($accountId, [], function ($q) {
return $q->with(['business', 'parent']);
});
if(empty($account)){
return $this->json(6001,"无效的用户");
}
if ($lat <= 0 || $lng <= 0) {
return $this->json(4001, "请授权定位");
}
$couponMainId = input("couponId/d", 0);
$couponMain = CouponMain::findOne(["id" => $couponMainId],[],function ($q){
//执行领取 开启锁
return $q->with("business")->lock(true);
});
//检查优惠券状态
$checkCouponMainReceiveStatus = CouponRepository::getInstance()->checkCouponMainReceiveStatus($couponMain);
if( $checkCouponMainReceiveStatus !== true ){
return $checkCouponMainReceiveStatus;
}
try {
//检查是否可以领取 0可领取 1已领取
AccountRepository::getInstance()->getCouponReceiveStatusText($account->user_code,$couponMain);//领取状态
}catch (RepositoryException $e){
return $this->json(4001,$e->getMessage());
}
//检查通过 执行领取
$time = time();
Db::startTrans();
try {
//写入领取记录
$data = [
"coupon_id" =>$couponMain->id,
"name" =>$couponMain->name,
"type_id" =>$couponMain->type,
"type_name" =>$couponMain->type_name,
"business_code" =>$couponMain->business_code,
"business_name" =>$couponMain->business?$couponMain->business->business_name:'',
"consumer_code" =>$account->user_code,
"consumer_name" =>$account->nick_name,
"money" => $couponMain->money,
"content" => createUuid(),//未知作用
"received_time" => date("Y-m-d H:i:s",$time),
"lat" => $lat,
"lng" => $lng,
"end_time" => date($couponMain->end_time . " 00:00:00"),
"edition" => couponMain::COMMON_ON,//版本 未知作用
"is_verificated" => couponMain::COMMON_OFF,//版本 未知作用
];
CouponRepository::getInstance()->receiveCoupon($data);
Db::commit();
return $this->json();
}catch (RepositoryException $e){
Log::error("优惠券领取失败RepositoryException:".$e->getMessage());
Db::rollback();
return $this->json(5001,"领取失败");
}catch (Exception $e){
Log::error("优惠券领取失败:".$e->getMessage());
Db::rollback();
return $this->json(5001,"领取失败");
}
}
/**
* 发布优惠券
* */
public function add()
{
$accountId = $this->request->user['user_id'] ?? 0;
$account = AccountRepository::getInstance()->findById($accountId, [], function ($q) {
return $q->with(['business'=>function($q){
$q->lock(true);
}, 'parent']);
});
if(empty($account)){
return $this->json(6001,"登录失效");
}
if ($account->type == Account::type_consumer) {
return $this->json(4001, "您不是商家");
}
if (!isset($account->business) || empty($account->business)) {
return $this->json(4001, "商家信息错误");
}
$data = input();
Config::load("extra/distribution_proportion","distribution_proportion");
$distributionProportion = config("distribution_proportion");
$totalC = $distributionProportion['agency'] + $distributionProportion['admin'] + $distributionProportion['consumer'];
if ($totalC != 100) {
return $this->json(5002, "系统设置分配比例总和不等于100,不能发布");
}
//验证通过 不管是商家还是工作人员 都可以发布优惠券
$couponMain = [
"name" => $data['name'] ?? '',
"business_code" => $account->business->code,
"money" => $data['money'] ?? 0,
"type" => $data['type'] ?? 0,
"count" => $data['count'] ?? 0,
"type_name" => $data['type_name'] ?? '',
"start_time" => $data['start_time'] ?? '',
"end_time" => $data['end_time'] ?? '',
"deduction_money" => $data['deduction_money'] ?? '',
"image_url" => $data['image_url'] ?? '',
"intro" => $data['intro'] ?? '',
"white_list" => $data['white_list'] ?? '',
"status" => CouponMain::status_on,
"on_shelf" => CouponMain::on_shelf_off,//默认下架 后天审核上架
"commission_agency" => $distributionProportion['agency'],
"commission_admin" => $distributionProportion['admin'],
"commission_consumer" => $distributionProportion['consumer'],
];
$usingRule = input("using_rule/a");
$validate = new CouponRelease();
if (!$validate->check($couponMain)) {
return $this->json(4001, $validate->getError());
}
$usingRuleValidate = new CouponUsingRule();
if (!$usingRuleValidate->check($usingRule)) {
return $this->json(4001, $usingRuleValidate->getError());
}
//验证通过
$couponMain['business_type'] = $account->business['type'];
$couponMain['business_name'] = $account->business['business_name'];
$couponMain['lng'] = $account->business['lng'];
$couponMain['lat'] = $account->business['lat'];
$couponMain['create_time'] = date("Y-m-d H:i:s");
//保留两位小数
$couponMain['money'] = floor($couponMain['money'] * 100) / 100;
$totalMoney = $couponMain['money'] * $couponMain['count'];
if ($account->business["balance"] < $totalMoney) {
return $this->json(4001, '商家余额不足');
}
Db::startTrans();
try {
CouponRepository::getInstance()->releaseCouponMain($couponMain, $totalMoney, $usingRule);
Db::commit();
return $this->json();
} catch (RepositoryException $e) {
Db::rollback();
return $this->json(5001, "发布失败" . $e->getMessage());
} catch (\think\Exception $e) {
Db::rollback();
return $this->json(5002, "发布失败" . $e->getMessage());
}
}
/**
* 修改优惠券
* */
public function edit()
{
$accountId = $this->request->user['user_id'] ?? 0;
$couponMainId = input("couponMainId/d");
$account = AccountRepository::getInstance()->findById($accountId, [], function ($q) {
return $q->with(['business'=>function($q){
$q->lock(true);
}, 'parent']);
});
if(empty($account)){
return $this->json(6001,"登录失效");
}
if ($account->type == Account::type_consumer) {
return $this->json(4001, "您不是商家");
}
if (!isset($account->business) || empty($account->business)) {
return $this->json(4001, "商家信息错误");
}
$couponMain = CouponMain::findById($couponMainId,[],function ($q){
return $q->with(["usingRule"]);
});
if (empty($couponMain)) {
return $this->json(4001, "优惠券不存在");
}
if (!isset($couponMain->usingRule)||empty($couponMain->usingRule)) {
return $this->json(4001, "优惠券信息错误");
}
$data = input();
//验证通过 不管是商家还是工作人员 都可以修改优惠券 只能修改指定字段
$couponMainData = [
"name" => $data['name'] ?? '',
"type" => $data['type'] ?? 0,
"type_name" => $data['type_name'] ?? '',
"start_time" => $data['start_time'] ?? '',
"end_time" => $data['end_time'] ?? '',
"image_url" => $data['image_url'] ?? '',
"intro" => $data['intro'] ?? '',
"white_list" => $data['white_list'] ?? '',
];
$usingRule = input("using_rule/a");
$validate = new CouponRelease();
if (!$validate->scene("api_edit")->check($couponMainData)) {
return $this->json(4001, $validate->getError());
}
$usingRuleValidate = new CouponUsingRule();
if (!$usingRuleValidate->check($usingRule)) {
return $this->json(4001, $usingRuleValidate->getError());
}
//验证通过
Db::startTrans();
try {
$couponMain->save($couponMainData);
$couponMain->usingRule->save($usingRule);
Db::commit();
return $this->json();
} catch (RepositoryException $e) {
Db::rollback();
return $this->json(5001, "修改失败失败" );
} catch (\think\Exception $e) {
Db::rollback();
return $this->json(5002, "修改失败500" );
}
}
/**
* 商家管理优惠券
* */
public function getPageList()
{
$accountId = $this->request->user['user_id'] ?? 0;
$account = AccountRepository::getInstance()->findById($accountId, [], function ($q) {
return $q->with(['business', 'parent']);
});
if(empty($account)){
return $this->json(6001,"登录失效");
}
if ($account->type == Account::type_consumer) {
return $this->json(4001, "您不是商家");
}
if (!isset($account->business) || empty($account->business)) {
return $this->json(4001, "商家信息错误");
}
$page = $this->request->param('page/d', 1);
$size = $this->request->param('rows/d', 10);
$page = $page < 1 ? 1 : $page;
$size = $size < 1 ? 10 : $size;
$keyword = $this->request->param('key/s',"");
$businessCode = $account->business_code;
try {
$whereMap = [];
$sortOrder = ['sort' => 'desc'];
$whereMap[] = ["business_code" ,"=", $businessCode ];
if(!empty($keyword)){
$whereMap[] = ["name" ,"like", "%{$keyword}%" ];
}
$res = CouponRepository::getInstance(new CouponMain())->findList($whereMap, [], $page, $size,function ($q){
return $q->with(["usingRule","couponType"]);
}, $sortOrder);
$time = time();
$res['list'] ->each(function ($item) use($time){
//已使用张数
$item->usingCount = CouponRepository::getInstance()->getCouponMainUsingCount($item->id);
if(strtotime($item->start_time) <= $time && strtotime($item->end_time) >= $time){
$item->conduct = true;
}else{
$item->conduct = false;
}
});
return $this->json(0, 'success', $res["list"]);
} catch (RepositoryException | \Exception $e) {
echo $e->getMessage();
return $this->json(5001, '优惠卷查询失败!');
}
}
/**
* 优惠券的领取 使用记录列表
* */
public function getShopCouponList()
{
$accountId = $this->request->user['user_id'] ?? 0;
$account = AccountRepository::getInstance()->findById($accountId, [], function ($q) {
return $q->with(['business', 'parent']);
});
if(empty($account)){
return $this->json(6001,"登录失效");
}
if ($account->type == Account::type_consumer) {
return $this->json(4001, "您不是商家");
}
if (!isset($account->business) || empty($account->business)) {
return $this->json(4001, "商家信息错误");
}
$couponMainId = input("couponId/d");
$couponMain = CouponMain::findById($couponMainId);
if(empty($couponMain)){
return $this->json(4001, "优惠券不存在");
}
if($couponMain->business_code != $account->business->code){
return $this->json(4001, "优惠券参数信息错误");
}
$page = $this->request->param('page/d', 1);
$size = $this->request->param('rows/d', 10);
$type = $this->request->param('type/s', 10);
$page = $page < 1 ? 1 : $page;
$size = $size < 1 ? 10 : $size;
$sortOrder = ["id"=>"desc"];
$whereMap = [
["coupon_id","=",$couponMainId]
];
switch ($type) {
case 'all':
// 全部持有优惠券
$sortOrder = [ 'end_time' => 'asc'];
break;
case 'notUsed':
// 未使用(包含已过期)
$whereMap[] = ['is_verificated', '=', self::BOOL_FALSE];
$sortOrder = ['end_time' => 'asc'];
break;
case 'normal':
// 未使用且未过期
$whereMap[] = ['is_verificated', '=', self::BOOL_FALSE];
$whereMap[] = ['end_time', '< TIME', date('Y-m-d H:i:s')];
break;
case 'used':
// 已使用
$whereMap[] = ['is_verificated', '=', self::BOOL_TRUE];
$sortOrder = ['verificate_time' => 'desc'];
break;
}
$field = ["is_verificated","received_time","verificate_time","consumer_code"];
$data = CouponRepository::getInstance()->findList($whereMap,$field,$page,$size,function($q){
return $q->withjoin(["account"=>function($q){
$q->field(["nick_name","avatar_url","gender","user_code"]);
}]);
},$sortOrder);
//所有
$data["allNum"] = CouponRepository::getInstance()->getModel()->where(["coupon_id"=>$couponMainId])->count();
//未使用
$data["unUsedNum"] = CouponRepository::getInstance()->getModel()->where(['is_verificated' => self::BOOL_FALSE,"coupon_id"=>$couponMainId])->count();
//已使用
$data["usedNum"] = CouponRepository::getInstance()->getModel()->where(['is_verificated' => self::BOOL_TRUE ,"coupon_id"=>$couponMainId])->count();
return $this->json(0,"success",$data);
}
/**
* 获取优惠券详情
* */
public function getCouponMainInfo()
{
$couponMainId = input("couponMainId/d");
$couponMain = CouponMain::findById($couponMainId,[],function ($q){
return $q->with("usingRule");
});
if(empty($couponMain)){
return $this->json(4001,"优惠券不存在");
}
return $this->json(0,"success",$couponMain->toArray());
}
}