CacheService.php 8.3 KB

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