UserRelationRepository.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\repositories\user;
  12. use app\common\dao\user\UserRelationDao as dao;
  13. use app\common\repositories\BaseRepository;
  14. use app\common\repositories\store\product\ProductAssistRepository;
  15. use app\common\repositories\store\product\ProductGroupRepository;
  16. use app\common\repositories\store\product\ProductPresellRepository;
  17. use app\common\repositories\store\product\ProductRepository;
  18. use app\common\repositories\store\product\SpuRepository;
  19. use app\common\repositories\system\merchant\MerchantRepository;
  20. use think\exception\ValidateException;
  21. use think\facade\Db;
  22. /**
  23. * Class UserRelationRepository
  24. * @package app\common\repositories\user
  25. * @mixin dao
  26. */
  27. class UserRelationRepository extends BaseRepository
  28. {
  29. protected $dao;
  30. /**
  31. * UserRelationRepository constructor.
  32. * @param dao $dao
  33. */
  34. public function __construct(dao $dao)
  35. {
  36. $this->dao = $dao;
  37. }
  38. /**
  39. * 检查特定类型的商品或服务是否存在。
  40. *
  41. * 本函数根据传入的类型参数,决定检查哪种类型的商品或服务是否存在。
  42. * 支持的类型包括普通商品、秒杀商品、预售商品、助力商品、拼团商品和商铺。
  43. * 通过调用相应类型的仓库方法来执行存在性检查。
  44. *
  45. * @param array $params 包含类型和类型ID的参数数组。
  46. * @param int $params['type'] 商品或服务的类型,对应不同的业务实体。
  47. * @param int $params['type_id'] 商品或服务的类型ID,用于特定类型的存在性检查。
  48. * @return bool|mixed 如果类型有效并找到对应的商品或服务,则返回true或相关对象;否则返回false。
  49. */
  50. public function fieldExists($params)
  51. {
  52. switch ($params['type']) {
  53. case 0: // 普通商品
  54. case 1: // 秒杀商品
  55. // 对于类型0和1,使用ProductRepository来检查商品是否存在
  56. return app()->make(ProductRepository::class)->apiExists(0, $params['type_id']);
  57. break;
  58. case 2: // 预售商品
  59. // 使用ProductPresellRepository来检查预售商品是否存在
  60. return app()->make(ProductPresellRepository::class)->getWhereCount(['product_presell_id' => $params['type_id']]);
  61. break;
  62. case 3: // 助力商品
  63. // 使用ProductAssistRepository来检查助力商品是否存在
  64. return app()->make(ProductAssistRepository::class)->getWhereCount(['product_assist_id' => $params['type_id']]);
  65. break;
  66. case 4: // 拼团商品
  67. // 使用ProductGroupRepository来检查拼团商品是否存在
  68. return app()->make(ProductGroupRepository::class)->getWhereCount(['product_group_id' => $params['type_id']]);
  69. break;
  70. case 10: // 商铺
  71. // 使用MerchantRepository来检查商铺是否存在
  72. return app()->make(MerchantRepository::class)->apiGetOne($params['type_id']);
  73. break;
  74. default:
  75. // 如果类型无效,返回false
  76. return false;
  77. break;
  78. }
  79. }
  80. /**
  81. * 检查用户与特定SPU的关系是否存在
  82. *
  83. * 本函数用于确定给定用户是否与特定类型的SPU存在某种关系。这可以通过检查用户ID是否出现在API字段中来实现。
  84. * 参数中的$type用于指定关系的类型,而$type_id则用于指定特定SPU的ID。
  85. *
  86. * @param array $params 包含关系类型和其他相关参数的数组
  87. * @param int $uid 用户的ID
  88. * @return bool 如果用户与SPU的关系存在,则返回true;否则返回false。
  89. */
  90. public function getUserRelation(array $params, int $uid)
  91. {
  92. // 检查传入的类型是否在允许的范围内
  93. if (in_array($params['type'], [0, 1, 2, 3, 4])) {
  94. // 获取SPU信息
  95. $spu = $this->getSpu($params);
  96. // 更新参数数组,以使用SPU的ID和类型1
  97. $params['type_id'] = $spu['spu_id'];
  98. $params['type'] = 1;
  99. }
  100. // 返回用户关系是否存在,通过检查特定字段在数据库中的数量是否大于0来确定
  101. return ($this->dao->apiFieldExists('type_id', $params['type_id'], $params['type'], $uid)->count()) > 0;
  102. }
  103. /**
  104. * 根据条件搜索信息,并分页返回结果。
  105. *
  106. * 此方法用于根据给定的条件数组$where,从数据库中搜索相关信息。
  107. * 它支持两种类型的信息搜索:SPU类型和商家类型。搜索结果将根据创建时间降序排列。
  108. * 方法返回一个包含搜索结果总数和分页后的结果列表的数组。
  109. *
  110. * @param array $where 搜索条件数组,包含各种过滤条件。
  111. * @param int $page 当前页码,用于分页。
  112. * @param int $limit 每页显示的记录数,用于分页。
  113. * @return array 返回一个包含总数和列表的数组。
  114. */
  115. public function search(array $where, int $page, int $limit)
  116. {
  117. // 初始化关联加载数组
  118. $with = [];
  119. // 当搜索类型为1时,加载SPU关联数据
  120. if($where['type'] == 1) {
  121. $with = [
  122. 'spu'
  123. ];
  124. }
  125. // 当搜索类型为10时,加载商家关联数据,并指定加载的字段
  126. if($where['type'] == 10) {
  127. $with = [
  128. 'merchant' => function($query){
  129. $query->field('mer_id,type_id,mer_name,mer_avatar,sales,mer_info,care_count,status,is_del,mer_state');
  130. }
  131. ];
  132. }
  133. // 初始化查询
  134. $query = $this->dao->search($where);
  135. // 关联加载并按创建时间降序排序
  136. $query->with($with)->order('create_time DESC');
  137. // 计算总记录数
  138. $count = $query->count();
  139. // 进行分页查询
  140. $list = $query->page($page, $limit)->select();
  141. // 遍历结果集,处理特定类型的数据显示
  142. foreach ($list as &$item) {
  143. if ($item['type'] == 1) {
  144. // 处理SPU类型,设置特定条件下的显示状态
  145. if(isset($item['spu']['product_type']) && $item['spu']['product_type'] == 1){
  146. $item['spu']['stop_time'] = $item->stop_time;
  147. $item['spu']['status'] = 1;
  148. unset($item['spu']['seckillActive']);
  149. }
  150. } else {
  151. // 处理商家类型,设置显示商品推荐标志
  152. if (isset($item['merchant']) && $item['merchant']) {
  153. $item['merchant']['showProduct'] = $item['merchant']['AllRecommend'];
  154. }
  155. }
  156. }
  157. // 返回计算后的总数和处理后的列表
  158. return compact('count', 'list');
  159. }
  160. /**
  161. * 批量创建记录
  162. *
  163. * 本函数用于在数据库中批量创建某种类型的记录。它首先检查每种类型是否已存在,
  164. * 如果不存在,则创建该记录。这个过程是在一个数据库事务中完成的,确保了数据的一致性。
  165. *
  166. * @param int $uid 用户ID,表示这些记录属于哪个用户。
  167. * @param array $data 包含待创建记录信息的数组。其中,'type_id' 键包含待创建记录的类型ID列表,
  168. * 'type' 键表示记录的类型。
  169. */
  170. public function batchCreate(int $uid, array $data)
  171. {
  172. // 开启数据库事务处理
  173. Db::transaction(function () use ($data, $uid) {
  174. // 遍历类型ID列表
  175. foreach ($data['type_id'] as $item) {
  176. // 组装待插入的数据参数
  177. $param = ['type' => $data['type'], 'type_id' => $item, 'uid' => $uid];
  178. // 检查当前类型ID是否已存在,如果不存在则创建新记录
  179. if(!$this->dao->getWhereCount($param)) {
  180. $this->dao->create($param);
  181. }
  182. }
  183. });
  184. }
  185. /**
  186. * 根据传入的参数创建相关记录。
  187. * 此函数用于处理不同类型项的创建逻辑,包括用户商家信息和商品信息的创建。
  188. * 根据$type的值,决定是创建用户商家关联还是商品关联。
  189. *
  190. * @param array $params 包含创建所需信息的参数数组。
  191. * @return bool|void 返回事务处理结果。
  192. */
  193. public function create(array $params)
  194. {
  195. // 根据$type的值来决定处理逻辑
  196. if($params['type'] == 10) {
  197. // 处理用户商家关联的创建逻辑
  198. $id = $params['type_id'];
  199. app()->make(UserMerchantRepository::class)->getInfo($params['uid'], $params['type_id']);
  200. $make = app()->make(MerchantRepository::class);
  201. }else{
  202. // 处理商品关联的创建逻辑
  203. $spu = $this->getSpu($params);
  204. $params['type_id'] = $spu->spu_id;
  205. $params['type'] = 1;
  206. $make = app()->make(ProductRepository::class);
  207. $id = $spu->product_id;
  208. }
  209. // 使用事务来确保操作的完整性
  210. return Db::transaction(function()use($params,$make,$id){
  211. // 增加关注计数
  212. $make->incCareCount($id);
  213. // 创建相关记录
  214. $this->dao->create($params);
  215. });
  216. }
  217. /**
  218. * 批量删除
  219. * @param array $ids
  220. * @param $uid
  221. * @param $type
  222. * @author Qinii
  223. * @day 2023/2/16
  224. */
  225. public function batchDestory(array $ids,$uid, $type = 1)
  226. {
  227. if ($type == 10) {
  228. app()->make(MerchantRepository::class)->decCareCount($ids);
  229. } else {
  230. $pids = app()->make(SpuRepository::class)->search(['spu_ids' => $ids])->column('S.product_id');
  231. app()->make(ProductRepository::class)->decCareCount($pids);
  232. }
  233. $this->dao->search(['uid' => $uid,'type' => $type])->where('type_id','in',$ids)->delete();
  234. }
  235. /**
  236. * 给指定用户添加支付者信息。
  237. * 该方法用于处理将一个用户与多个新的商户ID关联起来的逻辑。它首先检查哪些商户ID已经与用户关联,
  238. * 然后只处理那些还未关联的商户ID。这样可以避免重复添加相同的关联信息。
  239. *
  240. * @param int $uid 用户ID。表示要添加支付者信息的用户的唯一标识。
  241. * @param array $merIds 商户ID数组。包含要将用户与之关联的所有新的商户ID。
  242. */
  243. public function payer($uid, array $merIds)
  244. {
  245. // 检查已存在的商户ID与用户ID的交集,以避免重复添加
  246. $isset = $this->dao->intersectionPayer($uid, $merIds);
  247. // 筛选出还未关联的商户ID
  248. $merIds = array_diff($merIds, $isset);
  249. // 如果没有新的商户ID需要添加,则直接返回
  250. if (!count($merIds)) return;
  251. // 准备要插入的数据数组
  252. $data = [];
  253. foreach ($merIds as $merId) {
  254. $data[] = [
  255. 'type_id' => $merId,
  256. 'type' => 12, // 这里的类型标识12具体代表什么含义,需要根据实际业务进行解释
  257. 'uid' => $uid
  258. ];
  259. }
  260. // 批量插入新的支付者信息
  261. $this->dao->insertAll($data);
  262. }
  263. /**
  264. * 根据传入的数据获取SPU(Special Product Unit)信息。
  265. *
  266. * 此方法用于根据产品类型和相关ID获取特定的SPU。它支持三种类型的产品:
  267. * 0和1代表普通产品和秒杀产品,这两种类型的产品通过product_id来识别;
  268. * 其他类型的產品通过activity_id来识别。
  269. * 如果找不到对应的SPU信息,则抛出一个ValidateException异常。
  270. *
  271. * @param array $data 包含产品类型和相关ID的数据数组。
  272. * @return mixed 返回找到的SPU信息。
  273. * @throws ValidateException 如果SPU不存在则抛出异常。
  274. */
  275. public function getSpu(array $data)
  276. {
  277. // 通过依赖注入创建SpuRepository实例
  278. $make = app()->make(SpuRepository::class);
  279. // 初始化用于查询条件的数组
  280. $where['product_type'] = $data['type'];
  281. // 根据产品类型设置查询条件
  282. switch ($data['type']) {
  283. case 0:
  284. case 1:
  285. // 普通产品和秒杀产品通过product_id查询
  286. $where['product_id'] = $data['type_id'];
  287. break;
  288. default:
  289. // 其他类型产品通过activity_id查询
  290. $where['activity_id'] = $data['type_id'];
  291. break;
  292. }
  293. // 执行查询并获取SPU信息
  294. $ret = $make->getSearch($where)->find();
  295. // 如果查询结果为空,则抛出异常
  296. if (!$ret) {
  297. throw new ValidateException('SPU不存在');
  298. }
  299. // 返回查询结果
  300. return $ret;
  301. }
  302. /**
  303. * 获取用户发布到社区的产品信息
  304. *
  305. * 本函数用于查询用户发布到社区的产品列表,支持通过关键字进行筛选。
  306. * 参数:
  307. * $keyword - 可选,搜索关键字,用于筛选产品。
  308. * $uid - 用户ID,指定查询哪个用户的发布记录。
  309. * $page - 分页页码,用于分页查询。
  310. * $limit - 每页记录数,用于控制分页查询的数量。
  311. * 返回值:
  312. * 一个包含两个元素的数组,'count' 表示满足条件的记录总数,'list' 表示当前页的记录列表。
  313. *
  314. * @param ?string $keyword 搜索关键字
  315. * @param int $uid 用户ID
  316. * @param int $page 分页页码
  317. * @param int $limit 每页记录数
  318. * @return array 返回包含记录总数和列表的数组
  319. */
  320. public function getUserProductToCommunity(?string $keyword, int $uid, int $page, int $limit)
  321. {
  322. // 根据关键字和用户ID查询用户发布到社区的产品,并按产品ID分组
  323. $query = $this->dao->getUserProductToCommunity($keyword, $uid)->group('product_id');
  324. // 计算满足条件的记录总数
  325. $count = $query->count();
  326. // 设置查询字段,指定需要返回的字段列表,并进行分页查询,返回当前页的记录列表
  327. $list = $query->setOption('field',[])->field('uid,product_id,product_type,spu_id,image,store_name,price')
  328. ->page($page, $limit)->select();
  329. // 返回记录总数和记录列表
  330. return compact('count', 'list');
  331. }
  332. }