322 lines
13 KiB
Python
322 lines
13 KiB
Python
#!/usr/bin/env python3
|
|
"""Demo data seed script — called by cli.py, not part of application code."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
BACKEND_DIR = Path(__file__).resolve().parent.parent / "backend"
|
|
sys.path.insert(0, str(BACKEND_DIR))
|
|
|
|
from app.core.security import hash_password # noqa: E402
|
|
from app.services.repository import create_event, init_db # noqa: E402
|
|
|
|
_now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
|
|
def run(db_path: str, force: bool = False) -> None:
|
|
conn = sqlite3.connect(db_path)
|
|
conn.row_factory = sqlite3.Row
|
|
try:
|
|
init_db(conn)
|
|
|
|
if force:
|
|
conn.executescript("""
|
|
DELETE FROM feedback;
|
|
DELETE FROM order_events;
|
|
DELETE FROM attachments;
|
|
DELETE FROM saved_addresses;
|
|
DELETE FROM repair_orders;
|
|
DELETE FROM sessions;
|
|
DELETE FROM users;
|
|
""")
|
|
conn.commit()
|
|
|
|
existing = conn.execute("SELECT COUNT(*) AS count FROM repair_orders").fetchone()["count"]
|
|
if existing > 0:
|
|
print("Orders already exist, skipping. Use --force to overwrite.")
|
|
return
|
|
|
|
conn.executemany(
|
|
"INSERT OR IGNORE INTO users "
|
|
"(username, password_hash, role, display_name, created_at) "
|
|
"VALUES (?, ?, ?, ?, ?)",
|
|
[
|
|
("student01", hash_password("Student123"), "student", "张同学", _now),
|
|
("admin01", hash_password("Admin123"), "admin", "宿管老师", _now),
|
|
],
|
|
)
|
|
student = conn.execute("SELECT id FROM users WHERE username = 'student01'").fetchone()
|
|
if student is None:
|
|
conn.commit()
|
|
return
|
|
|
|
conn.execute(
|
|
"INSERT OR IGNORE INTO saved_addresses "
|
|
"(student_id, campus, building, room, last_used_at) "
|
|
"VALUES (?, ?, ?, ?, ?)",
|
|
(student["id"], "西海岸校区", "听海苑999号楼", "404", _now),
|
|
)
|
|
|
|
orders = [
|
|
{
|
|
"order_no": "DR20260601001",
|
|
"category": "给排水 / 水龙头类",
|
|
"raw_description": "卫生间水龙头关不严,一直滴水。",
|
|
"structured_summary": "给排水,建议管道处理。卫生间水龙头关不严持续滴水;洗手池位置;影响日常用水。",
|
|
"urgency": "中",
|
|
"status": "已提交",
|
|
"allow_room_entry": 0,
|
|
"assignee_name": None,
|
|
"expected_date": None,
|
|
"expected_time_segment": None,
|
|
"expected_arrival_at": None,
|
|
"admin_note": None,
|
|
"rework_reason": None,
|
|
},
|
|
{
|
|
"order_no": "DR20260601002",
|
|
"category": "电路照明 / 照明故障",
|
|
"raw_description": "宿舍顶灯一直闪烁,还有轻微焦味。",
|
|
"structured_summary": "电路照明,建议电工处理。顶灯闪烁有焦味;门口位置;影响整间照明;有轻微焦糊味。",
|
|
"urgency": "紧急",
|
|
"status": "待处理",
|
|
"allow_room_entry": 0,
|
|
"assignee_name": "王师傅",
|
|
"expected_date": "2026-06-02",
|
|
"expected_time_segment": "09:00-11:00",
|
|
"expected_arrival_at": "明天上午",
|
|
"admin_note": "已派电工王师傅,请提前清理顶灯下方区域。",
|
|
"rework_reason": None,
|
|
},
|
|
{
|
|
"order_no": "DR20260601003",
|
|
"category": "空调设备 / 制冷制热异常",
|
|
"raw_description": "空调开到16度还是不制冷,出风口感觉是自然风。",
|
|
"structured_summary": (
|
|
"空调设备,建议空调维修处理。空调16度不制冷;出风口常温风;已持续两天影响休息。"
|
|
),
|
|
"urgency": "高",
|
|
"status": "处理中",
|
|
"allow_room_entry": 1,
|
|
"assignee_name": "赵师傅",
|
|
"expected_date": "2026-06-02",
|
|
"expected_time_segment": "14:00-16:00",
|
|
"expected_arrival_at": "今天下午",
|
|
"admin_note": "已安排空调维修赵师傅上门检测,可能与制冷剂泄漏有关。",
|
|
"rework_reason": None,
|
|
},
|
|
{
|
|
"order_no": "DR20260601004",
|
|
"category": "门窗锁具 / 门锁钥匙",
|
|
"raw_description": "宿舍门锁很难拧开,偶尔会卡住。",
|
|
"structured_summary": (
|
|
"门窗锁具,建议门窗处理。门锁难拧开偶尔卡住;门口锁芯位置;影响进出;锁芯磨损严重。"
|
|
),
|
|
"urgency": "中",
|
|
"status": "待上门",
|
|
"allow_room_entry": 0,
|
|
"assignee_name": "李师傅",
|
|
"expected_date": "2026-06-03",
|
|
"expected_time_segment": "14:00-16:00",
|
|
"expected_arrival_at": "6月3日下午",
|
|
"admin_note": "已安排门窗维修李师傅上门更换锁芯,请当天留人在宿舍。",
|
|
"rework_reason": None,
|
|
},
|
|
{
|
|
"order_no": "DR20260528001",
|
|
"category": "网络弱电 / 网口异常",
|
|
"raw_description": "宿舍网口插上网线没反应,灯不亮。",
|
|
"structured_summary": "网络弱电,建议弱电维修处理。网口插网线无反应灯不亮;书桌下方;影响上网学习。",
|
|
"urgency": "中",
|
|
"status": "返工申请中",
|
|
"allow_room_entry": 1,
|
|
"assignee_name": "孙师傅",
|
|
"expected_date": None,
|
|
"expected_time_segment": None,
|
|
"expected_arrival_at": None,
|
|
"admin_note": "孙师傅已上门维修并更换网口面板,但学生反映问题仍存在,已进入返工流程。",
|
|
"rework_reason": "维修后网口仍无法使用,指示灯依然不亮,请重新排查线路问题。",
|
|
},
|
|
{
|
|
"order_no": "DR20260525003",
|
|
"category": "门窗锁具 / 窗户五金",
|
|
"raw_description": "宿舍窗户关不严,冬天漏风严重。",
|
|
"structured_summary": "门窗锁具,建议门窗处理。窗户关不严有缝隙;推拉窗轨道变形;冬天漏风影响室温。",
|
|
"urgency": "中",
|
|
"status": "已完成",
|
|
"allow_room_entry": 1,
|
|
"assignee_name": "李师傅",
|
|
"expected_date": "2026-05-24",
|
|
"expected_time_segment": "09:00-11:00",
|
|
"expected_arrival_at": "5月24日上午",
|
|
"admin_note": "已更换窗户密封条并调整轨道,请学生确认。",
|
|
"rework_reason": None,
|
|
},
|
|
{
|
|
"order_no": "DR20260520001",
|
|
"category": "家具设施 / 桌椅维修",
|
|
"raw_description": "书桌抽屉轨道坏了,拉出来会掉。",
|
|
"structured_summary": "家具设施,建议木工维修处理。抽屉轨道损坏拉出脱落;右侧抽屉;影响日常存放。",
|
|
"urgency": "低",
|
|
"status": "已确认",
|
|
"allow_room_entry": 0,
|
|
"assignee_name": "刘师傅",
|
|
"expected_date": "2026-05-20",
|
|
"expected_time_segment": "14:00-16:00",
|
|
"expected_arrival_at": "5月20日下午",
|
|
"admin_note": "已更换抽屉轨道,学生已确认维修结果。",
|
|
"rework_reason": None,
|
|
},
|
|
{
|
|
"order_no": "DR20260515001",
|
|
"category": "给排水 / 下水疏通类",
|
|
"raw_description": "洗手池下水很慢,水会积在池子里。",
|
|
"structured_summary": "给排水,建议管道疏通处理。洗手池下水缓慢积水;卫生间洗手池;影响日常洗漱。",
|
|
"urgency": "中",
|
|
"status": "已取消",
|
|
"allow_room_entry": 0,
|
|
"assignee_name": None,
|
|
"expected_date": None,
|
|
"expected_time_segment": None,
|
|
"expected_arrival_at": None,
|
|
"admin_note": None,
|
|
"rework_reason": None,
|
|
},
|
|
]
|
|
|
|
for o in orders:
|
|
cur = conn.execute(
|
|
"INSERT INTO repair_orders ("
|
|
"order_no, student_id, campus, building, room, category, "
|
|
"raw_description, structured_summary, urgency, status, "
|
|
"allow_room_entry, assignee_name, expected_date, "
|
|
"expected_time_segment, expected_arrival_at, admin_note, "
|
|
"rework_reason, diagnosis_session_id, created_at, updated_at"
|
|
") VALUES ("
|
|
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
|
|
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
|
|
")",
|
|
(
|
|
o["order_no"],
|
|
student["id"],
|
|
"西海岸校区",
|
|
"听海苑999号楼",
|
|
"404",
|
|
o["category"],
|
|
o["raw_description"],
|
|
o["structured_summary"],
|
|
o["urgency"],
|
|
o["status"],
|
|
o["allow_room_entry"],
|
|
o["assignee_name"],
|
|
o["expected_date"],
|
|
o["expected_time_segment"],
|
|
o["expected_arrival_at"],
|
|
o["admin_note"],
|
|
o["rework_reason"],
|
|
None,
|
|
_now,
|
|
_now,
|
|
),
|
|
)
|
|
oid = cur.lastrowid
|
|
|
|
create_event(
|
|
conn,
|
|
oid,
|
|
"student",
|
|
"张同学",
|
|
"created",
|
|
"学生提交报修",
|
|
o["raw_description"],
|
|
None,
|
|
"已提交",
|
|
)
|
|
|
|
if o["status"] != "已提交":
|
|
create_event(
|
|
conn,
|
|
oid,
|
|
"admin",
|
|
"宿管老师",
|
|
"status_updated",
|
|
"管理员更新工单状态",
|
|
o["admin_note"],
|
|
"已提交",
|
|
o["status"],
|
|
)
|
|
if o["status"] == "待上门":
|
|
expected_info = f"预计 {o['expected_date'] or ''} {o['expected_time_segment'] or ''}"
|
|
create_event(
|
|
conn,
|
|
oid,
|
|
"admin",
|
|
"宿管老师",
|
|
"scheduled",
|
|
"管理员安排上门时间",
|
|
expected_info,
|
|
o["status"],
|
|
o["status"],
|
|
)
|
|
if o["status"] == "返工申请中":
|
|
create_event(
|
|
conn,
|
|
oid,
|
|
"student",
|
|
"张同学",
|
|
"rework_requested",
|
|
"学生申请返工",
|
|
o["rework_reason"],
|
|
"已完成",
|
|
o["status"],
|
|
)
|
|
if o["status"] == "已确认":
|
|
create_event(
|
|
conn,
|
|
oid,
|
|
"student",
|
|
"张同学",
|
|
"confirmed",
|
|
"学生确认维修完成",
|
|
"维修结果满意,确认工单完成。",
|
|
"已完成",
|
|
o["status"],
|
|
)
|
|
if o["status"] == "已取消":
|
|
create_event(
|
|
conn,
|
|
oid,
|
|
"student",
|
|
"张同学",
|
|
"cancelled",
|
|
"学生取消工单",
|
|
"问题已自行解决,取消报修。",
|
|
o["status"],
|
|
o["status"],
|
|
)
|
|
if o["status"] in ("已完成", "已确认"):
|
|
conn.execute(
|
|
"INSERT INTO feedback (order_id, rating, comment, created_at) VALUES (?, ?, ?, ?)",
|
|
(oid, 5, "维修很快,问题已经解决。", _now),
|
|
)
|
|
|
|
conn.commit()
|
|
print("Seed complete.")
|
|
|
|
finally:
|
|
conn.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument("--db", type=str, default=str(BACKEND_DIR / "data" / "dorm_repair.sqlite3"))
|
|
p.add_argument("--force", action="store_true")
|
|
args = p.parse_args()
|
|
run(args.db, args.force)
|