diff --git a/db_migrations/deploy_production.sql b/db_migrations/deploy_production.sql index bdb0dd6..b4c1571 100644 --- a/db_migrations/deploy_production.sql +++ b/db_migrations/deploy_production.sql @@ -12,10 +12,13 @@ BEGIN; -- 1. 采购申请表新增 base_id(关联物料基础信息) ALTER TABLE purchase_request ADD COLUMN IF NOT EXISTS base_id INTEGER; --- 2. 采购入库表新增 request_id(关联采购申请单) +-- 2. 采购申请表新增 tax_rate(税率) +ALTER TABLE purchase_request ADD COLUMN IF NOT EXISTS tax_rate NUMERIC(5,2) DEFAULT 0; + +-- 3. 采购入库表新增 request_id(关联采购申请单) ALTER TABLE stock_buy ADD COLUMN IF NOT EXISTS request_id INTEGER; --- 3. 角色权限表新增 company_name(支持公司级别权限隔离) +-- 4. 角色权限表新增 company_name(支持公司级别权限隔离) ALTER TABLE sys_role_permission ADD COLUMN IF NOT EXISTS company_name VARCHAR(255); @@ -188,6 +191,57 @@ FROM sys_menu WHERE code IN ('system_mgmt', 'system_permission', 'system_audit') AND NOT EXISTS (SELECT 1 FROM sys_role_permission rp WHERE rp.role_code = 'SUPERVISOR' AND rp.target_code = sys_menu.code AND rp.type = 'menu'); +-- ============================================================ +-- 三补、借库管理菜单 + 权限码 + 角色分配 +-- ============================================================ + +-- 借库选单 & 借库审批 菜单 +INSERT INTO sys_menu (code, name, parent_id, is_visible) +SELECT 'op_borrow_apply', '借库选单', m.id, true +FROM sys_menu m WHERE m.code = 'operation_mgmt' +AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE code = 'op_borrow_apply'); + +INSERT INTO sys_menu (code, name, parent_id, is_visible) +SELECT 'op_borrow_approval', '借库审批', m.id, true +FROM sys_menu m WHERE m.code = 'operation_mgmt' +AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE code = 'op_borrow_approval'); + +-- 借库选单元素权限 +INSERT INTO sys_element (menu_code, name, code, element_type) SELECT 'op_borrow_apply', '物品名称', 'op_borrow_apply:name', 'column' WHERE NOT EXISTS (SELECT 1 FROM sys_element WHERE code = 'op_borrow_apply:name'); +INSERT INTO sys_element (menu_code, name, code, element_type) SELECT 'op_borrow_apply', '规格型号', 'op_borrow_apply:spec', 'column' WHERE NOT EXISTS (SELECT 1 FROM sys_element WHERE code = 'op_borrow_apply:spec'); +INSERT INTO sys_element (menu_code, name, code, element_type) SELECT 'op_borrow_apply', '可用库存', 'op_borrow_apply:available_quantity', 'column' WHERE NOT EXISTS (SELECT 1 FROM sys_element WHERE code = 'op_borrow_apply:available_quantity'); +INSERT INTO sys_element (menu_code, name, code, element_type) SELECT 'op_borrow_apply', '操作/编辑', 'op_borrow_apply:operation', 'column' WHERE NOT EXISTS (SELECT 1 FROM sys_element WHERE code = 'op_borrow_apply:operation'); + +-- 角色分配:有 operation_mgmt 的角色 → 获得借库选单/审批菜单 + 元素 +INSERT INTO sys_role_permission (role_code, target_code, type) +SELECT DISTINCT rp.role_code, 'op_borrow_apply', 'menu' +FROM sys_role_permission rp WHERE rp.target_code = 'operation_mgmt' +AND NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = rp.role_code AND target_code = 'op_borrow_apply'); + +INSERT INTO sys_role_permission (role_code, target_code, type) +SELECT DISTINCT rp.role_code, 'op_borrow_approval', 'menu' +FROM sys_role_permission rp WHERE rp.target_code = 'operation_mgmt' +AND NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = rp.role_code AND target_code = 'op_borrow_approval'); + +INSERT INTO sys_role_permission (role_code, target_code, type) +SELECT rp.role_code, elem.code, 'element' +FROM (SELECT DISTINCT role_code FROM sys_role_permission WHERE target_code = 'operation_mgmt') rp +CROSS JOIN (SELECT unnest(ARRAY['op_borrow_apply:name','op_borrow_apply:spec','op_borrow_apply:available_quantity','op_borrow_apply:operation']) AS code) elem +WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission rp2 WHERE rp2.role_code = rp.role_code AND rp2.target_code = elem.code); + +-- 补借库管理菜单给 SUPERVISOR(如缺) +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'operation_mgmt', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'operation_mgmt'); +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'op_borrow_apply', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'op_borrow_apply'); +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'op_borrow_approval', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'op_borrow_approval'); +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'op_borrow', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'op_borrow'); +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'op_return', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'op_return'); +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'op_records', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'op_records'); + +-- 出库管理菜单补 SUPERVISOR +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'outbound_mgmt', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'outbound_mgmt'); +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', 'outbound_approval', 'menu' WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = 'outbound_approval'); +INSERT INTO sys_role_permission (role_code, target_code, type) SELECT 'SUPERVISOR', elem.code, 'element' FROM (SELECT unnest(ARRAY['outbound_approval:request_no','outbound_approval:applicant','outbound_approval:approver','outbound_approval:status','outbound_approval:operation']) AS code) elem WHERE NOT EXISTS (SELECT 1 FROM sys_role_permission WHERE role_code = 'SUPERVISOR' AND target_code = elem.code); + -- ============================================================ -- 四、验证 -- ============================================================ @@ -196,7 +250,7 @@ SELECT '=== 验证 ===' AS info; SELECT '表结构' AS item, column_name, data_type FROM information_schema.columns WHERE table_name IN ('purchase_request', 'stock_buy', 'sys_role_permission') - AND column_name IN ('base_id', 'request_id', 'company_name') + AND column_name IN ('base_id', 'request_id', 'company_name', 'tax_rate') ORDER BY table_name, column_name; SELECT '权限码总数' AS item, count(*) FROM sys_element; diff --git a/inventory-backend/app/models/purchase.py b/inventory-backend/app/models/purchase.py index f689543..2f43f0d 100644 --- a/inventory-backend/app/models/purchase.py +++ b/inventory-backend/app/models/purchase.py @@ -20,8 +20,9 @@ class PurchaseRequest(db.Model): supplier_link = db.Column(db.String(500), comment='商家地址链接') remark = db.Column(db.Text, comment='备注信息') images = db.Column(db.Text, comment='图片列表JSON') - unit_price = db.Column(db.Numeric(19, 4), default=0, comment='单价') - total_price = db.Column(db.Numeric(19, 4), default=0, comment='总价') + unit_price = db.Column(db.Numeric(19, 4), default=0, comment='不含税单价') + total_price = db.Column(db.Numeric(19, 4), default=0, comment='不含税总价') + tax_rate = db.Column(db.Numeric(5, 2), default=0, comment='税率') status = db.Column(db.Integer, default=0, nullable=False) requester_id = db.Column(db.Integer, nullable=False, index=True) approver_id = db.Column(db.Integer, index=True) @@ -88,6 +89,7 @@ class PurchaseRequest(db.Model): 'images': self.get_images(), 'unit_price': float(self.unit_price) if self.unit_price else 0, 'total_price': float(self.total_price) if self.total_price else 0, + 'tax_rate': float(self.tax_rate) if self.tax_rate else 0, 'status': self.status, 'status_text': ['待审批', '已通过', '已驳回', '已完成'][self.status] if self.status in [0, 1, 2, 3] else '未知', 'requester_id': self.requester_id, diff --git a/inventory-backend/app/services/purchase_service.py b/inventory-backend/app/services/purchase_service.py index 3127307..e2005ac 100644 --- a/inventory-backend/app/services/purchase_service.py +++ b/inventory-backend/app/services/purchase_service.py @@ -79,6 +79,7 @@ class PurchaseService: images=json.dumps(data.get('images', []), ensure_ascii=False) if data.get('images') else '[]', unit_price=float(data.get('unit_price', 0) or 0), total_price=float(data.get('total_price', 0) or 0), + tax_rate=float(data.get('tax_rate', 0) or 0), requester_id=requester_id, approver_id=data.get('approver_id'), status=0 diff --git a/inventory-web/src/api/purchase.ts b/inventory-web/src/api/purchase.ts index a908720..fc2ed11 100644 --- a/inventory-web/src/api/purchase.ts +++ b/inventory-web/src/api/purchase.ts @@ -13,6 +13,7 @@ export interface PurchaseItem { images?: string[] unit_price?: number total_price?: number + tax_rate?: number status: number status_text?: string requester_id?: number diff --git a/inventory-web/src/views/outbound/create.vue b/inventory-web/src/views/outbound/create.vue index 1167861..e943a0f 100644 --- a/inventory-web/src/views/outbound/create.vue +++ b/inventory-web/src/views/outbound/create.vue @@ -79,25 +79,37 @@