一、实验名称
产品定制管理系统(WEB+框架)
二、实验目的
1.应用面向对象或结构化方法独立完成需求问题分析。
2.运用软件设计方法和原理设计项目解决方案,并能体现创新意识。
3.应用所学的语言或者框架技术完成软件项目的构造实现和测试。
4.应用文献研究等方法解决项目中的技术难题。
三、实验内容
本次实训的作品必须做成WEB版,且用框架完成!
实现产品定制管理系统的注册、登录、材料规格库、产品规格库、产品用料定制、产品生产工序定额设置、产品生产费用设置、产品价格预算公式设置、产品价格预算、下达产品生产任务、材料领用。具体功能要求如下:
1.注册/登录
注册:隐含功能按角色设置,角色不同,使用软件的功能不同
登录:登录后只能使用角色规定的功能
注:隐含权限管理
2.材料规格库
增删改,生产部门负责人,能分类管理
3.产品规格库/产品生产工序定额设置(生产部门负责人)
产品规格库:增删改,生产部门负责人,能分类管理
产品生产工序定额:定制产品的生产工时、镀锌面积等
4.产品用料定制
(设计部门负责人)定制产品用到材料规格库中的哪些定额材料(具体材料的货号、名称、规格型号、数量等)
5.产品生产费用设置
(生产部门负责人)按工序类别设置,如小时费用、按面积的镀锌费
6.产品价格预算公式设置
(设计部门负责人)产品大类:根据货号的前3位
公式设置等见附件
7.产品价格预算
能按产品公式显示各项数据
8.下达产品生产任务
(生产部门负责人)下达生产任务的同时,根据产品定制的用料,产生生产用的材料数据,以便供不同车间(部门)领用,具体车间(部门)由领用人或仓管员决定。注:生产用料不能随意改
9.材料领用
①能区分定制产品用料(定制产品用料,数量等不能改)跟一般材料领用(仓管员能修改材料数量)
②出库材料的单价按加权平均处理
10.辅助管理
涉及上述业务处理时所需的辅助表,如多仓库的仓库表管理、人员管理等等,只需提供简单的管理功能即可。
四、实验步骤
1.给出系统的需求分析;
2.给出仓库模型(所有与任务书有关的表);
3.给出事务处理算法;
4.系统的架构设计;
5.给出界面设计和有关样式/脚本等;
6.系统的详细设计;
7.系统的实现;
8.系统的测试。
五、需求分析(用例图/用例说明/业务用例)
1..用例图
2.用例说明
(一)注册/登录系统
- 用例编号:UC01
- 参与者:用户(包括设计部门、生产部门、仓管员)
- 前置条件:无
- 后置条件:用户成功注册或登录系统
- 主成功场景:
1. 用户访问系统并选择注册或登录。
2. 若注册,用户填写必要信息并提交。不同角色(设计部门、生产部门、仓管员)填写的信息可能存在差异,系统将根据角色设置隐含权限。
3. 若登录,用户输入用户名和密码,登录后只能使用角色规定的功能。
4. 系统验证信息并允许用户访问相应功能。
(二)管理材料规格库
- 用例编号:UC02
- 参与者:生产部门
- 前置条件:用户已登录系统
- 后置条件:材料规格信息被成功添加或更新
- 主成功场景:
1. 生产部门访问材料规格库。
2. 生产部门添加或修改材料规格信息,能对材料进行分类管理。
3. 系统保存更新后的信息。
(三)管理产品规格库
- 用例编号:UC03
- 参与者:生产部门
- 前置条件:用户已登录系统
- 后置条件:产品规格信息被成功添加或更新
- 主成功场景:
1. 生产部门访问产品规格库。
2. 生产部门添加或修改产品规格信息,能对产品进行分类管理。
3. 系统保存更新后的信息。
(四)定制产品用料
- 用例编号:UC04
- 参与者:设计部门
- 前置条件:产品规格已定义
- 后置条件:产品用料方案被创建
- 主成功场景:
1. 设计部门根据产品规格选择材料,具体为材料规格库中的定额材料(包括材料的货号、名称、规格型号、数量等)。
2. 设计部门定义每种材料的用量。
3. 系统记录用料方案。
(五)设置生产工序参数
- 用例编号:UC05
- 参与者:生产部门
- 前置条件:产品用料方案已定义
- 后置条件:生产工序参数被设置
- 主成功场景:
1. 生产部门定义每个生产步骤的参数,如定制产品的生产工时、镀锌面积等。
2. 生产部门输入所需时间、设备和人员信息。
3. 系统记录生产工序参数。
(六)设置产品生产费用
- 用例编号:UC06
- 参与者:生产部门
- 前置条件:生产工序参数已设置
- 后置条件:产品生产费用被计算并设置
- 主成功场景:
1. 生产部门根据工序参数计算成本,按工序类别设置费用,如小时费用、按面积的镀锌费。
2. 生产部门输入材料费、人工费等。
3. 系统计算各个成本并记录。
(七)设置产品价格预算公式
- 用例编号:UC07
- 参与者:设计部门
- 前置条件:无
- 后置条件:产品价格预算公式被定义
- 主成功场景:
1. 设计部门定义价格预算公式。根据产品大类(按货号的前3位)以及成本加成、市场调研等信息进行设置。
2. 设计部门输入相关参数,例如成本加成比例、市场预期利润率、不同材料成本占比等。。
3. 系统创建价格预算公式,公式可能是一个包含各种成本因素和加成比例的数学表达式,如:产品价格 = (材料成本 + 人工成本 + 设备折旧成本)×(1 + 成本加成比例)×(1 + 市场预期利润率)
(八)进行产品价格预算
- 用例编号:UC08
- 参与者:设计部门
- 前置条件:价格预算公式已定义
- 后置条件:产品价格被预算
- 主成功场景:
1. 设计部门输入相关参数,如产品用料定制中的定额材料费、产品生产工序参数设置中的镀锌费和制造工时费等。
2. 系统根据预算公式计算产品价格。具体算法如下:
- 首先对公式进行词法分析,分离出一个个单词。例如“{取镀锌费}*1.37”公式,分离
- 在词法分析的单词序列的基础上再解释求值。按照公式中规定的计算顺序(按序号排):1->2->3->4->5->11->6->7->8->9->10进行计算。其中,有关“取定额材料费”、 “取镀锌费”、“取制造工时费”等根据产品生产工序的需要设定,在系统设计中可以把这些设定映射成计算方法,通过方法(这些方法带货号参数或不带参数)的反射来辅助计算。
3. 系统显示预算结果。
(九)下达产品生产任务
- 用例编号:UC09
- 参与者:生产部门
- 前置条件:产品用料和生产费用已定义
- 后置条件:生产任务被下达
- 主成功场景:
1. 生产部门创建生产任务。
2. 生产部门分配任务到生产线。
3. 系统记录任务并通知相关人员。同时,根据产品定制的用料,产生生产用的材料数据,以便供不同车间(部门)领用,具体车间(部门)由领用人或仓管员决定,且生产用料不能随意改。
(十)领用材料
- 用例编号:UC10
- 参与者:仓管员
- 前置条件:生产任务已下达
- 后置条件:材料被领用
- 主成功场景:
1. 仓管员根据生产任务领用材料。对于定制产品用料,数量等不能改;对于一般材料领用,仓管员能修改材料数量。
2. 仓管员记录领用数量和时间。
3. 系统更新库存信息,出库材料的单价按加权平均处理。
(十一)管理仓库表
- 用例编号:UC11
- 参与者:仓管员
- 前置条件:仓库表存在
- 后置条件:仓库表被更新
- 主成功场景:
1. 仓管员访问仓库表。
2. 仓管员更新库存数量和状态。
3. 系统保存更新信息。
(十二)管理人员
- 用例编号:UC12
- 参与者:管理人员
- 前置条件:系统已登录
- 后置条件:人员信息被管理
- 主成功场景:
1. 管理人员访问人员管理模块。
2. 管理人员添加、修改或删除人员信息。
3. 系统保存更新后的人员信息。
3.业务用例
UC01:用户注册/登录 - 允许用户创建账户并登录系统,以访问系统功能。
UC02:管理材料规格库 - 使生产部门能够管理材料规格信息。
UC03:管理产品规格库 - 使生产部门能够管理产品规格信息。
UC04:定制产品用料 - 允许设计部门根据产品规格定制产品用料。
UC05:设置生产工序参数 - 使生产部门能够设置生产工序参数。
UC06:设置产品生产费用 - 使生产部门能够设置产品生产费用。
UC07:设置产品价格预算公式 - 允许设计部门设置产品价格预算公式。
UC08:进行产品价格预算 - 允许设计部门根据公式进行产品价格预算。
UC09:下达产品生产任务 - 使生产部门能够下达产品生产任务。
UC10:领用材料 - 允许仓管员领用材料。
UC11:管理仓库表 - 允许仓管员管理仓库信息。
UC12:管理人员 - 允许管理人员管理员工信息。
六、概要设计
1.仓库模型
1.1数据模型
用户表:存储用户信息,包括用户ID、账号、密码、角色等
材料规格表:存储材料信息,包括材料ID、名称、规格型号、分类、单位等
产品规格表:存储产品信息,包括产品ID、名称、规格型号、分类、货号等
产品生产工序参数表:存储产品生产所需的参数,包括参数ID、产品ID、参数名称、参数值等
产品用料定制表:存储产品所需的定额材料信息,包括产品ID、材料ID、数量等
产品生产费用表:存储不同工序的费用信息,包括费用ID、工序类别、费用值等
产品价格预算公式表:存储产品价格计算公式,包括公式ID、项目名称、计算公式等
生产任务表:存储生产任务信息,包括任务ID、产品ID、数量、车间/部门等
材料领用表:存储材料领用信息,包括领用ID、材料ID、数量、单价、总价等
仓库表:存储仓库信息,包括仓库ID、名称、地址等
人员表:存储人员信息,包括人员ID、姓名、职位、所属部门等
1.2表模型
1.用户表 (user)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
account Varchar 登录账号 50 N N NULL
password varchar 密码 50 N N NULL
role varchar 角色 20 N N NULL
表模型说明:
id:用户ID,主键,自动增长
account:登录账号,唯一
password:密码
role:角色,例如:生产部分负责人、设计部门负责人、仓管员
2. 材料规格表 (material)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
name varchar 材料名称 100 N N NULL
specification varchar 规格型号 100 N N NULL
category varchar 分类 20 N N NULL
unit varchar 单位 10 N N NULL
表模型说明**:
id:材料ID,主键,自动增长
name:材料名称
specification:规格型号
category:分类
unit:单位
3. 产品规格表 (product)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
name varchar 产品名称 100 N N NULL
specification varchar 规格型号 100 N N NULL
category varchar 分类 20 N N NULL
material_id int 所属材料ID 11 N N NULL
表模型说明:
id:产品ID,主键,自动增长
name:产品名称
specification:规格型号
category:分类
material_id:所属材料ID,外键关联材料规格表
4. 产品生产工序参数表 (production_parameter)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
product_id int 所属产品ID 11 N N NULL
parameter_name varchar 参数名称 50 N N NULL
parameter_value varchar 参数值 50 N N NULL
表模型说明:
id:参数ID,主键,自动增长
product_id:所属产品ID,外键关联产品规格表
parameter_name:参数名称,例如:工时、镀锌面积等
parameter_value:参数值
5. 产品用料定制表 (product_material)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
product_id int 所属产品ID 11 N N NULL
material_id int 材料ID 11 N N NULL
quantity int 数量 11 N N NULL
表模型说明:
id:用料ID,主键,自动增长
product_id:所属产品ID,外键关联产品规格表
material_id:材料ID,外键关联材料规格表
quantity:数量
6. 产品生产费用表 (production_cost)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
category varchar 工序类别 20 N N NULL
cost_value decimal 费用值 10,2 N N NULL
表模型说明:
id:费用ID,主键,自动增长
category:工序类别,例如:小时费用、镀锌费等
cost_value:费用值
7. 产品价格预算公式表 (price_formula)
字段名 字段类型 字段长度 是否可以为空值 是否是主键 初始值
id int 11 N Y NULL
item_name varchar 50 N N NULL
formula varchar 255 N N NULL
表模型说明:
id:公式ID,主键,自动增长
item_name:项目名称,例如:定额材料费、附加材料费等
formula:计算公式
8. 生产任务表 (production_task)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int Id 11 N Y NULL
product_id int 产品ID 11 N N NULL
quantity int 数量 11 N N NULL
department_id int 车间/部门ID 11 N N NULL
表模型说明:
id:任务ID,主键,自动增长
product_id:产品ID,外键关联产品规格表
quantity:数量
department_id:车间/部门ID
9. 材料领用表 (material_receiving)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
material_id int 材料ID 20 N N NULL
quantity int 数量 11 N N NULL
unit_price decimal 单价 10,2 N N NULL
total_price decimal 总价 10,2 N N NULL
表模型说明:
id:领用ID,主键,自动增长
material_id:材料ID,外键关联材料规格表
quantity:数量
unit_price:单价
total_price:总价
10. 仓库表 (warehouse)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
name varchar 仓库名称 50 N N NULL
address varchar 地址 100 N N NULL
表模型说明:
id:仓库ID,主键,自动增长
name:仓库名称
address:地址
11. 人员表 (staff)
字段名 字段类型 字段描述 字段长度 是否可以为空值 是否是主键 初始值
id int ID 11 N Y NULL
name varchar 姓名 50 N N NULL
position varchar 职位 50 N N NULL
department_id int 所属部门ID 11 N N NULL
表模型说明:
id:人员ID,主键,自动增长
name:姓名
position:职位
department_id:所属部门ID
2.权限管理
2.1权限控制的数据流图(DFD)
- 展示用户如何通过权限控制访问系统的不同模块
说明:
- [用户]:表示尝试访问系统的用户。
- (登录模块):用户提交登录请求的地方。
- {凭证有效}:系统验证用户的凭证(用户名和密码)。
- [角色分配模块]:根据用户的凭证验证结果,系统分配相应的角色。
- [拒绝访问]:如果凭证无效,用户将被拒绝访问。
- {角色}:表示不同的用户角色,包括设计部门、生产部门、仓管员和管理人员。
- [设计部门功能]、[生产部门功能]、[仓管员功能]、[管理人员功能]:根据不同的角色,用户被引导至相应的功能模块。
- [定制产品用料模块]、[设置产品价格预算公式模块]、[管理材料规格库模块]、[设置生产工序参数模块]、[领用材料模块]、[管理人员信息模块]:这些模块代表系统的具体功能,用户只能访问他们角色权限范围内的模块。
2.2权限管理的类图
- 展示系统中与权限管理相关的类以及它们之间的关系
说明:
- User:用户类,包含用户名、密码、部门和角色属性。
- Role:角色类,包含角色名和权限列表。
- Permission:权限类,包含权限名称。
- UserManager:用户管理类,负责管理用户信息,包括登录和注册用户。
- RoleManager:角色管理类,负责管理角色信息,包括根据用户获取角色。
- PermissionManager:权限管理类,负责管理权限信息,包括检查用户是否具有特定权限。
- AccessControl:访问控制类,负责用户的认证和授权。
类之间的关系:
- User与Role之间是多对一的关系,表示一个用户有一个角色。
- Role与Permission之间是多对多的关系,表示一个角色有多个权限。
- UserManager管理User对象。
- RoleManager管理Role对象。
- PermissionManager管理Permission对象。
- AccessControl使用UserManager、RoleManager和PermissionManager来执行认证和授权。
3.架构设计
产品定制管理系统采用分层架构模式,分为表现层、业务逻辑层、数据访问层和数据库层,有助于提高系统的可维护性、可扩展性和可测试性。
(一)表现层
1. 用户界面设计
- 采用响应式设计原则,确保系统能够在不同设备(如桌面电脑、平板电脑、智能手机)上提供良好的用户体验。
- 为不同角色(设计部门、生产部门、仓管员、管理人员)设计定制化的界面,根据其权限显示相关的功能菜单和操作按钮。例如,设计部门用户界面可能突出显示产品设计相关的功能模块,如定制产品用料、设置产品价格预算公式等;而仓管员界面则侧重于材料领用和仓库管理相关的操作。
2. 交互设计
- 使用直观的图形界面元素,如按钮、文本框、下拉菜单、表格等,方便用户操作。例如,在材料领用界面,仓管员可以通过下拉菜单选择材料名称,在文本框中输入领用数量等。
- 提供实时反馈机制,当用户进行操作(如提交注册信息、修改材料规格)时,系统及时显示操作结果(如注册成功提示、修改保存成功提示),增强用户对系统的信任和使用体验。
(二)业务逻辑层
1. 模块划分
- 用户管理模块
- 负责处理用户注册、登录验证以及权限管理。在注册过程中,根据用户输入的部门信息(设计部门、生产部门、仓管员、管理人员)为用户分配相应的角色,并将用户信息和角色权限信息存储在数据库中。登录验证时,比对用户输入的用户名和密码与数据库中的记录,同时根据用户角色确定其可访问的功能模块。
- 材料管理模块
- 包括材料规格库管理和材料领用管理两个子模块。材料规格库管理子模块负责材料规格信息的增删改查操作,支持生产部门对材料进行分类管理。材料领用管理子模块处理仓管员的材料领用操作,根据生产任务和定制产品用料要求验证领用数量,并更新库存信息。
- 产品管理模块
- 涵盖产品规格库管理、产品用料定制、生产工序参数设置和产品生产费用设置等功能。产品规格库管理子模块类似于材料规格库管理,负责产品规格信息的增删改查和分类管理。产品用料定制子模块由设计部门使用,根据产品规格选择材料并定义用量。生产工序参数设置子模块允许生产部门定义每个生产步骤的参数,如生产工时、镀锌面积等。产品生产费用设置子模块根据工序参数计算产品生产费用,包括材料费、人工费等。
- 生产任务管理模块
- 负责生产任务的下达和分配。生产部门创建生产任务时,系统根据产品用料和生产费用信息生成生产用的材料数据,并将任务分配到生产线。同时,系统记录任务相关信息并通知相关人员(如生产工人、仓管员)。
- 价格预算模块
- 包含产品价格预算公式设置和产品价格预算计算两个功能。设计部门在产品价格预算公式设置子模块中定义价格预算公式,考虑成本加成、市场调研等因素。产品价格预算计算子模块根据公式和输入的相关参数(如材料成本、人工成本、生产工序参数等)计算产品价格,采用词法分析和按顺序计算的算法。
2. 业务逻辑处理
- 各模块之间通过接口进行通信和协作。例如,当生产部门下达生产任务时,生产任务管理模块通过接口调用材料管理模块获取材料数据,调用产品管理模块获取产品规格和生产工序参数等信息。
- 在业务逻辑处理过程中,对数据进行严格的验证和处理。例如,在材料领用管理中,对领用数量进行验证,确保符合生产任务和定制产品用料要求;在价格预算计算中,对输入的参数进行验证,确保数据的准确性和完整性。
(三)数据访问层
1. 数据库接口设计
- 针对每个业务实体(用户、材料、产品、生产任务等)设计相应的数据库接口。这些接口提供了对数据库进行增删改查操作的方法。例如,用户数据库接口可能包括方法如`insertUser`(插入用户信息)、`updateUser`(更新用户信息)、`deleteUser`(删除用户信息)、`queryUser`(查询用户信息)等。
- 采用面向对象的设计方法,将数据库接口封装在类中,提高代码的可维护性和可重用性。例如,创建一个`UserDAO`类,其中包含上述用户数据库接口的方法。
2. 数据访问对象(DAO)实现
- 每个数据库接口类都有对应的实现类,负责实际执行对数据库的操作。这些实现类使用数据库连接技术(如JDBC for Java projects)与数据库进行交互。例如,`UserDAOImpl`类实现`UserDAO`接口,在其方法中使用JDBC代码来执行对用户数据库表的插入、更新、删除和查询操作。
- 在数据访问对象实现过程中,处理数据库连接的创建和关闭、事务管理等问题。例如,在一个包含多个数据库操作的业务逻辑中(如材料领用操作,涉及库存更新和材料领用记录插入),使用事务管理机制确保所有操作要么全部成功,要么全部失败,避免数据不一致性。
(四)数据库层
1. 数据库选型
- 根据系统的性能、功能和成本要求,选择合适的数据库管理系统。对于本产品定制管理系统,考虑到其数据量和并发访问需求,MySQL是一个合适的选择。MySQL具有良好的性能、稳定性和扩展性,能够满足系统的日常运行需求。
2. 数据库结构设计
- 用户表
- 存储用户信息,包括用户ID、用户名、密码、部门、角色等字段。其中,用户ID作为主键,确保每个用户的唯一性。
- 材料表
- 存储材料规格信息,如材料ID、材料名称、规格型号、分类类别、库存数量、单价等字段。材料ID作为主键,用于唯一标识每种材料。
- 产品表
- 存储产品规格信息,包括产品ID、产品名称、规格型号、分类类别、生产工序参数、生产费用等字段。产品ID作为主键,用于唯一标识每种产品。
- 生产任务表
- 存储生产任务信息,如任务ID、产品ID、生产部门、下达时间、材料数据(以JSON格式存储产品用料信息)等字段。任务ID作为主键,用于唯一标识每个生产任务。
- 价格预算
- 存储产品价格预算相关信息,包括预算ID、产品ID、价格预算公式、输入参数、预算结果等字段。预算ID作为主键,用于唯一标识每个价格预算记录。
七、详细设计
1.系统的详细设计
用例详细设计图:
1.用例 UC01: 注册/登录系统
类关系图:时序图:
2.用例 UC02: 管理材料规格库
类关系图:
时序图:
3.用例 UC03: 管理产品规格库
类关系图:
时序图:
4.用例 UC04: 定制产品用料
类关系图:
时序图:
5.用例 UC05: 设置生产工序参数
类关系图:
时序图:
6.用例 UC06: 设置产品生产费用
类关系图:
时序图:
7.用例 UC07: 设置产品价格预算公式
类关系图:
时序图:
8.用例 UC08: 进行产品价格预算
类关系图:
时序图:
9.用例 UC09: 下达产品生产任务
类关系图:
时序图:
10.用例 UC10: 领用材料
类关系图:
时序图:
11.用例 UC11: 管理仓库表
类关系图:
时序图:
12.用例 UC12: 管理人员
类关系图:
时序图:、
2.算法处理
(一)材料出库算法
1. 生产任务检查
- 当仓管员发起材料领用操作时,系统首先查询生产任务管理模块,检查相应的生产任务是否已下达。这一过程涉及到与生产任务数据库表的交互,通过查找生产任务记录中的下达状态字段来确定。如果生产任务未下达,则在系统界面弹出明确的错误提示信息,如“生产任务未下达,禁止材料出库”,同时阻止材料出库操作的执行,确保材料领用与生产任务的紧密关联。
-伪代码:
function checkProductionTask(taskId):
task = queryProductionTaskDatabase(taskId)
if task.status != "下达":
displayError("生产任务未下达,禁止材料出库")
return false
return true
2. 定制产品用料验证
- 对于定制产品用料,系统在仓管员输入领用数量后,会从生产任务中提取该定制产品用料的规定数量,并与输入的领用数量进行严格比对。这种比对是基于精确的数值匹配,因为定制产品的用料数量通常是根据特定设计和生产要求精确确定的。如果两者不一致,系统会在界面上显示详细的错误提示,例如“定制产品用料数量不符,请核对后重新操作”,并禁止材料出库,以保证定制产品的生产质量和成本控制符合设计要求。
-伪代码:
function verifyCustomMaterialUsage(materialId, requestedQuantity):
requiredQuantity = getCustomProductMaterialRequirement(materialId)
if requestedQuantity != requiredQuantity:
displayError("定制产品用料数量不符,请核对后重新操作")
return false
return true
3. 一般材料领用处理
- 对于一般材料领用,系统允许仓管员在合理范围内修改领用数量。仓管员可以根据实际生产需求和库存情况,在系统提供的输入界面中调整领用数量。系统会实时监测输入的数量是否在合理的库存和生产需求范围内,如果超出合理范围,会给予适当的提示,但不会像定制产品用料那样严格禁止操作。同时,系统会记录仓管员对领用数量的修改操作,以便后续审计和分析材料使用情况。
-伪代码:
function handleGeneralMaterialIssuance(materialId, requestedQuantity):
maxAllowedQuantity = getMaximumAllowedQuantity(materialId)
if requestedQuantity > maxAllowedQuantity:
displayWarning("领用数量超出合理范围,请调整")
else:
updateMaterialUsage(materialId, requestedQuantity)
recordMaterialIssuance(materialId, requestedQuantity)
4. 库存信息更新与单价计算
- 系统根据材料的出库情况更新库存信息,这涉及到对库存数据库表的更新操作。首先,系统会在库存表中找到对应的材料记录,将其库存数量字段的值减去出库数量。同时,根据材料的出库时间、入库时间以及当前库存数量等因素,更新库存状态字段,例如将库存状态从“充足”更新为“部分短缺”(如果出库后库存数量低于某个设定的阈值)。
- 对于出库材料的单价计算,系统按照加权平均算法进行。它会获取该材料的所有入库记录,包括入库数量和入库单价。然后根据加权平均公式:加权平均单价 = (入库数量1×入库单价1 + 入库数量2×入库单价2 + … + 入库数量n×入库单价n)/(入库数量1 + 入库数量2 + … + 入库数量n)计算出库材料的单价。最后,将计算出的单价以及出库数量、出库时间等相关信息记录在材料出库记录数据库表中,以便后续财务核算和成本分析。
-伪代码:
function updateInventoryAndCalculateUnitPrice(materialId, issuanceQuantity):
inventory = queryInventoryDatabase(materialId)
inventory.quantity -= issuanceQuantity
inventory.status = updateInventoryStatus(inventory.quantity)
updateInventoryDatabase(inventory)
unitPrice = calculateWeightedAveragePrice(materialId)
recordMaterialIssuancePrice(materialId, issuanceQuantity, unitPrice)
(二)产品价格预算算法
1. 公式词法分析
- 如上述产品价格预算部分所述,系统首先对价格预算公式进行词法分析。这一过程类似于编译器对编程语言的词法分析过程。系统会将公式字符串作为输入,按照预定的词法规则,将其分解为一个个单词。例如,对于公式“{取镀锌费}*1.37 + {取制造工时费}*2”,系统会识别出“{取镀锌费}”、“*”、“1.37”、“+”、“{取制造工时费}”、“*”、“2”等单词。同时,系统会为每个单词标记其类型,如“{取镀锌费}”和“{取制造工时费}”标记为元数据类型,“*”和“+”标记为算符类型,“1.37”和“2”标记为常量类型。
-伪代码:
function lexicalAnalysis(formula):
tokens = tokenize(formula)
for token in tokens:
if isMetadata(token):
token.value = getMetadataValue(token.name)
elif isOperator(token):
token.type = "operator"
elif isConstant(token):
token.type = "constant"
return tokens
2. 单词计算处理
- 根据单词的类型(元数据、算符、常量等)进行相应的计算处理。
- 对于元数据类型的单词,如“{取镀锌费}”,系统通过方法反射获取对应的数据值。这涉及到在系统的代码架构中,定义了一系列与获取各种成本数据相关的方法。当遇到元数据类型的单词时,系统会根据单词中的标识(如这里的“镀锌费”)找到对应的方法,并调用该方法获取实际的数据值。例如,如果系统中有一个方法名为“getZincPlatingFee”用于获取镀锌费,系统会调用这个方法并将其返回值作为“{取镀锌费}”这个单词的值。
- 对于算符类型的单词,系统按照预定义的运算规则进行处理。例如,当遇到“*”算符时,系统知道需要进行乘法运算;当遇到“+”算符时,系统知道需要进行加法运算。
- 对于常量类型的单词,系统直接使用其数值进行计算。例如,对于“1.37”和“2”,系统在计算过程中直接使用这些数值。
-伪代码:
function calculateTokenValue(token):
if isMetadata(token):
return getMetadataValue(token.name)
elif isOperator(token):
return performOperation(token)
elif isConstant(token):
return token.value
3. 按顺序计算结果
- 按照公式规定的计算顺序依次计算各个部分的值。系统会维护一个计算栈,将单词按照计算顺序依次压入栈中。当遇到算符时,从栈中弹出相应数量的操作数(根据算符的元数,如二元算符弹出两个操作数)进行计算,并将结果压回栈中。例如,对于公式“{取镀锌费}*1.37 + {取制造工时费}*2”,系统首先计算“{取镀锌费}*1.37”的值,将结果压回栈中,然后计算“{取制造工时费}*2”的值,再将两个结果相加,最终得到产品价格预算结果。系统会将最终的预算结果存储在产品价格预算结果数据库表中,同时在系统界面上显示给相关用户(如设计部门人员),以便他们进行进一步的分析和决策。
-伪代码:
function calculatePriceBudget(tokens):
stack = []
for token in tokens:
if isOperator(token):
operands = popOperands(stack, token.arity)
result = performOperation(token, operands)
stack.push(result)
else:
stack.push(token.value)
return stack.pop()
八、实现
九、测试