试剂与耗材管理涉及项目代码

main
李进才 3 months ago
parent 720ec5be6b
commit 3419abc974
  1. BIN
      .DS_Store
  2. BIN
      code/.DS_Store
  3. 8
      code/.idea/.gitignore
  4. 12
      code/.idea/code.iml
  5. 14
      code/.idea/deployment.xml
  6. 6
      code/.idea/inspectionProfiles/profiles_settings.xml
  7. 7
      code/.idea/misc.xml
  8. 8
      code/.idea/modules.xml
  9. 6
      code/.idea/sqldialects.xml
  10. 8
      code/api/__init__.py
  11. 53
      code/api/accounting.py
  12. 143
      code/api/approve.py
  13. 14
      code/api/authority.py
  14. 113
      code/api/bad.py
  15. 86
      code/api/basic.py
  16. 156
      code/api/dictionary.py
  17. 199
      code/api/entry.py
  18. 103
      code/api/file.py
  19. 83
      code/api/inventory.py
  20. 27
      code/api/log.py
  21. 210
      code/api/statistics.py
  22. 473
      code/api/stock.py
  23. 58
      code/api/user.py
  24. 4
      code/config.ini
  25. 10
      code/config/db.ini
  26. 17
      code/config/operatingType.ini
  27. 0
      code/diff/__init__.py
  28. 31
      code/diff/stock.py
  29. 26
      code/error.py
  30. BIN
      code/file/.DS_Store
  31. BIN
      code/file/2024-11-21 15-43-53.xlsx
  32. BIN
      code/file/2KMEB38L5WXR16QF.xlsx
  33. BIN
      code/file/3BAVBWRE111YJWSG.xlsx
  34. BIN
      code/file/6CHXGA8M3QT7OFYE.xlsx
  35. BIN
      code/file/7UM1PXA6AW4K6KSS.xlsx
  36. BIN
      code/file/ABQ5UE4PJQWY9ATB.xlsx
  37. BIN
      code/file/C4TWNLBAA7KDQOGY.xlsx
  38. BIN
      code/file/EAVRAVUF4HMSS1VY.xlsx
  39. BIN
      code/file/IJ8YUUATQZVW6ZHR.xlsx
  40. BIN
      code/file/IU8RDI3SCOLNZWXL.xlsx
  41. BIN
      code/file/J01ONHVTL3URBZ4X.xlsx
  42. BIN
      code/file/L4Z18OEAVZP9VWTU.xlsx
  43. BIN
      code/file/U1233S0OPIGA8PN0.xlsx
  44. BIN
      code/file/ZI9CVZ190MEXJRVC.xlsx
  45. BIN
      code/file/按试剂名称分类出入数汇总表1715132971-762088.xlsx
  46. BIN
      code/file/按试剂名称分类出入数汇总表1715133376-240133.xlsx
  47. BIN
      code/file/按试剂名称分类出入数汇总表1715149727-922671.xlsx
  48. BIN
      code/file/按试剂名称分类出入数汇总表1715149877-035809.xlsx
  49. BIN
      code/file/按试剂名称分类出入数汇总表1715149966-38028.xlsx
  50. BIN
      code/file/按试剂名称分类出入数汇总表1715150309-058657.xlsx
  51. BIN
      code/file/按试剂名称分类出入数汇总表1715150631-057252.xlsx
  52. BIN
      code/file/按试剂名称分类出入数汇总表1715151183-830989.xlsx
  53. BIN
      code/file/按试剂名称分类出入数汇总表1715152611-143278.xlsx
  54. BIN
      code/file/按试剂名称分类出入数汇总表1715152645-461841.xlsx
  55. BIN
      code/file/按试剂名称分类出入数汇总表1715153210-441213.xlsx
  56. BIN
      code/file/按试剂名称分类出入数汇总表1715154361-269477.xlsx
  57. BIN
      code/file/按试剂名称分类出入数汇总表1715154382-419685.xlsx
  58. BIN
      code/file/过期耗材汇总表1686818479-601265.xlsx
  59. BIN
      code/file/过期耗材汇总表1715139684-403379.xlsx
  60. BIN
      code/file/过期耗材汇总表1715139725-859153.xlsx
  61. BIN
      code/models/.DS_Store
  62. 68
      code/models/InStockModel.py
  63. 0
      code/models/__init__.py
  64. 44
      code/models/db.py
  65. 287
      code/models/entity.py
  66. 2
      code/models/inStockExcel.py
  67. 32
      code/models/reagentTypeList.py
  68. 75
      code/models/stockListModel.py
  69. 51
      code/py/Scripts/Activate.ps1
  70. 76
      code/py/Scripts/activate
  71. 45
      code/py/Scripts/activate.bat
  72. 21
      code/py/Scripts/deactivate.bat
  73. BIN
      code/py/Scripts/easy_install-3.7.exe
  74. BIN
      code/py/Scripts/easy_install.exe
  75. BIN
      code/py/Scripts/pip.exe
  76. BIN
      code/py/Scripts/pip3.7.exe
  77. BIN
      code/py/Scripts/pip3.exe
  78. BIN
      code/py/Scripts/pypinyin.exe
  79. BIN
      code/py/Scripts/python.exe
  80. BIN
      code/py/Scripts/pythonw.exe
  81. 3
      code/py/pyvenv.cfg
  82. 18
      code/server.py
  83. 0
      code/statusCode/__init__.py
  84. 22
      code/statusCode/responseEntity.py
  85. 33
      code/statusCode/result.py
  86. 69
      code/statusCode/resultCode.py
  87. BIN
      code/template/入库模版.xlsx
  88. 0
      code/test.py
  89. BIN
      code/utils/.DS_Store
  90. 31
      code/utils/BatchCode.py
  91. 22
      code/utils/Dict2Obj.py
  92. 54
      code/utils/List2Json.py
  93. 91
      code/utils/PageHepler.py
  94. 12
      code/utils/ReagentTypeListSort.py
  95. 0
      code/utils/__init__.py
  96. 56
      code/utils/apiDoc.py
  97. 21
      code/utils/basicHelper.py
  98. 64
      code/utils/configOperatingTypeHelper.py
  99. 26
      code/utils/desHelper.py
  100. 39
      code/utils/dictionaryHelper.py
  101. Some files were not shown because too many files have changed in this diff Show More

BIN
.DS_Store vendored

Binary file not shown.

BIN
code/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.7 (code)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData" serverName="ubuntu@www.summerlost.com:22" remoteFilesAllowedToDisappearOnAutoupload="false">
<serverData>
<paths name="ubuntu@www.summerlost.com:22">
<serverdata>
<mappings>
<mapping deploy="/docker/python3.7/" local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.7 (code)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (code)" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/code.iml" filepath="$PROJECT_DIR$/.idea/code.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/api/stock.py" dialect="GenericSQL" />
</component>
</project>

@ -0,0 +1,8 @@
import os
import pkgutil
pkg_path = os.path.dirname(__file__)
pkg_name = os.path.basename(pkg_path)
for _, file, _ in pkgutil.iter_modules([pkg_path]):
__import__(pkg_name + '.' + file)

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
"""
api.user
~~~~~~~~~~~~~~
有关用户操作的接口.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from sqlalchemy import func, or_
from utils.apiDoc import *
from utils.PageHepler import *
from utils.configOperatingTypeHelper import GetOperatingTypeOutStock
@accounting.route('/instrumentList')
class InstrumentList(Resource):
@staticmethod
def get():
dictFilter = db.session.query(DictInstrument.InsName.label('InsName'),
func.count(RptCheckresult.SampleCode).label('orderNumber')) \
.join(RptCheckresult, func.substring(RptCheckresult.SampleCode, 1, 2) == DictInstrument.SampleCode) \
.filter(RptCheckresult.TestDate >= request.args.get('startTime')) \
.filter(RptCheckresult.TestDate <= request.args.get('endTime')) \
.group_by(DictInstrument.InsName)
return SuccessResponse(ResultCode.SUCCESS, {'list': db_page(dictFilter,
DictInstrument.InsName,
request.args, 6),
'totalNumber': dictFilter.count()}, None)
@accounting.route('/reagentOutList')
class ReagentOutList(Resource):
@staticmethod
def get():
query = request.args.get('query')
reagent_out_filter = db.session.query(ReagtLog.ReagentName,
ReagtLog.ReagentSpecification,
func.sum(ReagtLog.ReagentNumber).label('ReagentNumber'),
func.sum(ReagtLog.OperateMinNumber).label('OperateMinNumber'))\
.filter(ReagtLog.OperatingType == GetOperatingTypeOutStock()) \
.filter(ReagtLog.OperatingTime >= request.args.get('startTime')) \
.filter(ReagtLog.OperatingTime <= request.args.get('endTime')) \
.filter(or_(ReagtLog.ReagentName.contains(query),
ReagtLog.PinYinCode.contains(query),
ReagtLog.ReagentPosition.contains(query)))\
.group_by(ReagtLog.ReagentName, ReagtLog.ReagentSpecification)
return SuccessResponse(ResultCode.SUCCESS, {'list': db_page(reagent_out_filter,
ReagtLog.ReagentName,
request.args, 6),
'totalNumber': reagent_out_filter.count()}, None)

@ -0,0 +1,143 @@
from sqlalchemy import or_
from utils.PageHepler import db_page
from utils.apiDoc import *
from utils.configOperatingTypeHelper import GetApproveTypeApproving, GetApproveTypeApproved, GetApproveTypeOverrule
import pandas as pd
@approve.route('/add')
class ApproveAdd(Resource):
@staticmethod
def post():
approve_people = verify_jwt_username(request.headers.get('X-Token'))
remark = request.json['remark']
approve_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
approve_status = ReagtApproveStatus.query.filter_by(StatusCode=GetApproveTypeApproving()).first().StatusId
for item in request.json['approveList']:
data = Dict2Obj(item)
reagent_approve = ReagtApprove(ApproveName=data.Name,
Specification=data.Specification,
Maker=data.Maker if 'Maker' in item.keys() else "",
Number=data.InputNumber,
ApprovePeople=approve_people,
ApproveTime=approve_time,
Unit=data.Unit,
ApproveStatus=approve_status,
Remark=remark)
db.session.add(reagent_approve)
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@approve.route('/list')
class ApproveList(Resource):
@staticmethod
def get():
approve_status = ReagtApproveStatus.query.filter_by(StatusCode=request.args.get('status')).first().StatusId
approve_filter = db.session.query(ReagtApprove.ApproveName,
ReagtApprove.ApproveId,
ReagtApprove.ApproveTime,
ReagtApprove.Maker,
ReagtApprove.Specification,
ReagtApprove.Number,
ReagtApprove.Unit,
ReagtApprove.ApproveTime,
ReagtApprove.ApprovePeople,
ReagtApproveStatus.StatusCode,
ReagtApprove.Verifier,
ReagtApprove.VerifyTime) \
.join(ReagtApproveStatus, ReagtApproveStatus.StatusId == ReagtApprove.ApproveStatus).filter(
ReagtApprove.ApproveStatus == approve_status)
data_list = db_page(approve_filter, ReagtApprove.ApproveTime, request.args, 6)
if request.args.get('pageSize') is not None:
data_list = db_page(approve_filter, ReagtApprove.ApproveTime, request.args,
int(request.args.get('pageSize')))
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': approve_filter.count(),
'list': data_list}, None)
@approve.route('/agree')
class ApproveAgree(Resource):
@staticmethod
def post():
people = verify_jwt_username(request.headers.get('X-Token'))
approve_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
Name, Specification, Maker, Number, Unit, ApprovePeople, Checker, Purchase, Leader, ApproveTime = [], [], [], [], [], \
[], [], [], [], []
approve_status = ReagtApproveStatus.query.filter_by(StatusCode=GetApproveTypeApproved()).first().StatusId
for item in request.json['approveList']:
data = Dict2Obj(item)
approve_entity = ReagtApprove.query.filter_by(ApproveId=data.ApproveId).first()
Name.append(approve_entity.ApproveName)
ApprovePeople.append(approve_entity.ApprovePeople)
Specification.append(approve_entity.Specification)
Maker.append(approve_entity.Maker)
ApproveTime.append(approve_entity.ApproveTime)
Number.append(approve_entity.Number)
Unit.append(approve_entity.Unit)
Purchase.append('')
Leader.append('')
Checker.append('')
approve_entity.ApproveStatus = approve_status
approve_entity.Verifier = people
approve_entity.VerifyTime = approve_time
db.session.commit()
dit = {'耗材名': Name, '耗材规格': Specification, '生产厂家': Maker, '欲购数量': Number, '耗材单位': Unit,
'申请人': ApprovePeople, '申请时间': ApproveTime, '审核人': Checker, '采购人': Purchase, '分管领导': Leader}
writer = pd.ExcelWriter('./file/'+approve_time.replace(':', '-')+'.xlsx')
df = pd.DataFrame(dit)
# columns参数用于指定生成的excel中列的顺序
df.to_excel(writer, columns=['耗材名', '耗材规格', '生产厂家', '欲购数量', '耗材单位', '申请人', '申请时间', '审核人', '采购人', '分管领导'], index=False, encoding='utf-8',
sheet_name='欲购耗材清单')
writer.save()
return SuccessResponse(ResultCode.SUCCESS, approve_time.replace(':', '-'), None)
@approve.route('/delete')
class ApproveDelete(Resource):
@staticmethod
def get():
db.session.delete(ReagtApprove.query.filter_by(ApproveId=request.args.get('ApproveId')).first())
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@approve.route('/overrule')
class ApproveOverrule(Resource):
@staticmethod
def get():
approve_status = ReagtApproveStatus.query.filter_by(StatusCode=GetApproveTypeOverrule()).first().StatusId
approve_entity = ReagtApprove.query.filter_by(ApproveId=request.args.get('ApproveId')).first()
approve_entity.ApproveStatus = approve_status
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@approve.route('/time')
class ApproveTime(Resource):
@staticmethod
def get():
approve_filter = db.session.query(ReagtApprove.VerifyTime).group_by(ReagtApprove.VerifyTime).distinct()
result_data = db_page(approve_filter, ReagtApprove.VerifyTime, request.args, 6)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': approve_filter.count(),
'list': result_data}, None)
@approve.route('/submitList')
class SubmitList(Resource):
@staticmethod
def get():
inventoryListFilter = db.session.query(ReagtReagent.Name, ReagtReagent.Specification). \
filter(ReagtReagent.Using == True). \
group_by(ReagtReagent.Name, ReagtReagent.Specification).distinct()
if request.args.get('query') is not None and request.args.get('query') != '':
inventoryListFilter = db.session.query(ReagtReagent.Name, ReagtReagent.Specification). \
group_by(ReagtReagent.Name, ReagtReagent.Specification). \
filter(ReagtReagent.Using == True). \
filter(or_(ReagtReagent.Name.contains(request.args.get('query')), ReagtReagent.Specification
.contains(request.args.get('query')),
ReagtReagent.PinYinCode.contains(request.args.get('query')))).distinct()
result_data = db_page(inventoryListFilter, ReagtReagent.Name, request.args, 10)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': inventoryListFilter.count(),
'list': result_data}, None)

@ -0,0 +1,14 @@
from utils.apiDoc import *
@authority.route('/director')
class AuthorityDirector(Resource):
@staticmethod
def get():
user_name = verify_jwt_username(request.headers.get('X-Token'))
director = db.session.query(DictUser.UserName).join(DictCommon, DictUser.RightCode == DictCommon.ItemCode).\
filter(DictCommon.ItemName == '主任').first()
if director.UserName == user_name:
return SuccessResponse(ResultCode.SUCCESS, True, None)
else:
return SuccessResponse(ResultCode.SUCCESS, False, None)

@ -0,0 +1,113 @@
# -*- coding: utf-8 -*-
"""
api.bai
~~~~~~~~~~~~~~
有关报损的接口.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
import pandas as pd
from diff.stock import getDiffStockList
from utils.PageHepler import db_page, db_page_entity
from utils.apiDoc import *
from utils.configOperatingTypeHelper import GetOperatingTypeScrap
from utils.outStockHelper import *
from utils.scrapHelper import scrap_
@bad.route('/upload')
class BadUpload(Resource):
"""
报损
"""
@staticmethod
def post():
token = request.headers.get('X-Token')
data = request.json
app.logger.info(data)
reagentStock = ReagtStock.query.filter_by(StockId=data['StockId']).first()
reagentReagent = ReagtReagent.query.filter_by(ReagentId=reagentStock.ReagentId).first()
if data['OutStockNumber'] > reagentStock.LastNumber:
return BadResponse(ResultCode.PARAM_IS_INVALID, None, None)
if data['OutStockNumber'] < reagentStock.LastNumber or (data['OutStockNumber'] == reagentStock.LastNumber and
reagentStock.MinNumberUnit > data['OutStockNumber'] *
reagentReagent.Ratio + data['MinNumberUnit']):
LogAdd(token, GetOperatingTypeBad(), data, data['Code'], data['Name'], reagentStock.PinYinCode,
data['OutStockNumber'], data['Specification'], data['Position'], operateMinNumber=
data['MinNumberUnit'],reagentId=reagentReagent.ReagentId)
reagentStock.LastNumber -= data['OutStockNumber']
reagentStock.MinNumberUnit -= data['OutStockNumber'] * reagentReagent.Ratio
reagentStock.MinNumberUnit -= data['MinNumberUnit']
db.session.commit()
elif data['OutStockNumber'] == reagentStock.LastNumber:
LogAdd(token, GetOperatingTypeBad(), data, data['Code'], data['Name'], reagentStock.PinYinCode,
data['OutStockNumber'], data['Specification'], data['Position'], operateMinNumber=
data['MinNumberUnit'], reagentId=reagentStock.ReagentId)
db.session.delete(reagentStock)
db.session.delete(reagentStock)
db.session.commit()
reagentBad = ReagtBad(VerifyTime=datetime.now().strftime("%Y-%m-%d %H:%M"), Number=data['OutStockNumber'],
VerifyPeople=verify_jwt_username(token), Code=data['Code'], Remark=data['Remark'])
db.session.add(reagentBad)
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@bad.route('/scrap')
class Scrap(Resource):
"""
报废单个试剂
"""
@staticmethod
def get():
token = request.headers.get('X-Token')
scrap_(request.args.get('StockId'), request.args.get('scrapNumber'), token, request.args)
return SuccessResponse(ResultCode.SUCCESS, None, None)
@bad.route('/scrapExpirationList')
class ScrapExpirationList(Resource):
"""
过期待报废药品列表
"""
@staticmethod
def get():
data = request.args
filterObject = getDiffStockList()
filterObject = filterObject.filter(ReagtStock.Expiration < datetime.now())
data_list = db_page(filterObject, ReagtStock.Expiration, data, 3)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': filterObject.count(), 'list': data_list}, None)
@bad.route('/scrapExpiration')
class ScrapExpiration(Resource):
"""
一键报废过期药品
"""
@staticmethod
def get():
token = request.headers.get('X-Token')
for expiration in ReagtStock.query.filter(ReagtStock.Expiration < datetime.now()).all():
scrap_(expiration.StockId, expiration.LastNumber, token, request.args)
return SuccessResponse(ResultCode.SUCCESS, None, None)
@bad.route('/scrapList')
class ScrapList(Resource):
"""
报废单 数据
"""
@staticmethod
def get():
scrap_list = ReagtLog.query.filter(ReagtLog.OperatingType == GetOperatingTypeScrap()). \
filter(ReagtLog.OperatingTime > request.args.get('startTime')). \
filter(ReagtLog.OperatingTime < request.args.get('endTime'))
return SuccessResponse(ResultCode.SUCCESS,
{'list': db_page_entity(scrap_list,
request.args, scrap_list.count())}, None)

@ -0,0 +1,86 @@
"""
api.basic
~~~~~~~~~~~~~~
有关基础字典的接口.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from pypinyin import lazy_pinyin, Style
from utils.apiDoc import *
from utils.basicHelper import get_basic_entry_list
from utils.configOperatingTypeHelper import GetOperatingTypeBasicEntryClose, GetOperatingTypeBasicEntryOpen, \
GetOperatingTypeBasicReagentClose, GetOperatingTypeBasicReagentOpen
from utils.listHelper import list2String
from utils.logHelper import LogAdd
@basic.route('/basicReagent')
class BasicReagent(Resource):
@staticmethod
def get():
return get_basic_entry_list(ReagtReagent, request.args, ReagtReagent.Using.desc())
@basic.route('/basicEntry')
class BasicEntry(Resource):
@staticmethod
def get():
return get_basic_entry_list(ReagtEntry, request.args, ReagtEntry.Using.desc())
@basic.route('/disableReagent')
class DisableReagent(Resource):
@staticmethod
def get():
token = request.headers.get('X-Token')
data = request.args
if len(ReagtStock.query.filter_by(ReagentId=int(data.get('ReagentId'))).all()) > 0:
return SuccessResponse(ResultCode.BASIC_INFO_IS_USING, None, None)
disable_reagent = ReagtReagent.query.filter_by(ReagentId=int(data.get('ReagentId'))).first()
disable_reagent.Using = not disable_reagent.Using
LogAdd(token,
GetOperatingTypeBasicReagentClose() if disable_reagent.Using else GetOperatingTypeBasicReagentOpen(),
data, None, data.get('Name'),
list2String(lazy_pinyin(disable_reagent.Name + disable_reagent.Specification, style=Style.FIRST_LETTER)),
'', disable_reagent.Specification, '', remark=F'{"停用" if disable_reagent.Using else "启用"}基础信息(库存盘点)')
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@basic.route('/disableEntry')
class DisableEntry(Resource):
@staticmethod
def get():
token = request.headers.get('X-Token')
data = request.args
disable_entry = ReagtEntry.query.filter_by(EntryId=int(data.get('EntryId'))).first()
disable_entry.Using = not disable_entry.Using
LogAdd(token,
GetOperatingTypeBasicEntryClose() if disable_entry.Using else GetOperatingTypeBasicEntryOpen(),
data, None, disable_entry.Name,
list2String(lazy_pinyin(disable_entry.Name + disable_entry.Specification, style=Style.FIRST_LETTER)),
disable_entry.Number, disable_entry.Specification, disable_entry.Position,
remark=F'{"停用" if disable_entry.Using else "启用"}基础信息(入库提示)')
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@basic.route('/groupBind')
class GroupBind(Resource):
@staticmethod
def post():
for item in request.json['reagentData']:
entity = Dict2Obj(item)
reagent_reagent = ReagtReagent.query.filter_by(ReagentId=entity.ReagentId).first()
reagent_reagent.GroupName = request.json.get('groupName')
reagent_reagent.ReportItemName = request.json.get('reportItemName')
reagent_reagent.ReportItemCode = request.json.get('reportItemCode')
reagent_reagent.ReagentMark = entity.ReagentMark
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)

@ -0,0 +1,156 @@
from pypinyin import lazy_pinyin, Style
from sqlalchemy import or_
from utils.BatchCode import GetGroupCode
from utils.apiDoc import *
from utils.dictionaryHelper import *
from utils.listHelper import list2String
@dictionary.route('/positionList')
class PositionList(Resource):
@staticmethod
def get():
return GetList(ReagtPosition, ReagtPosition.PositionId, ReagtPosition.Position,
ReagtPosition.PositionCode, request.args)
@dictionary.route('/positionChange')
class PositionChange(Resource):
@staticmethod
def post():
return StatusChange(ReagtPosition, request.args['PositionId'],
request.args, ReagtPosition.PositionId, ReagtStock.Position, request.args['Position'])
@dictionary.route('/positionAdd')
class PositionAdd(Resource):
@staticmethod
def post():
data = Dict2Obj(request.json)
return DictionaryAdd(ReagtPosition.query.filter_by(Position=data.Position).first(),
ReagtPosition(Position=data.Position, Using=data.Using,
PositionCode=list2String(lazy_pinyin(data.Position,
style=Style.FIRST_LETTER))))
# @dictionary.route('/positionEdit')
# class PositionEdit(Resource):
# @staticmethod
# def post():
# if ReagtPosition.query.filter_by(Position=request.args['Position']).first() is not None:
# return SuccessResponse(ResultCode.DATA_ALREADY_EXISTED, None, None)
# positionEntity = ReagtPosition.query.filter_by(PositionId=request.args['PositionId']).first()
# db.session.query(ReagtStock).filter(ReagtStock.Position == positionEntity.Position)\
# .update({ReagtStock.Position: request.args['Position']})
# positionEntity.Position = request.args['Position']
# db.session.commit()
# return SuccessResponse(ResultCode.SUCCESS, None, None)
@dictionary.route('/supplierList')
class SupplierList(Resource):
@staticmethod
def get():
return GetList(ReagtSupplier, ReagtSupplier.SupplierId, ReagtSupplier.SupplierName,
ReagtSupplier.SupplierCode, request.args)
@dictionary.route('/supplierChange')
class SupplierChange(Resource):
@staticmethod
def post():
return StatusChange(ReagtSupplier, request.args['SupplierId'],
request.args, ReagtSupplier.SupplierId, ReagtStock.SupplierName,
request.args['SupplierName'])
@dictionary.route('/supplierAdd')
class SupplierAdd(Resource):
@staticmethod
def post():
data = Dict2Obj(request.json)
return DictionaryAdd(ReagtSupplier.query.filter_by(SupplierName=data.SupplierName).first(),
ReagtSupplier(SupplierName=data.SupplierName, Using=data.Using,
SupplierCode=list2String(lazy_pinyin(data.SupplierName,
style=Style.FIRST_LETTER))))
@dictionary.route('/groupAdd')
class GroupAdd(Resource):
@staticmethod
def post():
data = Dict2Obj(request.json)
return DictionaryAdd(ReagtGroup.query.filter_by(GroupName=data.GroupName).first(),
ReagtGroup(GroupName=data.GroupName, GroupCode=GetGroupCode()))
@dictionary.route('/groupDelete')
class GroupDelete(Resource):
@staticmethod
def post():
data = Dict2Obj(request.json)
reagent = ReagtReagent.query.filter_by(GroupName=data.GroupName).all()
if len(reagent) > 0:
return BadResponse(ResultCode.GROUP_INFO_IS_USING, None, None)
group = ReagtGroup.query.filter_by(GroupName=data.GroupName).first()
db.session.delete(group)
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@dictionary.route('/groupList')
class GroupList(Resource):
@staticmethod
def get():
return GetList(ReagtGroup, ReagtGroup.GroupId, ReagtGroup.GroupName, ReagtGroup.GroupCode,
request.args, is_all=True)
@dictionary.route('/reportItemList')
class ReportItemList(Resource):
@staticmethod
def get():
reportItem = db.session.query(ReagtReagent.ReportItem).group_by(ReagtReagent.ReportItem)\
.filter(ReagtReagent.ReportItem != None).all()
list_result = []
for item in reportItem:
list_result.append(item[0])
return SuccessResponse(ResultCode.SUCCESS, list_result, None)
@dictionary.route('/groupReagent')
class GroupReagent(Resource):
@staticmethod
def get():
data = request.args
filter_item = ReagtReagent.query.filter(ReagtReagent.GroupName == data['groupName'])\
.order_by(ReagtReagent.ReagentId.desc())
if data.get('query') is not None:
filter_item = ReagtReagent.query.filter(
or_(ReagtReagent.Name.contains(data['query']),
ReagtReagent.PinYinCode.contains(data['query']))) \
.filter(ReagtReagent.GroupName == data['groupName']) \
.order_by(ReagtReagent.ReagentId.desc())
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': filter_item.count(),
'list': db_page_entity(filter_item, data, 10)}, None)
# @dictionary.route('/supplierEdit')
# class SupplierEdit(Resource):
# @staticmethod
# def post():
# if ReagtSupplier.query.filter_by(SupplierName=request.args['SupplierName']).first() is not None:
# return SuccessResponse(ResultCode.DATA_ALREADY_EXISTED, None, None)
# supplierEntity = ReagtSupplier.query.filter_by(SupplierId=request.args['SupplierId']).first()
# db.session.query(ReagtStock).filter(ReagtStock.SupplierName == supplierEntity.SupplierName)\
# .update({ReagtStock.SupplierName: request.args['SupplierName']})
# supplierEntity.SupplierName = request.args['SupplierName']
# db.session.commit()
# return SuccessResponse(ResultCode.SUCCESS, None, None)

@ -0,0 +1,199 @@
# -*- coding: utf-8 -*-
"""
api.entry
~~~~~~~~~~~~~~
有关进出库的接口.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from sqlalchemy import or_, func
import datetime
from utils.PageHepler import db_page
from utils.apiDoc import *
from utils.dictionaryHelper import GetList
from utils.entryHelper import get_entry_list
import pandas as pd
@entry.route('/all')
class EntryAll(Resource):
@staticmethod
def post():
data = request.args
if data.get('query') is None:
return SuccessResponse(ResultCode.SOURCE_DATA_NONE, None, None)
reagentQuery = db.session.query(ReagtEntry.Name,
ReagtEntry.Specification,
ReagtEntry.Maker,
ReagtEntry.Unit,
ReagtEntry.CertificationCode,
ReagtEntry.Number,
ReagtEntry.Ratio,
ReagtEntry.SmallestUnit,
ReagtEntry.UnitPrice,
ReagtEntry.SellingPrice,
ReagtEntry.ProductionBatch,
ReagtEntry.MinValue,
ReagtEntry.MaxValue,
ReagtEntry.SupplierName,
ReagtEntry.TypeName,
ReagtEntry.Position,
ReagtEntry.EntryId).filter(
or_(ReagtEntry.Name.contains(data['query']), ReagtEntry.PinYinCode
.contains(data['query']))) \
.filter(ReagtEntry.Using == True)
return SuccessResponse(ResultCode.SUCCESS,
{'list': db_page(reagentQuery, ReagtEntry.EntryId, data, 6),
'totalNumber': reagentQuery.count()},
None)
@entry.route('/expiration')
class EntryExpiration(Resource):
@staticmethod
def get():
data = request.args
expirationReagentFilter = db.session.query(ReagtReagent.Name, ReagtStock.Expiration,
ReagtReagent.Specification, ReagtStock.Code,
ReagtStock.Position). \
join(ReagtReagent, ReagtStock.ReagentId == ReagtReagent.ReagentId). \
filter(ReagtStock.Expiration > datetime.now()). \
filter(ReagtStock.Expiration < (datetime.now() + timedelta(days=10))). \
order_by(ReagtStock.InTime.desc())
expirationReagentPaginate = expirationReagentFilter.paginate(int(data['pageNumber']), 8,
error_out=False)
resultList = [dict(zip(result.keys(), result)) for result in expirationReagentPaginate.items]
return SuccessResponse(ResultCode.SUCCESS, {'list': resultList,
'totalNumber': expirationReagentFilter.count()},
None)
@entry.route('/expirationExport')
class EntryExpirationExport(Resource):
@staticmethod
def get():
timestamp = datetime.now().timestamp()
expirationReagentFilter = db.session.query(ReagtReagent.Name, ReagtStock.Expiration,
ReagtStock.LastNumber,
ReagtReagent.Unit,
ReagtStock.MinNumberUnit,
ReagtReagent.SmallestUnit,
ReagtStock.SupplierName,
ReagtReagent.UnitPrice,
ReagtReagent.Maker,
ReagtStock.ProductionBatch,
ReagtReagent.MinValue,
ReagtReagent.MaxValue,
ReagtReagent.Specification, ReagtStock.Code,
ReagtStock.Position). \
join(ReagtReagent, ReagtStock.ReagentId == ReagtReagent.ReagentId). \
filter(ReagtStock.Expiration <= datetime.now()). \
order_by(ReagtStock.InTime.desc())
Name, Specification, LastNumber, Unit, MinNumberUnit, \
SmallestUnit, SupplierName, UnitPrice, \
Maker, ProductionBatch, Expiration, MaxValue, MinValue = [], [], [], [], [], [], [], [], [], [], [], [], []
for item in expirationReagentFilter:
Name.append(item.Name)
Specification.append(item.Specification)
LastNumber.append(item.LastNumber)
Unit.append(item.Unit)
MinNumberUnit.append(item.MinNumberUnit)
SmallestUnit.append(item.SmallestUnit)
SupplierName.append(item.SupplierName)
UnitPrice.append(item.UnitPrice)
Maker.append(item.Maker)
ProductionBatch.append(item.ProductionBatch)
Expiration.append(item.Expiration)
MaxValue.append(item.MaxValue)
MinValue.append(item.MinValue)
dit = {'耗材名称': Name, '规格': Specification, '数量(大单位)': LastNumber, '大单位': Unit,
'数量(小单位)': MinNumberUnit, '小单位': SmallestUnit, '供应商': SupplierName, '单价': UnitPrice,
'生产厂家': Maker, '产品批号': ProductionBatch, '效期': Expiration, '最大库存数量': MaxValue,
'最小库存数量': MinValue}
writer = pd.ExcelWriter('./file/' + '过期耗材汇总表' + str(timestamp).replace('.', '-') + '.xlsx')
df = pd.DataFrame(dit)
# columns参数用于指定生成的excel中列的顺序
df.to_excel(writer, columns=['耗材名称', '规格', '数量(大单位)', '大单位', '数量(小单位)', '小单位',
'供应商', '单价', '生产厂家', '产品批号', '效期', '最大库存数量',
'最小库存数量'], index=False, encoding='utf-8',
sheet_name='过期耗材汇总表')
writer.save()
return SuccessResponse(ResultCode.SUCCESS, '过期耗材汇总表' + str(timestamp).replace('.', '-'), None)
@entry.route('/bottomLimit')
class BottomLimit(Resource):
@staticmethod
def get():
bottomLimitFilter = db.session.query(ReagtReagent.Name, ReagtReagent.Specification,
ReagtReagent.MinValue,
func.sum(func.coalesce(ReagtStock.LastNumber, 0)).label('AllLastNumber')). \
join(ReagtStock, ReagtStock.ReagentId == ReagtReagent.ReagentId, isouter=True). \
filter(ReagtReagent.Using == True). \
group_by(ReagtReagent.Name, ReagtReagent.Specification, ReagtReagent.MinValue).subquery()
bottomLimitFilter = db.session.query(bottomLimitFilter.c.Name, bottomLimitFilter.c.Specification,
bottomLimitFilter.c.MinValue,
bottomLimitFilter.c.AllLastNumber,
(bottomLimitFilter.c.MinValue - bottomLimitFilter.c.AllLastNumber).label(
'Difference')
). \
filter(bottomLimitFilter.c.AllLastNumber < bottomLimitFilter.c.MinValue). \
order_by((bottomLimitFilter.c.MinValue - bottomLimitFilter.c.AllLastNumber))
bottomLimitPaginate = bottomLimitFilter.paginate(int(request.args['pageNumber']), 8, error_out=False)
resultList = [dict(zip(result.keys(), result)) for result in bottomLimitPaginate.items]
return SuccessResponse(ResultCode.SUCCESS, {'list': resultList,
'totalNumber': bottomLimitFilter.count()}, None)
@entry.route('/upperLimit')
class UpperLimit(Resource):
@staticmethod
def get():
upperLimitFilter = db.session.query(ReagtReagent.Name, ReagtReagent.Specification,
ReagtReagent.MaxValue,
func.sum(ReagtStock.LastNumber).label('AllLastNumber')). \
join(ReagtReagent, ReagtStock.ReagentId == ReagtReagent.ReagentId). \
group_by(ReagtReagent.Name, ReagtReagent.Specification, ReagtReagent.MaxValue).subquery()
upperLimitFilter = db.session.query(upperLimitFilter.c.Name, upperLimitFilter.c.Specification,
upperLimitFilter.c.MaxValue,
upperLimitFilter.c.AllLastNumber,
(upperLimitFilter.c.AllLastNumber - upperLimitFilter.c.MaxValue).label(
'Difference')). \
filter(upperLimitFilter.c.AllLastNumber > upperLimitFilter.c.MaxValue). \
order_by((upperLimitFilter.c.AllLastNumber - upperLimitFilter.c.MaxValue))
upperLimitPaginate = upperLimitFilter.paginate(int(request.args['pageNumber']), 8, error_out=False)
app.logger.info(upperLimitPaginate.items)
resultList = [dict(zip(result.keys(), result)) for result in upperLimitPaginate.items]
return SuccessResponse(ResultCode.SUCCESS, {'list': resultList,
'totalNumber': upperLimitFilter.count()}, None)
@entry.route('/specification')
class Specification(Resource):
@staticmethod
def get():
return get_entry_list(ReagtReagent.Specification, request.args)
@entry.route('/maker')
class Maker(Resource):
@staticmethod
def get():
return get_entry_list(ReagtReagent.Maker, request.args)
@entry.route('/unit')
class Unit(Resource):
@staticmethod
def get():
return get_entry_list(ReagtReagent.Unit, request.args)
@entry.route('/reagentType')
class ReagentType(Resource):
@staticmethod
def get():
return get_entry_list(ReagtReagent.TypeName, request.args)

@ -0,0 +1,103 @@
import random
import string
import gevent
from flask import make_response, send_from_directory, current_app
from pypinyin import lazy_pinyin, Style
from models.inStockExcel import InStockExcel
from utils import instockHelper
from utils.BatchCode import GetBatchCode
from utils.apiDoc import *
import os
import pandas as pd
filePath = './file/'
@file.route('/inStock')
class FileInStock(Resource):
@staticmethod
def post():
token = request.headers.get('X-Token')
inStockTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
excelFile = request.files.get('files')
batchCode = GetBatchCode()
batch_code_list = []
is_his_file = False
if not os.path.exists(filePath):
os.makedirs(filePath)
fileName = ''.join(random.choices(string.ascii_uppercase +
string.digits, k=16)) + \
os.path.splitext(excelFile.filename)[-1]
excelFile.save(filePath + fileName)
df = pd.read_excel(filePath + fileName, sheet_name='Sheet1')
if df.keys()[0] == '出库单号':
is_his_file = True
df = pd.read_excel(filePath + fileName, sheet_name='Sheet1',
names=['Code', 'Name', 'Specification', 'SupplierName', 'Maker', 'CertificationCode',
'ProductionBatch', 'Position', 'TypeName', 'Unit', 'SmallestUnit',
'Ratio', 'UnitPrice', 'SellingPrice', 'MaxValue', 'MinValue',
'Number', 'Expiration'])
else:
df = pd.read_excel(filePath + fileName, sheet_name='Sheet1',
names=['Name', 'Specification', 'SupplierName', 'Maker', 'CertificationCode',
'ProductionBatch', 'Position', 'TypeName', 'Unit', 'SmallestUnit',
'Ratio', 'UnitPrice', 'SellingPrice', 'MaxValue', 'MinValue',
'Number', 'Expiration'])
# 文件转实体
for index in df.index:
data = InStockExcel()
setattr(data, 'Name', str(df['Name'][index]).strip())
setattr(data, 'Specification', str(df['Specification'][index]))
setattr(data, 'SupplierName',
'' if pd.isnull(df['SupplierName'][index]) else str(df['SupplierName'][index]))
setattr(data, 'Maker', str(df['Maker'][index]))
setattr(data, 'CertificationCode',
'' if pd.isnull(df['CertificationCode'][index]) else str(df['CertificationCode'][index]))
setattr(data, 'ProductionBatch',
'' if pd.isnull(df['ProductionBatch'][index]) else str(df['ProductionBatch'][index]))
setattr(data, 'Position', str(df['Position'][index]))
setattr(data, 'TypeName', str(df['TypeName'][index]))
setattr(data, 'Unit', str(df['Unit'][index]))
setattr(data, 'SmallestUnit',
None if pd.isnull(df['SmallestUnit'][index]) else str(df['SmallestUnit'][index]))
setattr(data, 'Ratio',
None if pd.isnull(df['Ratio'][index]) else int(df['Ratio'][index]))
setattr(data, 'UnitPrice', float(df['UnitPrice'][index]))
setattr(data, 'SellingPrice', float(df['SellingPrice'][index]))
setattr(data, 'MaxValue', int(df['MaxValue'][index]))
setattr(data, 'MinValue', int(df['MinValue'][index]))
setattr(data, 'Number', int(df['Number'][index]))
setattr(data, 'Expiration', str(df['Expiration'][index]))
if is_his_file:
batchCode = str(df['Code'][index])
batch_code_list.append(batchCode)
# 入库信息写入
instockHelper.in_stock(data, batchCode, inStockTime, token, request.json, remark='文件入库')
try:
# 是否入库成功
db.session.commit()
except gevent.Timeout:
# 回调
db.session.invalidate()
raise
return SuccessResponse(ResultCode.ERROR, None, None)
except Exception:
# 回调
db.session.rollback()
raise
return SuccessResponse(ResultCode.ERROR, None, None)
os.remove(filePath + fileName)
return SuccessResponse(ResultCode.SUCCESS, None, fileName)
@file.route('/downloadInStock')
class DownloadInStock(Resource):
@staticmethod
def get():
uploads = os.path.join(os.path.abspath(os.path.dirname(current_app.root_path)),
app.config[request.args.get('path')])
app.logger.info(uploads)
return send_from_directory(directory=uploads, filename=request.args.get('fileName'))

@ -0,0 +1,83 @@
from utils.PageHepler import db_page, db_page_entity
from utils.apiDoc import *
from sqlalchemy import or_
@inventory.route('/list')
class InventoryList(Resource):
@staticmethod
def get():
inventoryListFilter = db.session.query(ReagtReagent.Name, ReagtReagent.Specification). \
join(ReagtStock, ReagtStock.ReagentId == ReagtReagent.ReagentId). \
filter(ReagtReagent.Using == True). \
group_by(ReagtReagent.Name, ReagtReagent.Specification).distinct()
if request.args.get('query') is not None and request.args.get('query') != '':
inventoryListFilter = db.session.query(ReagtReagent.Name, ReagtReagent.Specification). \
join(ReagtStock, ReagtStock.ReagentId == ReagtReagent.ReagentId). \
group_by(ReagtReagent.Name, ReagtReagent.Specification). \
filter(ReagtReagent.Using == True). \
filter(or_(ReagtReagent.Name.contains(request.args.get('query')), ReagtReagent.Specification
.contains(request.args.get('query')),
ReagtReagent.PinYinCode.contains(request.args.get('query')))).distinct()
result_data = db_page(inventoryListFilter, ReagtReagent.Name, request.args, 10)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': inventoryListFilter.count(),
'list': result_data}, None)
@inventory.route('/info')
class InventoryInfo(Resource):
@staticmethod
def get():
data = request.args
inventoryInfoFilter = db.session.query(ReagtStock.Code,
ReagtReagent.Name,
ReagtStock.Position,
ReagtStock.LastNumber,
ReagtReagent.TypeName,
ReagtStock.Number,
ReagtStock.InTime,
ReagtReagent.Specification,
ReagtStock.Expiration,
ReagtReagent.Maker,
ReagtStock.SupplierName,
ReagtReagent.CertificationCode,
ReagtStock.ProductionBatch,
ReagtReagent.UnitPrice,
ReagtReagent.SellingPrice,
ReagtStock.VerifyPeople,
ReagtReagent.Unit,
ReagtReagent.SmallestUnit,
ReagtReagent.Ratio,
ReagtStock.MinNumberUnit,
ReagtStock.StockId). \
filter(ReagtReagent.Name == data.get('Name'), ReagtReagent.Specification == data.get('Specification')). \
join(ReagtStock, ReagtStock.ReagentId == ReagtReagent.ReagentId)
result_data = db_page(inventoryInfoFilter, ReagtStock.InTime, data, 12)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': inventoryInfoFilter.count(),
'list': result_data}, None)
@inventory.route('/stockList')
class StockFile(Resource):
"""
库存盘点单
"""
@staticmethod
def get():
inventoryListFilter = db.session.query(ReagtReagent.Name,
ReagtReagent.Specification,
ReagtStock.Position,
ReagtStock.LastNumber,
ReagtReagent.Unit,
ReagtStock.MinNumberUnit,
ReagtReagent.SmallestUnit,
ReagtReagent.Ratio,
ReagtReagent.Maker,
ReagtStock.ProductionBatch,
ReagtReagent.PinYinCode
). \
join(ReagtStock, ReagtStock.ReagentId == ReagtReagent.ReagentId).order_by(ReagtReagent.PinYinCode)
return SuccessResponse(ResultCode.SUCCESS,
{'list': db_page(inventoryListFilter, ReagtStock.InTime,
request.args, inventoryListFilter.count())}, None)

@ -0,0 +1,27 @@
from sqlalchemy import or_
from utils.PageHepler import db_page_entity
from utils.apiDoc import *
@log.route('/list')
class BadUpload(Resource):
@staticmethod
def get():
data = request.args
reagentLogFilter = ReagtLog.query.order_by(ReagtLog.OperatingTime.desc())
if data.get('query') is not None:
reagentLogFilter = ReagtLog.query.join(ReagtOperatingType,
ReagtLog.OperatingType == ReagtOperatingType.OperatingCode). \
filter(or_(ReagtLog.Code.contains(data['query']),
ReagtLog.OperatingPeople.contains((data['query'])),
ReagtLog.Remark.contains(data['query']),
ReagtOperatingType.OperatingName.contains(data['query']),
ReagtLog.ReagentName.contains(data['query']),
ReagtLog.ReagentPosition.contains(data['query']),
ReagtLog.ReagentSpecification.contains(data['query']))). \
order_by(ReagtLog.OperatingTime.desc())
if data.get('index') is not None:
reagentLogFilter = ReagtLog.query.filter_by(OperatingType=data['index']). \
order_by(ReagtLog.OperatingTime.desc())
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': reagentLogFilter.count(),
'list': db_page_entity(reagentLogFilter, data, 13)}, None)

@ -0,0 +1,210 @@
from diff.stock import getDiffStockList
from utils.PageHepler import db_page
from sqlalchemy import func
from utils.apiDoc import *
from utils.configOperatingTypeHelper import *
from utils.statisticsHelper import export_diff, get_complete_number, get_complete_current_type_number
from openpyxl import Workbook
from openpyxl.styles import Alignment, Border, Side, Font
import pandas as pd
def alignment_merge(ws, area, value, isAlignment=True):
name_area = ws[area]
ws.merge_cells(area)
if isAlignment:
name_area[0][0].alignment = Alignment(horizontal='center', vertical='center')
name_area[0][0].value = value
@statistics.route('/log')
class StatisticsInStock(Resource):
@staticmethod
def get():
if request.args.get('type') is None:
return BadResponse(ResultCode.PARAM_IS_INVALID, None, None)
outStockReagentFilter = db.session.query(
(ReagtLog.ReagentName + ReagtLog.ReagentSpecification).label('TotalName'),
func.sum(ReagtLog.ReagentNumber).label('TotalNumber')). \
group_by(ReagtLog.ReagentName, ReagtLog.ReagentSpecification).filter(
ReagtLog.OperatingType == GetOperatingTypeUseName(request.args['type'])).filter(
ReagtLog.OperatingTime < datetime.now()). \
filter(ReagtLog.OperatingTime > (datetime.now() - timedelta(days=10))).order_by(
func.sum(ReagtLog.ReagentNumber)).all()
if request.args.get('startTime') is not None and request.args.get('endTime') is not None:
outStockReagentFilter = db.session.query(
(ReagtLog.ReagentName + ReagtLog.ReagentSpecification).label('TotalName'),
func.sum(ReagtLog.ReagentNumber).label('TotalNumber')). \
group_by(ReagtLog.ReagentName, ReagtLog.ReagentSpecification).filter(
ReagtLog.OperatingType == GetOperatingTypeUseName(request.args['type'])).filter(
ReagtLog.OperatingTime < request.args['endTime']). \
filter(ReagtLog.OperatingTime > request.args['startTime']).order_by(
func.sum(ReagtLog.ReagentNumber)).all()
return SuccessResponse(ResultCode.SUCCESS, outStockReagentFilter, None)
@statistics.route('/list')
class StatisticsList(Resource):
@staticmethod
def get():
data = request.args
reagentLogFilter = export_diff(data)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': reagentLogFilter.count(),
'list': db_page(reagentLogFilter, ReagtLog.OperatingTime,
data, 13)}, None)
@statistics.route('/export')
class StatisticsExport(Resource):
@staticmethod
def get():
data = request.args
timestamp = datetime.now().timestamp()
reagentLogFilter = export_diff(data)
ReagentName, ReagentSpecification, ReagentNumber, \
Unit, OperateMinNumber, UnitPrice, SmallestUnit, ReagentPosition, \
ProductionBatch, Maker, Expiration, Code, OperatingTime, \
OperatingPeople, SupplierName, Remark = [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []
for item in reagentLogFilter:
ReagentName.append(item.ReagentName)
ReagentSpecification.append(item.ReagentSpecification)
ReagentNumber.append(item.ReagentNumber)
Unit.append(item.Unit)
UnitPrice.append(item.UnitPrice)
Maker.append(item.Maker)
OperateMinNumber.append(item.OperateMinNumber)
SmallestUnit.append(item.SmallestUnit)
ReagentPosition.append(item.ReagentPosition)
ProductionBatch.append(item.ProductionBatch)
Expiration.append(item.Expiration)
Code.append(item.Code)
OperatingTime.append(item.OperatingTime)
OperatingPeople.append(item.OperatingPeople)
SupplierName.append(item.SupplierName)
Remark.append(item.Remark)
dit = {'耗材名称': ReagentName, '规格': ReagentSpecification, '数量(大单位)': ReagentNumber, '大单位': Unit,
'数量(小单位)': OperateMinNumber, '小单位': SmallestUnit, '供应商': SupplierName, '单价': UnitPrice,
'生产厂家': Maker, '产品批号': ProductionBatch, '效期': Expiration, '操作时间': OperatingTime,
'入库批号': Code, '操作员': OperatingPeople}
writer = pd.ExcelWriter('./file/' + data.get('title') + str(timestamp).replace('.', '-') + '.xlsx')
df = pd.DataFrame(dit)
# columns参数用于指定生成的excel中列的顺序
df.to_excel(writer, columns=['耗材名称', '规格', '数量(大单位)', '大单位', '数量(小单位)', '小单位',
'供应商', '单价', '生产厂家', '产品批号', '效期', '操作时间',
'入库批号', '操作员'], index=False, encoding='utf-8',
sheet_name=data.get('title'))
writer.save()
return SuccessResponse(ResultCode.SUCCESS, data.get('title') + str(timestamp).replace('.', '-'), None)
@statistics.route('/complete')
class StatisticsComplete(Resource):
@staticmethod
def get():
data = request.args
start_date = data.get('startDate') if data.get('startDate') is not None else (datetime.now() -
timedelta(days=10))
end_data = data.get('endDate') if data.get('endDate') is not None else datetime.now()
timestamp = datetime.now().timestamp()
wb = Workbook()
ws = wb.active
ws.title = '试剂与耗材统计汇总表'
alignment = Alignment(horizontal='center', vertical='center')
border = Border(left=Side(border_style='thin', color='000000'),
right=Side(border_style='thin', color='000000'),
top=Side(border_style='thin', color='000000'),
bottom=Side(border_style='thin', color='000000'))
title_area = ws['A1:AH1']
ws.merge_cells('A1:AH1')
title_area[0][0].alignment = alignment
title_area[0][0].value = '按试剂名称分类出入数汇总表'
title_area[0][0].font = Font(name='黑体', bold=True, size=16)
alignment_merge(ws, 'A2:AH2', '统计日期:' + str(start_date) + '' + str(end_data),
isAlignment=False)
alignment_merge(ws, 'A3:A4', '耗材名称')
alignment_merge(ws, 'B3:B4', '规格')
alignment_merge(ws, 'C3:C4', '生产厂家')
alignment_merge(ws, 'D3:D4', '批准文号')
alignment_merge(ws, 'E3:E4', '生产批号')
alignment_merge(ws, 'F3:F4', '耗材类型')
alignment_merge(ws, 'G3:G4', '进货价')
alignment_merge(ws, 'H3:H4', '销售价')
alignment_merge(ws, 'I3:I4', '有效期')
alignment_merge(ws, 'J3:N3', '上期结存')
alignment_merge(ws, 'O3:S3', '本期进向汇总')
alignment_merge(ws, 'T3:X3', '本期出向汇总')
alignment_merge(ws, 'Y3:AC3', '本期调整数合计(报损、报废合计)')
alignment_merge(ws, 'AD3:AH3', '本期余额')
ws['J4'] = '数量'
ws['K4'] = '大单位'
ws['L4'] = '数量'
ws['M4'] = '小单位'
ws['N4'] = '数量描述'
ws['O4'] = '数量'
ws['P4'] = '大单位'
ws['Q4'] = '数量'
ws['R4'] = '小单位'
ws['S4'] = '数量描述'
ws['T4'] = '数量'
ws['U4'] = '大单位'
ws['V4'] = '数量'
ws['W4'] = '小单位'
ws['X4'] = '数量描述'
ws['Y4'] = '数量'
ws['Z4'] = '大单位'
ws['AA4'] = '数量'
ws['AB4'] = '小单位'
ws['AC4'] = '数量描述'
ws['AD4'] = '数量'
ws['AE4'] = '大单位'
ws['AF4'] = '数量'
ws['AG4'] = '小单位'
ws['AH4'] = '数量描述'
title_area = ws['A1:AH4']
for row in title_area:
for cell in row:
cell.border = border
filterObject = getDiffStockList()
reagent_stock = filterObject.filter(ReagtStock.Using).order_by(ReagtStock.PinYinCode).all()
reagent_id_list = []
index = 0
for reagent in reagent_stock:
if reagent.ReagentId in reagent_id_list:
continue
reagent_log_before = ReagtLog.query.filter_by(ReagentId=reagent.ReagentId) \
.filter(ReagtLog.OperatingTime < start_date) \
.order_by(ReagtLog.OperatingTime.desc()).all()
excel_cell = [reagent.Name, reagent.Specification, reagent.Maker, reagent.CertificationCode,
reagent.ProductionBatch,
reagent.TypeName, str(reagent.UnitPrice), str(reagent.SellingPrice), str(reagent.Expiration)]
get_complete_number(reagent_log_before, reagent, excel_cell)
reagent_log_current_in_stock = (ReagtLog.query.filter_by(ReagentId=reagent.ReagentId,
OperatingType=GetOperatingTypeInStock())
.filter(ReagtLog.OperatingTime > start_date)
.order_by(ReagtLog.OperatingTime).all())
get_complete_number(reagent_log_current_in_stock, reagent, excel_cell)
get_complete_current_type_number(start_date, reagent, excel_cell, GetOperatingTypeOutStock())
get_complete_current_type_number(start_date, reagent, excel_cell, GetOperatingTypeBad(),
GetOperatingTypeScrap())
excel_cell.append(str(reagent.LastNumber))
excel_cell.append(reagent.Unit)
excel_cell.append(str(reagent.MinNumberUnit))
excel_cell.append(reagent.SmallestUnit)
excel_cell.append(str(reagent.LastNumber) + reagent.Unit + str(reagent.MinNumberUnit) +
reagent.SmallestUnit)
ws._current_row = 4 + index
ws.append(excel_cell)
reagent_id_list.append(reagent.ReagentId)
index += 1
for row in ws.rows:
for cell in row:
cell.border = border
wb.save('./file/' + '按试剂名称分类出入数汇总表' + str(timestamp).replace('.', '-') + '.xlsx')
return SuccessResponse(ResultCode.SUCCESS, '按试剂名称分类出入数汇总表' + str(timestamp).replace('.', '-'),
None)

@ -0,0 +1,473 @@
# -*- coding: utf-8 -*-
"""
api.stock
~~~~~~~~~~~~~~
有关进出库的接口.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
import gevent
from diff.stock import getDiffStockList
from utils import instockHelper
from utils.PageHepler import db_page, entityDictToStringDict, db_page_entity
from utils.apiDoc import *
from models.stockListModel import *
from models.InStockModel import *
from utils.configOperatingTypeHelper import GetOperatingTypeInStock, GetOperatingTypeDelete, GetOperatingTypeUpdate, \
GetOperatingTypeEdit
from utils.entryHelper import get_entry_list
from utils.listHelper import *
from utils.BatchCode import *
from models.reagentTypeList import *
from pypinyin import lazy_pinyin, Style
from io import BytesIO
import pandas as pd
from utils.nativeDbHelper import HisMssqlConnect
from utils.outStockHelper import *
from sqlalchemy import or_, func
from utils.ReagentTypeListSort import *
from utils.pandasHelper import null_value
@stock.route('/list')
class StockList(Resource):
@staticmethod
def post():
"""
get stock info list
:return: stock list
"""
data = request.args
filterObject = getDiffStockList()
if data.get('query') is not None and data.get('query') != '':
filterObject = filterObject.filter(or_(ReagtStock.PinYinCode.contains(data['query']),
ReagtStock.Position.contains(data['query']),
ReagtReagent.Name.contains(data['query']),
ReagtStock.Code.contains(data['query'])))
if data.get('groupName') is not None and data.get('groupName') != '':
filterObject = filterObject.filter(ReagtReagent.GroupName == data['groupName'])
if data.get('reportItemName') is not None and data.get('reportItemName') != '':
filterObject = filterObject.filter(ReagtReagent.ReportItem == data.get('reportItemName'))
data_list = db_page(filterObject, ReagtStock.InTime, data, 10)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': filterObject.count(), 'list': data_list}, None)
@stock.route('/add')
class StockAdd(Resource):
"""
试剂耗材入库
"""
@staticmethod
@stock.doc(body=[in_stock_model])
def post():
token = request.headers.get('X-Token')
batchCode = GetBatchCode()
inStockTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
for item in request.json['inStockData']:
data = Dict2Obj(item)
instockHelper.in_stock(data, batchCode, inStockTime, token, request.json)
try:
db.session.commit()
except gevent.Timeout:
db.session.invalidate()
raise
return SuccessResponse(ResultCode.ERROR, None, None)
except Exception:
db.session.rollback()
raise
return SuccessResponse(ResultCode.ERROR, None, None)
return SuccessResponse(ResultCode.SUCCESS,
{'inStockBatchCode': batchCode, 'verifyPeople': verify_jwt_username(token)}, None)
@stock.route('/hisOutCodeList')
class HisOutCodeList(Resource):
"""
his出库单列表
"""
@staticmethod
def get():
reagent_int_int_code = db.session.query(ReagtReceipt.ReceiptCode.label('ReceiptCode')) \
.filter(ReagtReceipt.ReceiptCode.contains('E')) \
.group_by(ReagtReceipt.ReceiptCode).all()
reagent_int_int_code_string = ','.join(F'\'{str(code)[2:-2]}' for code in reagent_int_int_code)
if reagent_int_int_code_string is '':
his_out_list_code = HisMssqlConnect() \
.query("LIS_OutSheet_CL", F"select 出库单号,出库日期 from LIS_OutSheet_CL(nolock) "
F"where 出库名称 = '检验科' "
F"group by 出库单号,出库日期 "
F"ORDER BY 出库日期 DESC", cols=['出库单号', '出库日期']) \
.drop_duplicates()
else:
his_out_list_code = HisMssqlConnect() \
.query("LIS_OutSheet_CL", F"select 出库单号,出库日期 from LIS_OutSheet_CL(nolock) "
F"where 出库名称 = '检验科' "
F"and 出库单号 not in ({reagent_int_int_code_string}) "
F"group by 出库单号,出库日期 "
F"ORDER BY 出库日期 DESC", cols=['出库单号', '出库日期']) \
.drop_duplicates()
if request.args.get('query') is not None:
his_out_list_code = HisMssqlConnect() \
.query("LIS_OutSheet_CL",
F"select * from LIS_OutSheet_CL(nolock) where "
F"出库名称 = '检验科' and 出库单号 like '%{str.strip(request.args.get('query'))}%'") \
.drop_duplicates()
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': len(his_out_list_code),
'list': dataFrame_paginate(his_out_list_code,
request.args.get('pageNumber'), 10, 10)
.to_dict()},
None)
@stock.route('/hisOutList')
class HisOutList(Resource):
"""
出库单对应的试剂或者耗材列表
"""
@staticmethod
def get():
his_out_list = HisMssqlConnect() \
.query("LIS_OutSheet_CL",
F"select * from LIS_OutSheet_CL(nolock) where 出库名称 = '检验科' and 出库单号='{request.args.get('outCode')}'")
his_out_list_page = dataFrame_paginate(his_out_list, request.args.get('pageNumber'), 10, 10).to_dict()
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': len(his_out_list),
'list': his_out_list_page}, None)
@stock.route('/hisListExport')
class HisListExport(Resource):
"""
his出库的文件下载
"""
@staticmethod
def get():
if request.args.get('outCode') is not None:
his_out_list = HisMssqlConnect() \
.query("LIS_OutSheet_CL",
F"select * from LIS_OutSheet_CL(nolock) "
F"where 出库名称 = '检验科' and 出库单号='{request.args.get('outCode')}'")
else:
reagent_int_int_code = db.session.query(ReagtReceipt.ReceiptCode.label('ReceiptCode')) \
.filter(ReagtReceipt.ReceiptCode.contains('E')) \
.group_by(ReagtReceipt.ReceiptCode).all()
reagent_int_int_code_string = ','.join(F'\'{str(code)[2:-2]}' for code in reagent_int_int_code)
his_out_list = HisMssqlConnect() \
.query("LIS_OutSheet_CL",
F"select * from LIS_OutSheet_CL(nolock) "
F"where 出库名称 = '检验科' and 出库单号 not in ({reagent_int_int_code_string})"
F"ORDER BY 出库日期 DESC")
his_out_list.drop(his_out_list.columns[[i for i in range(1, 5)]], axis=1, inplace=True)
bio = BytesIO()
his_out_list.style.applymap(null_value, subset=['耗材名称', '耗材规格', '生产厂家',
'存放位置', '耗材类型', '最大单位',
'进价(元) 批发价(批发单位)', '售价(元) 零售价(批发单位)',
'最大库存量(大单位为主)', '出库数量(批发单位)',
'有效期']) \
.to_excel(bio, index=False, encoding='utf-8')
bio.seek(0)
fileByte = bio.getvalue()
bio.close()
return Response(fileByte, content_type='application/vnd.ms-excel')
@stock.route('/delete')
class Delete(Resource):
"""
删除试剂或者耗材
"""
@staticmethod
def get():
token = request.headers.get('X-Token')
data = request.args
app.logger.info(data)
delete_stock = ReagtStock.query.filter_by(StockId=int(data.get('StockId'))).first()
if 'E' in delete_stock.Code:
return SuccessResponse(ResultCode.NOT_ALLOW_DELETE_HIS_IN_STOCK_INTO, None, None)
db.session.delete(delete_stock)
LogAdd(token, GetOperatingTypeDelete(), data, delete_stock.Code, data.get('Name'),
list2String(lazy_pinyin(data.get('Name') + data.get('Specification'), style=Style.FIRST_LETTER)),
data.get('LastNumber'), data.get('Specification'), data.get('Position'),
reagentId=delete_stock.ReagentId)
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@stock.route('/receiptDelete')
class ReceiptDelete(Resource):
"""
从入库单删除整个入库信息
"""
@staticmethod
def get():
token = request.headers.get('X-Token')
data = request.args
app.logger.info(data)
delete_stock_list = ReagtStock.query.filter_by(Code=data.get('Code')).all()
delete_receipt = ReagtReceipt.query.filter_by(ReceiptCode=data.get('Code')).first()
db.session.delete(delete_receipt)
for delete_stock in delete_stock_list:
db.session.delete(delete_stock)
reagent = ReagtReagent.query.filter_by(ReagentId=delete_stock.ReagentId).first()
LogAdd(token, GetOperatingTypeDelete(), data, delete_stock.Code, reagent.Name,
list2String(lazy_pinyin(reagent.Name + reagent.Specification, style=Style.FIRST_LETTER)),
delete_stock.LastNumber, reagent.Specification, delete_stock.Position,
reagentId=delete_stock.ReagentId, remark='删除his入库信息')
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@stock.route('/typeList')
class TypeList(Resource):
"""
按照汇总分类列表
"""
@staticmethod
def post():
data = request.args
filterObject = ReagtReagent.query.join(ReagtStock,
ReagtStock.ReagentId == ReagtReagent.ReagentId).distinct().order_by(
ReagtReagent.ReagentId.desc())
if data.get('query') is not None:
filterObject = ReagtReagent.query.join(ReagtStock,
ReagtStock.ReagentId == ReagtReagent.ReagentId) \
.filter(or_(ReagtStock.PinYinCode.contains(data['query']), ReagtReagent.Name.contains(data['query']))) \
.distinct().order_by(ReagtReagent.ReagentId.desc())
reagentBasicsPaginate = filterObject.paginate(
int(data['pageNumber']), 10,
error_out=False)
reagentTypeList = []
if reagentBasicsPaginate.items is not None:
for reagent in reagentBasicsPaginate.items:
reagentType = ReagentTypeList(ReagentId=reagent.ReagentId, Name=reagent.Name,
Specification=reagent.Specification,
Maker=reagent.Maker, CertificationCode=reagent.CertificationCode,
UnitPrice=reagent.UnitPrice, SellingPrice=reagent.SellingPrice,
MaxValue=reagent.MaxValue, MinValue=reagent.MinValue,
TypeName=reagent.TypeName, hasChildren=True)
reagentTypeList.append(reagentType.value())
return SuccessResponse(ResultCode.SUCCESS, {"totalNumber": filterObject.count(),
"list": ReagentTypeSort(reagentTypeList)}, None)
@stock.route('/typeInfo')
class TypeInfo(Resource):
"""
汇总分类下的子信息
"""
@staticmethod
def get():
data = request.args
reagentStockInfo = ReagtStock.query.filter_by(ReagentId=data['ReagentId']).all()
return SuccessResponse(ResultCode.SUCCESS, reagentStockInfo, None)
@stock.route('/outStockList')
class OutStockList(Resource):
"""
出库列表
"""
@staticmethod
def get():
data = request.args
outStockReagentFilter = db.session.query(ReagtReagent.Name.label('Name'),
ReagtReagent.Specification.label('Specification'),
ReagtStock.Position.label('Position'),
ReagtReagent.Unit.label('Unit'),
ReagtReagent.SmallestUnit.label('SmallestUnit'),
ReagtReagent.Ratio.label('Ratio'),
ReagtStock.ProductionBatch.label('ProductionBatch'),
func.sum(ReagtStock.LastNumber).label('TotalNumber'),
func.sum(ReagtStock.MinNumberUnit).label('MinNumberUnit')). \
join(ReagtReagent, ReagtStock.ReagentId == ReagtReagent.ReagentId). \
group_by(ReagtReagent.Name, ReagtStock.ReagentId, ReagtStock.Position, ReagtReagent.Specification,
ReagtReagent.Unit, ReagtReagent.SmallestUnit, ReagtReagent.Ratio, ReagtStock.ProductionBatch)
if data.get('query') is not None and data.get('query') != '':
outStockReagentFilter = outStockReagentFilter.filter(
or_(ReagtReagent.Name.contains(data['query']), ReagtStock.Position.contains(data['query']),
ReagtReagent.Specification.contains(data['query']), ReagtStock.PinYinCode.contains(data['query'])))
if data.get('groupName') is not None and data.get('groupName') != '':
outStockReagentFilter = outStockReagentFilter.filter(ReagtReagent.GroupName == data.get('groupName'))
if data.get('reportItemName') is not None and data.get('reportItemName') != '':
outStockReagentFilter = outStockReagentFilter.filter(ReagtReagent.ReportItem == data.get('reportItemName'))
outStockReagentPage = outStockReagentFilter.order_by(ReagtStock.Position.desc()).paginate(
int(data['pageNumber']), 10,
error_out=False)
resultList = [dict(zip(result.keys(), result)) for result in outStockReagentPage.items]
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': outStockReagentFilter.count(),
'list': resultList}, None)
@stock.route('/outStock')
class OutStock(Resource):
"""
出库试剂或者耗材
"""
@staticmethod
def post():
token = request.headers.get('X-Token')
for item in request.json['outStockData']:
priorityDelivery(item, 1, token, request.json)
return SuccessResponse(ResultCode.SUCCESS,
{'outStockBatchCode': GetBatchCode(), 'verifyPeople': verify_jwt_username(token)}, None)
@stock.route('/update')
class Update(Resource):
"""
调整库存信息
"""
@staticmethod
def post():
token = request.headers.get('X-Token')
reagent_stock = ReagtStock.query.filter_by(StockId=request.json.get('StockId')).first()
data = {'Remark': '库存数量调整,大单位剩余数量由' + str(reagent_stock.LastNumber) + '调整为' +
str(request.json.get('ChangeNumber')) + '小单位数量由' + str(
reagent_stock.MinNumberUnit) + '调整为' +
str(request.json.get('ChangeMinUnitNumber'))}
if request.json.get('ChangeNumber') is 0 and request.json.get('ChangeMinUnitNumber') is 0:
db.session.delete(reagent_stock)
db.session.commit()
else:
reagent_stock.LastNumber = request.json.get('ChangeNumber')
reagent_stock.MinNumberUnit = request.json.get('ChangeMinUnitNumber')
db.session.commit()
reagent_reagent = ReagtReagent.query.filter_by(ReagentId=reagent_stock.ReagentId).first()
LogAdd(token, GetOperatingTypeUpdate(), data, reagent_stock.Code, reagent_reagent.Name,
list2String(lazy_pinyin(reagent_reagent.Name + reagent_reagent.Specification, style=Style.FIRST_LETTER)),
request.json.get('ChangeNumber'), reagent_reagent.Specification, reagent_stock.Position)
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@stock.route('/barCode')
class BarCode(Resource):
"""
条码出库信息根据条码查询当前试剂或者耗材信息
"""
@staticmethod
def get():
data = request.args
filterObject = getDiffStockList().filter(ReagtStock.BarCode == data.get('barCode'))
return SuccessResponse(ResultCode.SUCCESS, db_page(filterObject, ReagtStock.InTime, data, 1)
, None)
@stock.route('/barCodeHistory')
class BarCodeHistory(Resource):
"""
条码出库历史
"""
@staticmethod
def get():
data = request.args
filterObject = db.session.query(ReagtLog.OperatingTime,
ReagtLog.Code,
ReagtLog.BarCode,
ReagtLog.LogId,
ReagtLog.OperatingPeople,
ReagtLog.ReagentName,
ReagtLog.ReagentNumber,
ReagtLog.ReagentPosition,
ReagtLog.ReagentSpecification,
ReagtLog.Remark).filter(ReagtLog.OperatingType == 'OutStock')
return SuccessResponse(ResultCode.SUCCESS, db_page(filterObject, ReagtLog.OperatingTime, data, 5), None)
@stock.route('/barCodeOutStock')
class BarCodeOutStock(Resource):
"""
条码出库
"""
@staticmethod
def get():
date = request.args
outStockData = ReagtStock.query.filter_by(BarCode=date.get('barCode')).first()
if outStockData.LastNumber > date.get('outNumber'):
outStockData.LastNumber -= date.get('outNumber')
else:
db.session.delete(outStockData)
db.session.commit()
@stock.route('/editStock')
class EditStock(Resource):
"""
编辑库存
"""
@staticmethod
def post():
token = request.headers.get('X-Token')
log_info = ''
current_stock = ReagtStock.query.filter_by(StockId=request.json.get('StockId')).first()
current_reagent = ReagtReagent.query.filter_by(ReagentId=current_stock.ReagentId).first()
if current_stock.ProductionBatch != request.json.get('ProductionBatch'):
log_info += '将生产批次号从' + str(current_stock.ProductionBatch) + '修改为' + str(
request.json.get('ProductionBatch'))
current_stock.ProductionBatch = request.json.get('ProductionBatch')
if current_stock.Position != request.json.get('Position'):
log_info += '将耗材位置信息从' + str(current_stock.Position) + '修改为' + str(request.json.get('Position'))
current_stock.Position = request.json.get('Position')
data = {'Remark': log_info}
LogAdd(token, GetOperatingTypeEdit(), data, current_stock.Code, current_reagent.Name,
current_reagent.PinYinCode, 0, current_reagent.Specification,
current_stock.Position)
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
@stock.route('/noGroupList')
class NoGroupList(Resource):
@staticmethod
def post():
"""
get no group stock info list
:return: no group stock list
"""
data = request.args
filterObject = ReagtReagent.query.filter(
or_(ReagtReagent.GroupName == None, ReagtReagent.GroupName == '')).filter(ReagtReagent.Using == True)
if data.get('query') is not None and data.get('query') != '':
filterObject = ReagtReagent.query.filter(or_(
ReagtReagent.Name.contains(data['query']),
ReagtReagent.PinYinCode.contains(data['query']))) \
.filter(ReagtReagent.GroupName == None).filter(ReagtReagent.Using == True)
if data.get('groupName') is not None and data.get('groupName') != '':
filterObject = ReagtReagent.query.filter(ReagtReagent.GroupName == data.get('groupName')).filter(ReagtReagent.Using == True)
data_list = db_page_entity(filterObject, data, 10)
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': filterObject.count(), 'list': data_list}, None)
@stock.route('/setGroup')
class SetGroup(Resource):
@staticmethod
def post():
for item in request.json['groupData']:
item = Dict2Obj(item)
reagent_info = ReagtReagent.query.filter_by(ReagentId=item.ReagentId).first()
reagent_all = ReagtReagent.query.filter_by(Name=item.Name).all()
for reagent_item in reagent_all:
reagent_item.GroupName = request.json['groupName']
reagent_item.ReportItem = request.json['reportName']
reagent_info.GroupName = request.json['groupName']
reagent_info.ReportItem = request.json['reportName']
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
"""
api.user
~~~~~~~~~~~~~~
有关用户操作的接口.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from utils.PageHepler import singleEntityToJson
from utils.apiDoc import *
# 接口路由
@user.route('/login')
class IndexApi(Resource):
# @api.marshal_with(return_model,code=200)
# @api.expect(return_model)
@staticmethod
def post():
"""
user login
:return: user info token
"""
data = request.json
userInfo = DictUser.query.filter_by(UserCode=data['username'], PassWord=data['password']).first()
if userInfo is None:
return SuccessResponse(ResultCode.USER_LOGIN_ERROR, None, None)
return SuccessResponse(ResultCode.SUCCESS, None,
generate_jwt_long({'UserName': userInfo.UserName}))
@user.route('/info')
class UserInfo(Resource):
@staticmethod
def post():
"""
get user info
:return: user info
"""
token = request.headers.get('X-Token')
userInfo = DictUser.query.filter_by(UserName=verify_jwt_username(token)).first()
if userInfo is None:
return BadResponse(ResultCode.INVALID_TOKEN, None, None)
return SuccessResponse(ResultCode.SUCCESS, singleEntityToJson(userInfo),
None)
@user.route('/code')
class UserCode(Resource):
@staticmethod
def post():
data = request.json
user_info = DictUser.query.filter_by(UserCode=data['userCode']).first()
if user_info is None:
return BadResponse(ResultCode.USER_NOT_EXIST, None, None)
return SuccessResponse(ResultCode.SUCCESS, {'userName': user_info.UserName}, None)

@ -0,0 +1,4 @@
[jwt]
EXPIRY_HOURS=1
REFRESH_DAYS=1
SECRET='lis_reagent'

@ -0,0 +1,10 @@
[mssql-config]
host = 192.168.12.10
;host = 139.155.175.14
user = XBDLISUser
;user = sa
;pwd = BlueFlag.Lis!@#
pwd = 7439a39215e13707fcbbc444618dfd14
;pwd = e2ba51ec7efee717794b5c0084011c67
db = hisdata
charset = UTF-8

@ -0,0 +1,17 @@
[operatingType]
bad = Bad
inStock = InStock
outStock = OutStock
delete = Delete
update = Update
basicReagentOpen = BasicReagentOpen
basicReagentClose = BasicReagentClose
basicEntryOpen = BasicEntryOpen
basicEntryClose = BasicEntryClose
scrap = Scrap
edit = Edit
[approveType]
approving = Approving
approved = Approved
overrule = Overrule

@ -0,0 +1,31 @@
from models.db import db
from models.entity import ReagtStock, ReagtReagent
def getDiffStockList():
return db.session.query(
ReagtReagent.ReagentId,
ReagtStock.Code,
ReagtReagent.Name,
ReagtStock.Position,
ReagtStock.LastNumber,
ReagtReagent.TypeName,
ReagtStock.Number,
ReagtStock.InTime,
ReagtReagent.Specification,
ReagtStock.Expiration,
ReagtReagent.Maker,
ReagtStock.SupplierName,
ReagtReagent.CertificationCode,
ReagtStock.ProductionBatch,
ReagtReagent.UnitPrice,
ReagtReagent.SellingPrice,
ReagtStock.VerifyPeople,
ReagtReagent.Unit,
ReagtReagent.SmallestUnit,
ReagtReagent.Ratio,
ReagtStock.StockId,
ReagtStock.MinNumberUnit,
ReagtReagent.MaxValue,
ReagtReagent.MinValue). \
join(ReagtStock, ReagtStock.ReagentId == ReagtReagent.ReagentId)

@ -0,0 +1,26 @@
import json
from flask import Blueprint
from statusCode.responseEntity import SuccessResponse
from statusCode.resultCode import ResultCode
exception = Blueprint('exception', __name__)
@exception.app_errorhandler(404)
def error_404(error):
return SuccessResponse(ResultCode.NOT_FIND, None, None)
@exception.app_errorhandler(405)
def error_405(error):
return SuccessResponse(ResultCode.METHOD_ERROR, None, None)
@exception.app_errorhandler(Exception)
def error_500(error):
return SuccessResponse(ResultCode.SERVICE_ERROR, None, None)
class MyError(Exception):
"""自定义错误类"""
pass

BIN
code/file/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
"""
models.InStockModel
~~~~~~~~~~~~~~
进库实体.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
import json
from utils.List2Json import *
class InStockModel(object):
Name = '',
Specification = '',
day = 0,
Maker = '',
CertificationCode = '',
UnitPrice = 0,
SellingPrice = 0,
MaxValue = 0,
MinValue = 0,
ProductionBatch = '',
TypeName = '',
Position = '',
Number = 0,
SupplierName = ''
hasChildren = False
def __init__(self, Name, Specification, day, Maker, CertificationCode, UnitPrice, SellingPrice, MaxValue, MinValue,
ProductionBatch, TypeName, Position, Number, SupplierName, hasChildren):
self.Name = Name
self.Specification = Specification
self.day = day
self.Maker = Maker
self.CertificationCode = CertificationCode
self.UnitPrice = UnitPrice
self.Specification = Specification
self.SellingPrice = SellingPrice
self.MaxValue = MaxValue
self.MinValue = MinValue
self.ProductionBatch = ProductionBatch
self.TypeName = TypeName
self.Position = Position
self.Number = Number
self.SupplierName = SupplierName
self.hasChildren = hasChildren
@property
def value(self):
"""
StockListModel json data
:return: json data
"""
return {"Name": self.Name, "Specification": self.Specification, "day": self.day, "Maker":
self.Maker, "CertificationCode": self.CertificationCode, "UnitPrice": self.UnitPrice, "Specification":
self.Specification, "SellingPrice": self.SellingPrice, "MaxValue": self.MaxValue, "MinValue":
self.MinValue, "ProductionBatch": self.ProductionBatch, "TypeName": self.TypeName, "Position":
self.Position, "Number": self.Number, "SupplierName": self.SupplierName, "hasChildren":
self.hasChildren}
# return '{"Name":"' + self.Name + '", "Specification":"' + self.Specification + '", "day":"' + self.day + '", "Maker":"' + \
# self.Maker + '","CertificationCode":"' + self.CertificationCode + '", "UnitPrice":"' + self.UnitPrice + '", "Specification":"' + \
# self.Specification + '","SellingPrice":"' + self.SellingPrice + '", "MaxValue":"' + self.MaxValue + '", "MinValue":"' + \
# self.MinValue + '", "ProductionBatch":"' + self.ProductionBatch + '", "TypeName":"' + self.TypeName + '", "Position":"' + \
# self.Position + '","Number":"' + self.Number + '", "SupplierName":"' + self.SupplierName + '"}'

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
"""
models.db
~~~~~~~~~~~~~~
数据库连接配置.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import urllib
app = Flask(__name__)
# 数据库配置
# 本地
# params = urllib.parse.quote_plus("DRIVER={SQL Server};SERVER=127.0.0.1;DATABASE=lisdb;UID=sa;PWD=")
# 元谋中医院
# params = urllib.parse.quote_plus("DRIVER={SQL Server};SERVER=127.0.0.1;DATABASE=lisdb;UID=sa;PWD=sixflag")
# 武定中医院
# params = urllib.parse.quote_plus("DRIVER={SQL Server};SERVER=127.0.0.1;DATABASE=lisdb;UID=sa;PWD=000626")
# 阿里云
params = urllib.parse.quote_plus("DRIVER={ODBC Driver 17 for SQL Server};SERVER=192.168.12.188;DATABASE=lisdb;UID"
"=sa;PWD=000626")
app.config["SQLALCHEMY_DATABASE_URI"] = "mssql+pyodbc:///?odbc_connect=%s" % params
# app.config["SQLALCHEMY_DATABASE_URI"] = 'mssql+pyodbc://ruby/RMS?driver=SQL Server?Trusted_Connection=yes'
# 数据库配置
# app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:toor@localhost/lis_reagent"
# 查询时会显示原始SQL语句
app.config['SQLALCHEMY_ECHO'] = True
app.config['TEMPLATE_FOLDER'] = 'template'
app.config['FILE_FOLDER'] = 'file'
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {'pool_size': 10,
'pool_recycle': 120,
'pool_pre_ping': True
}
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)

@ -0,0 +1,287 @@
# -*- coding: utf-8 -*-
"""
models.entity
~~~~~~~~~~~~~~
Sql_alchemy的表实体编写.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from models.db import *
class ReagtReceiptStatus(db.Model):
ReceiptId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
ReceiptName = db.Column(db.String(20), default='')
ReceiptCode = db.Column(db.String(20), default='')
class ReagtReceipt(db.Model):
ReceiptCode = db.Column(db.String(20), primary_key=True, nullable=False)
Remark = db.Column(db.String(1000))
ReceiptTime = db.Column(db.DateTime)
VerifyPeople = db.Column(db.String(20))
Status = db.Column(db.Integer)
class ReagtMaker(db.Model):
MakerId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
Name = db.Column(db.String(100), default='')
MakerCode = db.Column(db.String(50), default='')
Using = db.Column(db.Boolean, default=False)
class DictUser(db.Model):
UserCode = db.Column(db.String(10), primary_key=True, nullable=False)
RoleCode = db.Column(db.String(8), default='')
GroupCode = db.Column(db.String(16), default='')
UserName = db.Column(db.String(40), default='')
PassWord = db.Column(db.String(20), default='')
Sex = db.Column(db.String(1), default='')
Birth = db.Column(db.Date, default='')
Tel = db.Column(db.String(20), default='')
Description = db.Column(db.String(100), default='')
Photo = db.Column(db.String)
SignImage = db.Column(db.String)
RightCode = db.Column(db.String(10), default='')
IsLab = db.Column(db.Boolean)
class ReagtReagent(db.Model):
ReagentId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
Name = db.Column(db.String(200), default='')
Specification = db.Column(db.String(200), default='')
Maker = db.Column(db.String(200), default='')
CertificationCode = db.Column(db.String(30), default='')
UnitPrice = db.Column(db.Numeric(11, 2))
SellingPrice = db.Column(db.Numeric(11, 2))
MaxValue = db.Column(db.Integer)
MinValue = db.Column(db.Integer)
TypeName = db.Column(db.String(50), default='')
PinYinCode = db.Column(db.String(50), default='')
Unit = db.Column(db.String(30), default='')
Ratio = db.Column(db.Integer)
SmallestUnit = db.Column(db.String(20), default='')
Using = db.Column(db.Boolean)
GroupName = db.Column(db.String(200), default='')
ReportItem = db.Column(db.String(200), default='')
ReportItemCode = db.Column(db.String(100), default='')
ReagentMark = db.Column(db.String(100), default='')
__mapper_args__ = {
"order_by": 'ReagentId'
}
class ReagtStock(db.Model):
StockId = db.Column(db.BigInteger, autoincrement=True, primary_key=True, nullable=False)
ReagentId = db.Column(db.Integer)
Code = db.Column(db.String(20), default='')
ProductionBatch = db.Column(db.String(50), default='')
PinYinCode = db.Column(db.String(50), default='')
Position = db.Column(db.String(100), default='')
Number = db.Column(db.Integer)
LastNumber = db.Column(db.Integer)
InTime = db.Column(db.DateTime)
Expiration = db.Column(db.Date)
VerifyPeople = db.Column(db.String(20), default='')
BarCode = db.Column(db.String(15), default='')
SupplierName = db.Column(db.String(100), default='')
Using = db.Column(db.Boolean)
MinNumberUnit = db.Column(db.Integer)
class ReagtEntry(db.Model):
EntryId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
Position = db.Column(db.String(100), default='')
Specification = db.Column(db.String(50), default='')
Unit = db.Column(db.String(20), default='')
Maker = db.Column(db.String(100), default='')
CertificationCode = db.Column(db.String(30), default='')
SupplierName = db.Column(db.String(100), default='')
TypeName = db.Column(db.String(50), default='')
Name = db.Column(db.String(100), default='')
Number = db.Column(db.Integer)
MaxValue = db.Column(db.Integer)
MinValue = db.Column(db.Integer)
UnitPrice = db.Column(db.Numeric(11, 2))
SellingPrice = db.Column(db.Numeric(11, 2))
PinYinCode = db.Column(db.String(50), default='')
ProductionBatch = db.Column(db.String(50), default='')
Using = db.Column(db.Boolean)
Ratio = db.Column(db.Integer)
SmallestUnit = db.Column(db.String(20), default='')
class ReagtBad(db.Model):
BadId = db.Column(db.BigInteger, autoincrement=True, primary_key=True, nullable=False)
VerifyTime = db.Column(db.DateTime)
Number = db.Column(db.Integer)
Code = db.Column(db.String(20), default='')
VerifyPeople = db.Column(db.String(50), default='')
Remark = db.Column(db.String(500), default='')
class ReagtCertification(db.Model):
CertificationId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
Code = db.Column(db.String(9), default='')
Using = db.Column(db.Boolean)
class ReagtInvalid(db.Model):
InvaId = db.Column(db.BigInteger, autoincrement=True, primary_key=True, nullable=False)
Code = db.Column(db.String(20), default='')
ProductionBatch = db.Column(db.String(50), default='')
Remark = db.Column(db.String(1000), default='')
Executor = db.Column(db.String(20), default='')
class ReagtLog(db.Model):
LogId = db.Column(db.BigInteger, autoincrement=True, primary_key=True, nullable=False)
OperatingPeople = db.Column(db.String(50), default='')
OperatingTime = db.Column(db.DateTime)
OperatingType = db.Column(db.String(20), default='')
Remark = db.Column(db.String(500), default='')
Code = db.Column(db.String(20), default='')
ReagentName = db.Column(db.String(200), default='')
BarCode = db.Column(db.String(15), default='')
PinYinCode = db.Column(db.String(50), default='')
ReagentNumber = db.Column(db.Integer)
ReagentSpecification = db.Column(db.String(200), default='')
ReagentPosition = db.Column(db.String(100), default='')
ReagentId = db.Column(db.Integer)
ProductionBatch = db.Column(db.String(50), default='')
Expiration = db.Column(db.Date)
SupplierName = db.Column(db.String(100), default='')
OperateMinNumber = db.Column(db.Integer)
Receiver = db.Column(db.String(20), default='')
class ReagtOperatingType(db.Model):
OperatingTypeId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
OperatingCode = db.Column(db.String(20), default='')
OperatingName = db.Column(db.String(20), default='')
class ReagtPosition(db.Model):
PositionId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
Position = db.Column(db.String(100), default='')
PositionCode = db.Column(db.String(30), default='')
Using = db.Column(db.Boolean)
class ReagtSpecification(db.Model):
SpecificationId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
Specification = db.Column(db.String(50), default='')
Using = db.Column(db.Boolean)
class ReagtSupplier(db.Model):
SupplierId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
SupplierName = db.Column(db.String(100), default='')
SupplierCode = db.Column(db.String(30), default='')
Using = db.Column(db.Boolean)
class ReagtTypeTable(db.Model):
TypeId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
TypeCode = db.Column(db.String(20), default='')
TypeName = db.Column(db.String(50), default='')
class ReagtUnit(db.Model):
UnitId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
UnitName = db.Column(db.String(20), default='')
Using = db.Column(db.Boolean)
class ReagtApprove(db.Model):
ApproveId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
ApproveName = db.Column(db.String(200), default='')
Specification = db.Column(db.String(200), default='')
Number = db.Column(db.DECIMAL)
Maker = db.Column(db.String(100), default='')
ApprovePeople = db.Column(db.String(20), default='')
Verifier = db.Column(db.String(20), default='')
ApproveStatus = db.Column(db.Integer)
Unit = db.Column(db.String(20), default='')
ApproveTime = db.Column(db.DateTime)
Remark = db.Column(db.String(200), default='')
VerifyTime = db.Column(db.DateTime)
class ReagtApproveStatus(db.Model):
StatusId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
StatusCode = db.Column(db.String(20), default='')
StatusName = db.Column(db.String(30), default='')
class ReagtGroup(db.Model):
GroupId = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
GroupName = db.Column(db.String(200), default='')
GroupCode = db.Column(db.String(100), default='')
class DictCommon(db.Model):
ClassCode = db.Column(db.String(16), primary_key=True, nullable=False)
ItemCode = db.Column(db.String(16), primary_key=True, nullable=False)
ItemName = db.Column(db.String(50), default='')
IsDefault = db.Column(db.Boolean)
Description = db.Column(db.String(100), default='')
class DictInstrument(db.Model):
InsCode = db.Column(db.String(20), primary_key=True, nullable=False)
SampleCode = db.Column(db.String(8), default='')
InsName = db.Column(db.String(100), default='')
InsClassCode = db.Column(db.String(10), default='')
NameShort = db.Column(db.String(50), default='')
SN = db.Column(db.String(32), default='')
IsDual = db.Column(db.Boolean)
HasStoped = db.Column(db.Boolean)
CommVersion = db.Column(db.String(10), default='')
DecVersion = db.Column(db.String(10), default='')
BarCode = db.Column(db.String(32), default='')
PYM = db.Column(db.Boolean)
DecApp = db.Column(db.String(100), default='')
FileName = db.Column(db.String(100), default='')
class DictReport(db.Model):
SampleCode = db.Column(db.String(8), primary_key=True, nullable=False)
SampleName = db.Column(db.String(100), default='')
GroupCode = db.Column(db.String(16), default='')
SpecimenCode = db.Column(db.String(8), default='')
IsLocal = db.Column(db.Boolean)
ReportClass = db.Column(db.String(20), default='')
PYM = db.Column(db.Boolean)
UniteCode = db.Column(db.String(50), default='')
Color = db.Column(db.DECIMAL(10), default='')
Title = db.Column(db.String(100), default='')
TitleEn = db.Column(db.String(500), default='')
FileName = db.Column(db.String(100), default='')
IsBloodRoutine = db.Column(db.Boolean)
IsUrineRoutine = db.Column(db.Boolean)
IsStoolRoutine = db.Column(db.Boolean)
IsCruor = db.Column(db.Boolean)
IsNcov = db.Column(db.Boolean)
class RptCheckresult(db.Model):
ID = db.Column(db.Integer, autoincrement=True, primary_key=True, nullable=False)
TestDate = db.Column(db.Date)
SampleCode = db.Column(db.String(10))
RptItemCode = db.Column(db.String(20))
Result = db.Column(db.Float)
ResultStr = db.Column(db.String(255))
Range = db.Column(db.String(2048))
Unit = db.Column(db.String(20))
UnusualFlag = db.Column(db.String(10))
Seq = db.Column(db.Integer)
IsReview = db.Column(db.Boolean)
InsCode = db.Column(db.String(20))
InTime = db.Column(db.DateTime)
OrderNo = db.Column(db.String(20))
OrderItemNo = db.Column(db.String(20))
RptItemName2 = db.Column(db.String(100))

@ -0,0 +1,2 @@
class InStockExcel(object):
Name = ""

@ -0,0 +1,32 @@
class ReagentTypeList(object):
ReagentId = None
Name = None
Specification = None
Maker = None
CertificationCode = None
UnitPrice = None
SellingPrice = None
MaxValue = None
MinValue = None
TypeName = None
hasChildren = None
def __init__(self, ReagentId, Name, Specification, Maker, CertificationCode, UnitPrice, SellingPrice, MaxValue,
MinValue, TypeName, hasChildren):
self.ReagentId = ReagentId,
self.Name = Name,
self.Specification = Specification,
self.Maker = Maker,
self.CertificationCode = CertificationCode,
self.UnitPrice = UnitPrice,
self.SellingPrice = SellingPrice,
self.MaxValue = MaxValue,
self.MinValue = MinValue,
self.TypeName = TypeName,
self.hasChildren = hasChildren
def value(self):
return {"ReagentId": self.ReagentId[0], "Name": self.Name[0], "Specification": self.Specification[0],
"Maker": self.Maker[0], "CertificationCode": self.CertificationCode[0], "UnitPrice": str(self.UnitPrice[0]),
"SellingPrice": str(self.SellingPrice[0]), "MaxValue": self.MaxValue[0], "MinValue": self.MinValue[0], "TypeName":
self.TypeName[0], "hasChildren": self.hasChildren}

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
"""
models.StockListModel
~~~~~~~~~~~~~~
库存实体.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
import json
from utils.List2Json import *
class StockListModel(object):
Id = None
StockId = None
Name = None
Code = None
Position = None
Number = None
LastNumber = None
InTime = None
Specification = None
Expiration = None
Maker = None
SupplierName = None
CertificationCode = None
ProductionBatch = None
UnitPrice = None
SellingPrice = None
VerifyPeople = None
TypeName = None
Unit = None
Ratio = None
SmallestUnit = None
def __init__(self, Id, Name, StockId, Code, Position, Number, LastNumber, InTime, Specification, Expiration, Maker,
SupplierName, CertificationCode, ProductionBatch, UnitPrice, SellingPrice, VerifyPeople,
TypeName, Unit, Ratio, SmallestUnit):
self.Id = Id
self.StockId = StockId
self.Name = Name
self.Code = Code
self.Position = Position
self.Number = Number
self.LastNumber = LastNumber
self.InTime = InTime
self.Specification = Specification
self.Expiration = Expiration
self.Maker = Maker
self.SupplierName = SupplierName
self.CertificationCode = CertificationCode
self.ProductionBatch = ProductionBatch
self.UnitPrice = UnitPrice
self.SellingPrice = SellingPrice
self.VerifyPeople = VerifyPeople
self.TypeName = TypeName
self.Unit = Unit
self.Ratio = Ratio
self.SmallestUnit = SmallestUnit
def value(self):
"""
StockListModel json data
:return: json data
"""
return '{"ID":"' + str(self.Id) + '","StockId":"' + str(self.StockId) + '","Name":"' + self.Name + '","Code":"' + self.Code + '","Position":"' + self.Position + '","Number":"' + \
str(self.Number) + '","LastNumber":"' + str(self.LastNumber) + '","InTime":"' + str(self.InTime) + '","Specification":"' + \
self.Specification + '","Expiration":"' + str(self.Expiration) + '","Maker":"' + self.Maker + '","SupplierName":"' + \
self.SupplierName + '","CertificationCode":"' + self.CertificationCode + '","ProductionBatch":"' + \
self.ProductionBatch + '","UnitPrice":"' + str(self.UnitPrice) + '","SellingPrice":"' + \
str(self.SellingPrice) + '","VerifyPeople":"' + self.VerifyPeople +\
'","Unit":"' + str(self.Unit) + '","TypeName":"' + \
self.TypeName + '","Ratio":"' + str(self.Ratio) + '","SmallestUnit":"' + str(self.SmallestUnit) + '"}'

@ -0,0 +1,51 @@
function global:deactivate ([switch]$NonDestructive) {
# Revert to original values
if (Test-Path function:_OLD_VIRTUAL_PROMPT) {
copy-item function:_OLD_VIRTUAL_PROMPT function:prompt
remove-item function:_OLD_VIRTUAL_PROMPT
}
if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) {
copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME
remove-item env:_OLD_VIRTUAL_PYTHONHOME
}
if (Test-Path env:_OLD_VIRTUAL_PATH) {
copy-item env:_OLD_VIRTUAL_PATH env:PATH
remove-item env:_OLD_VIRTUAL_PATH
}
if (Test-Path env:VIRTUAL_ENV) {
remove-item env:VIRTUAL_ENV
}
if (!$NonDestructive) {
# Self destruct!
remove-item function:deactivate
}
}
deactivate -nondestructive
$env:VIRTUAL_ENV="D:\Project\Python\web\Flask\py"
if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) {
# Set the prompt to include the env name
# Make sure _OLD_VIRTUAL_PROMPT is global
function global:_OLD_VIRTUAL_PROMPT {""}
copy-item function:prompt function:_OLD_VIRTUAL_PROMPT
function global:prompt {
Write-Host -NoNewline -ForegroundColor Green '(py) '
_OLD_VIRTUAL_PROMPT
}
}
# Clear PYTHONHOME
if (Test-Path env:PYTHONHOME) {
copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME
remove-item env:PYTHONHOME
}
# Add the venv to the PATH
copy-item env:PATH env:_OLD_VIRTUAL_PATH
$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH"

@ -0,0 +1,76 @@
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
PATH="${_OLD_VIRTUAL_PATH:-}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
PS1="${_OLD_VIRTUAL_PS1:-}"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "$1" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="D:\Project\Python\web\Flask\py"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/Scripts:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
if [ "x(py) " != x ] ; then
PS1="(py) ${PS1:-}"
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
fi
fi
export PS1
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi

@ -0,0 +1,45 @@
@echo off
rem This file is UTF-8 encoded, so we need to update the current code page while executing it
for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do (
set "_OLD_CODEPAGE=%%a"
)
if defined _OLD_CODEPAGE (
"%SystemRoot%\System32\chcp.com" 65001 > nul
)
set "VIRTUAL_ENV=D:\Project\Python\web\Flask\py"
if not defined PROMPT (
set "PROMPT=$P$G"
)
if defined _OLD_VIRTUAL_PROMPT (
set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
)
if defined _OLD_VIRTUAL_PYTHONHOME (
set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
)
set "_OLD_VIRTUAL_PROMPT=%PROMPT%"
set "PROMPT=(py) %PROMPT%"
if defined PYTHONHOME (
set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%"
set PYTHONHOME=
)
if defined _OLD_VIRTUAL_PATH (
set "PATH=%_OLD_VIRTUAL_PATH%"
) else (
set "_OLD_VIRTUAL_PATH=%PATH%"
)
set "PATH=%VIRTUAL_ENV%\Scripts;%PATH%"
:END
if defined _OLD_CODEPAGE (
"%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul
set "_OLD_CODEPAGE="
)

@ -0,0 +1,21 @@
@echo off
if defined _OLD_VIRTUAL_PROMPT (
set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
)
set _OLD_VIRTUAL_PROMPT=
if defined _OLD_VIRTUAL_PYTHONHOME (
set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
set _OLD_VIRTUAL_PYTHONHOME=
)
if defined _OLD_VIRTUAL_PATH (
set "PATH=%_OLD_VIRTUAL_PATH%"
)
set _OLD_VIRTUAL_PATH=
set VIRTUAL_ENV=
:END

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,3 @@
home = F:\Anaconda3
include-system-site-packages = true
version = 3.7.4

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
"""
server
~~~~~~~~~~~~~~
tornado转换server的启动端口无需启动默认5000端口即可用如有nginx等可混合使用.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from tornado.httpserver import HTTPServer
from tornado.wsgi import WSGIContainer
from web import app
from tornado.ioloop import IOLoop
s = HTTPServer(WSGIContainer(app))
s.listen(9900) # 监听 9900 端口
IOLoop.current().start()

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
"""
statusCode.responseEntity
~~~~~~~~~~~~~~
返回类型数据为json,状态为200或500.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from flask import Response
from statusCode.result import *
def SuccessResponse(resultCode, data, token):
return Response(response=resultData(resultCode.value['code'], resultCode.value['message'], data, token).value(),
status=200, mimetype="application/json")
def BadResponse(resultCode, data, token):
return Response(response=resultData(resultCode.value['code'], resultCode.value['message'], data, token).value(),
status=500, mimetype="application/json")

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
"""
statusCode.result
~~~~~~~~~~~~~~
返回前端的实体为code,message,data,token.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
import json
from utils.List2Json import *
class resultData(object):
code = None
message = None
data = None
token = None
def __init__(self, code, message, data, token):
self.code = code
self.message = message
self.data = data
self.token = token
def value(self):
"""
json data
:return: json data
"""
return json.dumps({'code': self.code, 'message': self.message, 'data': self.data, 'token': self.token},
cls=DecimalEncoder)

@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
"""
statusCode.resultCode
~~~~~~~~~~~~~~
code跟message的Enum.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from enum import Enum
class ResultCode(Enum):
"""docstring for ResultCode"""
# 成功状态码
SUCCESS = {'code': 200, 'message': "成功"}
# 失败状态码
ERROR = {'code': 401, 'message': "失败"}
NOT_FIND = {'code': 404, 'message': "请求路径无效"}
METHOD_ERROR = {'code': 405, 'message': "请求方式有误"}
SERVICE_ERROR = {'code': 500, 'message': "服务器错误"}
# 参数错误:10001-19999
PARAM_IS_BLANK = {'code': 10001, 'message': "参数为空"}
PARAM_IS_INVALID = {'code': 10002, 'message': "参数无效"}
PARAM_NOT_COMPLETE = {'code': 10003, 'message': "参数缺失"}
PARAM_TYPE_BIND_ERROR = {'code': 10004, 'message': "参数类型错误"}
# 账户错误:20001-29999
USER_NOT_EXIST = {'code': 20001, 'message': "账户不存在"}
USER_ACCOUNT_FORBIDDEN = {'code': 20002, 'message': "账号已禁用"}
USER_ACCOUNT_DELETE = {'code': 20003, 'message': "账号已删除"}
USER_LOGIN_ERROR = {'code': 20004, 'message': "账号或密码错误"}
LOGIN_EXPIRED = {'code': 20005, 'message': "登录信息过期"}
USER_LOGOUT = {'code': 20006, 'message': '用户注销'}
# 业务错误:30001-39999
SPECIFIED_QUESTIONED_USER_NOT_EXIST = {'code': 30001, 'message': "某业务出现问题"}
DATA_OCCUPATION = {'code': 30002, 'message': "数据占用"}
BASIC_INFO_IS_USING = {'code': 30003, 'message': "该基础信息正在被使用,请删除正在使用该信息的库存再删除该信息"}
NOT_ALLOW_DELETE_HIS_IN_STOCK_INTO = {'code': 30004, 'message': "不允许删除单条his入库信息,请从入库单删除"}
GROUP_INFO_IS_USING = {'code': 30005, 'message': "该小组信息正在被使用,无法直接删除小组名称"}
# 系统错误:40001-49999
SYSTEM_INNER_ERROR = {'code': 40001, 'message': "系统繁忙,请稍后重试"}
# 数据错误:50001-599999
SOURCE_DATA_NONE = {'code': 50001, 'message': "数据未找到"}
DATA_IS_WRONG = {'code': 50002, 'message': "数据有误"}
DATA_ALREADY_EXISTED = {'code': 50003, 'message': "数据已存在"}
# 接口错误:60001-69999
INTERFACE_INNER_INVOKE_ERROR = {'code': 60001, 'message': "内部系统接口调用异常"}
INTERFACE_OUTER_INVOKE_ERROR = {'code': 60002, 'message': "外部系统接口调用异常"}
INTERFACE_FORBID_VISIT = {'code': 60003, 'message': "该接口禁止访问"}
INTERFACE_ADDRESS_INVALID = {'code': 60004, 'message': "接口地址无效"}
INTERFACE_REQUEST_TIMEOUT = {'code': 60005, 'message': "接口请求超时"}
INTERFACE_EXCEED_LOAD = {'code': 60006, 'message': "接口负载过高"}
# 权限错误:70001-79999
NOT_FOUND_AUTHORIZATION = {'code': 70001, 'message': "请求头必须携带token字段"}
AUTHENTICATION_NO_ACCESS = {'code': 70002, 'message': "认证失败"}
PERMISSION_NO_ACCESS = {'code': 70003, 'message': "权限不足"}
INVALID_TOKEN = {'code': 70004, 'message': "无效token"}

Binary file not shown.

BIN
code/utils/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
"""
utils.BatchCode
~~~~~~~~~~~~~~
入库批次码生成随机9位.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from random import randint
from utils.apiDoc import *
def GetBatchCode():
range_start = 10 ** (9 - 1)
range_end = (10 ** 9) - 1
batchCode = randint(range_start, range_end)
while not ReagtStock.query.filter_by(Code=F'{batchCode}').first() is None:
batchCode = randint(range_start, range_end)
return batchCode
def GetGroupCode():
range_start = 10 ** (9 - 1)
range_end = (10 ** 9) - 1
batchCode = randint(range_start, range_end)
while not ReagtGroup.query.filter_by(GroupCode=F'{batchCode}').first() is None:
batchCode = randint(range_start, range_end)
return batchCode

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
"""
utils.Dict2Obj
~~~~~~~~~~~~~~
dic to class.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
class Dict2Obj(object):
"""
Turns a dictionary into a class
"""
# ----------------------------------------------------------------------
def __init__(self, dictionary):
"""Constructor"""
for key in dictionary:
setattr(self, key, dictionary[key])

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
"""
utils.List2Json
~~~~~~~~~~~~~~
Sql_alchemy的实体转json.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
import decimal
import types
from datetime import datetime
from flask import json
from sqlalchemy.ext.declarative import DeclarativeMeta
class AlchemyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj.__class__, DeclarativeMeta):
# an SQLAlchemy class
fields = {}
for field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata']:
data = obj.__getattribute__(field)
if field == 'query' or field == 'query_class':
continue
try:
# json.dumps(data, ensure_ascii=False) this will fail on non-encodable values, like other classes
if str(data) == 'None':
data = ''
if isinstance(data, types.GeneratorType):
data
fields[field] = str(data)
if isinstance(data, bool) or isinstance(data, int):
fields[field] = data
if isinstance(data, decimal.Decimal):
return (str(data) for data in [data])
except TypeError:
fields[field] = None
# a json-encodable dict
return fields
return json.JSONEncoder.default(self, obj)
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, decimal.Decimal):
return float(obj)
if isinstance(obj, datetime):
return str(obj)
return super(DecimalEncoder, self).default(obj)

@ -0,0 +1,91 @@
from datetime import datetime, date
def db_page(entity_filter, order, data, number):
"""分页帮助方法.
对db.session出来的实体进行分页
Args:
entity_filter: an entity that need pagination.
order: Sort by.
data: get pageNumber.
number: Number of lists per page
Returns:
可供json转换的dict
Raises:
TYPEError: 类型转换出错
"""
entityPaginate = entity_filter.order_by(order.desc()).paginate(
int(data.get('pageNumber')), number,
error_out=False)
resultList = []
for (i, result) in enumerate(entityPaginate.items):
result_modified = dict(zip(result.keys(), result))
for (j, child) in enumerate(result):
if type(child) == date or type(child) == datetime:
result_modified.__setitem__(result.keys()[j], str(child))
resultList.append(result_modified)
return resultList
def db_page_entity(entity, data, number):
"""分页帮助方法.
对实体查询出来的实体集合进行分页
Args:
entity: an entity that need pagination.
data: get pageNumber.
number: Number of lists per page
Returns:
可供json转换的dict
Raises:
TYPEError: 类型转换出错
"""
data_list = entity.paginate(int(data.get('pageNumber')), number, error_out=False)
result_list = [dict(zip([attr for attr in dir(result) if '_' not in attr and
attr is not 'query' and
attr is not 'metadata'],
[str(getattr(result, attr)) if
type(getattr(result, attr)) == date or
type(getattr(result, attr)) == datetime else
getattr(result, attr) for attr in dir(result) if '_' not in attr and
attr is not 'query' and
attr is not 'metadata']))
for result in data_list.items]
return result_list
def entityDictToStringDict(resultList):
"""
没啥用的函数以前用来转换json数据为string模式的更新了之后可以支持所有类型的数据 以前是因为json.dumps()不支持decimal类型的数据
用List2Json中的方法转换为float就解决了
"""
jsonList = []
for dic in resultList:
dicItem = {}
for key, value in dic.items():
if value is None:
value = ''
dicItem[key] = str(value)
jsonList.append(dicItem)
return jsonList
def singleEntityToJson(singleEntity):
"""
单条数据转json不需要分页的
"""
dictList = [dict(zip([attr for attr in dir(singleEntity) if '_' not in attr and
attr is not 'query' and
attr is not 'metadata'],
[getattr(singleEntity, attr) for attr in dir(singleEntity)
if '_' not in attr and
attr is not 'query' and
attr is not 'metadata']))]
return dictList[0]

@ -0,0 +1,12 @@
from web import *
def ReagentTypeSort(List):
newList = []
for item in List:
if item['hasChildren']:
newList.append(item)
for itemFalse in List:
if not itemFalse['hasChildren']:
newList.append(itemFalse)
return newList

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
"""
utils.apiDoc
~~~~~~~~~~~~~~
flask_rest_plus的配置以及所有接口的引用.
:copyright: 云南新八达科技有限公司.
:author: 李进才.
"""
from flask import Flask, url_for, redirect, request
from flask_sqlalchemy import SQLAlchemy
from utils.jwt import *
from models.entity import *
from statusCode.resultCode import *
from statusCode.responseEntity import *
import json
from utils.Dict2Obj import *
from flask_restplus import Resource, Api, fields
from models.db import *
@app.before_request
def authenticate():
token = request.headers.get('X-Token')
app.logger.info(request.path)
if verify_jwt(token) is None and request.path != '/User/login' and request.path != '/' and request.path.find(
'swagger') == -1:
return SuccessResponse(ResultCode.INVALID_TOKEN, None,
None)
api = Api(app, title="Reagent Information System", description="Reagent Management System")
user = api.namespace('User', description='User Information Operating')
stock = api.namespace('Stock', description='Reagent Stock Info And Management')
entry = api.namespace('Entry', description='input default tip management')
bad = api.namespace('Bad', description='Loss of reagent')
log = api.namespace('Log', description='Log of Stock')
dictionary = api.namespace('Dictionary', description='Basic Dictionary of reagent')
statistics = api.namespace('Statistics', description='Statistics of reagent')
inventory = api.namespace('Inventory', description='库存盘点')
approve = api.namespace('Approve', description='请购相关处理')
file = api.namespace('File', description='文件上传等相关操作')
authority = api.namespace("Authority", description='相关权限的操作')
basic = api.namespace('Basic', description='basic Dictionary of manager ')
accounting = api.namespace('Accounting', description='用量核算')
in_stock_model = stock.model("inStockData",
{"Name": fields.String, "Specification": fields.String, "Day": fields.Integer,
"Maker": fields.String, "CertificationCode": fields.String,
"UnitPrice": fields.Integer, "SellingPrice": fields.Integer,
"MaxValue": fields.Integer, "MinValue": fields.Integer,
"ProductionBatch": fields.String, "TypeName": fields.String,
"Position": fields.String, "Number": fields.Integer,
"SupplierName": fields.String},
"remark")

@ -0,0 +1,21 @@
from sqlalchemy import or_
from utils.PageHepler import db_page_entity
from utils.apiDoc import *
def get_basic_entry_list(entity, data, entity_order):
reagentEntity = db.session.query(entity) \
.order_by(entity_order)
if request.args.get('query') is not None:
reagentEntity = db.session.query(entity) \
.filter(or_(entity.Name.contains(data.get('query')),
entity.PinYinCode.contains(data.get('query')),
entity.Maker.contains(data.get('query')))) \
.order_by(entity_order)
return SuccessResponse(ResultCode.SUCCESS,
{'totalNumber': reagentEntity.count(), 'list':
db_page_entity(reagentEntity, data, 12)}, None)

@ -0,0 +1,64 @@
import configparser
config = configparser.ConfigParser()
config.read('./config/operatingType.ini')
def GetOperatingTypeBad():
return config.get('operatingType', 'bad')
def GetOperatingTypeScrap():
return config.get('operatingType', 'scrap')
def GetOperatingTypeInStock():
return config.get('operatingType', 'inStock')
def GetOperatingTypeOutStock():
return config.get('operatingType', 'outStock')
def GetOperatingTypeUpdate():
return config.get('operatingType', 'update')
def GetOperatingTypeEdit():
return config.get('operatingType', 'edit')
def GetOperatingTypeUseName(name):
return config.get('operatingType', name)
def GetOperatingTypeBasicReagentOpen():
return config.get('operatingType', 'basicReagentOpen')
def GetOperatingTypeBasicReagentClose():
return config.get('operatingType', 'basicReagentClose')
def GetOperatingTypeBasicEntryOpen():
return config.get('operatingType', 'basicEntryOpen')
def GetOperatingTypeBasicEntryClose():
return config.get('operatingType', 'basicEntryClose')
def GetOperatingTypeDelete():
return config.get('operatingType', 'delete')
def GetApproveTypeApproving():
return config.get('approveType', 'approving')
def GetApproveTypeApproved():
return config.get('approveType', 'approved')
def GetApproveTypeOverrule():
return config.get('approveType', 'overrule')

@ -0,0 +1,26 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import binascii
from pyDes import des, CBC, PAD_PKCS5
secret_key = '021ynxbd'
def des_encrypt(s):
iv = secret_key
k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
en = k.encrypt(s, padmode=PAD_PKCS5)
return binascii.b2a_hex(en)
def des_decrypt(s):
iv = secret_key
k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
return de
if __name__ == '__main__':
secret_str = des_encrypt('XBD.User@000626')
print('密文:', secret_str)
clear_str = des_decrypt(secret_str)
print('明文:', clear_str)

@ -0,0 +1,39 @@
from sqlalchemy import or_
from models.entity import *
from statusCode.responseEntity import SuccessResponse, BadResponse
from statusCode.resultCode import ResultCode
from utils.PageHepler import db_page_entity
def GetList(entity, entityId, name, code, data, length=6, is_all=False):
filterItem = entity.query.order_by(entityId.desc())
if data.get('query') is not None:
filterItem = entity.query.filter(
or_(name.contains(data['query']),
code.contains(data['query']))) \
.order_by(entityId.desc())
if is_all:
length = filterItem.count()
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': filterItem.count(),
'list': db_page_entity(filterItem, data, length)}, None)
def StatusChange(entity, dataId, data, entityId, stockNameLeft, stockNameRight):
filterItem = entity.query.filter(entityId == dataId).first()
if len(ReagtStock.query.filter(stockNameLeft == stockNameRight).all()) != 0:
return SuccessResponse(ResultCode.DATA_OCCUPATION, None, None)
using = data['Using'] != 'false'
if filterItem.Using == using:
return BadResponse(ResultCode.PARAM_IS_INVALID, None, None)
filterItem.Using = using
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)
def DictionaryAdd(existEntity, newEntity):
if existEntity is not None:
return SuccessResponse(ResultCode.DATA_ALREADY_EXISTED, None, None)
db.session.add(newEntity)
db.session.commit()
return SuccessResponse(ResultCode.SUCCESS, None, None)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save