youngtsai commited on
Commit
f1b30c1
·
1 Parent(s): 5ffa4f4

raise gr.Error("網路塞車,或是內容有誤,請稍後重新嘗試!")

Browse files
Files changed (3) hide show
  1. app.py +25 -4
  2. assignment_service.py +10 -10
  3. assignment_ui.py +158 -85
app.py CHANGED
@@ -618,6 +618,7 @@ def generate_paragraph_history(
618
  log_type_name = "jutor_write_paragraph_practice"
619
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
620
  content = {
 
621
  "session_timestamp": session_timestamp,
622
  "request_origin": request_origin,
623
  "scenario_input": scenario_input,
@@ -745,8 +746,10 @@ def get_paragraph_practice_log_session_content(file_name):
745
  # 全文批改歷史紀錄
746
  def generate_paragraph_evaluate_history(
747
  user_data,
 
748
  session_timestamp,
749
  request_origin,
 
750
  full_paragraph_input,
751
  full_paragraph_evaluate_output,
752
  full_paragraph_correct_grammatical_spelling_errors_input,
@@ -767,8 +770,10 @@ def generate_paragraph_evaluate_history(
767
  log_type_name = "jutor_write_full_paragraph_evaluation"
768
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
769
  content = {
 
770
  "session_timestamp": session_timestamp,
771
  "request_origin": request_origin,
 
772
  "full_paragraph_input": full_paragraph_input,
773
  "full_paragraph_evaluate_output": full_paragraph_evaluate_output.to_dict(orient='records'),
774
  "full_paragraph_correct_grammatical_spelling_errors_input": full_paragraph_correct_grammatical_spelling_errors_input,
@@ -782,6 +787,15 @@ def generate_paragraph_evaluate_history(
782
  print(content)
783
  GCS_SERVICE.upload_json_string("jutor_logs", file_name, json.dumps(content))
784
 
 
 
 
 
 
 
 
 
 
785
  return full_paragraph_input, \
786
  full_paragraph_evaluate_output, \
787
  full_paragraph_correct_grammatical_spelling_errors_input, \
@@ -849,6 +863,7 @@ def generate_past_exam_history(
849
  log_type_name = "jutor_write_past_exam"
850
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
851
  content = {
 
852
  "session_timestamp": session_timestamp,
853
  "request_origin": request_origin,
854
  "past_exam_title": past_exam_title,
@@ -942,6 +957,7 @@ def generate_chinese_paragraph_practice_history(
942
  log_type_name = "jutor_write_chinese_full_paragraph_evaluation"
943
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
944
  content = {
 
945
  "session_timestamp": session_timestamp,
946
  "request_origin": request_origin,
947
  "chinese_full_paragraph_input": chinese_full_paragraph_input,
@@ -1142,6 +1158,9 @@ def get_chinese_paragraph_evaluate_content(thread_id, model, user_content):
1142
  print(f"====generate_paragraph_evaluate====")
1143
  print(content)
1144
 
 
 
 
1145
  content_list = content.split("```json")
1146
  content_text = content_list[0]
1147
  print(f"content_text: {content_text}")
@@ -2542,8 +2561,10 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
2542
  fn=generate_paragraph_evaluate_history,
2543
  inputs=[
2544
  user_data,
 
2545
  session_timestamp,
2546
  request_origin,
 
2547
  full_paragraph_input,
2548
  full_paragraph_evaluate_output,
2549
  full_paragraph_correct_grammatical_spelling_errors_input,
@@ -2675,7 +2696,7 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
2675
  with gr.Row():
2676
  gr.Markdown("# 建立歷程回顧")
2677
  with gr.Row():
2678
- past_exam_history_save_button = gr.Button("建立歷程回顧", variant="primary")
2679
  with gr.Row():
2680
  with gr.Accordion("歷程回顧", open=False) as past_exam_history_accordion:
2681
  gr.Markdown("<span style='color:#4e80ee'>考古題</span>")
@@ -2702,7 +2723,7 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
2702
  past_exam_save_output_history = gr.Markdown()
2703
 
2704
 
2705
- past_exam_history_save_button.click(
2706
  fn=generate_past_exam_history,
2707
  inputs=[
2708
  user_data,
@@ -3130,7 +3151,7 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
3130
  user_generate_chinese_full_paragraph_refine_evaluate_prompt = gr.Textbox(label="Paragraph evaluate Prompt", value=default_user_generate_chinese_full_paragraph_refine_evaluate_prompt)
3131
  with gr.Row():
3132
  with gr.Column():
3133
- chinese_full_paragraph_refine_input = gr.TextArea(label="這是你的原始寫作內容,參考建議,你可以選擇是否修改:", show_copy_button=True)
3134
  with gr.Column():
3135
  with gr.Row():
3136
  generate_chinese_full_paragraph_refine_button = gr.Button("段落全文分析", variant="primary")
@@ -3160,7 +3181,7 @@ with gr.Blocks(theme=THEME, css=CSS) as demo:
3160
 
3161
  # 根據建議修改文章
3162
  gr.Markdown("<span style='color:#4e80ee'>根據建議修改文章 輸入</span>")
3163
- chinese_full_paragraph_refine_input_history = gr.Markdown()
3164
  gr.Markdown("<span style='color:#4e80ee'>全文分析</span>")
3165
  chinese_full_paragraph_refine_output_text_history = gr.Markdown()
3166
  chinese_full_paragraph_refine_output_table_history = gr.Dataframe(interactive=False, wrap=True, column_widths=[30, 30, 40])
 
618
  log_type_name = "jutor_write_paragraph_practice"
619
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
620
  content = {
621
+ "content_type": "english_paragraph_practice",
622
  "session_timestamp": session_timestamp,
623
  "request_origin": request_origin,
624
  "scenario_input": scenario_input,
 
746
  # 全文批改歷史紀錄
747
  def generate_paragraph_evaluate_history(
748
  user_data,
749
+ user_nickname,
750
  session_timestamp,
751
  request_origin,
752
+ assignment_id_input,
753
  full_paragraph_input,
754
  full_paragraph_evaluate_output,
755
  full_paragraph_correct_grammatical_spelling_errors_input,
 
770
  log_type_name = "jutor_write_full_paragraph_evaluation"
771
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
772
  content = {
773
+ "content_type": "english_full_paragraph_evaluation",
774
  "session_timestamp": session_timestamp,
775
  "request_origin": request_origin,
776
+ "assignment_id": assignment_id_input,
777
  "full_paragraph_input": full_paragraph_input,
778
  "full_paragraph_evaluate_output": full_paragraph_evaluate_output.to_dict(orient='records'),
779
  "full_paragraph_correct_grammatical_spelling_errors_input": full_paragraph_correct_grammatical_spelling_errors_input,
 
787
  print(content)
788
  GCS_SERVICE.upload_json_string("jutor_logs", file_name, json.dumps(content))
789
 
790
+ if assignment_id_input:
791
+ submission_id = submit_assignment(assignment_id_input, user_data, user_nickname, content, file_name)
792
+ if submission_id:
793
+ print(f"Assignment submitted successfully. Submission ID: {submission_id}")
794
+ else:
795
+ print("Failed to submit assignment.")
796
+ else:
797
+ gr.Error("請先登入")
798
+
799
  return full_paragraph_input, \
800
  full_paragraph_evaluate_output, \
801
  full_paragraph_correct_grammatical_spelling_errors_input, \
 
863
  log_type_name = "jutor_write_past_exam"
864
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
865
  content = {
866
+ "content_type": "english_past_exam",
867
  "session_timestamp": session_timestamp,
868
  "request_origin": request_origin,
869
  "past_exam_title": past_exam_title,
 
957
  log_type_name = "jutor_write_chinese_full_paragraph_evaluation"
958
  file_name = f"{encoded_user_id_url}/{log_type_name}/{session_timestamp}.json"
959
  content = {
960
+ "content_type": "chinese_full_paragraph_evaluation",
961
  "session_timestamp": session_timestamp,
962
  "request_origin": request_origin,
963
  "chinese_full_paragraph_input": chinese_full_paragraph_input,
 
1158
  print(f"====generate_paragraph_evaluate====")
1159
  print(content)
1160
 
1161
+ if "```json" not in content:
1162
+ raise gr.Error("網路塞車,或是內容有誤,請稍後重新嘗試!")
1163
+
1164
  content_list = content.split("```json")
1165
  content_text = content_list[0]
1166
  print(f"content_text: {content_text}")
 
2561
  fn=generate_paragraph_evaluate_history,
2562
  inputs=[
2563
  user_data,
2564
+ user_nickname,
2565
  session_timestamp,
2566
  request_origin,
2567
+ assignment_id_input,
2568
  full_paragraph_input,
2569
  full_paragraph_evaluate_output,
2570
  full_paragraph_correct_grammatical_spelling_errors_input,
 
2696
  with gr.Row():
2697
  gr.Markdown("# 建立歷程回顧")
2698
  with gr.Row():
2699
+ past_exam_history_save_button = gr.Button("建立歷程回顧", variant="primary")
2700
  with gr.Row():
2701
  with gr.Accordion("歷程回顧", open=False) as past_exam_history_accordion:
2702
  gr.Markdown("<span style='color:#4e80ee'>考古題</span>")
 
2723
  past_exam_save_output_history = gr.Markdown()
2724
 
2725
 
2726
+ past_exam_history_save_button.click(
2727
  fn=generate_past_exam_history,
2728
  inputs=[
2729
  user_data,
 
3151
  user_generate_chinese_full_paragraph_refine_evaluate_prompt = gr.Textbox(label="Paragraph evaluate Prompt", value=default_user_generate_chinese_full_paragraph_refine_evaluate_prompt)
3152
  with gr.Row():
3153
  with gr.Column():
3154
+ chinese_full_paragraph_refine_input = gr.TextArea(label="這是你的原始寫作內容,參考建議,你可以選擇是否修改:", show_copy_button=True)
3155
  with gr.Column():
3156
  with gr.Row():
3157
  generate_chinese_full_paragraph_refine_button = gr.Button("段落全文分析", variant="primary")
 
3181
 
3182
  # 根據建議修改文章
3183
  gr.Markdown("<span style='color:#4e80ee'>根據建議修改文章 輸入</span>")
3184
+ chinese_full_paragraph_refine_input_history = gr.Markdown()
3185
  gr.Markdown("<span style='color:#4e80ee'>全文分析</span>")
3186
  chinese_full_paragraph_refine_output_text_history = gr.Markdown()
3187
  chinese_full_paragraph_refine_output_table_history = gr.Dataframe(interactive=False, wrap=True, column_widths=[30, 30, 40])
assignment_service.py CHANGED
@@ -19,16 +19,16 @@ class AssignmentService:
19
  return assignment_id
20
 
21
  def create_assignment_metadata(self, assignment_type, grade, topic, introduction, description, attach_materials, submission_deadline):
22
- if assignment_type == "中文寫作 AI 批改":
23
- metadata = {
24
- "assignment_type": assignment_type,
25
- "grade": grade,
26
- "topic": topic,
27
- "introduction": introduction,
28
- "description": description,
29
- "attach_materials": attach_materials,
30
- "submission_deadline": submission_deadline
31
- }
32
 
33
  return metadata
34
 
 
19
  return assignment_id
20
 
21
  def create_assignment_metadata(self, assignment_type, grade, topic, introduction, description, attach_materials, submission_deadline):
22
+ # if assignment_type == ["中文寫作 AI 批改", "英文寫作 AI 批改"]:
23
+ metadata = {
24
+ "assignment_type": assignment_type,
25
+ "grade": grade,
26
+ "topic": topic,
27
+ "introduction": introduction,
28
+ "description": description,
29
+ "attach_materials": attach_materials,
30
+ "submission_deadline": submission_deadline
31
+ }
32
 
33
  return metadata
34
 
assignment_ui.py CHANGED
@@ -145,13 +145,14 @@ def create_assignment_ui(user_data, assignment_service, submission_service):
145
  def generate_submission_html(submission_json):
146
  submission_data = submission_json.get('submission_data', {})
147
  content = submission_data.get('content', {})
148
-
 
149
  html = f"""
150
  <div style="background-color: #f8f9fa; padding: 30px; border-radius: 15px; font-family: 'Helvetica', sans-serif;">
151
  <h2 style="color: #007bff; font-size: 28px; margin-bottom: 20px;">📝 學生回傳作業</h2>
152
  <div style="background-color: white; border-radius: 10px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
153
  <details>
154
- <summary style="cursor: pointer; font-weight: bold; color: #6c757d; padding: 10px; background-color: #e9ecef; border-radius: 5px;">學生資訊</summary>
155
  <div style="margin-top: 10px;">
156
  <div style="margin-bottom: 20px;">
157
  <div style="font-weight: bold; color: #6c757d; margin-bottom: 5px;">👤 學生姓名</div>
@@ -166,108 +167,180 @@ def create_assignment_ui(user_data, assignment_service, submission_service):
166
  </div>
167
  </div>
168
  <div style="margin-bottom: 20px;">
169
- <div style="font-weight: bold; color: #6c757d; margin-bottom: 5px;">🕒 繳交時間</div>
170
  <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px;">{submission_json.get('timestamp', '未提供')}</div>
171
  </div>
172
  </div>
173
  </details>
174
-
175
- <details open>
176
- <summary style="cursor: pointer; font-weight: bold; color: #28a745; padding: 10px; background-color: #e9ecef; border-radius: 5px; margin-top: 20px;">原文</summary>
177
- <div style="margin-top: 10px;">
178
- <div style="margin-bottom: 20px;">
179
- <div style="font-weight: bold; color: #28a745; margin-bottom: 5px;">📄 輸入段落全文</div>
180
- <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_input', '未提供')}</div>
181
- </div>
182
-
183
- <div style="margin-bottom: 20px;">
184
- <div style="font-weight: bold; color: #17a2b8; margin-bottom: 5px;">📊 段落全文分析</div>
185
- <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_evaluate_output_text', '未提供')}</div>
186
- </div>
187
  """
188
 
189
- if 'chinese_full_paragraph_evaluate_output_table' in content:
190
- html += """
191
- <div style="margin-bottom: 20px;">
192
- <div style="font-weight: bold; color: #dc3545; margin-bottom: 5px;">📊 評分結果</div>
193
- <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px;">
194
- <table style="width: 100%; border-collapse: collapse;">
195
- <tr style="background-color: #e9ecef;">
196
- <th style="padding: 10px; border: 1px solid #dee2e6;">評分項目</th>
197
- <th style="padding: 10px; border: 1px solid #dee2e6;">分數</th>
198
- <th style="padding: 10px; border: 1px solid #dee2e6;">評語</th>
199
- </tr>
200
- """
201
- for item in content['chinese_full_paragraph_evaluate_output_table']:
202
- html += f"""
203
- <tr>
204
- <td style='padding: 10px; border: 1px solid #dee2e6;'>{item.get('架構', '')}</td>
205
- <td style='padding: 10px; border: 1px solid #dee2e6;'>{item.get('評分', '')}</td>
206
- <td style='padding: 10px; border: 1px solid #dee2e6;'>{item.get('解釋', '')}</td>
207
- </tr>
208
- """
209
- html += """
210
- </table>
211
- </div>
212
- </div>
213
- """
214
 
215
  html += """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  </div>
217
- </details>
218
-
219
- <details>
220
- <summary style="cursor: pointer; font-weight: bold; color: #6610f2; padding: 10px; background-color: #e9ecef; border-radius: 5px; margin-top: 20px;">第二次修改</summary>
221
- <div style="margin-top: 10px;">
 
 
 
 
 
 
 
 
 
 
 
 
222
  """
223
 
224
  html += f"""
225
- <div style="margin-bottom: 20px;">
226
- <div style="font-weight: bold; color: #6610f2; margin-bottom: 5px;">🔄 段落改善建議 輸入</div>
227
- <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_refine_input', '未提供')}</div>
228
- </div>
229
-
230
- <div style="margin-bottom: 20px;">
231
- <div style="font-weight: bold; color: #fd7e14; margin-bottom: 5px;">🔄 段落改善建議</div>
232
- <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_refine_output_text', '未提供')}</div>
233
- </div>
234
  """
235
 
236
  if 'chinese_full_paragraph_refine_output_table' in content:
237
- html += """
238
- <div style="margin-bottom: 20px;">
239
- <div style="font-weight: bold; color: #20c997; margin-bottom: 5px;">📊 修改後評分</div>
240
- <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px;">
241
- <table style="width: 100%; border-collapse: collapse;">
242
- <tr style="background-color: #e9ecef;">
243
- <th style="padding: 10px; border: 1px solid #dee2e6;">評分項目</th>
244
- <th style="padding: 10px; border: 1px solid #dee2e6;">分數</th>
245
- <th style="padding: 10px; border: 1px solid #dee2e6;">評語</th>
246
- </tr>
247
- """
248
- for item in content['chinese_full_paragraph_refine_output_table']:
249
- html += f"""
250
- <tr>
251
- <td style='padding: 10px; border: 1px solid #dee2e6;'>{item.get('架構', '')}</td>
252
- <td style='padding: 10px; border: 1px solid #dee2e6;'>{item.get('評分', '')}</td>
253
- <td style='padding: 10px; border: 1px solid #dee2e6;'>{item.get('解釋', '')}</td>
254
- </tr>
255
- """
256
- html += """
257
- </table>
258
- </div>
259
- </div>
260
- """
261
 
262
  html += f"""
263
- <div style="margin-bottom: 20px;">
264
- <div style="font-weight: bold; color: #20c997; margin-bottom: 5px;">📝 修改結果</div>
265
- <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_save_output', '未提供')}</div>
266
- </div>
267
  </div>
268
- </details>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  </div>
270
- </div>
271
  """
272
  return html
273
 
 
145
  def generate_submission_html(submission_json):
146
  submission_data = submission_json.get('submission_data', {})
147
  content = submission_data.get('content', {})
148
+ content_type = content.get('content_type', '')
149
+
150
  html = f"""
151
  <div style="background-color: #f8f9fa; padding: 30px; border-radius: 15px; font-family: 'Helvetica', sans-serif;">
152
  <h2 style="color: #007bff; font-size: 28px; margin-bottom: 20px;">📝 學生回傳作業</h2>
153
  <div style="background-color: white; border-radius: 10px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
154
  <details>
155
+ <summary style="cursor: pointer; font-weight: bold; color: #6c757d; padding: 10px; background-color: #e9ecef; border-radius: 5px;">學生资讯</summary>
156
  <div style="margin-top: 10px;">
157
  <div style="margin-bottom: 20px;">
158
  <div style="font-weight: bold; color: #6c757d; margin-bottom: 5px;">👤 學生姓名</div>
 
167
  </div>
168
  </div>
169
  <div style="margin-bottom: 20px;">
170
+ <div style="font-weight: bold; color: #6c757d; margin-bottom: 5px;">🕒 缴交时间</div>
171
  <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px;">{submission_json.get('timestamp', '未提供')}</div>
172
  </div>
173
  </div>
174
  </details>
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  """
176
 
177
+ if content_type == 'chinese_full_paragraph_evaluation':
178
+ html += generate_chinese_full_paragraph_html(content)
179
+ elif content_type == 'english_full_paragraph_evaluation':
180
+ html += generate_english_full_paragraph_html(content)
181
+ else:
182
+ html += "<p>不支持的内容类型</p>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
  html += """
185
+ </div>
186
+ </div>
187
+ """
188
+ return html
189
+
190
+ def generate_chinese_full_paragraph_html(content):
191
+ html = """
192
+ <details open>
193
+ <summary style="cursor: pointer; font-weight: bold; color: #28a745; padding: 10px; background-color: #e9ecef; border-radius: 5px; margin-top: 20px;">原文評估</summary>
194
+ <div style="margin-top: 10px;">
195
+ """
196
+
197
+ html += f"""
198
+ <div style="margin-bottom: 20px;">
199
+ <div style="font-weight: bold; color: #28a745; margin-bottom: 5px;">📄 输入段落全文</div>
200
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_input', '未提供')}</div>
201
  </div>
202
+
203
+ <div style="margin-bottom: 20px;">
204
+ <div style="font-weight: bold; color: #17a2b8; margin-bottom: 5px;">📊 段落全文分析</div>
205
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_evaluate_output_text', '未提供')}</div>
206
+ </div>
207
+ """
208
+
209
+ if 'chinese_full_paragraph_evaluate_output_table' in content:
210
+ html += generate_table_html(content['chinese_full_paragraph_evaluate_output_table'], "📊 评分结果", "#dc3545")
211
+
212
+ html += """
213
+ </div>
214
+ </details>
215
+
216
+ <details>
217
+ <summary style="cursor: pointer; font-weight: bold; color: #6610f2; padding: 10px; background-color: #e9ecef; border-radius: 5px; margin-top: 20px;">第二次修改</summary>
218
+ <div style="margin-top: 10px;">
219
  """
220
 
221
  html += f"""
222
+ <div style="margin-bottom: 20px;">
223
+ <div style="font-weight: bold; color: #6610f2; margin-bottom: 5px;">🔄 段落改善建议 输入</div>
224
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_refine_input', '未提供')}</div>
225
+ </div>
226
+
227
+ <div style="margin-bottom: 20px;">
228
+ <div style="font-weight: bold; color: #fd7e14; margin-bottom: 5px;">🔄 段落改善建议</div>
229
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_refine_output_text', '未提供')}</div>
230
+ </div>
231
  """
232
 
233
  if 'chinese_full_paragraph_refine_output_table' in content:
234
+ html += generate_table_html(content['chinese_full_paragraph_refine_output_table'], "📊 修改后评分", "#20c997")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
  html += f"""
237
+ <div style="margin-bottom: 20px;">
238
+ <div style="font-weight: bold; color: #20c997; margin-bottom: 5px;">📝 修改结果</div>
239
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('chinese_full_paragraph_save_output', '未提供')}</div>
 
240
  </div>
241
+ </div>
242
+ </details>
243
+ """
244
+
245
+ return html
246
+
247
+ def generate_english_full_paragraph_html(content):
248
+ html = """
249
+ <details open>
250
+ <summary style="cursor: pointer; font-weight: bold; color: #28a745; padding: 10px; background-color: #e9ecef; border-radius: 5px; margin-top: 20px;">原文</summary>
251
+ <div style="margin-top: 10px;">
252
+ """
253
+
254
+ html += f"""
255
+ <div style="margin-bottom: 20px;">
256
+ <div style="font-weight: bold; color: #28a745; margin-bottom: 5px;">📄 輸入段落全文</div>
257
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('full_paragraph_input', '未提供')}</div>
258
+ </div>
259
+ """
260
+
261
+ if 'full_paragraph_evaluate_output' in content:
262
+ html += generate_table_html(content['full_paragraph_evaluate_output'], "📊 評分結果", "#dc3545")
263
+
264
+ html += """
265
+ </div>
266
+ </details>
267
+
268
+ <details>
269
+ <summary style="cursor: pointer; font-weight: bold; color: #6610f2; padding: 10px; background-color: #e9ecef; border-radius: 5px; margin-top: 20px;">修訂結果</summary>
270
+ <div style="margin-top: 10px;">
271
+ """
272
+
273
+ html += f"""
274
+ <div style="margin-bottom: 20px;">
275
+ <div style="font-weight: bold; color: #6610f2; margin-bottom: 5px;">🔄 修訂文法與拼字錯誤 輸入</div>
276
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('full_paragraph_correct_grammatical_spelling_errors_input', '未提供')}</div>
277
+ </div>
278
+ """
279
+
280
+ if 'full_paragraph_correct_grammatical_spelling_errors_output_table' in content:
281
+ html += generate_table_html(content['full_paragraph_correct_grammatical_spelling_errors_output_table'], "📊 修訂文法與拼字錯誤", "#20c997")
282
+
283
+ html += f"""
284
+ <div style="margin-bottom: 20px;">
285
+ <div style="font-weight: bold; color: #6610f2; margin-bottom: 5px;">🔄 段落改善建議 輸入</div>
286
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('full_paragraph_refine_input', '未提供')}</div>
287
+ </div>
288
+ """
289
+
290
+ if 'full_paragraph_refine_output_table' in content:
291
+ html += generate_table_html(content['full_paragraph_refine_output_table'], "📊 段落改善建議", "#20c997")
292
+
293
+ html += f"""
294
+ <div style="margin-bottom: 20px;">
295
+ <div style="font-weight: bold; color: #fd7e14; margin-bottom: 5px;">🔄 修改建議</div>
296
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('full_paragraph_refine_output', '未提供')}</div>
297
+ </div>
298
+
299
+ <div style="margin-bottom: 20px;">
300
+ <div style="font-weight: bold; color: #20c997; margin-bottom: 5px;">📝 修改結果</div>
301
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; white-space: pre-wrap;">{content.get('full_paragraph_save_output', '未提供')}</div>
302
+ </div>
303
+ </div>
304
+ </details>
305
+ """
306
+
307
+ return html
308
+
309
+ def generate_table_html(table_data, title, color):
310
+ if not table_data or not isinstance(table_data, list):
311
+ return ""
312
+
313
+ html = f"""
314
+ <div style="margin-bottom: 20px;">
315
+ <div style="font-weight: bold; color: {color}; margin-bottom: 5px;">{title}</div>
316
+ <div style="background-color: #f8f9fa; padding: 10px 15px; border-radius: 5px; overflow-x: auto;">
317
+ <table style="width: 100%; border-collapse: collapse; table-layout: fixed;">
318
+ <tr style="background-color: #e9ecef;">
319
+ """
320
+
321
+ # 動態生成表頭
322
+ headers = table_data[0].keys()
323
+ for header in headers:
324
+ if header.lower() == '評分' or header.lower() == 'score':
325
+ html += f'<th style="padding: 10px; border: 1px solid #dee2e6; width: 80px;">{header}</th>'
326
+ else:
327
+ html += f'<th style="padding: 10px; border: 1px solid #dee2e6;">{header}</th>'
328
+ html += '</tr>'
329
+
330
+ # 動態生成表格內容
331
+ for item in table_data:
332
+ html += '<tr>'
333
+ for key, value in item.items():
334
+ if key.lower() == '評分' or key.lower() == 'score':
335
+ html += f'<td style="padding: 10px; border: 1px solid #dee2e6; width: 80px; text-align: center;">{value}</td>'
336
+ else:
337
+ html += f'<td style="padding: 10px; border: 1px solid #dee2e6;">{value}</td>'
338
+ html += '</tr>'
339
+
340
+ html += """
341
+ </table>
342
+ </div>
343
  </div>
 
344
  """
345
  return html
346