You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

782 lines
30 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- coding: utf-8 -*-
# @Time : 2023/8/8 14:49
# @Author : tx
# @File : drug.py
# @Description :
import base64
import datetime
import os
import uuid
from decimal import Decimal
from typing import List
import json
from fastapi import Request, APIRouter, Depends, UploadFile, File
from fastapi.encoders import jsonable_encoder
from starlette.responses import FileResponse
from tortoise.expressions import Q
from tortoise.functions import Function
from pypika import CustomFunction
from helper import respond_to, login_required
from helper.GaoPaiYi import GaoPaiYi
from helper.drug import open_update_expired_at, simple_drugs_except_info, drugs_list_info, milligram_to_gram
from helper.log import logger_wrapper
from helper.logger import logger
from models import Drug, Dictionary, DrugStateEnum, Template, Terminal, DrugUseStateEnum, DrugUseLog, User
from pydantic import BaseModel
from models.archive import Archive
from models.cabinet import Cabinet
from models.drawers import Drawer
from models.drug_relation_image import DrugRelationImage
from models.log import EnvironmentLogs
from transfer.standard import Standard
from transfer.basic import BasicStandard
router = APIRouter(prefix='/drug', dependencies=[Depends(login_required)])
# router = APIRouter(prefix='/drug')
class DrugRfids(BaseModel):
rfids: list
class ReturnForm(BaseModel):
# barcode: str
weight: Decimal = 0.0 # 余量
use_weight: Decimal = 0.0 # 用量
drawer_id: str = '' # 层id
cabinet_id: str = '' # 柜体id
is_empty: int = 0 # 1空瓶 0非空瓶
class EmptyBottleDisposal(BaseModel):
rfid: str
weight: int | None
open_date: str | None
class DrugUpdateRequest(BaseModel):
open_date: str = "" # 开封日期
weight: Decimal = 0.0 # 余量
use_weight: str | Decimal = 0.0 # 用量
rfid: str = ""
id: str = ""
class DrugDeleteRequest(BaseModel):
drug_ids: list
class ImageDeleteRequest(BaseModel):
image_ids: list
class ImageUploadRequest(BaseModel):
upload_list: list = []
class DrugUpdateExpired(BaseModel):
expired_at: str
rfid: str = ""
id: str = ""
class UpdateDrugRequest(BaseModel):
cabinet_id: str
receive_id: str | None # 移库人
class JsonExtract(Function):
database_func=CustomFunction('JSON_EXTRACT', ['field', 'value'])
@router.get('/take_out', summary='药剂领用列表查询')
async def index(request: Request, cabinet_id: str = '', drug_name: str = '', page_no: int = 1, page_size: int = 20):
"""
药剂领用列表查询
:return:
"""
query = Drug.filter(state=DrugStateEnum.IN, template__archive_id=request.state.archive_id).order_by('-created_at')
if cabinet_id:
query = query.filter(cabinet_id=cabinet_id)
print(f'drug_name: {drug_name}')
if drug_name:
query = query.filter(Q(dictionary__k1__contains=drug_name) | Q(dictionary__k2__contains=drug_name))
total_count = await query.count()
offset = (page_no - 1) * page_size
drugs = await query.offset(offset).limit(page_size).all()
archive_id = request.state.archive_id
archive_obj = await Archive.get_or_none(id=archive_id)
archive_name = archive_obj.name if archive_obj else ""
result = list()
for drug_obj in drugs:
data = {
"drug_id": drug_obj.id,
"rfid": drug_obj.rfid,
"hole": drug_obj.hole,
"cabinet_id": drug_obj.cabinet_id,
"drawer_id": drug_obj.drawer_id,
"board_id": drug_obj.board_id,
"position": drug_obj.position,
"expired_at": drug_obj.expired_at,
"remain_gross_weight": await drug_obj.format_weight(),
"display_weight": await drug_obj.format_weight(),
"drug_info": drug_obj.fill_json_content,
"state": drug_obj.state,
"open_date": drug_obj.open_date
}
if archive_name == "耗材":
data.update({
"remain_count": int(drug_obj.attribute("total_count")) - drug_obj.total_use_weight if drug_obj.attribute("total_count") else "-"
})
result.append(data)
return respond_to(code=200, data=dict(count=total_count, list=result))
@router.post('/except', summary='RFID药剂异常信息')
async def index(request: DrugRfids):
"""
获取RFID药剂异常信息
:return:
"""
result = list()
drugs = await Drug.filter(rfid__in=request.rfids).all()
for drug in drugs:
data = await simple_drugs_except_info(drug)
data["rfid"] = drug.rfid
result.append(data)
# 传入rfid与data所有rfid比较差集就是非法标签
post_rfid = set(request.rfids)
effective_rfid = set([i["rfid"] for i in result])
diff_rfid = post_rfid - effective_rfid
if diff_rfid:
result.extend([{
"rfid": rfid,
"is_rfid_except": True,
"sound": True,
"message": "非法标签",
"state": 0,
} for rfid in diff_rfid])
return respond_to(code=200, desc="获取RFID药剂信息成功", data=result)
@router.post('', summary='RFID药剂详情')
async def index(request: Request, body: DrugRfids):
"""
获取RFID药剂信息 药剂信息详情
:return:
"""
drugs = list()
for rfid in body.rfids:
# rfid = bytes.hex(bytes.fromhex(rfid)[::-1]) if len(rfid) > 10 else rfid
drug_obj = await Drug.filter(Q(rfid=rfid) | Q(barcode=rfid)).prefetch_related('template__archive').prefetch_related('cabinet__terminal').first()
template_archive_obj = await Template.filter(id=drug_obj.template_id).prefetch_related('archive').first() if drug_obj and drug_obj.template_id else None
print(("drug_obj====", drug_obj))
print(("template_archive_obj====", template_archive_obj))
if drug_obj is None or template_archive_obj is None or str(template_archive_obj.archive_id) != str(request.state.archive_id):
drugs.append({
"drugs_except_info": {
"sound": False,
"message": "非法标签",
"state": 0,
},
"rfid_drug": {rfid: f"[{rfid}]未知药剂"}
})
continue
result = jsonable_encoder(drug_obj)
data = await simple_drugs_except_info(drug_obj)
drug_info = await drug_obj.attribute_drug_info()
parse_fill_json_content = await drug_obj.parse_fill_json_content()
parse_fill_json_content.update({f'余重': f'{milligram_to_gram(drug_obj.remain_gross_weight)}'})
return_require_weigh = template_archive_obj.archive.params.get("return_require_weigh", '')
user_obj = await User.get_or_none(id=drug_obj.last_receive_id).values("id", "name") if drug_obj.last_receive_id else ''
result.update({
"drugs_except_info": data,
"fill_json_content": parse_fill_json_content,
"rfid_drug": {drug_obj.rfid: f"[{drug_obj.rfid}]" + ",".join(list(map(lambda x:str(x), drug_info.values())))},
"return_require_weigh": return_require_weigh,
"last_user": user_obj.get("name") if user_obj else '',
"cabinet_label": drug_obj.cabinet.label if drug_obj.cabinet else "",
"cabinet_location": drug_obj.cabinet.location if drug_obj.cabinet else "",
"terminal": drug_obj.cabinet.terminal.name if drug_obj.cabinet and drug_obj.cabinet.terminal else None,
"position": drug_obj.position,
"unit_code": drug_obj.attribute("unit_code", ""),
"total_count": drug_obj.attribute("total_count"),
"total_use_weight": drug_obj.total_use_weight,
})
drugs.append(result)
return respond_to(code=200, desc="获取RFID药剂信息成功", data=drugs)
@router.put('/receive/{code}', summary='药剂领用')
async def update(request: Request, code: str, use_count: int = -1):
"""
药剂领用
耗材领用 输入使用数量余量为0则空 总量为fill_json_content中import_count,总用量存储在total_use_weight中
:return:
"""
# code = bytes.hex(bytes.fromhex(code)[::-1]) if len(code) > 10 else code
drug_obj = await Drug.filter(Q(rfid=code) | Q(barcode=code)).prefetch_related("cabinet", "template__archive").first()
if drug_obj is None:
return respond_to(code=404, desc='非法标签')
template_name = drug_obj.template.name
if not drug_obj:
return respond_to(code=404, desc='条码不存在')
if drug_obj.state == DrugStateEnum.OUT:
return respond_to(code=403, desc='条码不在库')
if drug_obj.state == DrugStateEnum.EMPTY:
return respond_to(code=403, desc='条码已空瓶')
if str(drug_obj.template.archive_id) != str(request.state.archive_id):
return respond_to(code=403, desc='条码不在当前大类')
current_user = request.state.current_user
users = request.state.users
if template_name == "耗材":
total_use_count = drug_obj.total_use_weight if drug_obj.total_use_weight else 0
if use_count > -1 and (total_use_count + use_count >= int(drug_obj.attribute("total_count"))):
print("用完", total_use_count, use_count)
drug_obj.state = DrugStateEnum.EMPTY
drug_obj.total_use_weight = drug_obj.attribute("total_count")
elif use_count > -1:
drug_obj.total_use_weight = total_use_count + use_count
else:
drug_obj.state = DrugStateEnum.OUT
drug_obj.last_receive_at = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
drug_obj.last_receive_id = current_user.id
await drug_obj.save()
# 流转日志保存
drug_use_dict = {
"drug": drug_obj,
"state": DrugUseStateEnum.TAKE,
"user_id": current_user.id,
"peer_ids": ",".join(users[1:]), # 陪同人id
"users": await User.parse_id_user(users),
"terminal_id": drug_obj.cabinet.terminal_id, # 终端id
"cabinet_id": drug_obj.cabinet.id if drug_obj.cabinet else None,
"drawer_id": drug_obj.drawer_id if drug_obj.drawer else None,
"drawer_board_id": drug_obj.drawer_board_id if drug_obj.drawer_board else None,
"hole": drug_obj.hole,
"position": drug_obj.position,
"alerted": False, # 是否报警 领用称重
"weight": drug_obj.remain_gross_weight,
}
if template_name == "耗材" and use_count > -1:
drug_use_dict.update({
"use_weight": use_count
})
drug_update_dict = {}
# 首次领用即空瓶逻辑
first_will_empty = await drug_obj.parse_archive_params("first_will_empty")
if first_will_empty:
drug_use_dict.update({
"state": DrugUseStateEnum.EMPTY,
"weight": 0,
"use_weight": drug_obj.remain_gross_weight,
})
# 领用即空瓶 药剂状态更改
drug_update_dict.update({
"state": DrugStateEnum.EMPTY,
"remain_gross_weight": 0,
})
await drug_obj.update_from_dict(drug_update_dict)
await drug_obj.save()
await DrugUseLog().create(**drug_use_dict)
# 药剂数据封装返回前端
result = jsonable_encoder(drug_obj)
drug_info = await drug_obj.attribute_drug_info()
parse_fill_json_content = await drug_obj.parse_fill_json_content()
result.update({
"drug_info": drug_info, # k1-k6数据
"fill_json_content": parse_fill_json_content,
"rfid_drug": {drug_obj.rfid: f"[{drug_obj.rfid}]" + ",".join(list(map(lambda x:str(x), drug_info.values()))) + "," +
f"{drug_obj.remain_gross_weight}"},
# "display_remain": drug_obj.change_display_remain() # 余量展示数据
})
return respond_to(code=200, desc="领用成功", data=result)
@router.get('/put_in', summary='待归还列表')
async def index(request: Request, cabinet_id: str = '', drug_name: str = '', page_no: int = 1, page_size: int = 10):
"""
获取当前用户待归还清单
:return:
"""
current_user = request.state.current_user
# 当前柜体待归还清单
query = Drug.filter(last_receive_id=current_user.id, state=2, template__archive_id=request.state.archive_id)
if cabinet_id:
query = query.filter(cabinet_id=cabinet_id)
if drug_name:
query = query.filter(Q(dictionary__k1__contains=drug_name) | Q(dictionary__k2__contains=drug_name))
total_count = await query.count()
offset = (page_no - 1) * page_size
drugs = await query.offset(offset).limit(page_size).all()
result = list()
for drug_obj in drugs:
receive_user_obj = await User.get_or_none(id=drug_obj.last_receive_id)
data = {
"drug_id": drug_obj.id,
"rfid": drug_obj.rfid,
"hole": drug_obj.hole,
"cabinet_id": drug_obj.cabinet_id if drug_obj.cabinet_id else None,
"drawer_id": drug_obj.drawer_id,
"board_id": drug_obj.board_id,
"position": drug_obj.position,
"expired_at": drug_obj.expired_at,
"remain_gross_weight": await drug_obj.format_weight(),
"display_weight": await drug_obj.format_weight(),
"last_receive_at": drug_obj.last_receive_at,
"last_receive_user": receive_user_obj.name if receive_user_obj else '',
"drug_info": await drug_obj.parse_fill_json_content()
}
result.append(data)
return respond_to(data=dict(count=total_count, drugs=result))
@router.put('/return/{code}', summary='药剂归还')
async def update(request: Request, code: str, keyword: ReturnForm):
"""
药剂归还
药剂扫码后填入用量/余量,归还成功
:param code: 药剂条码
:param post:
:return:
"""
# 如果调用保存已经保存过用量数据,则不再进行保存
# code = bytes.hex(bytes.fromhex(code)[::-1]) if len(code) > 10 else code
# print("code=============",code)
drug_obj = await Drug.get_or_none(Q(barcode=code) | Q(rfid=code)).prefetch_related('template', 'dictionary')
if not drug_obj:
return respond_to(code=404, desc="药剂未找到")
if str(drug_obj.template.archive_id) != str(request.state.archive_id):
return respond_to(code=403, desc='药剂不在当前大类')
if keyword.weight:
# 余量转用量,更新用量
mill_weight = drug_obj.remain_gross_weight - keyword.weight
drug_obj.total_use_weight = drug_obj.total_use_weight + mill_weight
# drug_obj.remain_gross_weight = keyword.weight
drug_obj.last_use_weight = float(mill_weight)
elif keyword.use_weight:
mill_weight = keyword.use_weight
drug_obj.total_use_weight = drug_obj.total_use_weight + mill_weight
# drug_obj.remain_gross_weight = drug_obj.remain_gross_weight - keyword.use_weight
drug_obj.last_use_weight = float(mill_weight)
# 位置更新
if keyword.drawer_id or keyword.cabinet_id:
position_str = ""
if keyword.cabinet_id:
cabinet = await Cabinet.get(id=keyword.cabinet_id)
drug_obj.cabinet = cabinet
position_str = f"{cabinet.label}"
if keyword.drawer_id:
drawer_obj = await Drawer.get(id=keyword.drawer_id).prefetch_related("cabinet")
drug_obj.drawer = drawer_obj
cabinet = await drawer_obj.cabinet
position_str = f"{cabinet.label}-{drawer_obj.label}"
drug_obj.position = position_str
cabinet_obj = await Cabinet.get(id=drug_obj.cabinet_id) if drug_obj.cabinet else None
users = request.state.current_user
if keyword.is_empty:
standard = Standard(request.state.users)
await standard.empty(code, 0, cabinet_obj.terminal_id)
open_date=drug_obj.open_date
if open_date:
drug_obj.open_date = datetime.datetime.now()
await drug_obj.save(update_fields=["open_date"])
return respond_to(desc="归还完成", data="空瓶")
drug_obj.last_return_at = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
open_date = drug_obj.open_date
if not open_date:
drug_obj.open_date = datetime.datetime.now()
drug_obj.last_return_id = users.id
await drug_obj.save()
basic_standard = BasicStandard()
standard = Standard(request.state.users)
await basic_standard.basic_put_in(standard, code, cabinet_id=drug_obj.cabinet_id, line_no=0, hole=None)
return respond_to(desc="归还完成")
@router.post('/empty', summary='试剂置为空瓶')
async def empty_bottle_disposal(request: Request, post: EmptyBottleDisposal):
"""
试剂置为空瓶
:param request: Request请求头信息
:param post: 空瓶信息的请求体
:return:
"""
users = request.state.users
rfid = post.rfid
drug = await Drug.get_or_none(Q(barcode=rfid) | Q(rfid=rfid)).prefetch_related("cabinet")
open_date = post.open_date
standard = Standard(users)
if open_date:
drug.open_date = open_date
await drug.save()
await standard.empty(rfid, 0, drug.cabinet.terminal_id)
return respond_to()
@router.post('/weight', summary="药剂用量或余量更新")
async def update(keyword: DrugUpdateRequest):
"""
药剂用量或余量更新
接收id或rfid都可以更新重量
余量与用量二选一,只有一个有值
:param keyword: 包含更新信息的请求体
:return:
"""
print("open_date", keyword.open_date)
rfid = keyword.rfid if keyword.rfid else ""
query_param = {"id": keyword.id} if keyword.id else {"rfid": rfid}
check_drug_obj = await Drug.get(**query_param)
if not check_drug_obj:
return respond_to(404, desc="药剂不存在")
drug_obj = await Drug.get(**query_param).prefetch_related("template")
if keyword.weight:
# 余量转用量,更新用量
mill_weight = drug_obj.remain_gross_weight - keyword.weight if drug_obj.remain_gross_weight else 0
await drug_obj.update_last_use_weight(weight=float(mill_weight))
drug_obj.remain_gross_weight = keyword.weight
await drug_obj.save()
elif keyword.use_weight:
mill_weight = keyword.use_weight if keyword.use_weight and keyword.use_weight != "NaN" else 0
await drug_obj.update_last_use_weight(weight=float(mill_weight))
if keyword.open_date:
if not drug_obj.open_date:
drug_obj.open_date = keyword.open_date
template_obj = drug_obj.template
new_expired_at = open_update_expired_at(drug_obj, template_obj, keyword.open_date)
if new_expired_at:
drug_obj.expired_at = new_expired_at
await drug_obj.save()
return respond_to(code=200, desc="重量更新成功")
@router.get('/data/list', summary='试剂数据 - 列表查询')
async def data_list(request: Request, state: int = -1, drug_type='', cabinet_id: str = '', drug_name: str = '', page_no: int = 1, page_size: int = 20):
"""
试剂数据 - 列表查询
:return:
"""
query = Drug.filter(template__archive_id=request.state.archive_id).order_by('-storage_at')
if state > -1:
query = query.filter(state=state)
if cabinet_id:
query = query.filter(cabinet_id=cabinet_id)
if drug_type:
query = query.filter(drug_type=drug_type)
if drug_name:
annotate = {}
annotate['json_batch_no'] = JsonExtract('fill_json_content', '$.cas_number')
query = query.annotate(**annotate).filter(
Q(json_batch_no__contains=drug_name) | Q(fill_json_content__filter={"unit_code": drug_name}) | Q(
dictionary__k1__contains=drug_name) | Q(dictionary__k2__contains=drug_name))
# query = query.filter(Q(dictionary__k1__contains=drug_name) | Q(dictionary__k2__contains=drug_name))
total_count = await query.count()
offset = (page_no - 1) * page_size
drugs = await query.prefetch_related("dictionary", "template__archive").offset(offset).limit(page_size)
result = list()
for drug_obj in drugs:
data = {
"drug_id": drug_obj.id,
"archive_name": drug_obj.template.archive.name,
"storage_at": drug_obj.storage_at,
"cas": drug_obj.attribute("cas_number"),
"remain_gross_weight": await drug_obj.format_weight(),
"rfid": drug_obj.rfid,
"expired_at": drug_obj.expired_at,
"state": drug_obj.state,
"last_user": await drug_obj.attribute_last_user(),
"position": drug_obj.position,
"drug_info": await drug_obj.parse_fill_json_content(False),
"dictionary_id": drug_obj.dictionary_id,
"unit_code": drug_obj.fill_json_content["unit_code"] if 'unit_code' in drug_obj.fill_json_content else '-',
"open_date": drug_obj.open_date, # 开瓶日期
"manufacturer": drug_obj.attribute("cs"), # 生产厂商
"produce_date": drug_obj.attribute("produce_date"), # 生产日期
"ph": drug_obj.attribute("ph"), # 批号
}
# 盒装药剂药剂信息
if drug_obj.drug_type == "box":
box_item_info = await drug_obj.attribute_box_item_info()
data.update({
"drug_info": await drug_obj.attribute_drug_info(),
**box_item_info,
})
if data.get("archive_name") == "耗材":
data.update({
"remain_count": int(drug_obj.attribute("total_count")) - drug_obj.total_use_weight if drug_obj.attribute("total_count") else "-" # 余量
})
result.append(data)
return respond_to(200, data=dict(count=total_count, drugs=result))
@router.get('/data/flowRecord', summary='试剂数据 - 流转记录')
async def data_flow_record(request: Request, drug_id: str = '', page_no: int = 1, page_size: int = 20):
"""
试剂数据 - 流转记录
:return:
"""
offset = (page_no - 1) * page_size
query = DrugUseLog.filter(drug_id=drug_id)
count = await query.count()
drug_use_log_list = await query.prefetch_related('drug').offset(offset).limit(page_size).order_by('-created_at')
result = list()
for log in drug_use_log_list:
if log.state in [1, 3]:
use_weight = log.use_weight
finally_use_weight = "" if not use_weight and log.state != DrugUseStateEnum.PUT else use_weight
else:
finally_use_weight = ''
# weight > 1000 转换为g 保留一位小数否则返回mg
weight = float(log.weight) if log.weight else 0
if weight > 1000:
weight_str = f"{milligram_to_gram(log.weight)}g"
else:
weight_str = f"{log.weight}mg" if log.weight is not None else "-"
finally_use_weight_str = log.parse_use_weight(finally_use_weight)
print("finally_use_weight_str", finally_use_weight_str)
result.append({
**jsonable_encoder(log),
"drug_info": await log.drug.attribute_drug_info(),
"weight": weight_str,
"use_weight": finally_use_weight_str
})
return respond_to(data=dict(count=count, data=result))
@router.delete('/data/drugDelete', summary='试剂数据 - 试剂删除')
@logger_wrapper
async def drug_delete(request: Request, body: DrugDeleteRequest):
"""
试剂数据 - 试剂删除
:return:
"""
if len(body.drug_ids) == 0:
return respond_to(code=403, desc='请选择试剂')
await Drug.filter(id__in=body.drug_ids).delete()
return respond_to(desc='删除成功')
@router.put('/expired_at', summary='药剂信息修改')
@logger_wrapper
async def update(keyword: DrugUpdateExpired):
"""
药剂信息过期时间修改
:param id: 用户药剂模板条目id
:param keyword:
:return:
"""
rfid = keyword.rfid if keyword.rfid else ""
query_param = {"id": keyword.id} if keyword.id else {"rfid": rfid}
drug_obj = await Drug.get(**query_param)
drug_obj.expired_at = keyword.expired_at
await drug_obj.save()
return respond_to(code=200, desc="更新成功")
@router.put('/move/{code}', summary='药剂移库')
async def update(request: Request, code: str, keyword: UpdateDrugRequest):
"""
药剂移库
:return:
"""
cabinet_id = keyword.cabinet_id
cabinet_obj = await Cabinet.get_or_none(id=cabinet_id)
if not cabinet_obj:
return respond_to(code=404, desc='柜体不存在')
position = cabinet_obj.label
drug_obj = await Drug.filter(Q(rfid=code) | Q(barcode=code)).prefetch_related("cabinet", "template__archive").first()
if not drug_obj:
return respond_to(code=404, desc='药剂条码不存在')
if drug_obj.state == DrugStateEnum.OUT:
return respond_to(code=403, desc='药剂不在库')
if drug_obj.state == DrugStateEnum.EMPTY:
return respond_to(code=403, desc='药剂已空瓶')
if str(drug_obj.template.archive_id) != str(request.state.archive_id):
return respond_to(code=403, desc='药剂不在当前大类')
# 移库人
receive_id = keyword.receive_id
drug_obj.state = DrugStateEnum.OUT
drug_obj.last_receive_at = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
drug_obj.last_receive_id = receive_id
drug_obj.cabinet_id = cabinet_id
drug_obj.drawer_id = None
drug_obj.drawer_board_id = None
drug_obj.hole = None
drug_obj.position = position
await drug_obj.save()
users = [receive_id]
# 流转日志保存
drug_use_dict = {
"drug": drug_obj,
"state": DrugUseStateEnum.TAKE,
"user_id": receive_id,
"peer_ids": ",".join(users[1:]), # 陪同人id
"users": await User.parse_id_user(users),
"terminal_id": cabinet_obj.terminal_id, # 终端id
"cabinet_id": cabinet_id,
"position": position,
"alerted": False, # 是否报警 领用称重
"weight": drug_obj.remain_gross_weight,
}
await DrugUseLog().create(**drug_use_dict)
# 药剂数据封装返回前端
result = jsonable_encoder(drug_obj)
drug_info = await drug_obj.attribute_drug_info()
parse_fill_json_content = await drug_obj.parse_fill_json_content()
result.update({
"drug_info": drug_info, # k1-k6数据
"fill_json_content": parse_fill_json_content,
"rfid_drug": {drug_obj.rfid: f"[{drug_obj.rfid}]" + ",".join(list(map(lambda x:str(x), drug_info.values()))) + "," +
f"{drug_obj.remain_gross_weight}"},
# "display_remain": drug_obj.change_display_remain() # 余量展示数据
})
return respond_to(code=200, desc="完成", data=result)
# 高拍仪拍照
@router.get("/use_gaopaiyi")
async def use_gaopaiyi(drug_id: str = '', dictionary_id: str = ''):
pic_data = GaoPaiYi().getPic()
if pic_data['code'] == 0:
# 根据条码查询试剂信息
drug_info = await Drug.get_or_none(id=drug_id)
if not drug_info:
return respond_to(code=404, desc='药剂不存在')
obj = {
"drug_id": drug_id if drug_id else None,
"dictionary_id": dictionary_id if dictionary_id else None,
"pic_url": pic_data['path'],
"is_add": 0,
}
await DrugRelationImage().create(**obj)
return respond_to(code=200, desc="高拍仪拍照成功", data=pic_data['path'])
else:
return respond_to(code=400, desc="高拍仪拍照失败", data=pic_data['msg'])
# 获取药剂图片列表
@router.get("/get_drug_image")
async def get_medicament_image(drug_id: str = '', dictionary_id: str = '', is_add: int = 1):
query = DrugRelationImage().filter(is_add=is_add)
# 药剂类别
if drug_id:
query = query.filter(drug_id=drug_id)
if dictionary_id:
query = query.filter(dictionary_id=dictionary_id)
count = await query.count()
data_list = await query.all()
return respond_to(data=dict(count=count, data=data_list))
# 删除药剂图片
@router.delete("/del_drug_image")
async def del_medicament_image(body: ImageDeleteRequest):
if len(body.image_ids) == 0:
return respond_to(code=403, desc='请选择图片')
await DrugRelationImage.filter(id__in=body.image_ids).delete()
return respond_to(desc='删除成功')
@router.get("/get_img_info/{img_path}")
def get_drug_img(img_path):
print(os.path.join(os.getcwd(), "static", "msds"))
file_path = os.path.join(GaoPaiYi().path, img_path)
return FileResponse(file_path)
@router.get("/get_img_info1/{img_path}")
def get_drug_img1(img_path):
path =os.path.join(os.getcwd(), "static", "msds")
file_path = os.path.join(path, img_path)
return FileResponse(file_path)
@router.get("/download_imgs")
def download_drug_imgs(img_paths: List[str]):
base64_files = [] # 存放多个文件的 Base64 编码
for img_path in img_paths:
file_path = os.path.join(GaoPaiYi().path, img_path)
with open(file_path, "rb") as file:
file_data = file.read()
base64_data = base64.b64encode(file_data).decode("utf-8")
base64_files.append(base64_data)
return respond_to(data=base64_files)
# 图片上传接口
@router.post("/save_drug_img")
async def save_drug_img_info( upload_list: list, file: UploadFile = File(...)):
"""
文件上传保存
:param upload_list:
:param file:
:return:
"""
# 保存文件
gaopaiyi_obj = GaoPaiYi()
img_path = f"{str(uuid.uuid4())}.jpg"
with open(os.path.join(gaopaiyi_obj.path, img_path), "wb") as f:
f.write(await file.read())
content = json.loads(upload_list[0])
# 添加关联关系
for upload_item in content:
dictionary_id = upload_item.get("dictionary_id")
drug_id = upload_item.get("drug_id")
# 根据条码查询试剂信息
drug_info = await Drug.get_or_none(id=drug_id)
dictionary_info = await Dictionary.get_or_none(id=dictionary_id)
if not drug_info and not dictionary_info:
return respond_to(code=400, desc="上传失败,参数异常")
obj = {
"drug_id": drug_id if drug_id else None,
"dictionary_id": dictionary_id if dictionary_id else None,
"pic_url": img_path,
"is_add": 0,
}
await DrugRelationImage().create(**obj)
return respond_to(desc='上传成功')