C语言课程设计 学生信息管理系统.doc

上传人:rrsccc 文档编号:8937403 上传时间:2021-01-26 格式:DOC 页数:285 大小:1.48MB
返回 下载 相关 举报
C语言课程设计 学生信息管理系统.doc_第1页
第1页 / 共285页
C语言课程设计 学生信息管理系统.doc_第2页
第2页 / 共285页
C语言课程设计 学生信息管理系统.doc_第3页
第3页 / 共285页
C语言课程设计 学生信息管理系统.doc_第4页
第4页 / 共285页
C语言课程设计 学生信息管理系统.doc_第5页
第5页 / 共285页
点击查看更多>>
资源描述

《C语言课程设计 学生信息管理系统.doc》由会员分享,可在线阅读,更多相关《C语言课程设计 学生信息管理系统.doc(285页珍藏版)》请在三一文库上搜索。

1、华中科技大学 细节成就未来2010/11/20C语言课程设计报告 课程成绩信息管理系统 控制科学与工程系 自动化0902邹天明 U200914289戴潜 U200914276目录一.引言41.任务背景42.编写目的43.任务概述4 (1)概述4(2)目标4(3)软件性能概述4二.功能及操作介绍51.系统用户对象及各自功能52.系统界面5(1)登录界面(login system)5(2)注册界面6(3)学生主界面(student system)6三、程序流程71.程序扼要流程72.学生用户类型流程83.教师用户类型流程84.管理员类型流程9四、系统模块分析91.整体模块关系92.菜单模块10(1

2、)本模块功能10(2)模块内部设计10(3)本模块重要结构体设计12(4)本模块重要函数设计152.链表模块183.文件模块18(1)文件模块组成18(2)模块内部机制19五核心算法分析221.事件的触发算法222.信息的保存及判定233.鼠标右键弹出快捷菜单25六程序制作过程难点分析251.内存问题252.登分问题25七.不足之处26八.编程分工26九程序设计心得261.戴潜262.邹天明26十参考资料26十一程序源代码27class.h27class.cpp28depart.h33depart.cpp34manger.h39manger.cpp40student.h42student.cp

3、p44teacher.h52teacher.cpp54page.h61page.cpp62conmicro.h67conmicro.cpp68initgra.h70initgra.cpp70message.h72message.cpp73position.h76mouse.h76mouse.cpp78menuID.h87conmenu.h90conmenu.cpp91menusys.h112menusys.cpp113stumenu.h135stumenu.cpp137teamenu.h175teamenu.cpp177mammenu.h217mammenu.cpp219window.h247

4、window.cpp251test.cpp287一.引言1.任务背景21世纪以来,人类经济高速发展,人们发生了日新月异的变化,特别是计算机的应用及普及到经济和社会生活的各个领域。使原本的旧的管理方法越来越不适应现在社会的发展。许多人还停留在以前的手工操作。这大大地阻碍了人类经济的发展。为了适应现代社会人们高度强烈的时间观念,学校信息管理系统软件为学校办公室带来了极大的方便。在我国,学生信息管理系统并非一个新的课题,虽然计算机技术在日新月异的发展,但是有的很多学校,学校的信息管理都依然由手工操作来完成,这种方法效率极低,而且容易出错。随着社会的发展,信息化是社会进程的必然趋势,学校的信息管理只有

5、自动化,高效化才能发挥其价值。有些学校虽使用了计算机管理学生信息,但是系统不完善到处是漏洞,信息往往不能同步更新,有时甚至出错,这样极不完善的系统对管理来说是没有任何保障的。因此,提出一个新型,高效的学生成绩管理系统是非常必要的。2.编写目的此次C语言课程设计是具有控制系特色的一次课程设计,具有重要的意义:通过上个学期对C语言的学习,对C语言编程有了初步的了解,获得了一定的基础但是非常缺乏实际的编程经验,无法从质上对自己的编程技巧有一个很大的提高,这次的课程设计给我们提供了一个非常好的锻炼机会。通过二个人的分工合作,在实际中运用和训练程序设计的模块化和工程化思想和技术,努力掌握C语言精髓;同时

6、提高自己的交流与团队合作的能力。为以后的更专业更复杂的课程设计和实践活动打好基础。3.任务概述(1)概述本软件是将现代化的计算机技术和传统的教学、教务工作相结合,按照学院的工作流程设计完成的.完全实现了工作过程的计算机化,提高了工作效率和工作质量,为管理员更好地决策有一定帮助.(2)目标 本软件旨在帮助教务人员更好地对学生进行管理, 教务人员首先编排班级,对学生进行基本的信息录入,再由任课老师对成绩进行录入。教务处、任课老师跟据实际情况对录入的成绩进行维护,各位同学对以上录入的信息可以跟据自己的需要进行适当的查询。通过软件的开发过程,了解掌握软件开发的基本流程,培养团队合作的能力。(3)软件性

7、能概述1)灵活性该系统给予tc2.0和bc31开发,适用于dos3.0以上的所有dos版本和windows操作系;本软件设计中加入了鼠标和键盘操作,因此操作过程必须依赖鼠标和键盘才能实现所有功能;本软件对于显卡无特殊要求。2)输入输出由于本软件由用户输入各种数据较多,因此采用全英文模式输入和输出。3)错误检测整个系统对用户的各种可能的输入做了各种检测和限制,能够及时以警示的方式提醒其错误操作,大大提高了系统运行的稳定性。二.功能及操作介绍1.系统用户对象及各自功能 本系统面向三种用户,分别有不同的权限,具体如下: 普通学生:可以通过注册本系统,实现查询自己信息,修改自己信息,查询课表,查询分数

8、,选课、查询自己教师信息的功能。普通教师:可以通过注册本系统,实现查询自己信息,修改自己信息,查询自己课程安排,查询自己学生信息,登记分数功能。系统管理员:最主要功能是发布课表,和院系,包括正常课表和选修课表。2.系统界面(1)登录界面(login system)说明:在当前界面,用户可以选择登录方式(即学生还是老师)进入自己的主界面,管理员无需选择自己的登录方式而按默认的用户名ADMIN即可登录(其它类型用户无法注册该用户名),用户也可以通过register按钮进入注册界面。同时,点击quit键即可退出当前程序。若用户输入错误则会弹出警告框,点击ok重新输入。(2)注册界面说明:在当前界面,

9、用户可以注册自己的信息,若输入信息不完整则会弹出警告框,此时点击ok键即可重新输入信息。若用户名或者用户ID已经注册,也会弹出警告框,此时应修改自己的用户名方能成功注册。点击back键可以返回至登录界面,点击quit键可以退出当前程序。(3)学生主界面(student system)说明:在当前界面,用户在主菜单栏有5个选项,依次是Information,Class,score,help,about选项。下面来详细介绍个选项的功能。1)Information该项菜单有3项子菜单,分别是my information,edit information,login again,EXIT。第一项可以查

10、看自己的所有当前信息,第三项可以重新进入登录界面,第二项可以编辑自己的信息,最后一项可退出系统。点击edit information后将出现如下界面:从左边起第1项为编辑个人基本信息(base information),第2项为编辑个人学校信息(school information),第3项为编辑个人登录密码(password),各项信息编辑完毕后务必点击save键保存。2)Class该项菜单有3项子菜单,分别是Class Table,my teacher,choose class。第一项可以查看自己的所有当前课程信息,第二项可以查看自己的老师,第三项可以选修课程。3)score该项有一项子菜

11、单,学生点击后可查看自己所有科目的分数。4)help点击该项会出现一个矩形框,帮助信息将会从矩形框底部缓慢向上浮现,此时鼠标将暂时停止响应,直到帮助信息输出完毕。5)about点击该项会出现一个矩形框,字符信息将会从矩形框底部缓慢向上浮现,此时鼠标将暂时停止响应,直到字符信息输出完毕。注:当前界面支持鼠标右键,点击后弹出快捷菜单,功能上面已提到。管理员界面及教师界面和学生界面类似,管理员拥有发布课表,新建院系的权限,且其发布的课程和院系会同步更新至文件中。教师拥有登分权限,他可以找到自己学生的所有课程,并选择自己所教授的课程登记分数。保存在学生相应学生文件中内。三、程序流程 1.程序扼要流程

12、程序扼要流程图2.学生用户类型流程 学生用户流程图3.教师用户类型流程 教师用户流程图4.管理员类型流程 . 管理员类型流程图四、系统模块分析 1.整体模块关系 整个程序由菜单、文件和链表模块组成模块关系图 2.菜单模块 (1)本模块功能对用户操作作出响应,返回用户输入信息,打印逻辑层结果至屏幕。如下图: 菜单作用示意图(2)模块内部设计 程序运行时,将建立一个界面对象链表,将所有当前界面上处于激活状态的窗口对象加入该连表。同时由一事件检测函数不断检测用户的鼠标和键盘事件,一旦发生,则将该事件的信息读入一MSG结构体并传入事件处理函数。事件处理函数将对当前链表逐一检测直到有节点能对该事件作出响

13、应,或者所有节点对此都无响应,则进入下一事件循环。窗口对象响应事件时除了自身响应外,还将判断是否击发与自身关联的窗口处理函数,若击发,则返回自己的窗口ID至一窗口处理函数分发函数(EventPro)中,该函数将根据获得的窗口ID调用对应的窗口函数以完成响应。 由此可见,事实上window process distribution function就是界面模块与逻辑层的接口,通过它实现与下层的交流。 界面模块内部关系图窗口链表运行示意图(3)本模块重要结构体设计1)window 结构体负责所有界面对象的绘制,包括下拉菜单,按钮和文本输入框。拥有共同的的窗口响应函数和独立的窗口处理函数,后者通过窗

14、口ID相互关联。#define TITLE_LENGTH 50#define TEXTDIALOG 0#define BUTTON 1#define DOWN_MENU_HEADER 2#define DOWN_MENU_BODY 3#define DOWN_TEXT_DIALOG 4#define WARNING_WINDOW 5#define RIGHT_BUTTON_MENU 6 #define CHOOSE_CIRCLE 7#define PASSWORD_DIALOG 8 #define NO_WINDOW_PRO_STOP_CHECK -1#define NO_WINDOW_PRO

15、_CONTINUE_CHECK -2#define NO_WINDOW_ACTION_CONTINUE_CHECK -3#define MENU_RESTORE_BACKGROUND -4#define DIALOG_MOVE_CURSOR -5#define MAX_DIALOG_SHOW_LENGTH 50#define MAX_INPUT_LENGTH 31#define BACKSPACE 8#define ENTER 13#define BK_COLOR BLUE#define BUTTON_COLOR 24#define BUTTON_COLOR_LIGHT 7#define BU

16、TTON_COLOR_DARK 8#define BUTTON_LENGTH 50#define BUTTON_HEIGHT 25#define DOWN_MENU_BODY_LENGTH 200#define DOWN_MENU_BODY_HEIGHT 25#define TEXT_DIALOG_LENGTH 250typedef struct tagWindowstPosition top;/菜单定点坐标/窗口拖动时,记录与鼠标当前位置的相对坐标stPosition mousePositionWhenLeftKit;/窗口长度int nLength;/窗口高度int nHeight; /记

17、录该窗口是否有父窗口int nHaveFather ; /若该窗口拥有父窗口,该项记录父窗口IDint nFatherID; /光标闪烁中,记录累计次数,以获得延时功能unsigned long int nLayTime;/*identify this windows ID in this system*/unsigned int nMenuID;/*identify the kind of the window object*/int nKind; /是否绘出窗口int nDraw; /窗口是否在鼠标的点击下开始移动int nStartMove; /窗口标题char acTitleTITLE

18、_LENGTH;/*when window object is a text dialog, keep the string inputed in this character array*/char acInputTextDialogMAX_INPUT_LENGTH;/*when window object is a text dialog,keep the string length inputed in this character array*/int nTextLength;/*identify the window is or not active*/int nActive; /按

19、纽是否被按下int nPress; /是否获得用户输入文本int nGetInputText; /下拉框是否处于下拉状态int nMenuDown; /该窗口是否需要加入当前事件检测int nCheckEvent; /保存需要保存背景的窗口的背景void far *pImage; /指向下一窗口节点指针struct tagWindow*pNextWindow; /指向上一窗口借点指针struct tagWindow*pLastWindow;/*draw the window object*/void (*pfDrawWindow)(struct tagWindow*); /函数指针, 内部事件

20、响应函数int(*pfEventSelfAction)(structtagWindow*,struct tagMessage*,struct tagMOUSE*); /函数指针,判断鼠标是否在当前窗口上int ( *pfIsMouseInside)(struct tagWindow*,struct tagMessage*); /函数指针,恢复当前窗口背景void (*pfPutImage)(struct tagWindow* ); stWindow;2)坐标结构体记录屏幕坐标 /*坐标结构体*/ typedef struct tagPositionint nX;int nY;stPositio

21、n;3)message 结构体事件检测函数检测到事件发生后就将事件填充入该结构体并向下传递。typedef struct tagMessage /当前鼠标的坐标stPosition MOUSE_position; /判断鼠标键击int nButton; /判断键盘键击int nKbhit; /若有键盘事件,该值保存输入的字符ascii码int nKeyInput;/*store the key value*/ /判断鼠标是否移动int nMouseMove; /是否重新检测当前事件int nBackToHeader ; / 指向当前学生用户 struct tagStudent * pstCur

22、rStudent ; /指向当前教师用户 struct tagTeacher* pstCurrTeacher ; /指向当前管理员 struct tagManger* pstCurrManger ; /指向某个系别 struct tagDepartment * pstDepartment ;stMessage;(4)本模块重要函数设计 #define NO_WINDOW_PRO_STOP_CHECK -1#define NO_WINDOW_PRO_CONTINUE_CHECK -2#define NO_WINDOW_ACTION_CONTINUE_CHECK -3#define MENU_RE

23、STORE_BACKGROUND -4#define DIALOG_MOVE_CURSOR -51)窗口事件内部响应函数隶属于窗口对象,对能够作出响应的事件作出窗口响应int eventSelfAction(struct tagWindow*pstCurrWindow,struct tagMessage*pstMsg,struct tagMOUSE*pstMOUSE) switch (pstCurrWindow-nKind) /判断窗口类型,转入相应的处理函数case TEXTDIALOG : /文本输入框和密码输入框case PASSWORD_DIALOG : textDialogEvent

24、SelfAction(pstCurrWindow,pstMsg,pstMOUSE);break;case BUTTON: /普通按钮if(TRU= buttonEventSelfAction(pstCurrWindow,pstMsg,pstMOUSE)return pstCurrWindow-nMenuID;break; /下拉框头部case DOWN_MENU_HEADER:if(TRUE=DownMenuHeaderSelfAction(pstCurrWindow,pstMsg,pstMOUSE)return pstCurrWindow-nMenuID;break; /下拉框体case D

25、OWN_MENU_BODY:if(TRUE=downMenuBodySelfAction(pstCurrWindow,pstMsg,pstMOUSE)return pstCurrWindow-nMenuID;break; /下拉文本框case DOWN_TEXT_DIALOG:if(TRUE=downTextDialogSelfAction(pstCurrWindow,pstMsg,pstMOUSE)return pstCurrWindow-nMenuID;break; /警告框case WARNING_WINDOW:if(TRUE=warningWindowSelfAction(pstCur

26、rWindow,pstMsg,pstMOUSE)return pstCurrWindow-nMenuID;break; /右键快捷菜单case RIGHT_BUTTON_MENU:if(TRUE=rightButtonMenuSelfAction(pstCurrWindow,pstMsg,pstMOUSE)return pstCurrWindow-nMenuID;break; /双选框case CHOOSE_CIRCLE:if(TRUE=chooseCircleSelfAction(pstCurrWindow,pstMsg,pstMOUSE)return pstCurrWindow-nMenu

27、ID;break;return FALSE;2)外部事件处理函数获得MSG并逐一检测,检测到对应节点后将调用该节点的selfeventAction函数,根据返回结果判断是否需要调用windowpro 函数。int Eventpro(struct tagWindow*pstMenuHeader, struct tagMessage*pstMsg,struct tagMOUSE*pstMOUSE)stWindow* pstWindowNode=pstMenuHeader-pNextWindow;while (NULL != pstWindowNode ) /*if this node should

28、 be checked , call its self function first*/if(TRUE = pstWindowNode-nCheckEvent)if (pstWindowNode-pfEventSelfAction(pstWindowNode,pstMsg,pstMOUSE) 0) /*if the return value of the self action function is bigger than zero ,implying that this windows process function should be called*/windowStuPro( pst

29、WindowNode,pstMsg,pstMOUSE);windowManPro( pstWindowNode,pstMsg,pstMOUSE);windowTeaPro( pstWindowNode,pstMsg,pstMOUSE);/*if this value is true ,back the check pointer tolist header to recheck the event */if (TRUE = pstMsg-nBackToHeader)pstWindowNode=pstMenuHeader-pNextWindow;pstMsg-nBackToHeader = FA

30、LSE ;windowLoginPro( pstWindowNode,pstMsg,pstMOUSE); /*check next node*/if (NULL != pstWindowNode) pstWindowNode = pstWindowNode-pNextWindow ;return TRUE;2.链表模块 在最初阶段,我们程序的整个包括菜单、学生、教师等信息都是在程序开始运行时读入链表再对其进行各种操作的,虽然方便,但是这样很块就出现了问题:内存不够。而且这种方案也不符合现实情况,对于一个信息管理系统系统,其管理的是大量的信息,不可能依赖将各种文件读入内存的方法来进行管理,所以我

31、们转为直接对文件进行操作,虽然复杂性增加,但是更加符合实际情况,改革时,我们保留原来的借口不变,只是在下层改变信息获取和修改方法,从而做到了对上层的细节隐藏,这样也很方便程序的改进,是模块化的典型优势。最终整个链表模块只在菜单系统中应用,通过一双向链表来对各菜单节点进行操作,其原理在菜单模块中已有详细图解,此不赘述。3.文件模块 为了实现大规模的信息管理,整个系统几乎都是直接对文件进行查找,修改,删除等操作。(1)文件模块组成1) student.dat 教师信息存储文件 2) teacher.dat 课表存储文件 3) class.dat 系别存储文件 4)department.dat 系统

32、管理员信息存储文件 5) manger.dat(2)模块内部机制1)saveXXToFile 事实上该函数已经暗含了修改功能,当将某结构体写入文件时,其将先查找文件中是否已有结构体,若有则将文件指针定位到该处将该结构体重写一遍,否则将新结构体添加到文件末尾。保存文件原理图2)getXXFromYYFile读取文件原理图3)文件内部组成 文件内部组成图每个文件开始初记录该文件保存的项目数,文件指针通过读取该数据,可以很方便的将其自身定位到所需要之处。五核心算法分析1.事件的触发算法因为我们的程序是基于窗口事件检测而产生相应反馈的,因此若想添加某项功能,只需把与这项功能对应的窗结构体加入当前事件检

33、测链表,再加上对应的自反应函数和窗口处理函数即可,若该功能无需激发窗口处理函数,则无需添加。这样看来,各个在同一层次的功能之间实现方法则完全相同。例如登录系统中的输入框,我们先把它加入当前事件监测链表,用如下函数:struct tagWindow* getNewWindow(int nX,int nY,int nLength,int nHeight, int nKind,unsigned long int nMenuID,char* pacTitle) /*allocate memory to this window*/ struct tagWindow* pstCurrWindow;if(p

34、stCurrWindow=(struct tagWindow*)malloc(1*sizeof(struct tagWindow)=NULL)printf(NO ENOUGH MEMORY);exit(1);/*init the varible in the window*/pstCurrWindow-top.nX = nX;pstCurrWindow-top.nY= nY;pstCurrWindow-mousePositionWhenLeftKit.nX=0; pstCurrWindow-mousePositionWhenLeftKit.nY=0;pstCurrWindow-nActive

35、= FALSE;pstCurrWindow-nFatherID = 0;pstCurrWindow-nHaveFather = FALSE;pstCurrWindow-nHeight=nHeight;pstCurrWindow-nLength=nLength;pstCurrWindow-nMenuID=nMenuID;pstCurrWindow-nPress = FALSE ; pstCurrWindow-nKind=nKind;pstCurrWindow-nGetInputText = FALSE;pstCurrWindow-nTextLength = 0 ;pstCurrWindow-nL

36、ayTime = 0;pstCurrWindow-nMenuDown = FALSE;pstCurrWindow-nStartMove = FALSE;pstCurrWindow-nDraw = FALSE;pstCurrWindow-pImage = NULL;pstCurrWindow-nCheckEvent = TRUE;strcpy(pstCurrWindow-acTitle,pacTitle);pstCurrWindow-pfDrawWindow=drawWindow; pstCurrWindow-pfIsMouseInside=isMouseInside;pstCurrWindow

37、-pfEventSelfAction=eventSelfAction; pstCurrWindow-pfPutImage = putImage; return pstCurrWindow;函数在初始化窗口时pstCurrWindow-pfEventSelfAction=eventSelfAction;这样事件检测函数就会知道当前鼠标位置在窗体内时激发该窗体自反应函数。而具体调用何种函数则是根据窗体的nkind来判断的。若调用自反应函数后返回值为FALSE,则不激发窗口处理函数,若为TRUE则激发。具体激发那个函数则有siwtch语句来判定(若该窗体有父窗口则调用其父窗口处理函数)。下图表示注册

38、界面中Department下拉文本框的处理过程。下拉文本框的处理过程2.信息的保存及判定当对话框为文本框或下拉框时,用户输入的信息只保存在属于自己的窗口结构体中,而要想集中保存或判定则要借助另外一个窗体,我们把他们叫做OKBOTTON,其窗口处理函数将通过如下函数找到要保存的信息所属于的窗口节点,并对节点中的信息进行判定或保存。stWindow*findNodeByID(stWindow*pstCurrWindow,unsigned long int unMeneID )stWindow*pstMenuHeader = getMenuHeader(pstCurrWindow);while (N

39、ULL != pstMenuHeader )if ( unMeneID = pstMenuHeader-nMenuID)return pstMenuHeader;pstMenuHeader = pstMenuHeader-pNextWindow;return NULL;下图表示在登陆界面中信息的判定过程:登陆界面中信息的判定过程3.鼠标右键弹出快捷菜单关于鼠标右键的问题我们提出了几种方案,最终敲定了以下方案,其实是对第一点深度理解后的运用。我们把鼠标右键也对应一个窗体,不过这个窗体是虚拟的,并不把它画出来,而且其大小跟电脑全屏幕接近,且把它的等级定位主菜单等级,自反应函数只是返回一个TRUE,

40、从而可以直接激发窗口处理函数。 以下为学生界面中该窗体节点的定义,自反应函数以及窗口处理函数:stWindow*pstRightMenu116=getNewWindow(483,22,116,25,RIGHT_BUTTON_MENU,STUDENT_RIGHTBUTTON_MENU,About); /内部反应函数,由于该窗口本身是虚拟的,故仅返回TRE 以激发对应外部/事件处理函数int rightButtonMenuSelfAction(struct tagWindow*pstCurrWindow, struct tagMessage*pstMsg,struct tagMOUSE*pstMO

41、USE) return TRUE ; /外部事件处理函数int winProFunc116(struct tagWindow*pstCurrWindow,struct tagMessage*pstMSG,struct tagMOUSE*pstMOUSE)六程序制作过程难点分析 1.内存问题内存不够的问题可以说是贯穿的整个课程设计,其中最大的一次滑铁卢是我们原想在用户登录之后,把与他相同类型的用户信息全部存入一个链表,在用户退出程序时在释放该链表。当我们用这种思想编写,只有管理员能成功登录,老师和学生登陆后程序会立刻跳出。最后我们意识到是内存不够的问题,便马上调整了思路,改成从与当前用户同类型的

42、文件里直接读取和写入信息,这就涉及到了对文件的精确操作,我们最终克服了困难。还有一个有趣的事情是对malloc函数的理解问题,就是我们发现malloc能成功分配的内存与其理论值有很大的出入,最后我们了解到那些库函数只不过是一些你我一样的程序员编写的,所以说不可能你要多大的内存他就会提供,例外由于我们用的编译器的局限性,进一步限制了我们可分配的内存。 2.登分问题表面看只是登分的问题,隐藏在其背后的却是信息查找的紊乱问题。之前,如果我们想通过老师来查找自己的学生,就必须先找到当前学生文件中所有学生的Department,然后一个个与自己的Department比较,进而找到自己的学生,这就必须绕两个圈子。当老师想登分是,就必训绕三个圈子,这样既麻烦有容易出错。这就造成了我们的程序好久都没有进展,最后我们想到可以把教师和学生的课程保存至其结构体中,这样,一个学生的结构体就比原来增加了7倍,但我们做多至保留一个学生或老师的结构体在Message结构体中,内存事实足够的。所以现在查找信息就变得清洗和简单了。七.不足之处八.编程分工 邹天明 整体设计 、代码编写 戴潜 页面设计、 功能点实现 、代码编写九程序设计心得1.戴潜 通过这

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1