AutoOptions.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import React, { useState } from 'react';
  2. // 定义输入框信息类型
  3. interface InputInfo {
  4. id: string;
  5. name: string;
  6. type: string;
  7. value: string;
  8. placeholder: string;
  9. }
  10. // 定义自动发送消息的配置
  11. interface AutoSendConfig {
  12. inputSelector: string;
  13. buttonSelector: string;
  14. messages: string[];
  15. }
  16. export default function AutoOptions() {
  17. const [inputs, setInputs] = useState<InputInfo[]>([]);
  18. const [showInputs, setShowInputs] = useState(false);
  19. const [autoSendConfig, setAutoSendConfig] = useState<AutoSendConfig>({
  20. inputSelector: '.semi-input-textarea', // 设置默认输入框选择器
  21. buttonSelector: '#flow-end-msg-send', // 设置默认按钮选择器
  22. messages: Array.from({ length: 10 }, (_, i) => {
  23. const num = i + 1;
  24. return num === 1 ? ['0', num.toString()] : [`0${num - 1}`, num.toString()];
  25. }).flat() // 生成 ["0", "1", "01", "2", "02", "3", ..., "09", "10"]
  26. });
  27. const [isAutoSending, setIsAutoSending] = useState(false);
  28. const [autoSendResults, setAutoSendResults] = useState<any[]>([]);
  29. // 自动发送消息
  30. const autoSendMessages = async () => {
  31. setIsAutoSending(true);
  32. setAutoSendResults([]);
  33. try {
  34. const [tab] = await browser.tabs.query({ active: true, currentWindow: true });
  35. if (tab.id) {
  36. const response = await browser.tabs.sendMessage(tab.id, {
  37. action: "autoSendMessages",
  38. ...autoSendConfig
  39. });
  40. if (response.success) {
  41. setAutoSendResults(response.results);
  42. } else {
  43. console.error('自动发送消息失败:', response.error);
  44. }
  45. }
  46. } catch (error) {
  47. console.error('自动发送消息出错:', error);
  48. } finally {
  49. setIsAutoSending(false);
  50. }
  51. };
  52. // 更新自动发送配置
  53. const updateAutoSendConfig = (field: keyof AutoSendConfig, value: string | string[]) => {
  54. setAutoSendConfig(prev => ({
  55. ...prev,
  56. [field]: value
  57. }));
  58. };
  59. return (
  60. <>
  61. <div>
  62. <h1>页面分析工具</h1>
  63. {/* 自动发送消息配置区域 */}
  64. <div style={{ marginTop: '20px', padding: '10px', border: '1px solid #ccc', borderRadius: '4px' }}>
  65. <h2>自动发送消息</h2>
  66. <div style={{ marginBottom: '10px' }}>
  67. <label>
  68. 输入框选择器:
  69. <input
  70. type="text"
  71. value={autoSendConfig.inputSelector}
  72. onChange={(e) => updateAutoSendConfig('inputSelector', e.target.value)}
  73. placeholder="例如: #message-input 或 .input-class"
  74. style={{ width: '100%', padding: '5px', marginTop: '5px' }}
  75. />
  76. </label>
  77. </div>
  78. <div style={{ marginBottom: '10px' }}>
  79. <label>
  80. 发送按钮选择器:
  81. <input
  82. type="text"
  83. value={autoSendConfig.buttonSelector}
  84. onChange={(e) => updateAutoSendConfig('buttonSelector', e.target.value)}
  85. placeholder="例如: #send-button 或 .send-btn"
  86. style={{ width: '100%', padding: '5px', marginTop: '5px' }}
  87. />
  88. </label>
  89. </div>
  90. <div style={{ marginBottom: '10px' }}>
  91. <label>
  92. 消息列表 (每行一条):
  93. <textarea
  94. value={autoSendConfig.messages.join('\n')}
  95. onChange={(e) => updateAutoSendConfig('messages', e.target.value.split('\n').filter(msg => msg.trim()))}
  96. placeholder="每行输入一条消息"
  97. rows={5}
  98. style={{ width: '100%', padding: '5px', marginTop: '5px' }}
  99. />
  100. </label>
  101. </div>
  102. <button
  103. onClick={autoSendMessages}
  104. disabled={isAutoSending || !autoSendConfig.inputSelector || !autoSendConfig.buttonSelector}
  105. style={{
  106. padding: '8px 16px',
  107. backgroundColor: isAutoSending ? '#6c757d' : '#28a745',
  108. color: 'white',
  109. border: 'none',
  110. borderRadius: '4px',
  111. cursor: isAutoSending ? 'not-allowed' : 'pointer'
  112. }}
  113. >
  114. {isAutoSending ? '发送中...' : '开始自动发送'}
  115. </button>
  116. {/* 显示发送结果 */}
  117. {autoSendResults.length > 0 && (
  118. <div style={{ marginTop: '10px' }}>
  119. <h3>发送结果:</h3>
  120. <div style={{ maxHeight: '200px', overflowY: 'auto' }}>
  121. {autoSendResults.map((result, index) => (
  122. <div
  123. key={index}
  124. style={{
  125. padding: '5px',
  126. marginBottom: '5px',
  127. backgroundColor: result.status === 'sent' ? '#d4edda' : '#f8d7da',
  128. borderRadius: '3px'
  129. }}
  130. >
  131. <span>[{new Date(result.timestamp).toLocaleTimeString()}] </span>
  132. <span>消息: {result.message} - </span>
  133. <span style={{ fontWeight: 'bold' }}>
  134. {result.status === 'sent' ? '已发送' : '发送失败'}
  135. </span>
  136. {result.error && <span> (错误: {result.error})</span>}
  137. </div>
  138. ))}
  139. </div>
  140. </div>
  141. )}
  142. </div>
  143. {showInputs && (
  144. <div style={{ marginTop: '20px' }}>
  145. <h2>页面输入框 ({inputs.length} 个):</h2>
  146. {inputs.length > 0 ? (
  147. <div style={{ maxHeight: '300px', overflowY: 'auto' }}>
  148. {inputs.map((input, index) => (
  149. <div
  150. key={index}
  151. style={{
  152. padding: '10px',
  153. border: '1px solid #eee',
  154. marginBottom: '10px',
  155. borderRadius: '4px'
  156. }}
  157. >
  158. <div><strong>ID:</strong> {input.id || '无'}</div>
  159. <div><strong>Name:</strong> {input.name || '无'}</div>
  160. <div><strong>Type:</strong> {input.type}</div>
  161. <div><strong>Placeholder:</strong> {input.placeholder || '无'}</div>
  162. <div><strong>Value:</strong> {input.value || '无'}</div>
  163. </div>
  164. ))}
  165. </div>
  166. ) : (
  167. <p>未找到输入框元素</p>
  168. )}
  169. <button
  170. onClick={() => setShowInputs(false)}
  171. style={{
  172. padding: '8px 16px',
  173. backgroundColor: '#6c757d',
  174. color: 'white',
  175. border: 'none',
  176. borderRadius: '4px',
  177. cursor: 'pointer'
  178. }}
  179. >
  180. 隐藏输入框信息
  181. </button>
  182. </div>
  183. )}
  184. </div>
  185. </>
  186. );
  187. }