UserMerchantRepository.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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\UserMerchantDao;
  13. use app\common\repositories\BaseRepository;
  14. use app\common\repositories\store\staff\StaffsRepository;
  15. use app\common\repositories\system\config\ConfigValueRepository;
  16. use FormBuilder\Factory\Elm;
  17. use think\facade\Db;
  18. use think\facade\Route;
  19. use app\common\repositories\store\service\StoreServiceRepository;
  20. /**
  21. * Class UserMerchantRepository
  22. * @package app\common\repositories\user
  23. * @author xaboy
  24. * @day 2020/10/20
  25. * @mixin UserMerchantDao
  26. */
  27. class UserMerchantRepository extends BaseRepository
  28. {
  29. /**
  30. * UserMerchantRepository constructor.
  31. * @param UserMerchantDao $dao
  32. */
  33. public function __construct(UserMerchantDao $dao)
  34. {
  35. $this->dao = $dao;
  36. }
  37. /**
  38. * 根据条件获取用户列表
  39. *
  40. * @param array $where 查询条件
  41. * @param int $page 分页页码
  42. * @param int $limit 每页数据数量
  43. * @return array 包含用户列表和总数的信息
  44. */
  45. public function getList(array $where, $page, $limit)
  46. {
  47. // 获取默认头像配置
  48. // 获取默认头像
  49. $user_default_avatar = app()->make(ConfigValueRepository::class)->get('user_default_avatar', 0);
  50. // 根据条件初始化查询
  51. $query = $this->dao->search($where);
  52. // 计算总条数
  53. $count = $query->count();
  54. // 实例化用户标签仓库
  55. $make = app()->make(UserLabelRepository::class);
  56. // 配置查询字段并进行分页查询,按用户商家ID降序排列
  57. $list = $query->setOption('field', [])->field('A.uid,A.user_merchant_id,B.avatar,B.nickname,B.user_type,A.last_pay_time,A.first_pay_time,A.label_id,A.create_time,A.last_time,A.pay_num,A.pay_price,B.phone,B.is_svip,B.svip_endtime')
  58. ->page($page, $limit)->order('A.user_merchant_id DESC')->select()
  59. ->each(function ($item) use ($where, $make, $user_default_avatar) {
  60. // 根据环境变量和用户类型,隐藏或显示电话号码
  61. if (env('SHOW_PHONE',false) && $item->phone && is_numeric($item->phone)){
  62. if (app('request')->userType() !== 2 || app('request')->adminInfo()['level'] != 0) {
  63. $item->phone = substr_replace($item->phone, '****', 3, 4);
  64. }
  65. }
  66. // 根据标签ID获取用户标签
  67. $item->label = count($item['label_id']) ? $make->labels($item['label_id'], $where['mer_id']) : [];
  68. // 设置默认头像
  69. if (empty($item->avatar)) {
  70. $item->avatar = $user_default_avatar;
  71. }
  72. });
  73. // 返回用户总数和列表信息
  74. return compact('count', 'list');
  75. }
  76. /**
  77. * 创建一个新的记录。
  78. *
  79. * 本函数用于通过提供的用户ID和商家ID创建一个新的数据记录。它不涉及具体的业务逻辑处理,仅负责数据的插入操作。
  80. * 参数$uid代表用户的唯一标识,$merId代表商家的唯一标识。这两个标识符一起用于唯一确定新创建的数据记录。
  81. *
  82. * @param int $uid 用户ID,用于标识数据记录的所属用户。
  83. * @param int $merId 商家ID,用于标识数据记录的所属商家。
  84. * @return bool|mixed 返回创建操作的结果。成功时返回新创建的记录的ID,失败时返回false。
  85. */
  86. public function create($uid, $merId)
  87. {
  88. // 调用DAO层的create方法,传入包含用户ID和商家ID的数组,执行创建操作。
  89. return $this->dao->create([
  90. 'uid' => $uid,
  91. 'mer_id' => $merId,
  92. ]);
  93. }
  94. /**
  95. * 根据用户ID和商家ID获取用户信息。
  96. *
  97. * 本函数旨在通过用户ID和商家ID查询用户信息。如果用户不存在,则尝试创建该用户并返回。
  98. * 这种设计确保了即使用户数据在调用前未存在,也能通过一次调用即创建并获取到用户信息,
  99. * 提高了代码的可靠性和效率。
  100. *
  101. * @param int $uid 用户ID。这是识别用户的唯一标识。
  102. * @param int $mer_id 商家ID。表示用户所属的商家。
  103. * @return object 用户对象,包含用户信息。如果用户不存在,则为新创建的用户对象。
  104. */
  105. public function getInfo($uid, $mer_id)
  106. {
  107. // 根据$uid和$mer_id查询用户信息
  108. $user = $this->dao->getWhere(compact('uid', 'mer_id'));
  109. // 如果用户不存在,则尝试创建该用户
  110. if (!$user) $user = $this->create($uid, $mer_id);
  111. // 返回用户对象
  112. return $user;
  113. }
  114. /**
  115. * 更新用户的支付时间及相关支付统计信息。
  116. *
  117. * 本函数用于在用户完成支付后,更新其支付时间、支付次数、支付总额等统计信息。
  118. * 如果是首次支付,还会记录首次支付时间。
  119. *
  120. * @param int $uid 用户ID,用于标识唯一用户。
  121. * @param string $merId 商户ID,用于标识用户是在哪个商户完成的支付。
  122. * @param float $pay_price 本次支付的金额,以浮点数表示。
  123. * @param bool $flag 标志位,用于决定是否增加支付次数。默认为true,即增加支付次数。
  124. */
  125. public function updatePayTime($uid, $merId, $pay_price, $flag = true)
  126. {
  127. // 根据用户ID和商户ID获取用户信息。
  128. $user = $this->getInfo($uid, $merId);
  129. // 获取当前时间,用于更新支付时间。
  130. $time = date('Y-m-d H:i:s');
  131. // 更新用户的最后一次支付时间。
  132. $user->last_pay_time = $time;
  133. // 如果标志位为true,增加用户的支付次数。
  134. if ($flag) {
  135. $user->pay_num++;
  136. }
  137. // 更新用户的累计支付金额,使用bcadd确保浮点数计算的准确性。
  138. $user->pay_price = bcadd($user->pay_price, $pay_price, 2);
  139. // 如果用户尚未记录首次支付时间,将当前时间设为首次支付时间。
  140. if (!$user->first_pay_time) {
  141. $user->first_pay_time = $time;
  142. }
  143. // 保存更新后的用户信息。
  144. $user->save();
  145. }
  146. /**
  147. * 移除标签
  148. * 本函数用于从数据库中移除指定ID的标签。它通过搜索具有指定标签ID的记录,
  149. * 然后更新这些记录的标签ID字段,从现有的标签列表中移除指定的标签ID。
  150. *
  151. * @param int $id 标签的ID,指定要移除的标签。
  152. * @return bool 更新操作的结果,true表示成功,false表示失败。
  153. */
  154. public function rmLabel($id)
  155. {
  156. // 使用DAO层的search方法查询具有指定标签ID的记录,并准备更新这些记录的标签ID字段。
  157. // 更新操作通过在标签ID字段上执行SQL函数来实现,该函数从现有的标签ID字符串中移除指定的ID。
  158. return $this->dao->search(['label_id' => $id])->update([
  159. 'A.label_id' => Db::raw('(trim(BOTH \',\' FROM replace(CONCAT(\',\',A.label_id,\',\'),\',' . $id . ',\',\',\')))')
  160. ]);
  161. }
  162. /**
  163. * 创建修改用户标签的表单
  164. *
  165. * 本函数用于生成一个表单,该表单允许操作者修改用户标签。通过提供的用户ID和商家ID,
  166. * 函数检索现有的用户标签,并为这些标签创建一个可以选择的列表。表单提交的URL是动态生成的,
  167. * 保证了表单提交的路由正确性。
  168. *
  169. * @param int $merId 商家ID,用于获取商家相关的用户标签选项
  170. * @param int $id 用户ID,用于获取当前用户已有的标签
  171. * @return \FormBuilder\Form|\Laravie\Codex\Contracts\Response
  172. */
  173. public function changeLabelForm($merId, $id)
  174. {
  175. // 通过用户ID获取用户对象
  176. $user = $this->dao->get($id);
  177. // 实例化用户标签仓库,用于后续获取所有标签选项和处理标签交集
  178. /** @var UserLabelRepository $make */
  179. $userLabelRepository = app()->make(UserLabelRepository::class);
  180. // 获取所有标签选项,包括商家拥有的标签
  181. $data = $userLabelRepository->allOptions($merId);
  182. // 创建表单,表单提交的URL是通过路由名称和参数动态构建的
  183. return Elm::createForm(Route::buildUrl('merchantUserChangeLabel', compact('id'))->build(), [
  184. // 创建多选下拉列表,用于选择用户的标签
  185. Elm::selectMultiple('label_id', '用户标签:', $userLabelRepository->intersection($user->label_id, $merId, 0))->options(function () use ($data) {
  186. $options = [];
  187. // 遍历标签数据,构建下拉列表的选项
  188. foreach ($data as $value => $label) {
  189. $options[] = compact('value', 'label');
  190. }
  191. return $options;
  192. })
  193. ])->setTitle('修改用户标签');
  194. }
  195. public function getManagerUid($where)
  196. {
  197. $staffsRepository = app()->make(StaffsRepository::class);
  198. $storeServiceRepository = app()->make(StoreServiceRepository::class);
  199. $uids1 = $storeServiceRepository->search($where)->column('uid');
  200. $uids2 = $staffsRepository->search($where)->column('uid');
  201. $uids = array_unique(array_merge($uids1, $uids2));
  202. return $uids;
  203. }
  204. }