ParameterTemplateRepository.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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\store\parameter;
  12. use app\common\dao\store\parameter\ParameterTemplateDao;
  13. use app\common\repositories\BaseRepository;
  14. use app\common\repositories\store\product\ProductRepository;
  15. use app\common\repositories\system\RelevanceRepository;
  16. use think\exception\ValidateException;
  17. use think\facade\Cache;
  18. use think\facade\Db;
  19. /**
  20. * 商品参数模板
  21. */
  22. class ParameterTemplateRepository extends BaseRepository
  23. {
  24. /**
  25. * @var ParameterTemplateDao
  26. */
  27. protected $dao;
  28. /**
  29. * ParameterRepository constructor.
  30. * @param ParameterTemplateDao $dao
  31. */
  32. public function __construct(ParameterTemplateDao $dao)
  33. {
  34. $this->dao = $dao;
  35. }
  36. /**
  37. * 根据条件获取列表数据
  38. *
  39. * 本函数用于根据给定的条件、分页和限制从数据库获取列表数据。它利用了DAO模式进行数据操作,
  40. * 提供了一个灵活的方式来检索包括分类和商家信息在内的复合数据。
  41. *
  42. * @param array $where 查询条件数组
  43. * @param int $page 当前页码
  44. * @param int $limit 每页数据的数量
  45. * @return array 包含总数和列表数据的数组
  46. */
  47. public function getList(array $where, int $page, int $limit)
  48. {
  49. // 初始化查询
  50. $query = $this->dao->getSearch($where)
  51. ->with([
  52. // 关联分类,并只获取特定字段
  53. 'cateId' => function ($query) {
  54. $query->with(['category' => function ($query) {
  55. $query->field('store_category_id,cate_name');
  56. }]);
  57. },
  58. // 关联商家,并只获取特定字段
  59. 'merchant' => function ($query) {
  60. $query->field('mer_id,mer_name');
  61. }
  62. // 注释掉的关联参数,可以根据需要进行恢复和调整
  63. ])
  64. ->order('sort DESC,create_time DESC'); // 按排序和创建时间降序排列
  65. // 计算总条数
  66. $count = $query->count();
  67. // 分页获取数据列表
  68. $list = $query->page($page, $limit)->select();
  69. // 返回包含总数和列表的数组
  70. return compact('count', 'list');
  71. }
  72. /**
  73. * 根据条件获取选择列表
  74. *
  75. * 本函数旨在根据传入的条件数组,从数据库中检索特定字段,并以适合下拉选择框的形式返回数据。
  76. * 这样做的目的是为了在前端界面提供一个可选择的列表,例如模板名称的列表,其中每个选项都有一个对应的唯一标识。
  77. *
  78. * @param array $where 查询条件数组
  79. * @return array 返回一个格式化后的数组,包含标签和值,适用于前端下拉选择框
  80. */
  81. public function getSelect(array $where)
  82. {
  83. // 通过DAO层的getSearch方法查询数据,根据$where条件进行筛选
  84. // 使用field方法指定只返回template_name和template_id字段,分别作为标签和值
  85. // 最后调用select方法执行查询并返回结果
  86. return $this->dao->getSearch($where)->field('template_name label,template_id value')->select();
  87. }
  88. /**
  89. * 根据模板ID和商家ID查询模板详情
  90. *
  91. * @param int $id 模板ID
  92. * @param int $merId 商家ID,可选参数,用于指定查询特定商家的模板
  93. * @return array 模板的详细信息
  94. * @throws ValidateException 如果模板不存在,则抛出异常
  95. */
  96. public function detail($id, $merId)
  97. {
  98. // 构建查询条件,指定模板ID
  99. $where['template_id'] = $id;
  100. // 如果提供了商家ID,则加入查询条件
  101. if ($merId) $where['mer_id'] = $merId;
  102. // 查询模板详情,包括分类、参数和商家信息
  103. // 使用with方法预加载关联数据,以减少数据库查询次数
  104. $data = $this->dao->getSearch($where)
  105. ->with([
  106. // 预加载模板的分类信息,包括分类ID和分类名称
  107. 'cateId' => function ($query) {
  108. $query->with(['category' => function ($query) {
  109. $query->field('store_category_id,cate_name');
  110. }]);
  111. },
  112. // 预加载模板的参数信息,按排序降序排列
  113. 'parameter' => function ($query) {
  114. $query ->field('parameter_id,template_id,name,sort')->order('sort DESC')->append(['values']);
  115. },
  116. // 预加载模板所属的商家信息,包括商家名称和商家ID
  117. 'merchant' => function ($query) {
  118. $query->field('mer_name,mer_id');
  119. }
  120. ])->find();
  121. // 如果查询结果为空,则抛出异常提示数据不存在
  122. if (!$data) throw new ValidateException('数据不存在');
  123. // 返回模板详情
  124. return $data;
  125. }
  126. /**
  127. * 根据条件展示搜索结果
  128. *
  129. * 本函数通过调用DAO层的getSearch方法,根据传入的$where条件获取搜索结果。
  130. * 结果数据包括主数据和关联的参数数据,其中参数数据通过嵌套查询获取,并进行排序。
  131. * 最后,将所有参数数据提取出来组成一个列表并返回。
  132. *
  133. * @param array $where 查询条件
  134. * @return array 返回包含所有参数数据的列表
  135. */
  136. public function show($where)
  137. {
  138. // 通过DAO层的getSearch方法查询数据,同时加载关联的parameter数据
  139. // 这里通过闭包指定了parameter表的查询字段和排序方式
  140. $data = $this->dao->getSearch($where)->with([
  141. 'parameter' => function ($query) {
  142. $query
  143. //->with([
  144. // 'paramValues' => function($query) {
  145. // $query->column('parameter_value_id,value,parameter_id','parameter_value_id');
  146. // }
  147. //])
  148. ->field('parameter_id,template_id,name')->order('sort DESC')->append(['values']);
  149. }
  150. ])->order('mer_id ASC,create_time DESC')->select();
  151. // 初始化空数组用于存放最终的参数数据列表
  152. $list = [];
  153. // 遍历查询结果,如果存在参数数据,则将其添加到列表中
  154. foreach ($data as $datum) {
  155. if ($datum['parameter']) {
  156. foreach ($datum['parameter'] as $item) {
  157. $item['template_name'] = $datum['template_name'];
  158. $item['mer_id'] = $datum['mer_id'];
  159. $list[] = $item;
  160. }
  161. }
  162. }
  163. // 返回参数数据列表
  164. return $list;
  165. }
  166. /**
  167. * 创建模板
  168. *
  169. * 本函数用于根据提供的商家ID和模板信息创建新的模板。它首先从传入的数据中提取必要的信息,
  170. * 然后在数据库事务中执行模板的创建、参数的创建或更新,以及相关类别的创建。
  171. * 这样做确保了数据的一致性和完整性。
  172. *
  173. * @param string $merId 商家ID,用于标识模板所属的商家。
  174. * @param array $data 包含模板详细信息和参数的数据数组。
  175. * - params: 模板的参数。
  176. * - cate_ids: 类别ID数组,用于将模板与类别相关联。
  177. * - template_name: 模板的名称。
  178. * - sort: 模板的排序值。
  179. * - mer_id: 商家ID(冗余参数,与函数参数相同,用于内部操作)。
  180. */
  181. public function create($merId, $data)
  182. {
  183. // 提取参数信息
  184. $params = $data['params'];
  185. // 去除重复的类别ID
  186. $cate = array_unique($data['cate_ids']);
  187. // 构建模板的基础信息
  188. $tem = [
  189. 'template_name' => $data['template_name'],
  190. 'sort' => $data['sort'],
  191. 'mer_id' => $merId
  192. ];
  193. // 实例化参数仓库和关联仓库
  194. $paramMake = app()->make(ParameterRepository::class);
  195. $releMake = app()->make(RelevanceRepository::class);
  196. // 使用数据库事务来确保操作的一致性
  197. //Db::transaction(function () use ($params, $tem, $cate, $merId, $paramMake, $releMake) {
  198. // 创建模板
  199. $temp = $this->dao->create($tem);
  200. // 创建或更新模板参数
  201. $paramMake->createOrUpdate($temp->template_id, $merId, $params);
  202. // 如果有类别ID,创建模板与类别的关联
  203. if (!empty($cate)) {
  204. $releMake->createMany($temp->template_id, $cate, RelevanceRepository::PRODUCT_PARAMES_CATE);
  205. }
  206. //});
  207. }
  208. /**
  209. * 更新产品信息。
  210. *
  211. * 该方法用于根据给定的ID和数据更新产品的详细信息。它处理产品模板名称、排序、
  212. * 参数和类别关联的更新。使用事务来确保数据库操作的一致性。
  213. *
  214. * @param int $id 产品的ID
  215. * @param array $data 包含产品更新信息的数组,如模板名称、排序、参数和类别ID
  216. * @param int $merId 商家ID,默认为0,用于指定操作的商家
  217. */
  218. public function update($id, $data, $merId = 0)
  219. {
  220. // 提取参数数据
  221. $params = $data['params'];
  222. // 去重处理类别ID数组
  223. $cate = array_unique($data['cate_ids']);
  224. // 构建要更新的模板名称和排序信息
  225. $tem = [
  226. 'template_name' => $data['template_name'],
  227. 'sort' => $data['sort'],
  228. ];
  229. if ($data['delete_params'] ?? []) {
  230. app()->make(ParameterValueRepository::class)->dostory($data['delete_params'], $merId);
  231. }
  232. // 实例化参数仓库和关联仓库
  233. $paramMake = app()->make(ParameterRepository::class);
  234. $releMake = app()->make(RelevanceRepository::class);
  235. // 使用事务处理数据库操作
  236. Db::transaction(function () use ($id, $params, $tem, $cate, $paramMake, $releMake, $merId) {
  237. // 更新产品的基本模板和排序信息
  238. $this->dao->update($id, $tem);
  239. $paramMake->createOrUpdate($id, $merId, $params);
  240. // 删除旧的类别关联,创建新的类别关联
  241. $releMake->batchDelete($id, RelevanceRepository::PRODUCT_PARAMES_CATE);
  242. if (!empty($cate)) {
  243. $releMake->createMany($id, $cate, RelevanceRepository::PRODUCT_PARAMES_CATE);
  244. }
  245. });
  246. }
  247. /**
  248. * 删除指定ID的记录及其相关参数和关联信息。
  249. *
  250. * 使用事务确保删除操作的原子性,即操作要么全部成功,要么全部失败。
  251. * 首先,删除指定ID的主记录,然后删除与该记录相关的所有参数记录,
  252. * 最后删除与产品参数相关的所有关联信息。
  253. *
  254. * @param int $id 需要删除的记录的ID。
  255. */
  256. public function delete($id)
  257. {
  258. // 创建参数仓库实例
  259. $paramMake = app()->make(ParameterRepository::class);
  260. // 创建关联仓库实例
  261. $releMake = app()->make(RelevanceRepository::class);
  262. // 使用事务处理删除操作
  263. Db::transaction(function () use ($id, $paramMake, $releMake) {
  264. // 删除主记录
  265. $this->dao->delete($id);
  266. // 删除与模板相关的所有参数
  267. $paramMake->getSearch(['template_id' => $id])->delete();
  268. // 批量删除与产品参数相关的所有关联信息
  269. $releMake->batchDelete($id, RelevanceRepository::PRODUCT_PARAMES_CATE);
  270. });
  271. }
  272. /**
  273. * 根据条件获取API列表。
  274. *
  275. * 本函数主要用于查询与商品分类相关的参数信息,可区分PC端和移动端的查询需求。
  276. * 通过传入的分类条件,首先获取对应分类的ID集合,然后根据这些分类ID查询相应的参数模板ID。
  277. * 最后,根据参数模板ID查询具体的参数信息,并根据需要(如PC端查询时)填充参数的值。
  278. *
  279. * @param array $where 查询条件,用于获取商品分类ID。
  280. * @param bool $isPc 是否为PC端查询,默认为false表示移动端。
  281. * @return array 返回查询到的参数信息列表。
  282. */
  283. public function getApiList($where, $isPc = false)
  284. {
  285. // 实例化商品仓库,用于获取商品分类ID
  286. /**
  287. * 通过筛选条件查询出商品的分类ID
  288. * 通过分类ID获取参数模板ID
  289. * 通过参数模板ID查询出参数
  290. */
  291. $productRepository = app()->make(ProductRepository::class);
  292. // 根据分类条件获取分类ID集合
  293. $template_id = $productRepository->getCateIdByCategory($where);
  294. // 根据分类ID集合查询对应的参数模板ID
  295. //$template_id = $this->dao->getSearch(['cate_id' => $cate_ids, 'mer_id' => 0])->column('template_id');
  296. // 实例化参数仓库,用于查询参数信息
  297. $parameterRepository = app()->make(ParameterRepository::class);
  298. // 根据参数模板ID查询参数信息,并按排序降序查询
  299. $query = $parameterRepository->getSearch(['template_id' => $template_id])->field('parameter_id,template_id,name')->order('sort DESC, create_time DESC,template_id DESC');
  300. // 执行查询并获取参数数据
  301. $data = $query->select();
  302. // 如果是PC端查询且有数据,则进一步处理参数的值
  303. //如果是pc端,需要同时返回参数的值
  304. if ($isPc && $data) {
  305. // 将查询结果转换为数组,并按参数名排序
  306. $data = $data->toArray();
  307. ksort($data);
  308. // 构建缓存键名
  309. $key = 'params_1' . json_encode($data);
  310. // 尝试从缓存中获取已处理的参数值
  311. $res = Cache::get($key);
  312. if ($res) {
  313. // 如果缓存中存在,则直接使用缓存数据
  314. $data = json_decode($res, true);
  315. } else {
  316. // 实例化参数值仓库,用于获取参数的具体值
  317. $parameterValueRepository = app()->make(ParameterValueRepository::class);
  318. // 遍历参数数据,填充参数值
  319. foreach ($data as &$datum) {
  320. $datum['value'] = $parameterValueRepository->getOptions(['parameter_id' => $datum['parameter_id']]);
  321. }
  322. // 将处理后的参数值数据缓存起来,有效期60秒
  323. Cache::set($key, json_encode($data), 60);
  324. }
  325. }
  326. // 返回最终的参数信息列表
  327. return $data;
  328. }
  329. }