ContactController.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use App\Services\LiquidRenderer;
  5. use App\Models\DistInquiry;
  6. use App\Services\MailService; // 导入 MailService
  7. class ContactController extends Controller
  8. {
  9. protected $liquidRenderer;
  10. public function __construct(LiquidRenderer $liquidRenderer)
  11. {
  12. $this->liquidRenderer = $liquidRenderer;
  13. }
  14. /**
  15. * 关键字过滤方法
  16. */
  17. private function filterKeywords($data)
  18. {
  19. // 检查是否启用内容过滤
  20. if (!config('content_filter.enabled', true)) {
  21. return [
  22. 'blocked' => false,
  23. 'data' => $data,
  24. 'filtered_words' => []
  25. ];
  26. }
  27. // 从配置文件获取过滤设置
  28. $blockedWords = config('content_filter.blocked_words', []);
  29. $fieldsToCheck = config('content_filter.filter_fields', ['customer_name', 'content']);
  30. $maxLengths = config('content_filter.max_length', []);
  31. $result = [
  32. 'blocked' => false,
  33. 'data' => $data,
  34. 'filtered_words' => []
  35. ];
  36. foreach ($fieldsToCheck as $field) {
  37. if (!isset($data[$field])) continue;
  38. $originalText = $data[$field];
  39. $cleanText = $originalText;
  40. // 长度检查
  41. $maxLength = $maxLengths[$field] ?? 5000;
  42. if (strlen($originalText) > $maxLength) {
  43. $result['blocked'] = true;
  44. break;
  45. }
  46. // 检查敏感词 - 直接阻止
  47. foreach ($blockedWords as $word) {
  48. if (stripos($originalText, $word) !== false) {
  49. $result['blocked'] = true;
  50. $result['filtered_words'][] = $word;
  51. // 记录过滤日志
  52. if (config('content_filter.log_filtered', false)) {
  53. \Log::warning('Content blocked due to sensitive word', [
  54. 'field' => $field,
  55. 'word' => $word,
  56. 'ip' => request()->ip(),
  57. 'user_agent' => request()->userAgent()
  58. ]);
  59. }
  60. break 2; // 跳出所有循环
  61. }
  62. }
  63. // 更新清理后的数据
  64. $result['data'][$field] = trim($originalText);
  65. }
  66. return $result;
  67. }
  68. function create()
  69. {
  70. // 构建导航数据 开始
  71. $breadcrumbs = [
  72. [
  73. 'url' => '/',
  74. 'name' => 'Home',
  75. ]
  76. ];
  77. $breadcrumbs[] = [
  78. 'url' => '#',
  79. 'name' => 'Contact Us',
  80. ];
  81. //模板支持多级目录,需要目录符号
  82. $output = LiquidRenderer::render('pages_sp_contact.liquid', [
  83. 'breadcrumbs' => $breadcrumbs,
  84. ]);
  85. return response($output);
  86. }
  87. function store(Request $request)
  88. {
  89. try {
  90. // 如果请求中有 Token,则进行验证
  91. if ($request->has('_token')) {
  92. if ($request->input('_token') !== csrf_token()) {
  93. return response()->json([
  94. 'status' => 'error',
  95. 'message' => 'Invalid token.',
  96. ], 403); // 返回 HTTP 403 错误
  97. }
  98. }
  99. // 验证请求数据
  100. $validatedData = $request->validate([
  101. 'customer_name' => 'required|string|max:255', // 必填,字符串,最大长度255
  102. 'content' => 'required|string', // 必填,字符串
  103. // 其他字段的验证规则可以在这里添加
  104. ]);
  105. // 关键字过滤
  106. $filteredResult = $this->filterKeywords($validatedData);
  107. if ($filteredResult['blocked']) {
  108. $response = [
  109. 'status' => 'error',
  110. 'message' => 'System error, please try again later.',
  111. ];
  112. return response()->json($response, 403);
  113. }
  114. // 从请求中获取所有数据
  115. $data = $request->all();
  116. // 应用过滤后的数据
  117. $data['customer_name'] = $filteredResult['data']['customer_name'];
  118. $data['content'] = $filteredResult['data']['content'];
  119. // 指定特殊字段的值
  120. $data['dist_id'] = 0; // app('dist')->id; // 指定当前登录的分销商ID
  121. $data['referer_url']=$request->headers->get('referer'); // 获取上一页的URL
  122. $data['ip_address'] = $request->server('HTTP_X_REAL_IP');
  123. if (empty($data['ip_address'])) {
  124. $forwardedFor = $request->server('HTTP_X_FORWARDED_FOR');
  125. if ($forwardedFor) {
  126. $ips = explode(',', $forwardedFor);
  127. $data['ip_address'] = trim($ips[0]); // 取第一个 IP 并去除空格
  128. } else {
  129. $data['ip_address'] = $request->ip(); // 备用方案
  130. }
  131. }
  132. $data['order_number']= generateOrderNumber('ORD');
  133. // 使用模型的 create 方法插入数据
  134. $distInquiry = DistInquiry::create($data);
  135. // 如果插入失败,抛出异常
  136. if (!$distInquiry) {
  137. throw new \Exception('submit failed, please try again later. ');
  138. }
  139. // 询盘数据
  140. $inquiryData = [
  141. 'order_number' => $distInquiry->order_number,
  142. 'customer_name' => $distInquiry->customer_name,
  143. 'email' => $distInquiry->email,
  144. 'whats_app' => $distInquiry->whats_app,
  145. 'consulting_products' => $distInquiry->consulting_products,
  146. 'freight_forwarder' => $distInquiry->freight_forwarder,
  147. 'business_model' => $distInquiry->business_model,
  148. 'content' => $distInquiry->content,
  149. 'referer_url' => $distInquiry->referer_url,
  150. 'ip'=> $data['ip_address'],
  151. ];
  152. // 使用 MailService 静态方法发送邮件
  153. $mailSent = MailService::sendInquiryMail($inquiryData);
  154. // 检查是否有重定向URL
  155. if ($request->has('redirect_url')) {
  156. return redirect($request->input('redirect_url'));
  157. }
  158. // 成功时的响应(没有重定向URL时返回JSON)
  159. $response = [
  160. 'status' => 'success'
  161. ];
  162. return response()->json($response, 200);
  163. } catch (\Exception $e) {
  164. // 捕获所有异常并返回错误信息
  165. $response = [
  166. 'status' => 'error',
  167. 'message' => 'submit failed, please try again later. ',
  168. ];
  169. // 检查是否有错误时的重定向URL
  170. if ($request->has('error_redirect_url')) {
  171. return redirect($request->input('error_redirect_url'))->with('error', $response['message']);
  172. }
  173. // 如果没有error_redirect_url但有redirect_url,也进行重定向
  174. elseif ($request->has('redirect_url')) {
  175. return redirect($request->input('redirect_url'))->with('error', $response['message']);
  176. }
  177. return response()->json($response, 500); // 返回 HTTP 500 错误
  178. }
  179. }
  180. }