CacheService.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <?php
  2. namespace App\Module\Admin\Services;
  3. use App\Module\Admin\Enums\CACHE_TYPE;
  4. use Illuminate\Support\Facades\Artisan;
  5. use Illuminate\Support\Facades\Cache;
  6. use Illuminate\Support\Facades\Log;
  7. /**
  8. * 缓存管理服务
  9. */
  10. class CacheService
  11. {
  12. /**
  13. * 清理所有缓存
  14. *
  15. * @return array
  16. */
  17. public function clearAll(): array
  18. {
  19. $results = [];
  20. try {
  21. // 清理应用缓存
  22. Cache::flush();
  23. $results['application'] = ['status' => 'success', 'message' => '应用缓存清理成功'];
  24. // 清理配置缓存
  25. Artisan::call('config:clear');
  26. $results['config'] = ['status' => 'success', 'message' => '配置缓存清理成功'];
  27. // 清理路由缓存
  28. Artisan::call('route:clear');
  29. $results['route'] = ['status' => 'success', 'message' => '路由缓存清理成功'];
  30. // 清理视图缓存
  31. Artisan::call('view:clear');
  32. $results['view'] = ['status' => 'success', 'message' => '视图缓存清理成功'];
  33. // 清理事件缓存
  34. Artisan::call('event:clear');
  35. $results['event'] = ['status' => 'success', 'message' => '事件缓存清理成功'];
  36. Log::info('Admin: 所有缓存清理完成');
  37. } catch (\Exception $e) {
  38. $results['error'] = ['status' => 'error', 'message' => $e->getMessage()];
  39. Log::error('Admin: 缓存清理失败', ['error' => $e->getMessage()]);
  40. }
  41. return $results;
  42. }
  43. /**
  44. * 按类型清理缓存
  45. *
  46. * @param CACHE_TYPE $type
  47. * @return array
  48. */
  49. public function clearByType(CACHE_TYPE $type): array
  50. {
  51. try {
  52. switch ($type) {
  53. case CACHE_TYPE::CONFIG:
  54. Artisan::call('config:clear');
  55. return ['status' => 'success', 'message' => '配置缓存清理成功'];
  56. case CACHE_TYPE::ROUTE:
  57. Artisan::call('route:clear');
  58. return ['status' => 'success', 'message' => '路由缓存清理成功'];
  59. case CACHE_TYPE::VIEW:
  60. Artisan::call('view:clear');
  61. return ['status' => 'success', 'message' => '视图缓存清理成功'];
  62. case CACHE_TYPE::EVENT:
  63. Artisan::call('event:clear');
  64. return ['status' => 'success', 'message' => '事件缓存清理成功'];
  65. case CACHE_TYPE::APPLICATION:
  66. Cache::flush();
  67. return ['status' => 'success', 'message' => '应用缓存清理成功'];
  68. default:
  69. // 按标签清理
  70. $tags = $type->getTags();
  71. if (!empty($tags)) {
  72. Cache::tags($tags)->flush();
  73. return ['status' => 'success', 'message' => "{$type->getLabel()}清理成功"];
  74. }
  75. return ['status' => 'error', 'message' => '不支持的缓存类型'];
  76. }
  77. } catch (\Exception $e) {
  78. Log::error("Admin: {$type->getLabel()}清理失败", ['error' => $e->getMessage()]);
  79. return ['status' => 'error', 'message' => $e->getMessage()];
  80. }
  81. }
  82. /**
  83. * 获取缓存状态
  84. *
  85. * @return array
  86. */
  87. public function getStatus(): array
  88. {
  89. $status = [];
  90. foreach (CACHE_TYPE::cases() as $type) {
  91. $status[$type->value] = $this->getCacheTypeStatus($type);
  92. }
  93. return $status;
  94. }
  95. /**
  96. * 获取特定类型缓存的状态
  97. *
  98. * @param CACHE_TYPE $type
  99. * @return array
  100. */
  101. protected function getCacheTypeStatus(CACHE_TYPE $type): array
  102. {
  103. try {
  104. $testKey = "admin.cache.test.{$type->value}";
  105. $testValue = 'test_' . time();
  106. // 测试写入
  107. Cache::tags($type->getTags())->put($testKey, $testValue, 60);
  108. // 测试读取
  109. $retrieved = Cache::tags($type->getTags())->get($testKey);
  110. // 清理测试数据
  111. Cache::tags($type->getTags())->forget($testKey);
  112. $isWorking = $retrieved === $testValue;
  113. return [
  114. 'type' => $type->value,
  115. 'label' => $type->getLabel(),
  116. 'status' => $isWorking ? 'healthy' : 'error',
  117. 'description' => $type->getDescription(),
  118. 'ttl' => $type->getDefaultTtl(),
  119. 'tags' => $type->getTags(),
  120. 'priority' => $type->getPriority(),
  121. 'is_critical' => $type->isCritical(),
  122. 'safe_to_clear' => $type->isSafeToClear(),
  123. ];
  124. } catch (\Exception $e) {
  125. return [
  126. 'type' => $type->value,
  127. 'label' => $type->getLabel(),
  128. 'status' => 'error',
  129. 'error' => $e->getMessage(),
  130. 'description' => $type->getDescription(),
  131. ];
  132. }
  133. }
  134. /**
  135. * 获取缓存统计信息
  136. *
  137. * @return array
  138. */
  139. public function getStatistics(): array
  140. {
  141. try {
  142. return [
  143. 'driver' => config('cache.default'),
  144. 'stores' => config('cache.stores'),
  145. 'total_types' => count(CACHE_TYPE::cases()),
  146. 'critical_types' => count(array_filter(CACHE_TYPE::cases(), fn($type) => $type->isCritical())),
  147. 'safe_to_clear' => count(array_filter(CACHE_TYPE::cases(), fn($type) => $type->isSafeToClear())),
  148. ];
  149. } catch (\Exception $e) {
  150. return [
  151. 'error' => $e->getMessage(),
  152. ];
  153. }
  154. }
  155. /**
  156. * 预热缓存
  157. *
  158. * @param array $types
  159. * @return array
  160. */
  161. public function warmup(array $types = []): array
  162. {
  163. $results = [];
  164. if (empty($types)) {
  165. $types = array_map(fn($type) => $type->value, CACHE_TYPE::cases());
  166. }
  167. foreach ($types as $typeValue) {
  168. try {
  169. $type = CACHE_TYPE::from($typeValue);
  170. $result = $this->warmupCacheType($type);
  171. $results[$type->value] = $result;
  172. } catch (\Exception $e) {
  173. $results[$typeValue] = [
  174. 'status' => 'error',
  175. 'message' => $e->getMessage(),
  176. ];
  177. }
  178. }
  179. return $results;
  180. }
  181. /**
  182. * 预热特定类型的缓存
  183. *
  184. * @param CACHE_TYPE $type
  185. * @return array
  186. */
  187. protected function warmupCacheType(CACHE_TYPE $type): array
  188. {
  189. try {
  190. switch ($type) {
  191. case CACHE_TYPE::CONFIG:
  192. // 预热配置缓存
  193. Artisan::call('config:cache');
  194. return ['status' => 'success', 'message' => '配置缓存预热成功'];
  195. case CACHE_TYPE::ROUTE:
  196. // 预热路由缓存
  197. Artisan::call('route:cache');
  198. return ['status' => 'success', 'message' => '路由缓存预热成功'];
  199. case CACHE_TYPE::VIEW:
  200. // 预热视图缓存
  201. Artisan::call('view:cache');
  202. return ['status' => 'success', 'message' => '视图缓存预热成功'];
  203. case CACHE_TYPE::EVENT:
  204. // 预热事件缓存
  205. Artisan::call('event:cache');
  206. return ['status' => 'success', 'message' => '事件缓存预热成功'];
  207. default:
  208. return ['status' => 'skipped', 'message' => '该类型缓存不支持预热'];
  209. }
  210. } catch (\Exception $e) {
  211. return ['status' => 'error', 'message' => $e->getMessage()];
  212. }
  213. }
  214. /**
  215. * 获取缓存大小信息
  216. *
  217. * @return array
  218. */
  219. public function getSizeInfo(): array
  220. {
  221. try {
  222. // 这里可以根据不同的缓存驱动实现大小统计
  223. // 目前返回基本信息
  224. return [
  225. 'driver' => config('cache.default'),
  226. 'message' => '缓存大小统计功能待实现',
  227. ];
  228. } catch (\Exception $e) {
  229. return [
  230. 'error' => $e->getMessage(),
  231. ];
  232. }
  233. }
  234. }