app.py
CHANGED
|
@@ -75,18 +75,17 @@ def handle_load(source, c_type, c_id, model):
|
|
| 75 |
json.dumps({})
|
| 76 |
]
|
| 77 |
|
| 78 |
-
#
|
| 79 |
def handle_qa_select(selection, qa_json):
|
| 80 |
if not selection or not qa_json:
|
| 81 |
-
|
| 82 |
-
return ["", "", "", "correct", "无", ""]
|
| 83 |
try:
|
| 84 |
qas = json.loads(qa_json)
|
| 85 |
idx = int(selection.split(":")[0][1:]) - 1
|
| 86 |
curr = qas[idx]
|
| 87 |
-
return [curr['id'], curr['q'], curr['a'], "
|
| 88 |
except:
|
| 89 |
-
return ["", "", "", "
|
| 90 |
|
| 91 |
# ============== UI 布局 ==============
|
| 92 |
def create_ui():
|
|
@@ -122,15 +121,16 @@ def create_ui():
|
|
| 122 |
curr_qid = gr.Text(visible=False)
|
| 123 |
q_disp = gr.Text(label="问题内容", lines=2)
|
| 124 |
a_disp = gr.Text(label="标准答案")
|
|
|
|
|
|
|
| 125 |
status_opt = gr.Radio(
|
| 126 |
label="审核结论",
|
| 127 |
-
choices=[
|
| 128 |
-
value="
|
| 129 |
)
|
| 130 |
err_type = gr.Dropdown(label="错误分类", choices=["无", "事实错误", "逻辑错误", "图表无法读取"])
|
| 131 |
|
| 132 |
comment = gr.Text(label="审核备注")
|
| 133 |
-
|
| 134 |
save_status = gr.Text(label="操作反馈", interactive=False)
|
| 135 |
save_btn = gr.Button("💾 提交单条审核", variant="primary")
|
| 136 |
|
|
@@ -139,9 +139,10 @@ def create_ui():
|
|
| 139 |
next_btn = gr.Button("➡️ 下一个图表")
|
| 140 |
|
| 141 |
gr.Markdown("---")
|
|
|
|
| 142 |
with gr.Row():
|
| 143 |
-
export_btn = gr.Button("📥
|
| 144 |
-
download_file = gr.File(label="
|
| 145 |
|
| 146 |
# --- 事件绑定 ---
|
| 147 |
demo.load(
|
|
@@ -156,14 +157,12 @@ def create_ui():
|
|
| 156 |
id_dd.change(handle_load, inputs=[src_dd, typ_dd, id_dd, mdl_dd], outputs=load_event_outputs)
|
| 157 |
mdl_dd.change(handle_load, inputs=[src_dd, typ_dd, id_dd, mdl_dd], outputs=load_event_outputs)
|
| 158 |
|
| 159 |
-
# 【修复处 2】移除这里 outputs 里的 gr.State(),使其与上方返回的 6 个值严格对齐
|
| 160 |
qa_radio.change(
|
| 161 |
handle_qa_select,
|
| 162 |
inputs=[qa_radio, qa_store],
|
| 163 |
outputs=[curr_qid, q_disp, a_disp, status_opt, err_type, comment]
|
| 164 |
)
|
| 165 |
|
| 166 |
-
# 导航逻辑
|
| 167 |
def navigate(direction):
|
| 168 |
target = nav_state.get_nav_target(direction)
|
| 169 |
if target:
|
|
@@ -172,21 +171,29 @@ def create_ui():
|
|
| 172 |
gr.update(value=target['chart_type']),
|
| 173 |
gr.update(value=target['chart_id']),
|
| 174 |
gr.update(value=target['model']),
|
| 175 |
-
gr.update(value="")
|
| 176 |
]
|
| 177 |
-
return [gr.update()
|
| 178 |
|
| 179 |
prev_btn.click(lambda: navigate(-1), outputs=[src_dd, typ_dd, id_dd, mdl_dd, save_status])
|
| 180 |
next_btn.click(lambda: navigate(1), outputs=[src_dd, typ_dd, id_dd, mdl_dd, save_status])
|
| 181 |
|
| 182 |
# 保存逻辑
|
| 183 |
-
def quick_save(qid, cid, src,
|
| 184 |
if not qid:
|
| 185 |
return "⚠️ 无效操作:未选择题目", gr.update()
|
| 186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
data_manager.save_review({
|
| 188 |
"qa_id": qid, "chart_id": cid, "source": src,
|
| 189 |
-
"status":
|
| 190 |
})
|
| 191 |
|
| 192 |
stats = data_manager.get_review_stats()
|
|
@@ -200,10 +207,10 @@ def create_ui():
|
|
| 200 |
outputs=[save_status, stats_txt]
|
| 201 |
)
|
| 202 |
|
| 203 |
-
# 导出下载逻辑
|
| 204 |
def handle_export():
|
| 205 |
file_path = data_manager.export_reviews()
|
| 206 |
-
return
|
| 207 |
|
| 208 |
export_btn.click(
|
| 209 |
handle_export,
|
|
@@ -215,6 +222,7 @@ def create_ui():
|
|
| 215 |
|
| 216 |
if __name__ == "__main__":
|
| 217 |
app = create_ui()
|
|
|
|
| 218 |
app.launch(
|
| 219 |
server_name="0.0.0.0",
|
| 220 |
server_port=7860,
|
|
|
|
| 75 |
json.dumps({})
|
| 76 |
]
|
| 77 |
|
| 78 |
+
# 严格匹配 6 个 outputs 数量
|
| 79 |
def handle_qa_select(selection, qa_json):
|
| 80 |
if not selection or not qa_json:
|
| 81 |
+
return ["", "", "", "正确", "无", ""]
|
|
|
|
| 82 |
try:
|
| 83 |
qas = json.loads(qa_json)
|
| 84 |
idx = int(selection.split(":")[0][1:]) - 1
|
| 85 |
curr = qas[idx]
|
| 86 |
+
return [curr['id'], curr['q'], curr['a'], "正确", "无", ""]
|
| 87 |
except:
|
| 88 |
+
return ["", "", "", "正确", "无", ""]
|
| 89 |
|
| 90 |
# ============== UI 布局 ==============
|
| 91 |
def create_ui():
|
|
|
|
| 121 |
curr_qid = gr.Text(visible=False)
|
| 122 |
q_disp = gr.Text(label="问题内容", lines=2)
|
| 123 |
a_disp = gr.Text(label="标准答案")
|
| 124 |
+
|
| 125 |
+
# 【修复关键点1】移除 Tuple 选项,规避底层 Schema 渲染崩溃 Bug
|
| 126 |
status_opt = gr.Radio(
|
| 127 |
label="审核结论",
|
| 128 |
+
choices=["正确", "错误", "优化"],
|
| 129 |
+
value="正确"
|
| 130 |
)
|
| 131 |
err_type = gr.Dropdown(label="错误分类", choices=["无", "事实错误", "逻辑错误", "图表无法读取"])
|
| 132 |
|
| 133 |
comment = gr.Text(label="审核备注")
|
|
|
|
| 134 |
save_status = gr.Text(label="操作反馈", interactive=False)
|
| 135 |
save_btn = gr.Button("💾 提交单条审核", variant="primary")
|
| 136 |
|
|
|
|
| 139 |
next_btn = gr.Button("➡️ 下一个图表")
|
| 140 |
|
| 141 |
gr.Markdown("---")
|
| 142 |
+
# 【新增】导出下载区
|
| 143 |
with gr.Row():
|
| 144 |
+
export_btn = gr.Button("📥 生成并下载记录文件", variant="secondary")
|
| 145 |
+
download_file = gr.File(label="获取的文件")
|
| 146 |
|
| 147 |
# --- 事件绑定 ---
|
| 148 |
demo.load(
|
|
|
|
| 157 |
id_dd.change(handle_load, inputs=[src_dd, typ_dd, id_dd, mdl_dd], outputs=load_event_outputs)
|
| 158 |
mdl_dd.change(handle_load, inputs=[src_dd, typ_dd, id_dd, mdl_dd], outputs=load_event_outputs)
|
| 159 |
|
|
|
|
| 160 |
qa_radio.change(
|
| 161 |
handle_qa_select,
|
| 162 |
inputs=[qa_radio, qa_store],
|
| 163 |
outputs=[curr_qid, q_disp, a_disp, status_opt, err_type, comment]
|
| 164 |
)
|
| 165 |
|
|
|
|
| 166 |
def navigate(direction):
|
| 167 |
target = nav_state.get_nav_target(direction)
|
| 168 |
if target:
|
|
|
|
| 171 |
gr.update(value=target['chart_type']),
|
| 172 |
gr.update(value=target['chart_id']),
|
| 173 |
gr.update(value=target['model']),
|
| 174 |
+
gr.update(value="")
|
| 175 |
]
|
| 176 |
+
return [gr.update(), gr.update(), gr.update(), gr.update(), gr.update()]
|
| 177 |
|
| 178 |
prev_btn.click(lambda: navigate(-1), outputs=[src_dd, typ_dd, id_dd, mdl_dd, save_status])
|
| 179 |
next_btn.click(lambda: navigate(1), outputs=[src_dd, typ_dd, id_dd, mdl_dd, save_status])
|
| 180 |
|
| 181 |
# 保存逻辑
|
| 182 |
+
def quick_save(qid, cid, src, status_label, cmt):
|
| 183 |
if not qid:
|
| 184 |
return "⚠️ 无效操作:未选择题目", gr.update()
|
| 185 |
|
| 186 |
+
# 【修复关键点2】在后台进行一层映射,以确保数据模块得到正确的英文状态标识
|
| 187 |
+
status_map = {
|
| 188 |
+
"正确": "correct",
|
| 189 |
+
"错误": "incorrect",
|
| 190 |
+
"优化": "needs_modification"
|
| 191 |
+
}
|
| 192 |
+
mapped_status = status_map.get(status_label, "correct")
|
| 193 |
+
|
| 194 |
data_manager.save_review({
|
| 195 |
"qa_id": qid, "chart_id": cid, "source": src,
|
| 196 |
+
"status": mapped_status, "comment": cmt
|
| 197 |
})
|
| 198 |
|
| 199 |
stats = data_manager.get_review_stats()
|
|
|
|
| 207 |
outputs=[save_status, stats_txt]
|
| 208 |
)
|
| 209 |
|
| 210 |
+
# 【修复关键点3】导出下载逻辑,直接返回文件路径本身,绕过任何可能触发类型推断崩溃的包装
|
| 211 |
def handle_export():
|
| 212 |
file_path = data_manager.export_reviews()
|
| 213 |
+
return file_path
|
| 214 |
|
| 215 |
export_btn.click(
|
| 216 |
handle_export,
|
|
|
|
| 222 |
|
| 223 |
if __name__ == "__main__":
|
| 224 |
app = create_ui()
|
| 225 |
+
# show_api=False 依然保留,同时移除了所有容易触发 Schema 崩溃的类型定义
|
| 226 |
app.launch(
|
| 227 |
server_name="0.0.0.0",
|
| 228 |
server_port=7860,
|