This commit is contained in:
zlwu committed 2026-06-14 09:14:11 +08:00
1 parent 5ad07c8cac
commit a79aee2614
61 files changed
+9220 -9348

No files matched your search

+272
View File
@@ -0,0 +1,272 @@
#!/usr/bin/env python3
"""批量初始化洁净室及子表测试数据(biz_clean_room + access_log + uv_disinfect_log),已存在编码则跳过。"""
from __future__ import annotations
import sys
from datetime import datetime
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from app.core.database import SessionLocal
from app.crud import clean_room as clean_room_svc
ADMIN_ID = "d3000000000000000000000000000001"
TEST_USER_ID = "b13c2be24e7111f19f4700163e3bdd9601"
# (room_code, room_name, room_grade, room_status, area_sqm, order_num, remark)
CLEAN_ROOMS = [
("CR-A01", "细胞制备A级洁净室", "A", "zc", 45.50, 1, "主制备区,日常细胞培养"),
("CR-B01", "样本接收B级洁净室", "B", "zc", 32.00, 2, "样本接收与初检"),
("CR-B02", "质检B级洁净室", "B", "zc", 28.80, 3, "质检与留样"),
("CR-C01", "物料暂存C级洁净室", "C", "zc", 18.60, 4, "物料暂存与缓冲"),
("CR-D01", "更衣D级洁净室", "D", "yc", 12.00, 5, "压差异常,待检修"),
]
# room_code -> list of access log dicts
ACCESS_LOGS = {
"CR-A01": [
{
"user_id": ADMIN_ID,
"person_name": "管理员",
"dept_name": "综合部",
"enter_time": datetime(2026, 6, 10, 8, 15),
"purpose": "日常巡检",
"leave_time": datetime(2026, 6, 10, 8, 45),
"body_temp": "36.5",
},
{
"user_id": TEST_USER_ID,
"person_name": "中科兴皖测试1",
"dept_name": "技术研发部",
"enter_time": datetime(2026, 6, 10, 9, 0),
"purpose": "细胞培养操作",
"leave_time": datetime(2026, 6, 10, 12, 30),
"body_temp": "36.4",
},
],
"CR-B01": [
{
"user_id": TEST_USER_ID,
"person_name": "中科兴皖测试1",
"dept_name": "生产部",
"enter_time": datetime(2026, 6, 11, 7, 50),
"purpose": "样本接收登记",
"leave_time": datetime(2026, 6, 11, 8, 40),
"body_temp": "36.6",
},
{
"person_name": "张质检",
"dept_name": "质量安全部",
"enter_time": datetime(2026, 6, 11, 14, 0),
"purpose": "样本初检",
"leave_time": datetime(2026, 6, 11, 15, 20),
"body_temp": "36.3",
"remark": "外部访客",
},
],
"CR-B02": [
{
"user_id": ADMIN_ID,
"person_name": "管理员",
"dept_name": "质量安全部",
"enter_time": datetime(2026, 6, 12, 10, 0),
"purpose": "留样复核",
"leave_time": datetime(2026, 6, 12, 11, 0),
"body_temp": "36.5",
},
],
"CR-C01": [
{
"person_name": "李物料",
"dept_name": "生产部",
"enter_time": datetime(2026, 6, 12, 15, 30),
"purpose": "物料入库",
"leave_time": datetime(2026, 6, 12, 16, 0),
"body_temp": "36.7",
},
],
"CR-D01": [
{
"user_id": ADMIN_ID,
"person_name": "管理员",
"dept_name": "综合部",
"enter_time": datetime(2026, 6, 10, 16, 0),
"purpose": "压差异常排查",
"leave_time": None,
"body_temp": "36.5",
"remark": "尚未离开",
},
],
}
# room_code -> list of uv disinfect log dicts
UV_LOGS = {
"CR-A01": [
{
"user_id": ADMIN_ID,
"operator_name": "管理员",
"start_time": datetime(2026, 6, 9, 18, 0),
"end_time": datetime(2026, 6, 9, 19, 0),
"remark": "班后消毒",
},
{
"user_id": ADMIN_ID,
"operator_name": "管理员",
"start_time": datetime(2026, 6, 10, 18, 0),
"end_time": datetime(2026, 6, 10, 19, 0),
"remark": "班后消毒",
},
],
"CR-B01": [
{
"user_id": ADMIN_ID,
"operator_name": "管理员",
"start_time": datetime(2026, 6, 10, 17, 30),
"end_time": datetime(2026, 6, 10, 18, 30),
},
],
"CR-B02": [
{
"user_id": ADMIN_ID,
"operator_name": "管理员",
"start_time": datetime(2026, 6, 11, 18, 0),
"end_time": datetime(2026, 6, 11, 19, 0),
},
],
"CR-C01": [
{
"user_id": ADMIN_ID,
"operator_name": "管理员",
"start_time": datetime(2026, 6, 11, 17, 0),
"end_time": datetime(2026, 6, 11, 17, 45),
"remark": "C级区缩短时长",
},
],
"CR-D01": [
{
"user_id": ADMIN_ID,
"operator_name": "管理员",
"start_time": datetime(2026, 6, 10, 14, 30),
"end_time": None,
"remark": "异常区暂停消毒",
},
],
}
def _room_exists(db, code: str, tenant_no: str) -> bool:
return clean_room_svc.room_code_exists(db, code, tenant_no)
def _access_log_exists(db, room_id: str, enter_time: datetime, tenant_no: str) -> bool:
rows, _ = clean_room_svc.list_access_logs(
db, page=1, page_size=100, clean_room_id=room_id, tenant_no=tenant_no
)
ts = enter_time.strftime("%Y-%m-%d %H:%M:%S")
return any(r.get("enterTime") == ts for r in rows)
def _uv_log_exists(db, room_id: str, start_time: datetime, tenant_no: str) -> bool:
rows, _ = clean_room_svc.list_uv_disinfect_logs(
db, page=1, page_size=100, clean_room_id=room_id, tenant_no=tenant_no
)
ts = start_time.strftime("%Y-%m-%d %H:%M:%S")
return any(r.get("startTime") == ts for r in rows)
def seed(tenant_no: str = "zkxw", user_id: str = ADMIN_ID) -> None:
db = SessionLocal()
rooms_created = 0
rooms_skipped = 0
access_created = 0
access_skipped = 0
uv_created = 0
uv_skipped = 0
try:
room_ids: dict[str, str] = {}
for code, name, grade, status, area, order_num, remark in CLEAN_ROOMS:
if _room_exists(db, code, tenant_no):
rooms_skipped += 1
existing = clean_room_svc.list_clean_rooms(db, page=1, page_size=1, keyword=code, tenant_no=tenant_no)
if existing[0]:
room_ids[code] = existing[0][0]["id"]
continue
obj = clean_room_svc.create_clean_room(
db,
room_code=code,
room_name=name,
room_grade=grade,
room_status=status,
area_sqm=area,
tenant_no=tenant_no,
order_num=order_num,
remark=remark,
user_id=user_id,
)
room_ids[code] = obj.id
rooms_created += 1
for code, logs in ACCESS_LOGS.items():
room_id = room_ids.get(code)
if not room_id:
continue
for idx, log in enumerate(logs, start=1):
enter_time = log["enter_time"]
if _access_log_exists(db, room_id, enter_time, tenant_no):
access_skipped += 1
continue
clean_room_svc.create_access_log(
db,
clean_room_id=room_id,
user_id=log.get("user_id"),
person_name=log.get("person_name"),
dept_name=log.get("dept_name"),
enter_time=enter_time,
purpose=log.get("purpose"),
leave_time=log.get("leave_time"),
body_temp=log.get("body_temp"),
tenant_no=tenant_no,
order_num=idx,
remark=log.get("remark"),
user_id_param=user_id,
)
access_created += 1
for code, logs in UV_LOGS.items():
room_id = room_ids.get(code)
if not room_id:
continue
for idx, log in enumerate(logs, start=1):
start_time = log["start_time"]
if _uv_log_exists(db, room_id, start_time, tenant_no):
uv_skipped += 1
continue
clean_room_svc.create_uv_disinfect_log(
db,
clean_room_id=room_id,
user_id=log.get("user_id"),
operator_name=log.get("operator_name"),
start_time=start_time,
end_time=log.get("end_time"),
tenant_no=tenant_no,
order_num=idx,
remark=log.get("remark"),
user_id_param=user_id,
)
uv_created += 1
print(
f"洁净室测试数据初始化完成:"
f"洁净室 新增 {rooms_created} / 跳过 {rooms_skipped};"
f"进出记录 新增 {access_created} / 跳过 {access_skipped};"
f"消毒记录 新增 {uv_created} / 跳过 {uv_skipped}。"
)
finally:
db.close()
if __name__ == "__main__":
seed()
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env python3
"""批量初始化常用快递公司(biz_express_company),已存在编码则跳过。"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from app.core.database import SessionLocal
from app.crud import express_company as express_company_svc
# (express_code, express_name, order_num, remark)
EXPRESS_COMPANIES = [
("SF", "顺丰速运", 1, "常用快递"),
("YTO", "圆通速递", 2, "常用快递"),
("ZTO", "中通快递", 3, "常用快递"),
("STO", "申通快递", 4, "常用快递"),
("YD", "韵达速递", 5, "常用快递"),
("JD", "京东物流", 6, "常用快递"),
("EMS", "中国邮政EMS", 7, "常用快递"),
("HTKY", "百世快递", 8, "常用快递"),
("JTSD", "极兔速递", 9, "常用快递"),
("DBL", "德邦快递", 10, "常用快递"),
]
def seed(tenant_no: str = "zkxw", user_id: str = "d3000000000000000000000000000001") -> None:
db = SessionLocal()
created = 0
skipped = 0
try:
for code, name, order_num, remark in EXPRESS_COMPANIES:
if express_company_svc.express_code_exists(db, code, tenant_no):
skipped += 1
continue
express_company_svc.create_express_company(
db,
express_code=code,
express_name=name,
tenant_no=tenant_no,
order_num=order_num,
remark=remark,
user_id=user_id,
)
created += 1
print(f"快递公司初始化完成:新增 {created} 条,跳过 {skipped} 条(编码已存在)。")
finally:
db.close()
if __name__ == "__main__":
seed()
+232
View File
@@ -0,0 +1,232 @@
#!/usr/bin/env python3
"""批量初始化物品单位(biz_item_unit),已存在编码则跳过。"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from app.core.database import SessionLocal
from app.crud import item_unit as item_unit_svc
# (unit_code, unit_name, order_num, remark)
ITEM_UNITS = [
# —— 计数 / 件数 ——
("ge", "个", 1, "计数"),
("jian", "件", 2, "计数"),
("tao", "套", 3, "计数"),
("tai", "台", 4, "计数"),
("liang_che", "辆", 5, "计数"),
("jia", "架", 6, "计数"),
("bu", "部", 7, "计数"),
("zhi", "支", 8, "计数"),
("tiao", "条", 9, "计数"),
("gen", "根", 10, "计数"),
("zhang", "张", 11, "计数"),
("pian", "片", 12, "计数"),
("kuai", "块", 13, "计数"),
("ke", "颗", 14, "计数"),
("li", "粒", 15, "计数"),
("mei", "枚", 16, "计数"),
("zhi_zhi", "只", 17, "计数"),
("tou", "头", 18, "计数"),
("wei_tail", "尾", 19, "计数"),
("pi", "匹", 20, "计数"),
("shuang", "双", 21, "计数"),
("dui", "对", 22, "计数"),
("fu", "副", 23, "计数"),
("zu", "组", 24, "计数"),
("pi_pi", "批", 25, "计数"),
("fen", "份", 26, "计数"),
("ci", "次", 27, "计数"),
("hui", "回", 28, "计数"),
("lun", "轮", 29, "计数"),
("ba", "把", 30, "计数"),
("kun", "捆", 31, "计数"),
("chuan", "串", 32, "计数"),
("shu", "束", 33, "计数"),
("pai", "排", 34, "计数"),
("kong", "孔", 35, "计数"),
("zhu", "株", 36, "计数"),
("ke_shu", "棵", 37, "计数"),
("cong", "丛", 38, "计数"),
("duo", "朵", 39, "计数"),
("ban_petal", "瓣", 40, "计数"),
("ren", "人", 41, "计数"),
("wei_pos", "位", 42, "计数"),
("hu_hu", "户", 43, "计数"),
("jia_hu", "家", 44, "计数"),
("kou", "口", 45, "计数"),
("dun", "顿", 46, "计数"),
("xiang_mu", "项", 47, "计数"),
("ben", "本", 48, "计数"),
("ce", "册", 49, "计数"),
("zhang_page", "页", 50, "计数"),
# —— 质量 ——
("ug", "微克", 100, "质量"),
("mg", "毫克", 101, "质量"),
("g", "克", 102, "质量"),
("kg", "千克", 103, "质量"),
("t", "吨", 104, "质量"),
("jin", "斤", 105, "质量"),
("liang_w", "两", 106, "质量"),
("lb", "磅", 107, "质量"),
("oz", "盎司", 108, "质量"),
("dan", "担", 109, "质量"),
("gongjin", "公斤", 110, "质量"),
# —— 体积 ——
("ul", "微升", 200, "体积"),
("ml", "毫升", 201, "体积"),
("l", "升", 202, "体积"),
("dl", "分升", 203, "体积"),
("cl", "厘升", 204, "体积"),
("m3", "立方米", 205, "体积"),
("dm3", "立方分米", 206, "体积"),
("cm3", "立方厘米", 207, "体积"),
("mm3", "立方毫米", 208, "体积"),
("gal", "加仑", 209, "体积"),
# —— 长度 / 面积 ——
("mm", "毫米", 300, "长度"),
("cm", "厘米", 301, "长度"),
("dm", "分米", 302, "长度"),
("m", "米", 303, "长度"),
("km", "千米", 304, "长度"),
("inch", "英寸", 305, "长度"),
("ft", "英尺", 306, "长度"),
("chi", "尺", 307, "长度"),
("cun", "寸", 308, "长度"),
("mm2", "平方毫米", 320, "面积"),
("cm2", "平方厘米", 321, "面积"),
("m2", "平方米", 322, "面积"),
("km2", "平方千米", 323, "面积"),
("mu_area", "亩", 324, "面积"),
("ha", "公顷", 325, "面积"),
# —— 包装 ——
("he", "盒", 400, "包装"),
("xiang", "箱", 401, "包装"),
("dai", "袋", 402, "包装"),
("bao", "包", 403, "包装"),
("ping", "瓶", 404, "包装"),
("guan", "罐", 405, "包装"),
("tong", "桶", 406, "包装"),
("tong_tube", "筒", 407, "包装"),
("juan", "卷", 408, "包装"),
("ban_board", "板", 409, "包装"),
("tuo", "托", 410, "包装"),
("pan", "盘", 411, "包装"),
("kuang", "筐", 412, "包装"),
("lan", "篮", 413, "包装"),
("lou", "篓", 414, "包装"),
("long", "笼", 415, "包装"),
("bei", "杯", 416, "包装"),
("wan", "碗", 417, "包装"),
("hu_pot", "壶", 418, "包装"),
("pen", "盆", 419, "包装"),
("guan_tube", "管", 420, "包装"),
("nang", "囊", 421, "包装"),
("tie", "贴", 422, "包装"),
("za", "扎", 423, "包装"),
("ceng", "层", 424, "包装"),
("ge_pack", "格", 425, "包装"),
("xi_tou", "吸头", 426, "包装"),
("qiang_tou", "枪头", 427, "包装"),
("kong_ban", "孔板", 428, "包装"),
("yang_ben_guan", "样本管", 429, "包装"),
("dong_cun_guan", "冻存管", 430, "包装"),
("pei_yang_ping", "培养瓶", 431, "包装"),
("pei_yang_min", "培养皿", 432, "包装"),
("liu_guan", "六孔板", 433, "包装"),
("shi_er_guan", "十二孔板", 434, "包装"),
("ershi_si_guan", "二十四孔板", 435, "包装"),
("jiu_shi_liu_guan", "九十六孔板", 436, "包装"),
("san_bai_ba_shi_guan", "三百八十四孔板", 437, "包装"),
# —— 实验室 / 生物 ——
("u", "单位", 500, "实验室"),
("iu", "IU", 501, "实验室"),
("ku", "KU", 502, "实验室"),
("mu_act", "MU", 503, "实验室"),
("cells_ml", "cells/mL", 504, "实验室"),
("cells_ul", "cells/μL", 505, "实验室"),
("cfu", "CFU", 506, "实验室"),
("cfu_ml", "CFU/mL", 507, "实验室"),
("pfu", "PFU", 508, "实验室"),
("pfu_ml", "PFU/mL", 509, "实验室"),
("od", "OD", 510, "实验室"),
("copies_ml", "copies/mL", 511, "实验室"),
("copies_ul", "copies/μL", 512, "实验室"),
("mol", "摩尔", 513, "实验室"),
("mmol", "毫摩尔", 514, "实验室"),
("umol", "微摩尔", 515, "实验室"),
("nmol", "纳摩尔", 516, "实验室"),
("mol_l", "mol/L", 517, "实验室"),
("mmol_l", "mmol/L", 518, "实验室"),
("umol_l", "μmol/L", 519, "实验室"),
("nmol_l", "nmol/L", 520, "实验室"),
("m_l", "M", 521, "实验室"),
("percent", "%", 522, "实验室"),
("ppm", "ppm", 523, "实验室"),
("ppb", "ppb", 524, "实验室"),
("mg_ml", "mg/mL", 525, "实验室"),
("ug_ml", "μg/mL", 526, "实验室"),
("ng_ml", "ng/mL", 527, "实验室"),
("pg_ml", "pg/mL", 528, "实验室"),
("mg_l", "mg/L", 529, "实验室"),
("ug_l", "μg/L", 530, "实验室"),
("ng_l", "ng/L", 531, "实验室"),
("iu_ml", "IU/mL", 532, "实验室"),
("u_ml", "U/mL", 533, "实验室"),
("x_be", "×", 534, "实验室"),
("ren_fen", "人份", 535, "实验室"),
("yang_ben", "样本", 536, "实验室"),
("ji_yin", "基因", 537, "实验室"),
("tiao_dai", "条带", 538, "实验室"),
("kuai_jiao", "块胶", 539, "实验室"),
# —— 时间 ——
("s", "秒", 600, "时间"),
("min", "分钟", 601, "时间"),
("h", "小时", 602, "时间"),
("d", "天", 603, "时间"),
("week", "周", 604, "时间"),
("month", "月", 605, "时间"),
("year", "年", 606, "时间"),
("ji", "季", 607, "时间"),
# —— 其他 ——
("yuan", "元", 700, "其他"),
("kwh", "千瓦时", 701, "其他"),
("du", "度", 702, "其他"),
("zhi_plant", "枝", 703, "其他"),
("dai_pack", "袋装", 704, "其他"),
("xiang_pack", "箱装", 705, "其他"),
("he_pack", "盒装", 706, "其他"),
]
def seed(tenant_no: str = "zkxw", user_id: str = "d3000000000000000000000000000001") -> None:
db = SessionLocal()
created = 0
skipped = 0
try:
for code, name, order_num, remark in ITEM_UNITS:
if item_unit_svc.unit_code_exists(db, code, tenant_no):
skipped += 1
continue
item_unit_svc.create_item_unit(
db,
unit_code=code,
unit_name=name,
tenant_no=tenant_no,
order_num=order_num,
remark=remark,
user_id=user_id,
)
created += 1
print(f"物品单位初始化完成:新增 {created} 条,跳过 {skipped} 条(编码已存在)。")
finally:
db.close()
if __name__ == "__main__":
seed()