zx/app/common/repositories/store/StoreActivityRepository.php

526 lines
20 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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\common\repositories\store;
use app\common\dao\store\StoreActivityDao;
use app\common\model\store\StoreActivity;
use app\common\repositories\BaseRepository;
use app\common\repositories\store\product\ProductLabelRepository;
use app\common\repositories\store\product\SpuRepository;
use app\common\repositories\system\merchant\MerchantRepository;
use app\common\repositories\system\RelevanceRepository;
use crmeb\services\QrcodeService;
use Exception;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Db;
/**
* @mixin StoreActivityDao
*/
class StoreActivityRepository extends BaseRepository
{
//氛围图
const ACTIVITY_TYPE_ATMOSPHERE = 1;
//活动边框
const ACTIVITY_TYPE_BORDER = 2;
//报名活动
const ACTIVITY_TYPE_FORM = 4;
//指定范围类型
//0全部商品
const TYPE_ALL = 0;
//指定商品
const TYPE_MUST_PRODUCT = 1;
//指定分类
const TYPE_MUST_CATEGORY = 2;
//指定商户
const TYPE_MUST_STORE = 3;
//指定商品标签
const TYPE_MUST_PRODUCT_LABEL = 4;
//秒杀活动商品
const TYPE_MUST_SECKILL_ACTIVE = 5;
public $activeProductType = [1];
//使用范围对应的类型
public $typeData = [
self::TYPE_ALL => '',
self::TYPE_MUST_PRODUCT => RelevanceRepository::SCOPE_TYPE_PRODUCT,
self::TYPE_MUST_CATEGORY => RelevanceRepository::SCOPE_TYPE_CATEGORY,
self::TYPE_MUST_STORE => RelevanceRepository::SCOPE_TYPE_STORE,
self::TYPE_MUST_PRODUCT_LABEL => RelevanceRepository::SCOPE_TYPE_PRODUCT_LABEL,
self::TYPE_MUST_SECKILL_ACTIVE => '',
];
/**
* @var StoreActivityDao
*/
protected $dao;
/**
* StoreActivityDao constructor.
* @param StoreActivityDao $dao
*/
public function __construct(StoreActivityDao $dao)
{
$this->dao = $dao;
}
public function getActiveScopeType($type = null)
{
$data = [
1 => self::TYPE_MUST_SECKILL_ACTIVE,
];
return $type ? $data[$type] : $data;
}
public function getList($where, $page, $limit)
{
$query = $this->dao->search($where)->append(['time_status']);
$count = $query->count();
$list = $query->page($page, $limit)->order('sort DESC,activity_id DESC')->select();
return compact('count', 'list');
}
/**
* 创建活动商品 的活动关联氛围图等
* @param $data 主要信息
* @param $type 商品类型
* @return mixed
* @author Qinii
* @day 2024/4/15
*/
public function saveByType(array $data, int $type)
{
$createData = [
'activity_name' => $data['activity_name'],
'start_time' => $data['start_time'],
'end_time' => $data['end_time'],
'pic' => $data['pic'],
'link_id' => $data['link_id'],
'activity_type' => $data['activity_type'],
];
if (!in_array($data['activity_type'], [self::ACTIVITY_TYPE_ATMOSPHERE,self::ACTIVITY_TYPE_BORDER]))
throw new ValidateException('活动类型错误');
if (!in_array($type, $this->activeProductType))
throw new ValidateException('请选择指定商品');
if (count(array_filter($createData ?? [])) < 6)
throw new ValidateException('缺少必传参数');
$scope_type = $this->getActiveScopeType($type);
$res = $this->getSearch(['activity_type' => $createData['activity_type']])
->where(['scope_type' => $scope_type, 'link_id' => $createData['link_id'],])->find();
try {
if ($res) {
$this->dao->update($res->activity_id,$createData);
} else {
$createData['scope_type'] = $scope_type;
$createData['status'] = strtotime($createData['start_time']) <= time() ? 1 : 0;
$createData['sort'] = 999;
$createData['is_display'] = 0;
$createData['is_show'] = 1;
$this->createActivity($createData);
}
return true;
}catch (Exception $e) {
throw new ValidateException($e->getMessage());
}
}
/**
* 创建活动
* @param data['activity_name'] 名称
* @param data['start_time'] 开始时间
* @param data['end_time'] 结束时间
* @param data['pic'] 活动图片
* @param data['is_show'] 是否显示
* @param data['status'] 是否在活动中
* @param data['sort'] 排序
* @param data['activity_type'] 活动类型
* @param data['is_display'] 是否展示活动
* @param data['link_id'] 关联ID
* @param array $data
* @param $extend
* @param $func
* @author Qinii
* @day 2023/10/13
*/
public function createActivity(array $data, $extend = null, $func = null)
{
$paramsData = $extend ? $this->getParams($data, $extend) : [];
return Db::transaction(function () use ($data, $extend, $func, $paramsData) {
$createData = $this->dao->create($data);
if (isset($paramsData['ids']) && !empty($paramsData['ids']))
app()->make(RelevanceRepository::class)->createMany($createData->activity_id, $paramsData['ids'], $paramsData['type']);
if ($func && function_exists($func)) $this->$func($createData, $extend);
});
}
/**
* 整理关联参数
* @param $data
* @param $extend
* @return array
* @author Qinii
* @day 2023/10/13
*/
public function getParams($data, $extend)
{
if (!$extend) return [];
$res = [];
$type = '';
switch ($data['scope_type']) {
case self::TYPE_ALL;
break;
case self::TYPE_MUST_PRODUCT:
if (!isset($extend['spu_ids']) || empty($extend['spu_ids']))
throw new ValidateException('请选择指定商品');
$res = app()->make(SpuRepository::class)->getSearch(['spu_ids' => $extend['spu_ids'], 'status' => 1])->column('spu_id');
$type = RelevanceRepository::SCOPE_TYPE_PRODUCT;
break;
case self::TYPE_MUST_CATEGORY:
if (!isset($extend['cate_ids']) || empty($extend['cate_ids']))
throw new ValidateException('请选择指定商品分类');
$res = app()->make(StoreCategoryRepository::class)->getSearch(['ids' => $extend['cate_ids'], 'status' => 1])->column('store_category_id');
$type = RelevanceRepository::SCOPE_TYPE_CATEGORY;
break;
case self::TYPE_MUST_STORE:
if (!isset($extend['mer_ids']) || empty($extend['mer_ids']))
throw new ValidateException('请选择指定商户');
$res = app()->make(MerchantRepository::class)->getSearch(['mer_ids' => $extend['mer_ids']])->column('mer_id');
$type = RelevanceRepository::SCOPE_TYPE_STORE;
break;
case self::TYPE_MUST_PRODUCT_LABEL:
if (!isset($extend['label_ids']) || empty($extend['label_ids']))
throw new ValidateException('请选择指定商品标签');
$res = app()->make(ProductLabelRepository::class)->getSearch(['product_label_id' => $extend['label_ids']])->column('product_label_id');
$type = RelevanceRepository::SCOPE_TYPE_PRODUCT_LABEL;
break;
default:
throw new ValidateException('缺少活动类型');
break;
}
$ids = array_unique($res);
return compact('ids', 'type');
}
public function updateActivity(int $id, array $data, $extend = null, $func = null)
{
$paramsData = $this->getParams($data, $extend);
Db::transaction(function () use ($id, $data, $extend, $func, $paramsData) {
$createData = $this->dao->update($id, $data);
if (!empty($paramsData)) {
app()->make(RelevanceRepository::class)->clear($id, $paramsData['type'], 'left_id');
if (isset($paramsData['ids']) && !empty($paramsData['ids']))
app()->make(RelevanceRepository::class)->createMany($id, $paramsData['ids'], $paramsData['type']);
}
if ($func && function_exists($func)) $this->$func($createData, $extend);
});
}
/**
* TODO 详情
* @param $where
* @param $page
* @param $limit
* @return array
* @author Qinii
* @day 2022/9/17
*/
public function getAdminList($where, $page, $limit, array $with = [])
{
$where['is_display'] = 1;
$query = $this->dao->search($where, $with)->order('sort DESC,activity_id DESC');
$count = $query->count();
$list = $query->page($page, $limit)->select()->append(['time_status']);
return compact('count', 'list');
}
/**
* TODO 详情
* @param $id
* @return array
* @author Qinii
* @day 2022/9/16
*/
public function detail($id, $type = true)
{
$with = [];
if ($type) $with[] = 'socpeData';
$data = $this->dao->getSearch([$this->dao->getPk() => $id])->with($with)->append(['time_status'])->find()->toArray();
if ($type) {
try {
$arr = array_column($data['socpeData'], 'right_id');
if ($data['scope_type'] == self::TYPE_MUST_CATEGORY) {
$data['cate_ids'] = $arr;
} else if ($data['scope_type'] == self::TYPE_MUST_STORE) {
$data['mer_ids'] = $arr;
} else if ($data['scope_type'] == self::TYPE_MUST_PRODUCT_LABEL) {
$data['label_ids'] = $arr;
} else {
$data['spu_ids'] = $arr;
}
} catch (Exception $e) {
}
unset($data['socpeData']);
}
return $data;
}
/**
* TODO 删除活动
* @param $id
* @return mixed
* @author Qinii
* @day 2022/9/17
*/
public function deleteActivity($id)
{
return Db::transaction(function () use ($id) {
$this->dao->delete($id);
app()->make(RelevanceRepository::class)->clear($id, [RelevanceRepository::SCOPE_TYPE_PRODUCT, RelevanceRepository::SCOPE_TYPE_STORE, RelevanceRepository::SCOPE_TYPE_CATEGORY], 'left_id');
Cache::tag('get_product')->clear();
});
}
/**
* 秒杀活动删除后删除边框
* @param $linkId
* @param $scope_type
* @param $activity_type
* @author Qinii
* @day 2024/5/10
*/
public function deleteSeckll(int $linkId, $activity_type = 2,$type = 1)
{
$scope_type = $this->getActiveScopeType($type);
$argc = $this->dao->search(['activity_type' => $activity_type])
->where('link_id',$linkId)
->where('scope_type',$scope_type)
->find();
if ($argc) $this->deleteActivity($argc->activity_id);
return ;
}
/**
* 获取需要的商品 或 商品列表 所需要的活动图
* @param array $data
* @param int $type
* @return array
* @author Qinii
* @day 2024/4/16
*/
public function getPic(array $data, int $type, $push_key = 'border_pic')
{
if (!$data) return [];
$where = [
'activity_type' => $type,
'status' => 1,
'is_show' => 1,
'gt_end_time' => date('Y-m-d H:i:s', time())
];
$activeData = $this->dao->getSearch($where)
->setOption('field', [])
->field('activity_id,scope_type,activity_type,pic')
->order('scope_type DESC,sort DESC,create_time DESC')->limit(10)->select();
$onList = $data;
$list = $data;
if ($onList) {
foreach ($activeData as $active) {
if (!$onList) break;
switch ($active['scope_type']) {
case self::TYPE_ALL:
$newList = array_map(function ($item) use ($active, $push_key) {
$item[$push_key] = $active['pic'];
return $item;
}, $list);
$list = $newList;
$onList = [];
return $list;
break;
case self::TYPE_MUST_PRODUCT:
$field = 'spu_id';
break;
case self::TYPE_MUST_CATEGORY:
$field = 'cate_id';
break;
case self::TYPE_MUST_STORE:
$field = 'mer_id';
break;
case self::TYPE_MUST_PRODUCT_LABEL:
$field = 'sys_labels';
break;
case self::TYPE_MUST_SECKILL_ACTIVE:
$field = 'active_id';
break;
}
$this->activeProductAndList($list, $onList, $active, $field, $push_key);
}
}
return $list;
}
/**
* 根据当前的数组 获取所有活动是否存在符合的图片活动
* @param $active
* @param $field
* @param $list
* @param $onList
* @author Qinii
* @day 2024/4/16
*/
public function activeProductAndList(&$list, &$onList,$active,$field,$push_key)
{
$_type = $this->typeData[$active['scope_type']];
//获得所有商品的spuID
$ids = array_column($onList, $field);
$idss = array_unique($ids);
if (count($idss) == 1 && !$idss[0]) return ;
//以需求的字段为主键的数组
$funList = [];
if ($ids && $onList) $funList = array_combine($ids, $onList);
if ($field == 'active_id') {
//获取交集ID
$intersectId = $ids;
} else {
$relevanceRepository = app()->make(RelevanceRepository::class);
$params = ['type' => $_type, 'left_id' => $active['activity_id']];
$rightIds = $relevanceRepository->getSearch($params)->whereIn('right_id', $ids)->select()->toArray();
$rightIds = array_column($rightIds,'right_id');
$intersectId = array_values(array_intersect($ids, $rightIds));
}
//存在交集则有符合条件的商品
if (!empty($intersectId)) {
$newList = array_map(function ($item) use ($intersectId, $active, $field, $push_key) {
if (
($field !== 'active_id' || $item['active_id'] !== 0) &&
in_array($item[$field], $intersectId) && !isset($item[$push_key])
) {
$item[$push_key] = $active['pic'];
}
return $item;
}, $list);
foreach ($intersectId as $spu_id) {
unset($funList[$spu_id]);
}
$list = $newList;
$onList = array_values($funList);
}
}
/**
* 弃用
* @param int $type
* @param $spuId
* @param $cateId
* @param $merId
* @param $labelId
* @return array|mixed
* @author Qinii
* @day 2024/5/10
*/
public function getActivityBySpu(int $type, $spuId, $cateId, $merId, $labelId)
{
$make = app()->make(RelevanceRepository::class);
$list = $this->dao->getSearch(['activity_type' => $type, 'status' => 1, 'is_show' => 1, 'gt_end_time' => date('Y-m-d H:i:s', time())])
->setOption('field', [])
->field('activity_id,scope_type,activity_type,pic')
->order('sort DESC,create_time DESC')
->select()
->toArray();
foreach ($list as $item) {
switch ($item['scope_type']) {
case self::TYPE_ALL:
return $item;
case self::TYPE_MUST_PRODUCT:
$_type = RelevanceRepository::SCOPE_TYPE_PRODUCT;
$right_id = $spuId ?: 0;
break;
case self::TYPE_MUST_CATEGORY:
$_type = RelevanceRepository::SCOPE_TYPE_CATEGORY;
$right_id = $cateId ?: 0;
break;
case self::TYPE_MUST_STORE:
$_type = RelevanceRepository::SCOPE_TYPE_STORE;
$right_id = $merId ?: 0;
break;
case self::TYPE_MUST_PRODUCT_LABEL:
$_type = RelevanceRepository::SCOPE_TYPE_PRODUCT_LABEL;
$right_id = $labelId ?: '';
break;
}
if (isset($_type)) {
$res = $make->checkHas($item['activity_id'], $right_id, $_type);
if ($res) return $item;
}
}
return [];
}
public function wxQrcode(int $uid, StoreActivity $activity)
{
$name = md5('wxactform_i' . $uid . $activity['activity_id'] . date('Ymd')) . '.jpg';
$key = 'form_' . $activity['activity_id'] . '_' . $uid;
return app()->make(QrcodeService::class)->getWechatQrcodePath($name, '/pages/activity/registrate_activity/index?id=' . $activity['activity_id'] . '&spid=' . $uid, false, $key);
}
public function mpQrcode(int $uid, StoreActivity $activity)
{
$name = md5('mpactform_i' . $uid . $activity['activity_id'] . date('Ymd')) . '.jpg';
return app()->make(QrcodeService::class)->getRoutineQrcodePath($name, 'pages/activity/registrate_activity/index', 'id=' . $activity['activity_id'] . 'spid=' . $uid);
}
/**
* 验证活动状态
* @param StoreActivity|null $activity
* @return true
*/
public function verifyActivityStatus(?StoreActivity $activity, $isCreate = false)
{
if (empty($activity)) {
throw new ValidateException('活动数据异常');
}
if (!$activity['is_show']) {
throw new ValidateException('活动已被关闭');
}
if ($isCreate) {
if ($activity['status'] == -1) {
throw new ValidateException('活动已结束');
}
if ($activity['status'] == 0) {
throw new ValidateException('活动未开始');
}
//如果存在结束时间,则判断当前时间是否大于结束时间
$end_time = $activity['end_time'] ? (strtotime($activity['end_time']) <= time() ?: false) : false;
if ($end_time)
throw new ValidateException('活动已结束');
//如果没有结束时间 则判断总人数
if ($activity['count'] > 0 && $activity['count'] <= $activity['total'])
throw new ValidateException('活动参与人数已满');
}
return true;
}
public function verifyActivityData(int $uid, int $activity_id)
{
$formRelated = app()->make(StoreActivityRelatedRepository::class);
$createData = [
'uid' => $uid,
'activity_id' => $activity_id,
'activity_type' => $formRelated::ACTIVITY_TYPE_FORM,
];
return $formRelated->getSearch($createData)->value('id');
}
}