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.

191 lines
6.1 KiB

#!/usr/bin/env python
# encoding: utf-8
"""
@author: tx
@file: template.py
@time: 2023/5/8 19:23
@desc:
"""
import re
import urllib.parse
from io import BytesIO
from fastapi import APIRouter, Response, Depends, Request
from openpyxl.styles import Font
from openpyxl.utils import get_column_letter
from openpyxl.workbook import Workbook
from pydantic import BaseModel
from helper import respond_to, usb, login_required
from helper.utils import timezone_now
from models import Template, TemplateItem, Archive
router = APIRouter(prefix='/template', dependencies=[Depends(login_required)])
class TemplateXlsxEdit(BaseModel):
xlsx: list[dict]
class TemplateParamsEdit(BaseModel):
params: dict | None
@router.get('/index', summary='模板列表')
async def index():
"""
获取模板列表数据
:return:
"""
templates = await Template.filter().prefetch_related("archive").all()
dic = {
"return_fixed_at": "每天固定时间规划",
"first_will_empty": "首次领用即空瓶",
"first_will_open": "首次领用即开封",
"receive_use_duration": "每试剂每次使用时长",
"return_require_weigh": "归还需称重",
"receive_require_weigh": "领用需称重",
"storage_require_weigh": "入库需称重",
}
result_list = []
for item in templates:
keys = dict(item.archive.params).keys() if item.archive else {}
data = dict(item)
content = ""
for key in keys:
content = content + dic.get(key) + ","
params = re.sub(r',\s*$', '', content)
data.setdefault("params", params)
result_list.append(data)
return respond_to(data=result_list)
@router.put('/{template_id}/xlsx', summary='更新模板内容')
async def update(template_id: str, model: TemplateXlsxEdit):
"""
更新模板配置
:return:
"""
result = await Template.filter(id=template_id).update(xlsx=model.xlsx)
if not result:
return respond_to(code=400, desc='更新失败')
return respond_to(desc='更新成功')
@router.get('/{template_id}/xlsx', summary="查看模板内容")
async def index(template_id: str):
"""
查看模板内容
:return:
"""
template = await Template.get_or_none(id=template_id)
if not template:
return respond_to(code=400, desc='未找到模板')
result = []
if not template.xlsx:
result.extend({
"key": f"k{i}",
"text": text,
"checked": True,
"required": True,
"type": "string",
"reserved": 0,
} for i, text in enumerate(template.tags.split(","), start=1))
important = await TemplateItem.all().values('key', 'text', 'checked', 'required', 'type', 'reserved')
if important:
result.extend(important)
else:
return respond_to(code=400, desc='No Template Items found')
else:
if isinstance(template.xlsx, list):
result = template.xlsx
else:
return respond_to(code=400, desc="Xlsx should be a list")
return respond_to(data=result)
@router.get('/{template_id}/download/{download_type}', summary='下载入库模板')
async def show(template_id: str, download_type: str):
template = await Template.get_or_none(id=template_id)
if not template:
return respond_to(code=400, desc='未找到模板信息')
xlsx = template.xlsx or []
xlsx = [item for item in xlsx if item.get("checked")]
workbook = Workbook()
sheet = workbook.active
for index, item in enumerate(xlsx, 1):
chr = get_column_letter(index)
sheet[f'{chr}1'] = item.get('text', None)
if item.get('required', False):
sheet[f'{chr}1'].font = Font(color='FF0000')
index = len(xlsx)
# 设置每列为文本格式
for row in sheet.iter_rows(min_row=1, max_row=1000, min_col=1, max_col=index + 1):
for cell in row:
cell.number_format = '@'
binary = BytesIO()
workbook.save(binary)
binary.seek(0)
filename = f"{timezone_now().strftime('%Y%m%d%H%M')}-{template.name}-入库模板.xlsx"
if download_type == 'usb':
try:
usb.put_in(filename, binary)
return respond_to()
except usb.DeviceNotFound:
return respond_to(code=404, desc='请先插入U盘')
encoded_filename = urllib.parse.quote(filename)
return Response(content=binary.getvalue(),
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
headers={'Content-Disposition': f'attachment; filename={encoded_filename}'})
# @router.get('/{template_id}', summary='获取称重/使用期限')
# async def update(template_id: str):
# """
# 获取称重/使用期限
# :return:
# """
# template = await Template.get_or_none(id=template_id).prefetch_related('archive')
# if not template:
# return respond_to(code=400, desc='未找到该大类')
# return respond_to(data=template.archive.params)
@router.put('/{template_id}', summary='配置称重/使用期限')
async def update(template_id: str, params: dict):
"""
配置称重/使用期限
:return:
"""
template = await Template.get_or_none(id=template_id).prefetch_related('archive')
if not template:
return respond_to(code=400, desc='未找到该模版')
archive = await Archive.get_or_none(id=template.archive.id)
print(params)
archive.params = params
await archive.save()
return respond_to(desc='更新配置成功')
@router.get('/translate', summary='大类模板内容')
async def translate(request: Request):
"""
大类模板内容
:return:
"""
template = await Template.get(archive_id=request.state.archive_id)
if not template.xlsx:
result = {
"template_xlsx": {},
}
return result
template_xlsx = template.parse_xlsx_transfer()
result = {
"template_xlsx": template_xlsx,
}
return respond_to(data=result)