item.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. """Item API routes."""
  2. from flask_restx import Namespace, Resource, fields
  3. from app.services.item_service import ItemService
  4. from app.utils.auth_decorator import require_auth
  5. item_ns = Namespace('items', description='物品管理接口')
  6. # API models for Swagger documentation
  7. item_model = item_ns.model('Item', {
  8. 'id': fields.Integer(readonly=True, description='物品ID'),
  9. 'name': fields.String(required=True, description='物品名称'),
  10. 'unit_price': fields.Float(required=True, description='单价'),
  11. 'supplier_id': fields.Integer(description='供应商ID'),
  12. 'supplier_name': fields.String(readonly=True, description='供应商名称'),
  13. 'created_at': fields.String(readonly=True, description='创建时间'),
  14. 'updated_at': fields.String(readonly=True, description='更新时间')
  15. })
  16. item_input = item_ns.model('ItemInput', {
  17. 'name': fields.String(required=True, description='物品名称'),
  18. 'unit_price': fields.Float(required=True, description='单价'),
  19. 'supplier_id': fields.Integer(description='供应商ID(可选)')
  20. })
  21. item_update = item_ns.model('ItemUpdate', {
  22. 'id': fields.Integer(required=True, description='物品ID'),
  23. 'name': fields.String(description='物品名称'),
  24. 'unit_price': fields.Float(description='单价'),
  25. 'supplier_id': fields.Integer(description='供应商ID(可选,-1表示清除)')
  26. })
  27. item_delete = item_ns.model('ItemDelete', {
  28. 'id': fields.Integer(required=True, description='物品ID')
  29. })
  30. # Response models
  31. success_response = item_ns.model('SuccessResponse', {
  32. 'success': fields.Boolean(description='操作是否成功'),
  33. 'data': fields.Raw(description='返回数据'),
  34. 'message': fields.String(description='消息')
  35. })
  36. error_response = item_ns.model('ErrorResponse', {
  37. 'success': fields.Boolean(description='操作是否成功'),
  38. 'error': fields.String(description='错误信息'),
  39. 'code': fields.String(description='错误代码')
  40. })
  41. @item_ns.route('')
  42. class ItemList(Resource):
  43. """Resource for listing all items."""
  44. @item_ns.doc('list_items')
  45. @item_ns.response(200, 'Success', success_response)
  46. @require_auth
  47. def get(self):
  48. """获取所有物品列表"""
  49. items = ItemService.get_all()
  50. return {
  51. 'success': True,
  52. 'data': items,
  53. 'message': 'Items retrieved successfully'
  54. }, 200
  55. @item_ns.route('/<int:id>')
  56. @item_ns.param('id', '物品ID')
  57. class ItemDetail(Resource):
  58. """Resource for getting a single item."""
  59. @item_ns.doc('get_item')
  60. @item_ns.response(200, 'Success', success_response)
  61. @item_ns.response(404, 'Item not found', error_response)
  62. @require_auth
  63. def get(self, id):
  64. """根据ID获取物品信息"""
  65. item, error = ItemService.get_by_id(id)
  66. if error:
  67. return {
  68. 'success': False,
  69. 'error': error,
  70. 'code': 'NOT_FOUND'
  71. }, 404
  72. return {
  73. 'success': True,
  74. 'data': item,
  75. 'message': 'Item retrieved successfully'
  76. }, 200
  77. @item_ns.route('/create')
  78. class ItemCreate(Resource):
  79. """Resource for creating an item."""
  80. @item_ns.doc('create_item')
  81. @item_ns.expect(item_input)
  82. @item_ns.response(200, 'Success', success_response)
  83. @item_ns.response(400, 'Validation error', error_response)
  84. @require_auth
  85. def post(self):
  86. """创建新物品"""
  87. data = item_ns.payload
  88. name = data.get('name', '')
  89. unit_price = data.get('unit_price')
  90. supplier_id = data.get('supplier_id')
  91. item, error = ItemService.create(name, unit_price, supplier_id)
  92. if error:
  93. # Determine error code based on error message
  94. error_code = 'DUPLICATE_NAME' if '已存在' in error else 'VALIDATION_ERROR'
  95. return {
  96. 'success': False,
  97. 'error': error,
  98. 'code': error_code
  99. }, 400
  100. return {
  101. 'success': True,
  102. 'data': item,
  103. 'message': 'Item created successfully'
  104. }, 200
  105. @item_ns.route('/update')
  106. class ItemUpdate(Resource):
  107. """Resource for updating an item."""
  108. @item_ns.doc('update_item')
  109. @item_ns.expect(item_update)
  110. @item_ns.response(200, 'Success', success_response)
  111. @item_ns.response(400, 'Validation error', error_response)
  112. @item_ns.response(404, 'Item not found', error_response)
  113. @require_auth
  114. def post(self):
  115. """更新物品信息"""
  116. data = item_ns.payload
  117. item_id = data.get('id')
  118. name = data.get('name')
  119. unit_price = data.get('unit_price')
  120. supplier_id = data.get('supplier_id')
  121. if not item_id:
  122. return {
  123. 'success': False,
  124. 'error': 'Item ID is required',
  125. 'code': 'VALIDATION_ERROR'
  126. }, 400
  127. item, error = ItemService.update(item_id, name, unit_price, supplier_id)
  128. if error:
  129. if '未找到' in error:
  130. return {
  131. 'success': False,
  132. 'error': error,
  133. 'code': 'NOT_FOUND'
  134. }, 404
  135. # Determine error code based on error message
  136. error_code = 'DUPLICATE_NAME' if '已存在' in error else 'VALIDATION_ERROR'
  137. return {
  138. 'success': False,
  139. 'error': error,
  140. 'code': error_code
  141. }, 400
  142. return {
  143. 'success': True,
  144. 'data': item,
  145. 'message': 'Item updated successfully'
  146. }, 200
  147. @item_ns.route('/delete')
  148. class ItemDelete(Resource):
  149. """Resource for deleting an item."""
  150. @item_ns.doc('delete_item')
  151. @item_ns.expect(item_delete)
  152. @item_ns.response(200, 'Success', success_response)
  153. @item_ns.response(404, 'Item not found', error_response)
  154. @require_auth
  155. def post(self):
  156. """删除物品"""
  157. data = item_ns.payload
  158. item_id = data.get('id')
  159. if not item_id:
  160. return {
  161. 'success': False,
  162. 'error': 'Item ID is required',
  163. 'code': 'VALIDATION_ERROR'
  164. }, 400
  165. success, error = ItemService.delete(item_id)
  166. if error:
  167. return {
  168. 'success': False,
  169. 'error': error,
  170. 'code': 'NOT_FOUND'
  171. }, 404
  172. return {
  173. 'success': True,
  174. 'data': None,
  175. 'message': 'Item deleted successfully'
  176. }, 200