Config.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. namespace app\admin\controller\routine;
  3. use Throwable;
  4. use ba\Filesystem;
  5. use app\common\library\Email;
  6. use PHPMailer\PHPMailer\PHPMailer;
  7. use app\common\controller\Backend;
  8. use app\admin\model\Config as ConfigModel;
  9. use PHPMailer\PHPMailer\Exception as PHPMailerException;
  10. class Config extends Backend
  11. {
  12. /**
  13. * @var object
  14. * @phpstan-var ConfigModel
  15. */
  16. protected object $model;
  17. protected array $filePath = [
  18. 'appConfig' => 'config/app.php',
  19. 'webAdminBase' => 'web/src/router/static/adminBase.ts',
  20. 'backendEntranceStub' => 'app/admin/library/stubs/backendEntrance.stub',
  21. ];
  22. public function initialize(): void
  23. {
  24. parent::initialize();
  25. $this->model = new ConfigModel();
  26. }
  27. public function index(): void
  28. {
  29. $configGroup = get_sys_config('config_group');
  30. $config = $this->model->order('weigh desc')->select()->toArray();
  31. $list = [];
  32. $newConfigGroup = [];
  33. foreach ($configGroup as $item) {
  34. $list[$item['key']]['name'] = $item['key'];
  35. $list[$item['key']]['title'] = __($item['value']);
  36. $newConfigGroup[$item['key']] = $list[$item['key']]['title'];
  37. }
  38. foreach ($config as $item) {
  39. if (array_key_exists($item['group'], $newConfigGroup)) {
  40. $item['title'] = __($item['title']);
  41. $list[$item['group']]['list'][] = $item;
  42. }
  43. }
  44. $this->success('', [
  45. 'list' => $list,
  46. 'remark' => get_route_remark(),
  47. 'configGroup' => $newConfigGroup ?? [],
  48. 'quickEntrance' => get_sys_config('config_quick_entrance'),
  49. ]);
  50. }
  51. /**
  52. * 编辑
  53. * @throws Throwable
  54. */
  55. public function edit(): void
  56. {
  57. $all = $this->model->select();
  58. foreach ($all as $item) {
  59. if ($item['type'] == 'editor') {
  60. $this->request->filter('clean_xss');
  61. break;
  62. }
  63. }
  64. if ($this->request->isPost()) {
  65. $this->modelValidate = false;
  66. $data = $this->request->post();
  67. if (!$data) {
  68. $this->error(__('Parameter %s can not be empty', ['']));
  69. }
  70. $data = $this->excludeFields($data);
  71. $configValue = [];
  72. foreach ($all as $item) {
  73. if (array_key_exists($item->name, $data)) {
  74. $configValue[] = [
  75. 'id' => $item->id,
  76. 'type' => $item->getData('type'),
  77. 'value' => $data[$item->name]
  78. ];
  79. // 自定义后台入口
  80. if ($item->name == 'backend_entrance') {
  81. $backendEntrance = get_sys_config('backend_entrance');
  82. if ($backendEntrance == $data[$item->name]) continue;
  83. if (!preg_match("/^\/[a-zA-Z0-9]+$/", $data[$item->name])) {
  84. $this->error(__('Backend entrance rule'));
  85. }
  86. // 修改 adminBaseRoutePath
  87. $adminBaseFilePath = Filesystem::fsFit(root_path() . $this->filePath['webAdminBase']);
  88. $adminBaseContent = @file_get_contents($adminBaseFilePath);
  89. if (!$adminBaseContent) $this->error(__('Configuration write failed: %s', [$this->filePath['webAdminBase']]));
  90. $adminBaseContent = str_replace("export const adminBaseRoutePath = '$backendEntrance'", "export const adminBaseRoutePath = '{$data[$item->name]}'", $adminBaseContent);
  91. $result = @file_put_contents($adminBaseFilePath, $adminBaseContent);
  92. if (!$result) $this->error(__('Configuration write failed: %s', [$this->filePath['webAdminBase']]));
  93. // 去除后台入口开头的斜杠
  94. $oldBackendEntrance = ltrim($backendEntrance, '/');
  95. $newBackendEntrance = ltrim($data[$item->name], '/');
  96. // 设置应用别名映射
  97. $appMap = config('app.app_map');
  98. $adminMapKey = array_search('admin', $appMap);
  99. if ($adminMapKey !== false) {
  100. unset($appMap[$adminMapKey]);
  101. }
  102. if ($newBackendEntrance != 'admin') {
  103. $appMap[$newBackendEntrance] = 'admin';
  104. }
  105. $appConfigFilePath = Filesystem::fsFit(root_path() . $this->filePath['appConfig']);
  106. $appConfigContent = @file_get_contents($appConfigFilePath);
  107. if (!$appConfigContent) $this->error(__('Configuration write failed: %s', [$this->filePath['appConfig']]));
  108. $appMapStr = '';
  109. foreach ($appMap as $newAppName => $oldAppName) {
  110. $appMapStr .= "'$newAppName' => '$oldAppName', ";
  111. }
  112. $appMapStr = rtrim($appMapStr, ', ');
  113. $appMapStr = "[$appMapStr]";
  114. $appConfigContent = preg_replace("/'app_map'(\s+)=>(\s+)(.*)\/\/ 域名/s", "'app_map'\$1=>\$2$appMapStr,\n // 域名", $appConfigContent);
  115. $result = @file_put_contents($appConfigFilePath, $appConfigContent);
  116. if (!$result) $this->error(__('Configuration write failed: %s', [$this->filePath['appConfig']]));
  117. // 建立API入口文件
  118. $oldBackendEntranceFile = Filesystem::fsFit(public_path() . $oldBackendEntrance . '.php');
  119. $newBackendEntranceFile = Filesystem::fsFit(public_path() . $newBackendEntrance . '.php');
  120. if (file_exists($oldBackendEntranceFile)) @unlink($oldBackendEntranceFile);
  121. if ($newBackendEntrance != 'admin') {
  122. $backendEntranceStub = @file_get_contents(Filesystem::fsFit(root_path() . $this->filePath['backendEntranceStub']));
  123. if (!$backendEntranceStub) $this->error(__('Configuration write failed: %s', [$this->filePath['backendEntranceStub']]));
  124. $result = @file_put_contents($newBackendEntranceFile, $backendEntranceStub);
  125. if (!$result) $this->error(__('Configuration write failed: %s', [$newBackendEntranceFile]));
  126. }
  127. }
  128. }
  129. }
  130. $result = false;
  131. $this->model->startTrans();
  132. try {
  133. // 模型验证
  134. if ($this->modelValidate) {
  135. $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  136. if (class_exists($validate)) {
  137. $validate = new $validate();
  138. if ($this->modelSceneValidate) $validate->scene('edit');
  139. $validate->check($data);
  140. }
  141. }
  142. $result = $this->model->saveAll($configValue);
  143. $this->model->commit();
  144. } catch (Throwable $e) {
  145. $this->model->rollback();
  146. $this->error($e->getMessage());
  147. }
  148. if ($result !== false) {
  149. $this->success(__('The current page configuration item was updated successfully'));
  150. } else {
  151. $this->error(__('No rows updated'));
  152. }
  153. }
  154. }
  155. public function add(): void
  156. {
  157. if ($this->request->isPost()) {
  158. $data = $this->request->post();
  159. if (!$data) {
  160. $this->error(__('Parameter %s can not be empty', ['']));
  161. }
  162. $data = $this->excludeFields($data);
  163. $result = false;
  164. $this->model->startTrans();
  165. try {
  166. // 模型验证
  167. if ($this->modelValidate) {
  168. $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  169. if (class_exists($validate)) {
  170. $validate = new $validate();
  171. if ($this->modelSceneValidate) $validate->scene('add');
  172. $validate->check($data);
  173. }
  174. }
  175. $result = $this->model->save($data);
  176. $this->model->commit();
  177. } catch (Throwable $e) {
  178. $this->model->rollback();
  179. $this->error($e->getMessage());
  180. }
  181. if ($result !== false) {
  182. $this->success(__('Added successfully'));
  183. } else {
  184. $this->error(__('No rows were added'));
  185. }
  186. }
  187. $this->error(__('Parameter error'));
  188. }
  189. /**
  190. * 发送邮件测试
  191. * @throws Throwable
  192. */
  193. public function sendTestMail(): void
  194. {
  195. $data = $this->request->post();
  196. $mail = new Email();
  197. try {
  198. $mail->Host = $data['smtp_server'];
  199. $mail->SMTPAuth = true;
  200. $mail->Username = $data['smtp_user'];
  201. $mail->Password = $data['smtp_pass'];
  202. $mail->SMTPSecure = $data['smtp_verification'] == 'SSL' ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
  203. $mail->Port = $data['smtp_port'];
  204. $mail->setFrom($data['smtp_sender_mail'], $data['smtp_user']);
  205. $mail->isSMTP();
  206. $mail->addAddress($data['testMail']);
  207. $mail->isHTML();
  208. $mail->setSubject(__('This is a test email') . '-' . get_sys_config('site_name'));
  209. $mail->Body = __('Congratulations, receiving this email means that your email service has been configured correctly');
  210. $mail->send();
  211. } catch (PHPMailerException) {
  212. $this->error($mail->ErrorInfo);
  213. }
  214. $this->success(__('Test mail sent successfully~'));
  215. }
  216. }