Browse Source

Merge branch 'hotfix_index'

# Conflicts:
#	app/Request/v3/CommunityBindRequest.php
master
Lemon 5 years ago
parent
commit
6012dc888e
  1. 12
      app/Constants/v3/ErrorCode.php
  2. 5
      app/Constants/v3/Tabs.php
  3. 54
      app/Controller/v3/CouponController.php
  4. 3
      app/Controller/v3/HomeController.php
  5. 16
      app/Controller/v3/StoreController.php
  6. 8
      app/Model/v3/Coupon.php
  7. 36
      app/Request/v3/CouponReceiveRequest.php
  8. 187
      app/Service/v3/Implementations/CouponRecService.php
  9. 26
      app/Service/v3/Implementations/OrderOnlineService.php
  10. 37
      app/Service/v3/Implementations/StoreService.php
  11. 13
      app/Service/v3/Implementations/TabsService.php
  12. 2
      app/Service/v3/Interfaces/CouponRecServiceInterface.php
  13. 2
      app/Service/v3/Interfaces/StoreServiceInterface.php
  14. 2
      app/Service/v3/Interfaces/TabsServiceInterface.php
  15. 4
      config/routes.php

12
app/Constants/v3/ErrorCode.php

@ -330,6 +330,18 @@ class ErrorCode extends AbstractConstants
*/
const COUPON_USE_FAILURE = 1202;
/**
* 不是新用户无法领券
* @Message("不是新用户无法领券")
*/
const COUPON_IS_NOT_NEW_USER = 1203;
/**
* 优惠券领取失败
* @Message("优惠券领取失败")
*/
const COUPON_RECEIVE_FAILURE = 1204;
/************************************/
/* 提现相关 1251-1300 */
/************************************/

5
app/Constants/v3/Tabs.php

@ -30,6 +30,11 @@ class Tabs extends AbstractConstants
*/
const APPLET_INDEX_OFFICE = 'applet_index_office';
/**
* @Message("小程序首页店铺列表")
*/
const APPLET_INDEX_STORE = 'applet_index_store';
/**
* @Message("搜索商品为你推荐")
*/

54
app/Controller/v3/CouponController.php

@ -12,10 +12,15 @@ declare(strict_types=1);
namespace App\Controller\v3;
use App\Constants\v3\ErrorCode;
use App\Exception\ErrorCodeException;
use App\Constants\v3\OrderState;
use App\Model\v3\OrderMain;
use App\Request\v3\UserRequest;
use Hyperf\Di\Annotation\Inject;
use App\Controller\BaseController;
use App\Service\v3\Interfaces\CouponRecServiceInterface;
use App\Request\v3\CouponReceiveRequest;
class CouponController extends BaseController
{
@ -75,4 +80,53 @@ class CouponController extends BaseController
return $this->success($res);
}
public function getAvailableListByNewUser()
{
$userId = $this->request->input("user_id", 0);
$receiveType = $this->request->input("receive_type", 0);
$newUserCheck = OrderMain::query()
->where('user_id',$userId)
->whereIn('state',OrderState::CAN_DEL)
->whereIn('state',OrderState::REFUND)
->exists();
if($newUserCheck){
return $this->success(
[
'status' => 'error',
'message' => '不是新用户无法领券',
'text'=>'关注懒族菜市微信公众号,更多精彩活动一手掌握!'
]
);
}
$res = $this->couponRecService->getAvailableList($userId,$receiveType);
if(empty($res['not_receive'])){
return $this->success(
[
'status' => 'error',
'message' => '未满足领取条件',
'text'=>'关注懒族菜市微信公众号,更多精彩活动一手掌握!'
]
);
}
return $this->success($res);
}
/**
* 用户领取优惠卷
*/
public function Receive(CouponReceiveRequest $request)
{
$userId = $this->request->input("user_id", 0);
$receiveType = $this->request->input("receive_type", 0);
$ids = $this->request->input("ids", '');
$res = $this->couponRecService->receive($userId,$receiveType,$ids);
if(!empty($res['success'])){
return $this->success([
'status' => 'ok',
'message' => '红包领取成功,请到“我的-红包”中查看']
);
}else{
throw new ErrorCodeException(ErrorCode::COUPON_RECEIVE_FAILURE);
}
}
}

3
app/Controller/v3/HomeController.php

@ -131,10 +131,11 @@ class HomeController extends BaseController
public function appletIndex()
{
$marketId = $this->request->input('market_id', -1);
$version = $this->request->input('version', -1);
$banners = $this->bannerService->all(Banner::TYPE_APPLET_INDEX, $marketId);
$categories = $this->categoryService->allForAppletIndex();
$activity = $this->activityService->allForAppletIndex(env('APPLET_INDEX_ACTIVITY_TYPE'), $marketId);
$tabs = $this->tabsService->allForAppletIndex();
$tabs = $this->tabsService->allForAppletIndex($version);
return $this->success([
'banners' => $banners,

16
app/Controller/v3/StoreController.php

@ -123,4 +123,20 @@ class StoreController extends BaseController
$res = $data['goods_types'] = $this->categoryService->allForStoreIncludeOff($storeId);
return $this->success(['goods_types' => $res]);
}
public function getListByMarketId()
{
$marketId = $this->request->input('market_id');
$page = $this->request->input('page',1);
$pagesize = $this->request->input('pagesize',10);
$res = $this->storeService->getListByMarketId($marketId,$page,$pagesize);
return $this->success($res);
}
public function updateIsRest()
{
$storeId = $this->request->input('store_id');
$res = $this->storeService->updateIsRest($storeId);
return $this->success($res);
}
}

8
app/Model/v3/Coupon.php

@ -14,7 +14,8 @@ class Coupon extends Model
protected $appends = [
'full_amount_text',
'discounts_text',
'time_text'
'time_text',
'effective_time_text'
];
protected $casts = [
@ -41,4 +42,9 @@ class Coupon extends Model
return date("Y-m-d H:i:s",$this->attributes['usable_start_time']). ' - ' .date("Y-m-d H:i:s",$this->attributes['usable_end_time']);
}
public function getEffectiveTimeTextAttribute()
{
return '有效期:'.date("Y-m-d",$this->attributes['usable_start_time']). ' - ' .date("Y-m-d",$this->attributes['usable_end_time']);
}
}

36
app/Request/v3/CouponReceiveRequest.php

@ -0,0 +1,36 @@
<?php
namespace App\Request\v3;
use App\Request\BaseFormRequest;
class CouponReceiveRequest extends BaseFormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'user_id' => 'required|nonempty|integer',
'receive_type' => 'required|nonempty|integer',
'ids' => 'required',
];
}
/**
* @return array
*/
public function messages(): array
{
return [
'*.*' => ':attribute无效',
];
}
public function attributes(): array
{
return parent::attributes();
}
}

187
app/Service/v3/Implementations/CouponRecService.php

@ -4,7 +4,9 @@ namespace App\Service\v3\Implementations;
use App\Model\v3\Coupon;
use App\Model\v3\CouponRec;
use App\Model\v3\CouponRecType;
use App\Model\v3\GoodsActivity;
use App\Service\CommonService;
use App\Service\v3\Interfaces\CouponRecServiceInterface;
use App\Service\v3\Interfaces\CouponServiceInterface;
use App\Service\v3\Interfaces\ShopCartServiceInterface;
@ -12,6 +14,8 @@ use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Di\Annotation\Inject;
use App\Constants\v3\SsdbKeys;
use App\TaskWorker\SSDBTask;
class CouponRecService implements CouponRecServiceInterface
{
@ -28,6 +32,12 @@ class CouponRecService implements CouponRecServiceInterface
*/
protected $couponService;
/**
* @Inject
* @var HelperService
*/
protected $helperService;
public function do()
{
// TODO: Implement do() method.
@ -290,4 +300,181 @@ class CouponRecService implements CouponRecServiceInterface
}
return $res;
}
public function getAvailableList($userId,$receiveType)
{
/* 优惠券活动标志 2 */
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
$couponActivity = $ssdb->exec('hgetall', SsdbKeys::COUPON_REBATE_ACTIVITY);
$activityType = $couponActivity === false ? 0 : $couponActivity['activity'];
$result = [
'active_type' => 1,
'not_receive' => [],
'jump_data' => [
'src' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType,
'src2' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType,
'share_bg' => env('OSS_IMG_HOST').'/static/img/coupon_share.png',
'receive_bg' => env('OSS_IMG_HOST').'/static/img/coupon_bg.png',
'coupons' => []
]
];
$nowTime = time();
$c_ids = [];
// 渠道开启,查询该渠道可以领取的优惠券ID
// 渠道未开启,查询所有优惠券
if (env('SUB_CHANNEL') == 1) {
$c_ids = CouponRecType::join('lanzu_coupon','lanzu_coupon.id','lanzu_coupon_receive_type.coupon_id')
->where([
['lanzu_coupon_receive_type.receive_type','=',$receiveType],
['lanzu_coupon.end_time','>',$nowTime],
['lanzu_coupon.start_time','<=',$nowTime],
['lanzu_coupon.status','=',1]
])
->pluck('lanzu_coupon.id');
} else {
$c_ids = Coupon::where([
['end_time','>',$nowTime],
['start_time','<=',$nowTime],
['status','=',1]
])->pluck('id');
}
$couponReceive = CouponRec::where('user_id',$userId);
// 渠道开启,查询该用户在此渠道领过的优惠券ID
if (env('SUB_CHANNEL') == 1) {
$couponReceive->where('receive_type', $receiveType);
}
$cr_ids = $couponReceive->pluck('coupon_id');
// 可领取的券ID
$c_ids = $c_ids->toArray();
// 已经领取的券ID
$cr_ids = $cr_ids->toArray();
// 当前用户可领的优惠券ID
$couponIds = array_diff($c_ids, $cr_ids);
// 转发型优惠券
$couponReceiveIds = ($couponActivity === false || $this->helperService->nonempty($couponActivity['forward']) )? [] : explode(',',$couponActivity['forward']);
// 所有优惠券
$couponIds = array_merge($couponIds,$couponReceiveIds);
$whereC = [
['lanzu_coupon.end_time','>',$nowTime],
['lanzu_coupon.start_time','<=',$nowTime],
['lanzu_coupon.status','=',1]
];
// 查询领取型1 和 转发型2
$whereActiveType = [1,2];
if (env('SUB_CHANNEL') == 1) {
array_push($whereC, ['type.receive_type','=', $receiveType]);
}
$coupons = Coupon::join('lanzu_coupon_receive_type as type', 'lanzu_coupon.id', '=', 'type.coupon_id')
->whereIn('lanzu_coupon.id', $couponIds)
->whereIn('lanzu_coupon.active_type', $whereActiveType)
->where($whereC)
->whereRaw('lanzu_coupon.inventory_use < lanzu_coupon.inventory and lanzu_coupon.inventory-lanzu_coupon.inventory_use >= type.one_receive_number')
->select('lanzu_coupon.*','type.one_receive_number')
->orderBy('lanzu_coupon.weigh','desc')
->get();
foreach ($coupons as $k => &$v){
if($v->active_type == 1){
$result['not_receive'][] = $v;
}else if($v->active_type == 2 && in_array($v->id,$couponReceiveIds)){
$result['jump_data']['coupons'][] = $v->id;
}
if($v->discount_type == 2){
$v->discounts = floatval($v->discounts);
}
}
$result['active_type'] = count($result['jump_data']['coupons']) > 0 ? 2 : $result['active_type'] ;
return $result;
}
/**
* @param $userId
* @param $receiveType
* @param $ids
*/
public function receive($userId, $receiveType, $ids)
{
$ids = explode(',', $ids);
$now = time();
$success = [];
$fail = [];
// if ($this->empty($userId) || $this->empty($receiveType) || $this->empty($ids)) {
// return [
// 'success' => $success,
// 'fail' => $fail,
// ];
// }
Db::transaction(function () use ($ids,$receiveType,$userId,&$success,&$fail,$now) {
//读写锁,完全控制,性能底
$builder = Coupon::whereIn('id', $ids);
if (env('SUB_CHANNEL') == 1) {
$builder->where('receive_type',$receiveType);
}
$cps = $builder->lockForUpdate()->get();
//写锁,可能在高并发下,读取到脏数据,写入可能有超发情况
//$cps = Coupon::whereIn('id', $ids)->sharedLock()->get();
foreach ($cps as $key => $cp) {
$where = [
'coupon_id' => $cp->id,
];
$oneReceiveNumber = CouponRecType::where($where)->value('one_receive_number');
$couponInventory = $cp->inventory - $cp->inventory_use;
if($couponInventory < $oneReceiveNumber){
continue;
}
$couponReceiveExists = CouponRec::query()->where(['coupon_id'=>$cp->id,'user_id'=>$userId])->exists();
if($couponReceiveExists){
continue;
}
$cr = new CouponRec;
$cr->user_id = $userId;
$cr->coupon_id = $cp->id;
$cr->order_main_id = 0;
$cr->receive_time = $now;
$cr->number = $oneReceiveNumber;
$cr->number_remain = $oneReceiveNumber;
$cr->status = 0;
$cr->update_time = $now;
$cr->receive_type = $receiveType;
//如果优惠卷库存小于等于已领取的数量, 则返回领取失败的优惠券
if ($cp->inventory<=$cp->inventory_use||$cp->inventory<($cp->inventory_use+$cr->number)){
$fail[] = $cp;
}else{
$cp->inventory_use += $cr->number;//记录已领取的数量
if ($cr->save()&&$cp->save()) {
$success[] = $cp;
} else {
$fail[] = $cp;
}
}
}
});
return [
'success' => $success,
'fail' => $fail,
];
}
}

26
app/Service/v3/Implementations/OrderOnlineService.php

@ -176,19 +176,6 @@ class OrderOnlineService implements OrderOnlineServiceInterface
// $userAddr->lng = $market->lng;
}
// 优惠券数据,当前订单可用个优惠券
$couponRecs = $this->couponRecService->allForOnlineOrderAvailable($userId, $marketId);
$canRealUseCoupons = $couponRecs['available'];
$canRealUseCouponRecIds = array_values(array_column($canRealUseCoupons, 'id'));
if (!empty(array_diff($receiveCouponIds, $canRealUseCouponRecIds))) {
$this->log->event(LogLabel::ORDER_ONLINE_LOG, ['msg' => '订单中有不能使用优惠券的商品', 'data' => json_encode([
'all_user_coupons_rec' => json_encode($couponRecs),
'can_real_user_coupons' => json_encode($canRealUseCoupons),
'receive_coupon_ids' => json_encode($canRealUseCouponRecIds),
])]);
throw new ErrorCodeException(ErrorCode::GOODS_ACTIVITY_CANNOT_USE_COUPON);
}
// 处理购物车数据,计算订单金额、子订单数据处理等
$totalAmount = 0; # 实付金额
$orderAmount = 0; # 订单金额
@ -324,6 +311,19 @@ class OrderOnlineService implements OrderOnlineServiceInterface
$orderAmount = bcadd((string)$orderAmount, (string)$subAmount);
}
// 优惠券数据,当前订单可用个优惠券
$couponRecs = $this->couponRecService->allForOnlineOrderAvailable($userId, $marketId ,$shopcartIds);
$canRealUseCoupons = $couponRecs['available'];
$canRealUseCouponRecIds = array_values(array_column($canRealUseCoupons, 'id'));
if (!empty(array_diff($receiveCouponIds, $canRealUseCouponRecIds))) {
$this->log->event(LogLabel::ORDER_ONLINE_LOG, ['msg' => '订单中有不能使用优惠券的商品', 'data' => json_encode([
'all_user_coupons_rec' => json_encode($couponRecs),
'can_real_user_coupons' => json_encode($canRealUseCoupons),
'receive_coupon_ids' => json_encode($canRealUseCouponRecIds),
])]);
throw new ErrorCodeException(ErrorCode::GOODS_ACTIVITY_CANNOT_USE_COUPON);
}
// 优惠券的使用
$couponMoney = 0;
if (!empty($receiveCouponIds)) {

37
app/Service/v3/Implementations/StoreService.php

@ -3,9 +3,13 @@
namespace App\Service\v3\Implementations;
use App\Constants\v3\Goods as GoodsConstants;
use App\Constants\v3\Store as StoreConstants;
use App\Model\v3\Market;
use App\Model\v3\Store;
use App\Model\v3\Goods;
use App\Service\v3\Interfaces\StoreServiceInterface;
use Hyperf\Utils\ApplicationContext;
class StoreService implements StoreServiceInterface
{
@ -63,4 +67,37 @@ class StoreService implements StoreServiceInterface
$market->stores = $stores['data'];
return ['has_more_pages' => $paginate->hasMorePages(), 'market' => $market];
}
public function getListByMarketId($marketId, $page=1, $pagesize=10)
{
$storeTable = ApplicationContext::getContainer()->get(Store::class)->getTable();
$goodsTable = ApplicationContext::getContainer()->get(Goods::class)->getTable();
$builder = Store::query()
->select(''.$storeTable.'.*')
->join($goodsTable,''.$storeTable.'.id', '=', ''.$goodsTable.'.store_id')
->where([''.$goodsTable.'.on_sale' => GoodsConstants::ON_SALE_YES])
->where([''.$goodsTable.'.market_id' => $marketId])
->where(function ($query) use ($goodsTable) {
$query->where(''.$goodsTable.'.inventory', '>', 0)->orWhere(''.$goodsTable.'.is_infinite', '=', 1);
})
->whereRaw(''.$goodsTable.'.deleted_at IS NULL')
->where([''.$storeTable.'.market_id' => $marketId, ''.$storeTable.'.is_rest' => StoreConstants::IS_REST_NO]);
$paginate = $builder->groupBy(''.$storeTable.'.id')->orderByDesc($storeTable.'.sales')->paginate($pagesize);
$stores = $paginate->map(function ($item, $key) {
$item->goods;
return $item;
})->all();
return ['has_more_pages' => $paginate->hasMorePages(), 'stores' => $stores];
}
public function updateIsRest($storeId)
{
$store = Store::query()->withoutGlobalScope('normal')->find($storeId);
$isRest = $store->is_rest + 1;
$store->is_rest = $isRest % 2;
return $store->save();
}
}

13
app/Service/v3/Implementations/TabsService.php

@ -23,9 +23,19 @@ class TabsService implements TabsServiceInterface
// TODO: Implement undo() method.
}
public function allForAppletIndex()
public function allForAppletIndex($version)
{
if($version == '3.0.12'){
return [
['tab' => Tabs::APPLET_INDEX_STORE, 'title' => '推荐店铺', 'subtitle' => '物美价廉', 'badge' => '', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
['tab' => Tabs::APPLET_INDEX_RECOMMEND, 'title' => '猜你喜欢', 'subtitle' => '我是你的菜', 'badge' => '', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
['tab' => Tabs::APPLET_INDEX_NEW, 'title' => '每日上新', 'subtitle' => '新鲜当日达', 'badge' => '好新鲜', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
['tab' => Tabs::APPLET_INDEX_FRESH, 'title' => '懒族优选', 'subtitle' => '发现不一样', 'badge' => '', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
//['tab' => Tabs::APPLET_INDEX_OFFICE, 'title' => '白领餐食', 'subtitle' => '轻奢快手菜', 'badge' => '手到食来', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
];
}else{
return [
//['tab' => Tabs::APPLET_INDEX_STORE, 'title' => '推荐店铺', 'subtitle' => '物美价廉', 'badge' => '', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
['tab' => Tabs::APPLET_INDEX_RECOMMEND, 'title' => '猜你喜欢', 'subtitle' => '我是你的菜', 'badge' => '', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
['tab' => Tabs::APPLET_INDEX_NEW, 'title' => '每日上新', 'subtitle' => '新鲜当日达', 'badge' => '好新鲜', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
['tab' => Tabs::APPLET_INDEX_FRESH, 'title' => '懒族优选', 'subtitle' => '发现不一样', 'badge' => '', 'bg_color' => '#FF0000', 'font_color' => '#FFFFFF'],
@ -33,3 +43,4 @@ class TabsService implements TabsServiceInterface
];
}
}
}

2
app/Service/v3/Interfaces/CouponRecServiceInterface.php

@ -16,4 +16,6 @@ interface CouponRecServiceInterface
* @return mixed
*/
public function statistics($userId);
public function getAvailableList($userId,$receiveType);
public function receive($userId,$receiveType,$ids);
}

2
app/Service/v3/Interfaces/StoreServiceInterface.php

@ -9,4 +9,6 @@ interface StoreServiceInterface
public function undo();
public function detail($storeId);
public function getList($marketId ,$page=1, $pagesize=10);
public function getListByMarketId($marketId ,$page=1, $pagesize=10);
public function updateIsRest($storeId);
}

2
app/Service/v3/Interfaces/TabsServiceInterface.php

@ -7,5 +7,5 @@ interface TabsServiceInterface
public function do();
public function check();
public function undo();
public function allForAppletIndex();
public function allForAppletIndex($version);
}

4
config/routes.php

@ -156,6 +156,7 @@ Router::addGroup('/v3/', function () {
Router::post('store/getGoodsByType', 'App\Controller\v3\StoreController@getGoodsByType');
Router::post('goods/update', 'App\Controller\v3\GoodsController@update');
Router::post('store/getList', 'App\Controller\v3\StoreController@getList');
Router::post('store/getListByMarketId', 'App\Controller\v3\StoreController@getListByMarketId');
Router::post('goods/info', 'App\Controller\v3\GoodsController@info');
Router::post('store/getCategory', 'App\Controller\v3\StoreController@getCategory');
Router::post('category/first', 'App\Controller\v3\CategoryController@first');
@ -163,6 +164,9 @@ Router::addGroup('/v3/', function () {
Router::post('category/third', 'App\Controller\v3\CategoryController@third');
Router::post('goods/create', 'App\Controller\v3\GoodsController@create');
Router::post('goods/updateOnSale', 'App\Controller\v3\GoodsController@updateOnSale');
Router::post('store/updateIsRest', 'App\Controller\v3\StoreController@updateIsRest');
Router::post('coupon/getAvailableListByNewUser', 'App\Controller\v3\CouponController@getAvailableListByNewUser');
Router::post('coupon/receive', 'App\Controller\v3\CouponController@receive');
},['middleware' => [\App\Middleware\Auth\ApiMiddleware::class, \App\Middleware\Auth\UserMiddleware::class]]);
// 微信支付回调

Loading…
Cancel
Save