资源描述
学校内部工资管理系统
53
2020年4月19日
文档仅供参考,不当之处,请联系改正。
目录
目录 1
1问题定义 2
2可行性研究 2
2.1 系统流程图 3
2.2 高层数据流图 3
2.3 可行性分析 4
2.4 开发计划 4
3 需求分析 5
3.1 E-R图 5
3.2 细化的数据流图 6
3.3 数据字典 6
3.4 状态转换图 7
4 概要设计 9
4.1 系统层次图 9
4.2 IPO表 9
4.3 文件设计 11
5 详细设计 13
5.1 人机界面设计 13
5.2 过程设计 14
6 测试报告 16
7 总结 17
参考文献 17
附录 17
1问题定义
随着公司规模的不断扩大,职工数量急剧增加,有关职工的各种信息量也成倍增长,而当前许多公司的职工工资管理系统仍停留在复杂的人工操作上,重复工作较多,工作量大,效率低,因此该设计要求学生设计一套计算机“职工工资管理系统”,以提高信息的开放性,大大地改进了公司、职工对其最新信息查询的准确性,从而提高管理水平和工作效率,公司员工的工资情况进行管理,完成员工基本信息的添加、修改、删除和查询功能,考勤管理功能,工资结算功能。
关于系统规模和目标的报告书
项目名称: 职工工资管理系统
问题: 当前计算工资和编制报表的费用太高。
项目目标: 研究开发费用较低的新工资支付系统的可能性。
项目规模: 开发成本应该不超过7.2万元(±50%)
初步设想: 用公司自己的计算机系统生成工资明细表
可行性研究:为了更全面的研究工资支付项目的可能性,建议进行大约历时两周的可行性研究。研究的成本不超过4000元。
2可行性研究
当接受一个软件开发任务,就进入软件生命的第一个阶段,即进行可行性的研究。并不是所有问题具有简单的解决办法,许多问题不能在预定的规模之内解决。因此经过可行性的研究分析能够知道问题。
有无可行性的解决方法,进而避免人力、物力和才力的浪费。在现行系统初步调查的基础上就能够提出新系统目标,即新系统建立后所要求达到的运行指标,这是系统开发和评价的依据。系统目标应充分体现,直接为学生档案信息管理系统服务,而且,程序能够分期分批实现。可是,需要指出的是,系统目标是不可能在总体规划阶段就提得非常具体,它还将在开发过程中逐步明确和定量化。以达到更加出众的程序系统。可是,目标的提法不尽相同。
2.1 系统流程图
图2.1系统流程图
2.2 高层数据流图
从硬件方面来说,数据流图(Data Flow Diagram,DFD)是用来描绘软件系统逻辑模型的图形工具,用于描绘信息在系统中的流动和处理情况。数据流图是结构系统分析的主要工具,它表示了系统内部信息的流向,并表示了系统的逻辑处理的功能,是一种功能模型。数据流图具体功能分析如下:
(1)数据源点和数据终点: 数据源点和数据终点用方框表示,它是系统之外的实体,能够是人、事、物、部门或其它系统。
(2)加工(数据处理变换):加工用圆框表示,是对数据进行处理的逻辑单元,它接受若干输入数据流,经过加工,内部产生规定的输出数据流。
(3)数据流:数据流用带数据流标识的箭头表示,表示系统处理的数据对象和数据流动的方向。数据流的方向能够是:从一加工流向另一加工、从加工流向数据存储或数据存储流向加工、从源点流向加工或从加工流向终点。
(4)数据存储文件:数据存储文件在数据流图中起着保存数据的作用,它能够是数据库、文件或任何其它形式,指向存储的数据流可理解为数据写入,从存储引出的数据流可理解为数据读出。公司职工工资管理系统的高层数据流图:
图2.1高层数据流图
2.3 可行性分析
为了澄清问题定义之后,分析员应该导出系统的逻辑模型。然后从系统逻辑模型出发,探索若干种可供选择的主要解决(即系统实现方案)。对每种解法都应该仔细研究它的可行性,一般说来,至少应该从以下述三个方面研究每种解法的可行性:
2.3.1技术可行性
技术上的可行性分析主要分析现有技术条件能否顺利完成开发工作,硬、软件配置能否满足开发者需要等。当前公司各工作点均采用PC机作为工作台,其容量、速度能满足系统要求。
根据客户提出的系统功能、性能及实现系统的各项约束条件,根据新系统目
标来衡量所需的技术是否具备,本系统是一个文件管理和查询的系统,现有的技术以较为成熟,硬件、软件的性能要求、环境条件等各项条件良好,估计利用现有技术条件应完全能够达到该系统的功能目标。同时,考虑给予的开发期限也较为充裕,预计系统是能够在规定期限内完成开发。
2.3.2经济可行性
主要是对开发公司职工工资管理系统的经济效益进行评价,一方面是估算开发它的支出费用,其中包括设备购置费、软件开发费、管理和维护费、人员工资和培训费等。另一方面是估算职工工资管理这个软件可能取得的收益中能够用钱来衡量的那部分。并对当前的软件市场进行调查,所做软件是否有很大的销售市场和相当规模的用户群。所做软件的开发成本与客户提出的要求是否可达到双方都满意。而且,分析系统开发是否会对其它产品或利润带来一定影响。经过对上述几个方面的调查研究和分析,我们得出职工工资管理这个软件的使用性非常强,减轻人力成本,在经济角度来说,开发职工工资管理是可行的。
2.3.3操作可行性
主要是了解职工工资管理的相关人员对开发信息系统是否支持,现有职工工资管理制度和方法是否科学,规章制度是否齐全,原始数据是否正确等。职工工资管理人员积极支持该系统开发,使新系统能够充分的发挥作用;系统操作简单,易于理解,操作者经过短时间的培训就能够使用职工工资管理系统。
2.4 开发计划
职工工资管理系统的粗略计划
阶段
要用的时间(天)
可行性研究
1
需求分析
1
概要设计
2
详细设计
2
实现
8
总计
14
3 需求分析
该系统主要包括系统功能输入模块、基本资料维护模块、报表模块、综合查询功能模块和统计模块等。系统要实现基本信息录入、修改、查询等功能:
(1)信息的输入,职工基本信息、工作信息、相关资料信息等。
(2)信息的修改、删除。
(3)根据要求,查询统计符合条件的各类信息。
3.1 E-R图
图3.1职工工资管理系统E-R图
将工资管理系统的E-R图转换为关系模型如下:
管理员(管理员名,密码)
管理(编号,姓名)
职工(编号,姓名,性别,职位,基本工资,加班工资,其它奖金)
工资(基本工资,加班工资,其它奖金)
3.2 细化的数据流图
图3.2 职工工资管理系统细化了的数据流图
3.3 数据字典
数据字典是关于数据的信息的集合,也就是对数据流图中包含的所有元素的定义的集合。任何字典最主要的用途都是供人们查阅对不了解的条目的解释,数据字典的作用也正是在软件分析和设计的过程中给人提供关于数据的描述信息。公司职工工资管理系统的数据字典如下:
名称:职工信息文件
别名:
描述:文件中所存储的职工信息
定义:职工信息=姓名+编号+性别+基本工资+加班工资+其它奖金+总额
位置:职工工资信息表,输出到打印机
表3.1 职工信息文件的数据字典
名称:管理员信息
别名:
描述:描述管理员的信息
定义:管理员信息=管理员名+密码
位置:管理员信息
表3.2 管理员信息的数据字典
名称:工资信息
别名:
描述:描述职工的工资信息
定义:工资信息=基本工资+加班工资+其它奖金
位置:职工工资信息表
表3.3 工资信息的数据字典
3.4 状态转换图
状态转换图(简称状态图)经过描绘系统的状态及引起系统状态装换的事件,来表示系统的行为。另外,状态图还指明了作为特定事件的结果系统将做哪些动作。
状态是任何能够被视察到得系统行为模式,一个状态代表系统的一种行为模式。状态规定了系统对事件的响应方式。系统对事件的响应,既能够是做一个(或一系列)动作,也能够是仅仅改变系统本身的状态,还能够是既改变状态又做动作。
在状态中定义的状态主要有:初态(即初始状态)、终态(即最终状态)和中间状态。在一张状态图中只能有一个初态,儿终态则能够有0至多个。
事件是在某个特定时刻发生的事情,它是对引起系统做动作或(和)从一个状态换到另一个状态的外界事件的抽象。
公司职工工资管理系统的状态转换图:
图3.4职工工资管理系统的状态图
4 概要设计
4.1 系统层次图
图4.1层次方框图
4.2 IPO表
IPO表
系统:职工工资管理系统
模块:输入信息
编号:2.2
作者:庞金凤
日期: -7-13
被调用:职工信息表
调用:旧得存储信息
输入:按要求输入职工基本情况
输出:职工信息
处理:存入职工信息
局部数据元素:
注释:
表4.2.1输入模块的IPO表
IPO表
系统:职工工资管理系统
模块:显示信息
编号:2.3
作者:庞金凤
日期: -7-13
被调用:职工信息表
调用:存储信息
输入:显示按钮
输出:显示所有职工信息
处理:讲所有职工信息显示在屏幕上
局部数据元素:
注释:
表4.2.2显示模块的IPO表
IPO表
系统:职工工资管理系统
模块:查找信息
编号:2.4
作者:庞金凤
日期: -7-13
被调用:职工信息表
调用:存储信息
输入:要查找职工的编号
输出:显示出查找的职工的详细信息
处理:查找对应的职工信息
局部数据元素:
注释:
表4.2.3查找模块的IPO表
IPO表
系统:职工工资管理系统
模块:增加信息
编号:2.4
作者:庞金凤
日期: -7-13
被调用:职工信息表
调用:存储信息
输入:要添加的职工信息
输出:显示所有职工信息
处理:存入职工信息
局部数据元素:
注释:
表4.2.4增加模块的IPO表
4.3 文件设计
本系统中,我们使用了文件管理的方式,对职工信息的保存,读取等操作。
(1)读取的代码段
staff *Information::Read()
{
system("cls");
int i=0;
p1=p2=( staff *)malloc(LEN);
head=NULL;
ifstream in("data",ios::out);
in>>i;
if(i==0){cout<<" data 文件中的数据为空,请先输入数据!"<<endl; return 0;}
else {
cout<<"\n原文件已保存的信息如下:\n";
cout<<" ………………………………………………………………………………………………"<<endl;
cout<<"|姓 名| |编 号| |性别| |基本工资| |加班工资| |其它奖金| |总额|\n";
cout<<" ………………………………………………………………………………………………"<<endl;
for(;i>0;i--)
{
p1=(staff *)malloc(LEN);
in>>st.name>>st.id>>st.sex
>>st.paid[0]>>st.paid[1]>>st.paid[2]>>st.total;
strcpy(p1->name,st.name);
p1->id=st.id;
strcpy(p1->sex,st.sex);
p1->paid[0]=st.paid[0];
p1->paid[1]=st.paid[1];
p1->paid[2]=st.paid[2];
p1->total=st.total;
if(n==0)head=p1; //如果是输入第一组职工信息就将指针p1赋给指针head
else p2->next=p1; //否则将p1赋给p2所指结构体的next指针
p2=p1; //将指针p1赋给指针p2
n++; //将n的值加1
//显示读入数据
cout<<" "<<p1->name<<"\t"
<<p1->id<<" \t"
<< p1->sex <<" \t"
<< p1->paid[0] <<" \t"
<< p1->paid[1] <<" \t"
<< p1->paid[2] <<" \t"
<< p1->total<<endl;
cout<<" ………………………………………………………………………………………………"<<endl;
}
cout<<" 数据已经成功读取完毕!\n\n"<<endl;
p2->next=NULL;
return (head);
}
(2)保存的代码段
void Information::save(staff *head)
{
system("cls");
ofstream out("data",ios::out);
out<<count(head)<<endl;
while(head!=NULL)
{ out<<head->name<<"\t"
<<head->id<<"\t"<<"\t"
<<head->sex<<"\t"
<<head->paid[0]<<"\t"
<<head->paid[1]<<"\t"
<<head->paid[2]<<"\t"
<<head->total<<endl;
head=head->next;
}
}
5 详细设计
5.1 人机界面设计
(1)登录界面
图5.1.1登录界面
(2)进入管理员所管理的界面
图5.1.2管理界面
5.2 过程设计
(1)登录界面
用户名是否输入
否 是
密码是否输入
否 是
查找管理员表中对应密码的用户
否 存在? 是
打开主窗体
检查输入次数>4
关闭窗体
图5.2.1 登录界面图
(2)职工信息添加
是否为已存在职工
是 否
提示:需要在保存后退出
是否保存?
否 是
保存成功
否 是
Rollback Commit
关闭窗体
5.2.2职工信息添加
(3)查询操作
输入查询信息
否 是
是否存在该信息数据
否 是
提示没有 输出该信息
所要查询
的信息
确认信息
关闭窗体
图5.2.3 查询操作图
6 测试报告
1、软件的测试方法有两种,一种是黑盒测试(功能测试),另外一种是白盒测试(结构测试)。
(1)黑盒测试
黑盒测试把程序看作一个黑盒子,完全不考虑程序的内部结构和处理过程。也就是说,黑盒测试是在程序接口进行的测试,它只检查程序功能是否能按照规格说明书的规定正常使用,程序是否能适当的接受输入数据并产生正确的输出信息,程序运行过程中能否保持外部信息的完整性。
(2)白盒测试
白盒测试的前提是能够把程序看成装在一个透明的白盒子里,测试者完全知道程序的结构和处理算法。这种方法按照程序内部的逻辑测试程序,检测程序中的主要执行通路是否能按预定的要求正确工作。
在本次软件的测试工作中,由于水平的限制,仅仅对软件的各个功能模块进行了测试,并对各个模块之间的接口进行了详细的测试(用黑盒测试法)。
2、测试的步骤
由于该系统是一个小系统,能够把整个系统作为一个单独的实体来测试。当然,在测试的过程中能够分模块、分阶段来进行。大型软件系统一般是有若干个子系统组成,且每个子系统由由许多模块组成,因此,软件的测试过程基本上由以下步骤组成:
(1)模块测试
(2)子系统测试
(3)系统测试
(4)验收测试
(5)平行运行
3、测试用例:
本次主要负责模块有四个,即输入模块、查找模块、显示模块和增加模块,这里只列出这四个模块的测试用例。
(1) 输入模块
在主界面中选择输入模块的按钮后,根据界面提示依次输入职工的信息,如果输入内容与管理要求相一致,则输入成功。
(2)查找模块
在主界面中选择查找模块的按钮后,将要查找的编号,并确认后,查询模块的窗体应显示某职工的所有信息,包括姓名、性别、编号、基本工资、加班工资、其它奖金等。查找成功。
(3)显示模块
在主界面中选择显示模块的按钮后,屏幕则会显示所有职工工资信息,显示成功。
(4)增加模块
在主界面中选择增加模块的按钮,则根据界面提示依次增加职工信息跟工资情况,增加成功。
7 总结
经过两个星期的职工工资管理系统的课程设计,使我们对开发一个软件的步骤,过程有了更加清晰明朗的思路。知道设计一个软件需要经过可行性分析,需求分析,总体设计,详细设计,实现,维护等阶段。
职工工资管理系统实现了工作人员的登录,身份认证;系统对该职工信息的读取、输入、显示、查找、增加、删除、修改、保存等。系统根据输入的信息。
在课程设计的起初阶段,我对整个系统的设计充满困惑,也有很多疑虑和不安。不会的技术太多,要学习的东西太多。但经过我的努力和指导老师以及小组同学的帮助,终于完成了整个系统的开发工作。这次课程设计我的收获很多,我学会了自己解决问题,学会了坚持。但由于个人经验和技术问题,系统中也存在着很多的不足,比如很多功能没有实现。但相信自己在以后的工作过程中,一定能考虑多方面的需求,尽力完成一个产品所力求达到的高度。
参考文献
[1] 张海藩 软件工程导论 清华大学出版社
[2] 李爱华 面向对象程序设计(c++语言) 清华大学出版社
附录
程序源代码:
#include <iomanip>
#include <iostream>
#include <fstream>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define NULL 0
int const N=20;
#define LEN sizeof(struct staff)
using namespace std;
void Menu();
void Pass();
int n=0; //定义一个全局变量统计职工人数
//——--------->定义一个职工信息的结构体
struct staff
{
char name[N]; //用来存放姓名
char sex[N]; //用来存放性别
long id; //用来存放编号
float paid[3]; //用来存放工资
int total; //用来存放总工资
struct staff *next;
};
//-------------->职工类
class Information
{
public:
Information() ; //构造函数.
~Information() ; //析构函数.
staff *creat(); //建立链表
void output(staff *head); //显示职工信息
int count(staff *head); //定义函数count()统计职工总数
staff *insert(staff*head); //指针函数*insert()用来添加职工信息.
staff *cancel(staff *head,long id); //指针函数*cancel()用来删除职工信息.
staff *find(staff *head,long id); //指针函数*find()用来查找职工信息.
staff *modify(staff *head,long id); //指针函数*modife()用来修改职工的信息.
void save(staff *head); //保存文件信息
staff *Read(); //读取文件信息
private:
staff *p1,*p2,*p3,*head,st;
};
Information::Information()
{cout<<" ******************************************************************************\n";
cout<<" ------------------------<<欢迎您使用职工工资管理系统>>------------------------\n";
cout<<" ******************************************************************************\n\n";
}
//------------------>作者的信息和提示
void zuozhe()
{cout<<"按<Enter>键进入登陆界面!!";
}
Information::~Information()
{ cout<<" ******************************************************************************\n";
cout<<" ------------------------<<谢谢您使用职工工资管理系统>>------------------------\n";
cout<<" ******************************************************************************\n";
}
//------------>建立链表信息
staff *Information::creat(void)
{//定义一个指向struct student的结构体指针函数*creat()用来录入职工信息.
char ch[N];n=0; //用来存放职工姓名
p1=p2=(staff *)malloc(LEN);//调用malloc()函数用来开辟一个新的存储单元
cout<<" -------------<<请建立职工信息表,在姓名处键以 # 结束输入!>>--------------"<<endl;
cout<<" 姓名:";
cin>>ch;
head=NULL; //给指针head赋初值
while (strcmp(ch,"#")!=0)
{ //调用字符比较函数strcmp()用来判断是否继续输入
p1=(staff *)malloc(LEN); //调用malloc()函数用来开辟一个新的存储单元
strcpy(p1->name,ch); //将循环结构前面输入的姓名复制到结构体名为p1的数组name中
cout<<" 性别:";
cin>>p1->sex;
cout<<" 编号:";
cin>>p1->id;
cout<<" 基本工资:";
cin>>p1->paid[0];
cout<<" 加班工资:";
cin>>p1->paid[1];
cout<<" 其它奖金:";
cin>>p1->paid[2];
p1->total=p1->paid[0]+p1->paid[1]+p1->paid[2]; //计算总额
if(n==0)head=p1; //如果是输入第一组职工信息就将指针p1赋给指针head
else p2->next=p1; //否则将p1赋给p2所指结构体的next指针
p2=p1; //将指针p1赋给指针p2
n++; //将职工人数n的值加1
cout<<"\n 姓名:";
cin>>ch; //将输入的姓名存放到字符数组ch中
}
p2->next=NULL; //将p2所指结构体的next指针重新赋空值
return (head);//将输入的第一组职工信息返回
}
//--------------->定义output()函数将职工的信息从头指针所指内容开始输出
void Information::output(staff *head)
{
system("cls");
if(head==NULL) cout<<" 这是一个空表,请先输入职工信息!\n";
else{
cout<<"-------------------------------------------------------------------------------\n";
cout<<" *职工工资信息表*\n";
cout<<"-------------------------------------------------------------------------------\n";
cout<<"|编 号| |姓 名| |性别| |基本工资| |加班工资| |其它奖金| |总额|\n";
cout<<"-------------------------------------------------------------------------------\n";
p1=head; //将头指针赋给p1
do
{
cout<<setw(6)<<p1->id
<<setw(10)<<p1->name
<<setw(10)<<p1->sex
<<setw(10)<<p1->paid[0]
<<setw(10)<<p1->paid[1]
<<setw(12)<<p1->paid[2]
<<setw(12)<<p1->total<<endl;
cout<<"-------------------------------------------------------------------------------\n";
p1=p1->next; //将下一组职工信息的next指针赋给p1
}while(p1!=NULL); //若指针p非空则继续,目的是把所有的职工信息都传给指针p然后输出.
}
}
//------------>统计职工人数的函数
int Information::count(struct staff *head) //定义函数count()统计职工总数
{
if(head==NULL)return(0); //若指针head为空返回值为0
else return(1+count(head->next)); //函数的递归调用
}
//----------->添加职工的信息的函数
staff *Information::insert( staff *head)
//插入新结点定义一个指向struct student的结构体指针函数*insert()用来添加职工信息.
{
system("cls");
cout<<"\t----------------<<请输入新增职工信息>>----------------\n"<<endl;
p1=(staff *)malloc(LEN); //使p1指向插入的新结点
cout<<" 编号:";
cin>>p1->id;
cout<<" 姓名:";
cin>>p1->name; //将输入的姓名存放到结构体名为p1的数组name中
cout<<" 性别:";
cin>>p1->sex;
cout<<" 基本工资:";
cin>>p1->paid[0];
cout<<" 加班工资:";
cin>>p1->paid[1];
cout<<" 其它奖金:";
cin>>p1->paid[2];
p1->total=p1->paid[0]+p1->paid[1]+p1->paid[2];//计算总分
p2=head; //将头指针赋给p2
if(head==NULL) //若没调用次函数以前的头指针head为空
{
head=p1;p1->next=NULL;
} //则将p1赋给头指针head并将p1所指结构体成员指针next赋空值
else
{
while((p1->id>p2->id)&&(p2->next!=NULL))
{
p3=p2; //p3指向原p2指向的结点
p2=p2->next;
} //p2后移一个结点
if(p1->id<=p2->id)
{
if(head==p2)
{
p1->next=head;
head=p1;
} //插入到第一个结点之前
else
{
p3->next=p1;
p1->next=p2;
} //插入到p3所指结点之后
}
else
{
p2->next=p1;
p1->next=NULL;
} //插入到尾结点之后
}
n++; //将职工人数加1
cout<<"\t----------------<<你输入的职工信息已经成功插入>>----------------"<<endl;
return (head);
}
//------------>删除职工信息
staff *Information::cancel(staff *head,long id) //定义一个指向struct student的结构体指针函数*delete()用来删除考生信息.
{
system("cls");
if(head==NULL) //若调用次函数以前的头指针head为空
{
return(head);
}
else
{
p1=head; //否则将头指针赋给p1
while(id!=p1->id&&p1->next!=NULL) //寻找要删除的结点当p1所指的职工编号不是输入的职工编号而且p1所指的next指针不为空
{
p2=p1;
p1=p1->next;
} //p2指向原p1指向的结点p1后移一个结点
if(id==p1->id) //如果输入的职工编号是p1所指的职工编号//结点找到后删除
{
if(p1==head) head=p1->next; //如果head指针和p1指针相等则将下一个结点赋给指针head
else
p2->next=p1->next; //否则将p1所指结点赋给p2所指结点将要删除的职工信息跳过去
cout<<" 删除编号为"<<id<<"的职工\n";
n--; //将职工人数
展开阅读全文