Spaces:
Sleeping
Sleeping
raise gr.Error("網路塞車,或是內容有誤,請稍後重新嘗試!")
Browse files- app.py +25 -4
- assignment_service.py +10 -10
- 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 |
-
|
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 |
-
|
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 |
-
|
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 |
-
|
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 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
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;"
|
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;">🕒
|
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 '
|
190 |
-
html +=
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
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 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
"""
|
223 |
|
224 |
html += f"""
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
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 |
-
|
264 |
-
|
265 |
-
|
266 |
-
</div>
|
267 |
</div>
|
268 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|