Upload.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace app\admin\controller;
  3. use think\Db;
  4. use think\Log;
  5. use app\common\util\UeditorAiCsrf;
  6. use app\common\util\UeditorAiProxy;
  7. class Upload extends Base
  8. {
  9. public function __construct()
  10. {
  11. parent::__construct();
  12. }
  13. public function index()
  14. {
  15. $param = input();
  16. $this->assign('path',$param['path']);
  17. $this->assign('id',$param['id']);
  18. $this->assign('title',lang('upload_pic'));
  19. return $this->fetch('admin@upload/index');
  20. }
  21. public function test()
  22. {
  23. $temp_file = tempnam(sys_get_temp_dir(), 'Tux');
  24. if($temp_file){
  25. echo lang('admin/upload/test_write_ok').':' . $temp_file;
  26. }
  27. else{
  28. echo lang('admin/upload/test_write_err').':' . sys_get_temp_dir() ;
  29. }
  30. }
  31. public function upload($p=[])
  32. {
  33. return model('Upload')->upload($p);
  34. }
  35. /**
  36. * UEditorPlus AI dialog proxy (JSON). Key and api_base only from ai_seo server-side.
  37. */
  38. public function ueditorAi()
  39. {
  40. /* 对话框与后台可能不同 iframe/静态域,读不到 UE_AI_CSRF;用同源 GET + Cookie 取 session 内令牌再 POST */
  41. if ($this->request->isGet() && (string) input('fetch_csrf', '') === '1') {
  42. return json(['code' => 0, 'msg' => 'ok', 'data' => ['token' => UeditorAiCsrf::token()]]);
  43. }
  44. if (!$this->request->isPost()) {
  45. return json(['code' => 1, 'msg' => lang('admin/ueditor_ai/bad_method'), 'data' => null]);
  46. }
  47. $raw = $this->request->getContent();
  48. $in = [];
  49. if ($raw !== '') {
  50. $decoded = json_decode($raw, true);
  51. $in = is_array($decoded) ? $decoded : [];
  52. }
  53. $csrf = isset($in['_csrf_token']) ? (string) $in['_csrf_token'] : '';
  54. if ($csrf === '' && method_exists($this->request, 'cookie')) {
  55. $ck = $this->request->cookie('ueditor_ai_csrf');
  56. if ($ck !== null && $ck !== '') {
  57. $csrf = (string) $ck;
  58. }
  59. }
  60. if (!UeditorAiCsrf::validate($csrf)) {
  61. return json(['code' => 1, 'msg' => lang('admin/ueditor_ai/invalid_token'), 'data' => null]);
  62. }
  63. if (!$this->ueditorAiRateLimit(30, 60)) {
  64. return json(['code' => 1, 'msg' => lang('admin/ueditor_ai/rate_limit'), 'data' => null]);
  65. }
  66. $system = isset($in['system_prompt']) ? (string) $in['system_prompt'] : '';
  67. $user = isset($in['user_prompt']) ? (string) $in['user_prompt'] : '';
  68. $config = config('maccms');
  69. $ai = isset($config['ai_seo']) && is_array($config['ai_seo']) ? $config['ai_seo'] : [];
  70. $enabled = isset($ai['enabled']) ? (string) $ai['enabled'] : '0';
  71. if ($enabled !== '1') {
  72. return json(['code' => 1, 'msg' => lang('admin/ueditor_ai/disabled'), 'data' => null]);
  73. }
  74. if (trim((string) (isset($ai['api_key']) ? $ai['api_key'] : '')) === '') {
  75. return json(['code' => 1, 'msg' => lang('admin/ueditor_ai/no_key'), 'data' => null]);
  76. }
  77. $provider = isset($ai['provider']) ? strtolower(trim((string) $ai['provider'])) : '';
  78. try {
  79. $result = UeditorAiProxy::complete($ai, $system, $user);
  80. } catch (\Throwable $e) {
  81. Log::error('ueditor_ai exception: ' . $e->getMessage());
  82. return json(['code' => 1, 'msg' => lang('admin/ueditor_ai/upstream_fail'), 'data' => null]);
  83. }
  84. if (!$result['ok']) {
  85. Log::error('ueditor_ai upstream fail admin_id=' . (isset($this->_admin['admin_id']) ? $this->_admin['admin_id'] : '')
  86. . ' provider=' . $provider . ' detail=' . (isset($result['log_detail']) ? $result['log_detail'] : ''));
  87. return json(['code' => 1, 'msg' => $result['error'], 'data' => null]);
  88. }
  89. Log::write(
  90. 'ueditor_ai ok admin_id=' . (isset($this->_admin['admin_id']) ? $this->_admin['admin_id'] : '') . ' provider=' . $provider,
  91. 'log'
  92. );
  93. return json(['code' => 0, 'msg' => 'ok', 'data' => ['text' => $result['text']]]);
  94. }
  95. private function ueditorAiRateLimit($limit, $window)
  96. {
  97. $adminId = isset($this->_admin['admin_id']) ? (string) $this->_admin['admin_id'] : '0';
  98. $key = 'ueditor_ai_rl_' . $adminId;
  99. $count = (int) cache($key);
  100. if ($count >= $limit) {
  101. return false;
  102. }
  103. if ($count === 0) {
  104. cache($key, 1, $window);
  105. } else {
  106. cache($key, $count + 1, $window);
  107. }
  108. return true;
  109. }
  110. }