diff --git a/inventory-backend/app/api/v1/purchase.py b/inventory-backend/app/api/v1/purchase.py
index 462d247..fe37823 100644
--- a/inventory-backend/app/api/v1/purchase.py
+++ b/inventory-backend/app/api/v1/purchase.py
@@ -34,6 +34,25 @@ def _user_has_purchase_perm():
)
+def _filter_purchase_prices(item_dict):
+ """Fail-Closed: 无价格权限则剥离采购价格字段"""
+ from app.services.auth_service import AuthService
+ claims = get_jwt()
+ role = claims.get('role', '')
+ if role.upper() in ('SUPER_ADMIN', 'SUPERVISOR'):
+ return
+ perm_dict = AuthService.get_user_permissions(role, company_name=claims.get('company_name', ''))
+ all_perms = perm_dict.get('menus', []) + perm_dict.get('elements', [])
+ if 'inbound_purchase:unit_price' not in all_perms:
+ item_dict.pop('unit_price', None)
+ item_dict.pop('pre_tax_unit_price', None)
+ item_dict.pop('post_tax_unit_price', None)
+ if 'inbound_purchase:total_price' not in all_perms:
+ item_dict.pop('total_price', None)
+ if 'inbound_purchase:tax_rate' not in all_perms:
+ item_dict.pop('tax_rate', None)
+
+
# --------------------------------------------------------
# 1. 采购申请列表
# GET /api/v1/purchase
@@ -58,6 +77,10 @@ def get_purchase_list():
status=status
)
+ # ★ 字段级价格过滤
+ for item in (result.get('items') or []):
+ _filter_purchase_prices(item)
+
return jsonify({'code': 200, 'msg': '获取成功', 'data': result})
except Exception as e:
traceback.print_exc()
@@ -128,6 +151,7 @@ def get_purchase_detail(purchase_id):
if purchase['requester_id'] != user_id and not _user_has_purchase_perm():
return jsonify({'code': 403, 'msg': '无权查看此申请'}), 403
+ _filter_purchase_prices(purchase)
return jsonify({'code': 200, 'msg': '获取成功', 'data': purchase}), 200
except Exception as e:
return jsonify({'code': 500, 'msg': str(e)}), 500
@@ -241,6 +265,8 @@ def get_approved_unstocked_requests():
page=page, per_page=per_page, keyword=keyword
)
+ # ★ 注意:不在此处过滤价格。此端点用于按单入库,
+ # 价格数据需随响应传递到入库表单(前端通过 inbound_buy:unit_price 权限控制写入)
return jsonify({'code': 200, 'msg': '获取成功', 'data': result}), 200
except Exception as e:
traceback.print_exc()
diff --git a/inventory-backend/app/services/permission_service.py b/inventory-backend/app/services/permission_service.py
index 55b42a0..d446859 100644
--- a/inventory-backend/app/services/permission_service.py
+++ b/inventory-backend/app/services/permission_service.py
@@ -638,19 +638,23 @@ class PermissionService:
db.session.add(new_perm)
db.session.commit()
- # ★ 采购申请操作权限元素
- purchase_op = SysElement.query.filter_by(
- menu_code='inbound_purchase',
- code='inbound_purchase:operation'
- ).first()
- if not purchase_op:
- db.session.add(SysElement(
- menu_code='inbound_purchase',
- name='可编辑',
- code='inbound_purchase:operation',
- element_type='operation'
- ))
- print(f"✅ 采购申请操作权限元素已创建")
+ # ★ 采购申请权限元素
+ purchase_elements = [
+ ('inbound_purchase:operation', '可编辑', 'operation'),
+ ('inbound_purchase:unit_price', '采购单价', 'column'),
+ ('inbound_purchase:total_price', '采购总价', 'column'),
+ ('inbound_purchase:tax_rate', '税率', 'column'),
+ ]
+ for code, name, etype in purchase_elements:
+ existing = SysElement.query.filter_by(
+ menu_code='inbound_purchase', code=code
+ ).first()
+ if not existing:
+ db.session.add(SysElement(
+ menu_code='inbound_purchase', name=name,
+ code=code, element_type=etype
+ ))
+ print(f"✅ 采购申请元素已创建: {code}")
print(f"✅ 所有菜单初始化完成")
return True
diff --git a/inventory-web/src/views/purchase/index.vue b/inventory-web/src/views/purchase/index.vue
index f02039d..7b18acc 100644
--- a/inventory-web/src/views/purchase/index.vue
+++ b/inventory-web/src/views/purchase/index.vue
@@ -24,17 +24,17 @@
-
+
{{ row.unit_price ? '¥' + Number(row.unit_price).toFixed(2) : '-' }}
-
+
{{ row.total_price ? '¥' + Number(row.total_price).toFixed(2) : '-' }}
-
+
{{ row.tax_rate != null ? row.tax_rate + '%' : '-' }}
@@ -200,8 +200,8 @@
{{ detail.spec_model || '-' }}
{{ detail.quantity }}
{{ detail.purchase_date }}
- {{ detail.unit_price || '-' }}
- {{ detail.total_price || '-' }}
+ {{ detail.unit_price || '-' }}
+ {{ detail.total_price || '-' }}
{{ detail.requester_name }}
{{ detail.approver_name || '-' }}
{{ detail.approved_at || '-' }}