123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- <?php
- /**
- * Created by PhpStorm.
- * User: lts
- * Date: 2019-07-08
- * Time: 13:48
- */
- namespace app\main\service;
- use app\main\constants\CacheConstants;
- use app\main\constants\GoodsConstants;
- use app\main\constants\PayConstants;
- use app\main\model\object\UserObject;
- use think\Config;
- use think\Exception;
- use app\common\library\Redis;
- class GoodsService extends BaseService
- {
- const CUSTOM_GOODS_KEY = 'CGN:';//渠道商自定义商品列表key前缀
- const TEST_CATEGORY_ID_KEY = 'TCID';//测试类商品id
- const ACTIVITY_CATEGORY_ID_KEY = 'ACIK';//活动类商品id
- protected static $self = null;
- public static function instance()
- {
- if (self::$self == null) {
- self::$self = new self();
- }
- return self::$self;
- }
- /**
- * @return \app\common\model\GoodsChannelRel
- */
- public function getGoodsChannelRelModel()
- {
- return model('GoodsChannelRel');
- }
- public function getGoodsModel()
- {
- return model('Goods');
- }
- /**
- * 获取默认商品列表
- * @return array|false|\PDOStatement|string|\think\Collection
- */
- public function getDefaultGoodsList()
- {
- $channelId = 0;
- $redis = Redis::instance();
- $rKey = $this->getCustomGoodsKey($channelId);
- if ($redis->exists($rKey)) {
- $strGoodsList = $redis->get($rKey);
- $goodsList = json_decode($strGoodsList, true);
- return $goodsList;
- } else {
- $goodsList = $this->getChannelGoodsListFromDB($channelId);
- Redis::instance()->set($rKey, json_encode($goodsList));
- return $goodsList;
- }
- }
- /**
- * 从数据库获取渠道商自定义商品列表
- * @param $channelId
- * @return array|false|\PDOStatement|string|\think\Collection
- */
- private function getChannelGoodsListFromDB($channelId)
- {
- $customGoodsList = $this->getGoodsChannelRelModel()->join(['goods' => 'g'], 'g.id = goods_channel_rel.goods_id')
- ->field([
- 'g.id',
- 'category_id',
- 'title',
- 'money',
- 'first_description',
- 'second_description',
- 'kandian',
- 'free_kandian',
- 'icon',
- 'show_type',
- 'group_ids',
- 'g.type',
- 'goods_channel_rel.business_line',
- 'goods_channel_rel.default',
- ])
- ->where(['goods_channel_rel.admin_id' => $channelId])
- ->order('goods_channel_rel.position_index')
- ->select();
- foreach ($customGoodsList as $item) {
- $item['show_type_text'] = PayConstants::$goodsShowTypeList[$item['show_type']];
- }
- return $customGoodsList;
- }
- /**
- * 获取自定义商品列表
- * @param $channelId int 渠道商id,超管id为0
- * @return array|false|mixed|\PDOStatement|string|\think\Collection
- */
- public function getCustomGoodsList($channelId, $isVip = false)
- {
- if (!empty($channelId)) {
- $isTest = AdminService::instance()->checkIsTestChannel(null, $channelId);
- $redis = Redis::instance();
- $goodsList = $this->getChannelGoodsList($channelId, $isVip);
- if (!$isTest) {//当前渠道商不是测试渠道商,需要剔除测试商品
- if ($redis->exists(self::TEST_CATEGORY_ID_KEY)) {
- $testCategoryId = $redis->get(self::TEST_CATEGORY_ID_KEY);
- } else {
- $testCategoryIds = $this->getGoodsModel()->getGoodsCategoryIds([PayConstants::GOODS_CATEGORY_TEST]);
- $testCategoryId = current($testCategoryIds);
- $redis->set(self::TEST_CATEGORY_ID_KEY, $testCategoryId);
- }
- foreach ($goodsList as $key => $item) {
- $tempCategoryIds = explode(',', $item['category_id']);
- if (in_array($testCategoryId, $tempCategoryIds)) {
- unset($goodsList[$key]);
- }
- }
- }
- return $goodsList;
- } else {
- return $this->getDefaultGoodsList();
- }
- }
- /**
- * 获取活动商品的分类id
- * @return bool|mixed|string
- */
- public function getActivityGoodsCategoryId()
- {
- $redis = Redis::instance();
- if ($redis->exists(self::ACTIVITY_CATEGORY_ID_KEY)) {
- $categoryId = $redis->get(self::ACTIVITY_CATEGORY_ID_KEY);
- } else {
- $testCategoryIds = $this->getGoodsModel()->getGoodsCategoryIds([PayConstants::GOODS_CATEGORY_ACTIVITY]);
- $categoryId = current($testCategoryIds);
- $redis->set(self::ACTIVITY_CATEGORY_ID_KEY, $categoryId);
- }
- return $categoryId;
- }
- /**
- * 获取自定义商品的redis-key
- * @param $channelId
- * @return string
- */
- private function getCustomGoodsKey($channelId)
- {
- return self::CUSTOM_GOODS_KEY . $channelId;
- }
- /**
- * 获取渠道商自定义商品列表
- * @param $channelId
- * @return array|false|mixed|\PDOStatement|string|\think\Collection
- */
- public function getChannelGoodsList($channelId,$isVip = false)
- {
- $adminConfig = AdminService::instance()->getAdminConfigModel()->getAdminInfoAll($channelId);
- $redis = Redis::instance();
- $rKey = $this->getCustomGoodsKey($channelId);
- if (($adminConfig && $adminConfig['custom_goods'] == 1) || $isVip) {
- if ($redis->exists($rKey)) {
- $strGoodsList = $redis->get($rKey);
- $goodsList = json_decode($strGoodsList, true);
- return $goodsList;
- } else {
- $goodsList = $this->getChannelGoodsListFromDB($channelId);
- if (empty($goodsList)) {
- $goodsList = $this->getDefaultGoodsList();
- }
- Redis::instance()->set($rKey, json_encode($goodsList));
- return $goodsList;
- }
- } else {
- $goodsList = $this->getDefaultGoodsList();
- return $goodsList;
- }
- }
- /**
- * 保存自定义商品信息
- * @param $goodsIds
- * @param $channelId
- * @throws Exception
- */
- public function saveChannelGoodsList($goodsIds, $channelId, $businessLine = '0', $default = false, $groupIds='')
- {
- if (!is_array($goodsIds)) {
- throw new Exception('goodsIds必须为数组');
- }
- if (empty($goodsIds)) {
- throw new Exception('至少选择一个商品');
- }
- if (!$default) {
- $default = $goodsIds[0];
- }
- $goodsList = $this->getGoodsModel()->whereIn('id', $goodsIds)->select();
- $showTypeList = [];
- foreach ($goodsList as $item) {
- $showTypeList[$item['show_type']][] = $item['id'];
- }
- if (empty($showTypeList[PayConstants::GOODS_SHOW_TYPE_ALL])) {
- if (empty($showTypeList[PayConstants::GOODS_SHOW_TYPE_RECHARGED])) {
- throw new Exception('必须配置一个已充值用户的商品');
- } elseif (empty($showTypeList[PayConstants::GOODS_SHOW_TYPE_UN_RECHARGED])) {
- throw new Exception('必须配置一个未充值用户的商品');
- }
- }
- $relList = [];
- try {
- $goodsOrderList = [];
- foreach ($goodsIds as $key => $goodId) {
- $relList[] = [
- 'admin_id' => $channelId,
- 'goods_id' => $goodId,
- 'group_ids' => $groupIds,
- 'position_index' => $key + 1,
- 'createtime' => time(),
- 'business_line' => $businessLine,
- 'default' => (int)($goodId == $default)
- ];
- foreach ($goodsList as $item) {
- if ($item['id'] == $goodId) {
- $goodsOrderList[] = $item;
- break;
- }
- }
- }
- $goodsChannelRel = $this->getGoodsChannelRelModel();
- $goodsChannelRel->where('admin_id', $channelId)->where('business_line', $businessLine)->delete();
- $goodsChannelRel->insertAll($relList);
- $goodsChannelRelHistory = model('GoodsChannelRelHistory');
- $goodsChannelRelHistory->insert([
- 'admin_id' => $channelId,
- 'goods_ids' => implode(',', $goodsIds),
- 'createtime' => time(),
- ]);
- $rKey = $this->getCustomGoodsKey($channelId);
- $rKeyApp = CacheConstants::getGoodsListAppKey($businessLine);
- Redis::instance()->del($rKey);
- Redis::instance()->del($rKeyApp);
- } catch (Exception $e) {
- LogService::error($e->getMessage());
- throw $e;
- }
- }
- /**
- * 删除渠道商自定义商品列表
- * @param $channelId
- * @throws Exception
- */
- public function delChannelGoodsList($channelId)
- {
- $rKey = $this->getCustomGoodsKey($channelId);
- try {
- $goodsChannelRel = $this->getGoodsChannelRelModel();
- $goodsChannelRel->where('admin_id', $channelId)->delete();
- $goodsChannelRelHistory = model('GoodsChannelRelHistory');
- $goodsChannelRelHistory->insert([
- 'admin_id' => $channelId,
- 'goods_ids' => '',
- 'createtime' => time(),
- ]);
- Redis::instance()->del($rKey);
- } catch (Exception $e) {
- LogService::error($e->getMessage());
- throw $e;
- }
- }
- /**
- * 选择商品页面,获取商品列表
- * @param $channelId
- * @param $selectedIds
- * @param $where
- * @param $offset
- * @param $limit
- * @param $goodsCategory
- * @return array
- */
- public function getSelectGoodsList($channelId, $selectedIds, $where, $offset, $limit, $goodsCategory, $goodsTypes, $maps = [])
- {
- // if (empty($goodsCategory)) {
- // $goodsCategory = [PayConstants::GOODS_CATEGORY_RECHARGE];
- // }
- $listFetchObj = $this->getSelectGoodsObj($channelId, $selectedIds, $where, $offset, $limit, $goodsCategory,
- $goodsTypes, $maps);
- $list = $listFetchObj->select();
- $countFetchObj = $this->getSelectGoodsObj($channelId, $selectedIds, $where, $offset, $limit, $goodsCategory,
- $goodsTypes, $maps);
- $total = $countFetchObj->count();
- return [$list, $total];
- }
- /**
- * 构造查询自定义商品的model对象
- * @param $channelId 渠道商id
- * @param $selectedIds 已选商品id
- * @param $where
- * @param $offset
- * @param $limit
- * @param $goodsCategory
- * @return \app\common\model\Goods
- */
- private function getSelectGoodsObj($channelId, $selectedIds, $where, $offset, $limit, $goodsCategory, $goodsTypes, $maps = [])
- {
- $goodsModel = $this->getGoodsModel();
- $isTest = AdminService::instance()->checkIsTestChannel(0, $channelId);
- $goodsCategory = (array)$goodsCategory;
- $obj = $goodsModel->where($where)
- ->where($maps)
- ->whereIn('type', $goodsTypes)
- ->limit($offset, $limit);
- if ($isTest) {
- $goodsCategory[] = PayConstants::GOODS_CATEGORY_TEST;
- }
- if ($categoryIds = $goodsModel->getGoodsCategoryIds($goodsCategory)) {
- $categoryMap = [];
- foreach ($categoryIds as $categoryId) {
- array_push($categoryMap, "find_in_set({$categoryId},category_id)");
- }
- }
- //分类不为空时
- if (!empty($categoryMap)) {
- if (count($categoryMap) > 1) {
- $obj->where("(" . implode(' or ', $categoryMap) . ")");
- } else {
- $obj->where(current($categoryMap));
- }
- }
- if (!empty($selectedIds)) {
- $obj->whereNotIn('id', $selectedIds);
- }
- return $obj;
- }
- /**
- * 删除配置此商品的渠道商自定义商品
- * @param $goodsId
- */
- public function delCustomGoodsId($goodsId)
- {
- $ids = $this->removeCacheCustomGoods($goodsId);
- if (!empty($ids)) {
- $this->getGoodsChannelRelModel()->whereIn('id', $ids)->delete();
- }
- }
- /**
- * 删除配置此商品的自定义商品缓存
- * @param $goodsId
- * @return array
- */
- public function removeCacheCustomGoods($goodsId)
- {
- $key = CacheConstants::getGoodsInfoKey($goodsId);
- Redis::instance()->del($key);
- $goodsChannelRelList = $this->getGoodsChannelRelModel()->where('goods_id', $goodsId)->field([
- 'id',
- 'admin_id'
- ])->select();
- $ids = [];
- $keys = [];
- foreach ($goodsChannelRelList as $item) {
- $ids[] = $item['id'];
- $keys[] = $this->getCustomGoodsKey($item['admin_id']);
- }
- $delCustomGoodsRedisIndex = Redis::splitKeysByRule($keys);
- foreach ($delCustomGoodsRedisIndex as $k => $v) {
- $redis = Redis::getRedisConnect($k);
- $redis->del(...$v);
- }
- return $ids;
- }
- /**
- * 获取前台用户使用的商品列表
- * @param $channelId 渠道商id
- * @param $isPay 用户是否支付过订单。0未充值 1已充值
- * @return array|false|mixed|\PDOStatement|string|\think\Collection
- */
- public function getCustomGoodsForFront($channelId, $isPay, $isNew, $businessLine = PayConstants::BUSINESS_WECHAT)
- {
- $goodsList = $this->getCustomGoodsList($channelId);
- $goodsResultList = [];
- foreach ($goodsList as $item) {
- if ($item['business_line'] != $businessLine) {
- continue;
- }
- if (intval($isPay) == 0) {//未充值用户
- if (in_array($item['show_type'],
- [PayConstants::GOODS_SHOW_TYPE_UN_RECHARGED, PayConstants::GOODS_SHOW_TYPE_ALL])) {
- $goodsResultList[] = $item;
- }
- } else {//已充值用户
- if (in_array($item['show_type'],
- [PayConstants::GOODS_SHOW_TYPE_RECHARGED, PayConstants::GOODS_SHOW_TYPE_ALL])) {
- $goodsResultList[] = $item;
- }
- }
- if ($isNew && $item['show_type'] == PayConstants::GOODS_SHOW_TYPE_NEW) {
- $goodsResultList[] = $item;
- } else if(!$isNew && $item['show_type'] == PayConstants::GOODS_SHOW_TYPE_OLD){
- $goodsResultList[] = $item;
- }
- }
- return $goodsResultList;
- }
- public function checkGoodsTypeValid($showType, UserObject $user)
- {
- if (Config::get('site.goods_type_new_user') == GoodsConstants::GOODS_TYPE_NEW_DAY) {
- $isNew = date('Ymd', $user->createtime) == date('Ymd');
- } else {
- $isNew = time() - $user->createtime < 86400;
- }
- $return = true;
- switch ($showType) {
- case PayConstants::GOODS_SHOW_TYPE_RECHARGED:
- $return = $user->is_pay;
- break;
- case PayConstants::GOODS_SHOW_TYPE_UN_RECHARGED:
- $return = !$user->is_pay;
- break;
- case PayConstants::GOODS_SHOW_TYPE_NEW:
- $return = $isNew;
- break;
- case PayConstants::GOODS_SHOW_TYPE_OLD:
- $return = !$isNew;
- break;
- }
- return $this->setData($return)->getReturn();
- }
- }
|