Index.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace app\api\controller;
  3. use ba\Tree;
  4. use Throwable;
  5. use think\facade\Db;
  6. use think\facade\Config;
  7. use app\common\controller\Frontend;
  8. use app\common\library\token\TokenExpirationException;
  9. class Index extends Frontend
  10. {
  11. protected array $noNeedLogin = ['index','checkExpiredProducts'];
  12. public function initialize(): void
  13. {
  14. parent::initialize();
  15. }
  16. /**
  17. * 前台和会员中心的初始化请求
  18. * @throws Throwable
  19. */
  20. public function index(): void
  21. {
  22. $menus = [];
  23. if ($this->auth->isLogin()) {
  24. $rules = [];
  25. $userMenus = $this->auth->getMenus();
  26. // 首页加载的规则,验权,但过滤掉会员中心菜单
  27. foreach ($userMenus as $item) {
  28. if ($item['type'] == 'menu_dir') {
  29. $menus[] = $item;
  30. } elseif ($item['type'] != 'menu') {
  31. $rules[] = $item;
  32. }
  33. }
  34. $rules = array_values($rules);
  35. } else {
  36. // 若是从前台会员中心内发出的请求,要求必须登录,否则会员中心异常
  37. $requiredLogin = $this->request->get('requiredLogin/b', false);
  38. if ($requiredLogin) {
  39. // 触发可能的 token 过期异常
  40. try {
  41. $token = get_auth_token(['ba', 'user', 'token']);
  42. $this->auth->init($token);
  43. } catch (TokenExpirationException) {
  44. $this->error(__('Token expiration'), [], 409);
  45. }
  46. $this->error(__('Please login first'), [
  47. 'type' => $this->auth::NEED_LOGIN
  48. ], $this->auth::LOGIN_RESPONSE_CODE);
  49. }
  50. $rules = Db::name('user_rule')
  51. ->where('status', 1)
  52. ->where('no_login_valid', 1)
  53. ->where('type', 'in', ['route', 'nav', 'button'])
  54. ->order('weigh', 'desc')
  55. ->select()
  56. ->toArray();
  57. $rules = Tree::instance()->assembleChild($rules);
  58. }
  59. $this->success('', [
  60. 'site' => [
  61. 'siteName' => get_sys_config('site_name'),
  62. 'version' => get_sys_config('version'),
  63. 'cdnUrl' => full_url(),
  64. 'upload' => keys_to_camel_case(get_upload_config(), ['max_size', 'save_name', 'allowed_suffixes', 'allowed_mime_types']),
  65. 'recordNumber' => get_sys_config('record_number'),
  66. 'cdnUrlParams' => Config::get('buildadmin.cdn_url_params'),
  67. ],
  68. 'openMemberCenter' => Config::get('buildadmin.open_member_center'),
  69. 'userInfo' => $this->auth->getUserInfo(),
  70. 'rules' => $rules,
  71. 'menus' => $menus,
  72. ]);
  73. }
  74. /*
  75. * 批量更新过期记录
  76. */
  77. /**
  78. * 检查并更新过期套餐
  79. * @return int 更新的记录数
  80. */
  81. public function checkExpiredProducts()
  82. {
  83. $now = date('Y-m-d H:i:s');
  84. Db::startTrans();
  85. try {
  86. // 1. 查询所有已过期且状态仍有效的 usage 记录(加锁)
  87. $expiredList = Db::table('ba_user_product_usage')
  88. ->where('status', 1)
  89. ->where('end_time', '<=', $now)
  90. ->whereNotNull('end_time')
  91. ->lock(true)
  92. ->select()
  93. ->toArray();
  94. if (empty($expiredList)) {
  95. Db::commit();
  96. return 0;
  97. }
  98. $ids = array_column($expiredList, 'id');
  99. // 提取企业套餐的 allocation_id
  100. $allocationIds = [];
  101. foreach ($expiredList as $item) {
  102. if (!empty($item['allocation_id'])) {
  103. $allocationIds[] = $item['allocation_id'];
  104. }
  105. }
  106. $allocationIds = array_unique($allocationIds);
  107. // 2. 更新 usage 表状态
  108. Db::table('ba_user_product_usage')
  109. ->whereIn('id', $ids)
  110. ->update([
  111. 'status' => 2,
  112. 'update_time' => $now
  113. ]);
  114. // 3. 更新企业套餐分配记录状态(如果业务需要)
  115. if (!empty($allocationIds)) {
  116. Db::table('ba_company_package_allocation')
  117. ->whereIn('id', $allocationIds)
  118. ->where('allocation_status', 1) // 假设 1 表示已分配/有效
  119. ->update([
  120. 'allocation_status' => 2, // 2 表示已过期或取消
  121. 'update_time' => $now
  122. ]);
  123. // 可选:更新企业套餐席位表的 assigned_seats / available_seats
  124. // 这需要根据分配记录找到对应的企业套餐席位,然后减少 assigned_seats 并增加 available_seats
  125. // 此处省略,可根据实际业务补充
  126. }
  127. // 4. 处理个人套餐的 ba_user_product 表
  128. $personalCombos = [];
  129. foreach ($expiredList as $item) {
  130. if ($item['package_type'] == 1) { // 个人套餐
  131. $key = $item['user_id'] . '_' . $item['product_id'] . '_' . $item['package_price_id'];
  132. $personalCombos[$key] = [
  133. 'user_id' => $item['user_id'],
  134. 'product_id' => $item['product_id'],
  135. 'package_price_id' => $item['package_price_id']
  136. ];
  137. }
  138. }
  139. foreach ($personalCombos as $combo) {
  140. // 检查该组合是否还有任何有效的 usage 记录
  141. $hasValid = Db::table('ba_user_product_usage')
  142. ->where('user_id', $combo['user_id'])
  143. ->where('product_id', $combo['product_id'])
  144. ->where('package_price_id', $combo['package_price_id'])
  145. ->where('package_type', 1)
  146. ->where('status', 1)
  147. ->where(function ($query) use ($now) {
  148. $query->where('end_time', '>', $now)
  149. ->whereOr('end_time', 'null'); // 永久有效
  150. })
  151. ->count();
  152. if ($hasValid == 0) {
  153. // 无有效记录,将汇总表状态置为过期
  154. Db::table('ba_user_product')
  155. ->where('user_id', $combo['user_id'])
  156. ->where('product_id', $combo['product_id'])
  157. ->where('package_price_id', $combo['package_price_id'])
  158. ->update([
  159. 'status' => 2, // 已过期
  160. 'update_time' => $now
  161. ]);
  162. } else {
  163. // 还有有效记录,更新 expire_time 为最新的有效记录
  164. $latestEndTime = Db::table('ba_user_product_usage')
  165. ->where('user_id', $combo['user_id'])
  166. ->where('product_id', $combo['product_id'])
  167. ->where('package_price_id', $combo['package_price_id'])
  168. ->where('package_type', 1)
  169. ->where('status', 1)
  170. ->order('end_time', 'desc')
  171. ->value('end_time');
  172. if ($latestEndTime) {
  173. Db::table('ba_user_product')
  174. ->where('user_id', $combo['user_id'])
  175. ->where('product_id', $combo['product_id'])
  176. ->where('package_price_id', $combo['package_price_id'])
  177. ->update([
  178. 'expire_time' => $latestEndTime,
  179. 'update_time' => $now
  180. ]);
  181. }
  182. }
  183. }
  184. Db::commit();
  185. return count($expiredList);
  186. } catch (\Throwable $e) {
  187. Db::rollback();
  188. throw $e;
  189. }
  190. }
  191. }