记录一下之前的软件综合实践的课设,可以说是真的很赶时间,原计划五天的软件综合实践时间,除去此前云计算还占用了两天,我们宿舍从零开始做到答辩总共用时三天,整个过程大家几乎都没有睡几个小时的觉(干活的时候倒没觉得很累),答辩前一晚小组所有人都通宵,宿舍组队的好处就体现在这里了,大家都一起熬夜,大家都在干活,真的很赞。
只是真的很可惜这一次的软件实践的时间给的实在是太少了,满打满算只有三天,原本希望用C/S架构保证数据的安全性,同时学习和验证学习的知识,和舍友们好好做一次项目,只可惜在时间限制这条红线下只能被迫调整思路,按照软件开发的步骤一步步做只能选择一个相对简单的架构,更何况从软件需求开发、数据库相关的定义就已经花去了很多时间,还要编写软件开发文档,可以说这几天是这个学期过的最疯狂的日子了,虽然超累但是在答辩的时候比较有底气(至少我们做完了),真的令人印象深刻。以下是我们的软件设计课设文档。
项目内容:金融管理系统
专 业 计算机科学与技术 | |
---|---|
组长 王远卓 | |
小组成员 韩瑞乾 周健杰 金桥 | |
指导教师 余宇峰 | |
评 阅 人 余宇峰 |
2022年6月
中国 南京
目录
一、系统需求分析
- 引言
1.1编写目的
1.2 文档约定
1.3 预期的读者和阅读建议
- 项目概述
2.1项目背景
2.2项目目标
2.3运行环境
2.4设计和实现的限制
2.5假定和依赖
- 系统需求分析
3.1项目名称
3.2需求概述
3.3功能需求
3.4角色定义
3.5可行性分析
- 系统分析
4.1目标系统逻辑模型
4.2数据字典
- 系统接口分析
5.1用户功能模块与管理员功能模块之间的交互
5.2不同子模块之间的交互
二、总体结构确认
- 系统组成确认
- 软件功能确认
三、系统设计文档
- 软件功能设计
- 数据库设计
2.1概念结构设计
2.2 逻辑结构设计
2.3 物理结构设计
2.4 详细数据字典
2.5 数据库安全
- 用户界面设计
3.1交互逻辑总览
3.2详细界面设计
四、系统实现文档
- 开发工具平台选择
- 编码规范
2.1命名规范
2.2编程规范
2.3协同规范
五、测试文档
- 概述
1.1背景
1.2产品描述
1.3目的
- 测试概要(测试方法、范围、测试环境、工具、周期)
2.1测试方法:
2.2单元测试:
2.3白盒测试:
2.4性能测试
- 动态测试结果与缺陷分析
3.1动态测试结果
3.2缺陷分析
- 测试结论与建议(项目概况、测试时间 测试情况、结论性能汇总)
六、总结
1.个人总结
2 组员自评分
七、附录
1 数据库建表代码
2 以账户操作为例核心代码
2.1 管理员冻结账户功能
2.2 管理员查询账户
2.3 管理员更新用户信用分
2.4 用户修改账户信息
2.5 用户查询账户信息
2.6 数据库操作账户类
2.7 账户基本类
2.8 用户修改账户信息布局文件
一、系统需求分析
引言
1.1编写目的
本文的编写目的是为银行的金融管理系统项目开发提供,主要有以下几条:
-
软件总体要求,本文档作为用户与软件开发人员之间相互了解的基础;
-
关于功能,性能,接口和可靠性的要求,作为软件人员进行设计和编码的基础;
-
作为用户客户确认测试的依据;
1.2 文档约定
-
文档描述的内容是金融管理系统的需求分析说明书;
-
文档采用基于UML建模语言的面向对象和流程建模方式对功能需求进行描述
-
性能需求以文字和列表的方式具体给出
1.3 预期的读者和阅读建议
编号 | 预期读者 | 阅读建议 |
---|---|---|
1 | 用户 | 确认文档中给出的功能需求描述 |
2 | 开发者 | 熟悉并掌握项目的共同功能需求 |
2 项目概述
2.1项目背景
随着信息科技及互联网产业的迅速发展,现代化社会中各行各业产生激烈的竞争,如何提高工作效率,降低成本,提高生产及交易过程的现代化和自动化程度,充分满足生产者和消费者的需求,提供更优质的服务成为各行各业追逐的目标,对于传统银行来说,整个交易流程自动化程度很低,难以满足日益增长的物质文化需求,因此开发一套方便快捷,高效实用且安全稳定的银行金融业务管理系统成为了传统书店的当务之急,银行需要开发一套满足相关需求的金融业务管理系统。
2.2项目目标
1.加强银行金融业务管理,提高整体工作效率,通过金融业务管理系统实现对金融业务的管理和交易过程的信息化。
2.为银行管理者,用户提供在线信息交流和交易的平台。
2.3运行环境
系统运行环境要求如下:
编号 | 名称 | 运行环境 |
---|---|---|
1 | 数据库 | MySQL |
2 | 客户端 | Android APP |
2.4设计和实现的限制
限制因素 | 限制说明 | 备注 |
---|---|---|
必须采用的技术/工具/编程语言/数据库等 | 无特殊限制 | |
不能使用的技术/工具/编程语言/数据库等 | 无特殊限制 | |
硬件限制 | 无特殊限制 | |
性能限制 | 无特殊限制 |
2.5假定和依赖
定义各个子系统运行和开发中可能的假定条件因素如下:
编号 | 名称 | 备注 |
---|---|---|
1 | 客户端操作系统为Android | |
2 | 对现有业务/功能描述与实际情况基本符合,对需求的变更不导致系统框架大调整 |
定义各个子系统运行和开发中可能的依赖因素如下:
编号 | 依赖 | 依赖说明 | 备注 |
---|---|---|---|
1 | 数据库 | 业务数据存储在数据库中 | |
2 | 运行平台 | 系统运行依赖于Android平台 |
3 系统需求分析
3.1项目名称
金融管理系统
3.2需求概述
通过对市面上已有银行金融管理系统进行相关调查,关注用户在金融管理系统方面的使用需求,我们将用户对金融管理系统的需求总结为以下几点:
用户:
-
账号管理:用户可以管理自己的账号信息
-
账号的创建
-
密码、绑定手机号、绑定邮箱等信息的改动
-
使用账号登陆系统
-
查询总资产,查询总体资金使用记录
-
账号的注销
-
-
银行卡管理:用户可以管理自己的银行卡
-
办理银行卡,需提供身份证号、手机号等个人信息
-
银行卡的挂失、补办等操作
-
对已持有的银行卡信息进行查询,包括银行卡号、办理日期、使用状态等
-
查询余额
-
存款
-
取款
-
转账
-
交易信息查询、包括交易时间、交易双方银行卡号等信息,或者购买信息
-
-
信用卡管理:
-
查询信用卡办理资格,根据用户个人信誉积分等信息进行判断
-
存款
-
取款
-
转账
-
查询交易信息、交易时间、交易双方银行卡号等信息,或者购买信息
-
查询余额
-
-
理财产品管理:用户可以查询、购买和出售理财产品
-
查询银行可提供的理财产品,支持按名字、编号、类别等方式查询
-
能够购买、出售理财产品
-
查询已有理财产品,可以按照类别分类
-
查询已有理财产品的收益情况
-
-
保险产品管理:
-
查询银行可提供的保险产品信息,支持按名字、编号、类别等方式进行查询
-
能够购买保险产品,需要根据保险类别提供相关信息
-
提供保险理赔功能的接口
-
管理员:
-
理财产品管理:管理员可以管理理财产品相关信息
-
理财产品管理操作包括理财产品的增删查改
-
理财产品信息的维护,包括价格变动的维护等
-
-
保险产品管理:管理员可以管理保险产品管理
-
保险产品管理操作包括保险产品信息的增删查改
-
-
账户管理:
-
账户类型包括用户、管理员
-
用户可以注册账户,需要通过管理员的审核,管理员也可以在后台手动添加用户
-
管理员也可以在后台封禁账户
-
密码、绑定手机号、绑定邮箱等信息的查询
-
用户总资产,总体资金使用记录的查询
-
-
银行卡信息管理
-
管理员可以根据用户ID查询该用户的所有银行卡信息
-
管理员可以在后台停用用户的银行卡
-
管理员需要根据用户的操作,如理财产品的购买、出售,保险的购买、理赔来对用户相关信息进行增删查改
-
管理员需审核用户办理银行卡的请求
-
-
信用卡信息管理
-
管理员可以根据用户ID查询该用户的所有信用卡信息
-
管理员可以在后台停用用户的信用卡
-
管理员需要根据用户的操作,如理财产品的购买、出售,保险的购买、理赔来对用户相关信息进行增删查改
-
管理员需根据用户信誉情况审核用户办理信用卡的请求
-
3.3功能需求
业务功能需求如下:
用户业务功能需求模块划分:
-
账号管理
-
银行卡管理
-
信用卡管理
-
存款管理
-
理财产品管理
-
保险产品管理
-
管理员业务功能需求模块划分:
-
理财产品管理
-
保险产品管理
-
用户管理
-
用户信息管理
3.4角色定义
角色名称:管理员
角色职责:
-
及时更新数据库中相关金融产品信息
-
管理用户和各种金融交易信息
角色名称:用户
角色职责:
-
寻找自己想购买的理财产品
-
管理自己的金融资产
-
办理或注销储蓄卡、信用卡
3.5可行性分析
-
技术可行性分析:
要实现金融管理系统,首先需要一个数据库来进行数据存储,然后需要能够连接数据库的界面平台来进行数据库连接,能够完成金融管理系统基本的操作功能,最后决定使用哪种语句来进行数据编写。最后我们采用Navicat premium进行数据库搭建,Navicat premium可以自由组合其他 Navicat 项目的活动和辅助,以用于高级数据库管理,如触发器、视图、存储过程、函数和事件。并且允许我们轻松地跨不同的数据库方案或 SQL 格式的文本文件传输数据;使用Android Studio完成界面平台设计,Android studio有稳定速度快、是一个功能强大的UI编辑器、完善的插件管理、多种代码管理工具、智能、可以在手机端上运行界面等优势,Android studio可以很好完成界面设计的要求;SQL语句具有综合统一、高度非过程化、面向集合的操作方法、语言简洁等等特点,所以决定使用SQL语句来进行语句编写,通过SQL语句、Navicat premium数据库、Android studio三项确认实现金融管理系统技术的可行。
-
经济可行性:
Navicat premium数据库、Android studio都是免费使用的编辑工具、我们这个系统功能又较为简单,所以我们只需要人力和些许的资金,投入小,回报大,所以在经济上这个项目是可行的。
-
社会可行性:
设计计划基本功能为系统能够进行基本的信息增删查改,我们设置的系统环境是使用Navicat premium来进行数据库的搭建、使用Android studio进行界面搭建,Android studio连接Navicat premium获取数据和插入数据,所以可以在Navicat premium 和Android Studio的环境下搭建出所需金融管理系统,在两者的系统能够实现相关系统的基本功能,在该环境下可以按照设计方案顺利运转。
4 系统分析
目标系统拥有用户登录界面和用户注册界面,用户通过用户注册界面注册账号,然后通过用户登录界面进行登录,登录后用户可以使用银行卡管理功能和保险管理功能、理财产品管理功能,在每个功能中都具有查询、办理等相关功能;目标系统拥有管理员功能界面,管理员能够对用户信息及相关的金融产品进行查询和管理
4.1目标系统逻辑模型
-
1层DFD图
考虑外部实体:数据的源点为用户和管理员,数据的终点为前台展示界面
考虑处理:用户和管理员操作金融管理系统、金融管理系统反馈信息给前台展示界面
考虑数据流:用户和管理员产生数据流给金融管理系统、金融管理系统产生数据流给前台展示界面
-
2层与3层DFD图
对数据流关联图进行细分,将金融管理系统中的每个功能进行单独细分,分别进行“考虑外部实体”“考虑处理”“考虑数据流和数据存储”。最后得到的各结构数据流图如下
在该数据流程图中用户使用账户信息系统功能和管理员进行相应管理的数据流图,在图中用户的请求账号信息修改、账号注销、查询数据都会先通过管理员进行审查然后完成相应增删查改后将结果反馈给用户
在该数据流程图中用户使用保险产品信息系统功能和管理员进行相应管理的数据流图,在图中用户的请求查询、购买、申请理赔等数据都会先通过管理员进行审查然后管理员将最终结果反馈给用户。
在该数据流程图中用户使用理财产品信息系统功能和管理员进行相应管理的数据流图,在图中用户的请求出售理财产品、购买理财产品等操作的数据流都会先通过管理员进行审查然后将用户进行的操作结果反馈给用户。
在该数据流程图中用户使用银行卡信息系统功能和管理员进行相应管理的数据流图,在图中用户的请求办理银行卡、查询银行卡信息、进行银行卡挂失、存款、取款、转账等功能数据都会先通过管理员进行审核然后将相应功能结果反馈给用户。
4.2数据字典
名字 | 客户表 |
---|---|
描述 | 存储用户的相关信息 |
定义 | 客户表=身份证号+姓名+电话号码+电子邮箱+系统密码+信用分+状态 |
位置 | 输出到显示平台 |
名字 | 资产表 |
---|---|
描述 | 存储用户个人信息 |
定义 | 资产表=身份证号+姓名 |
位置 | 输出到显示平台 |
名字 | 银行卡表 |
---|---|
描述 | 存储用户银行卡信息 |
定义 | 银行卡表=银行卡号+身份证号+办理时间+预留手机号+种类+余额+银行卡密码+状态 |
位置 | 输出到显示平台 |
名字 | 交易记录表 |
---|---|
描述 | 存储用户进行存款、取款、转账相关信息 |
定义 | 交易记录表=交易时间+对方银行卡号+我方银行卡号+交易编号+交易金额 |
位置 | 输出到显示平台 |
名字 | 理财产品表 |
---|---|
描述 | 存储理财产品信息 |
定义 | 理财产品表=产品编号+产品名称+产品描述+单价+理财年限 |
位置 | 输出到显示平台 |
名字 | 理财产品价格变动记录表 |
---|---|
描述 | 记录理财产品在一定时间内的价格变动情况 |
定义 | 理财产品价格变动记录表=理财产品编号+变动时间+历史价格 |
位置 | 输出到显示平台 |
名字 | 持有理财产品表 |
---|---|
描述 | 记录用户的理财产品持有情况 |
定义 | 持有理财产品表=产品编号+身份证号+购买时间+购买编号+购买数量+购买价格+收益+状态 |
位置 | 输出到显示平台 |
名字 | 保险表 |
---|---|
描述 | 记录保险产品的相关信息 |
定义 | 保险表=保险编号+保险名称+适用人群+保险项目+保险金额+保险年限+保险所有时间 |
位置 | 输出到显示平台 |
名字 | 持有保险表 |
---|---|
描述 | 描述用户持有保险的情况 |
定义 | 持有保险表=保险编号+身份证号+购买时间+购买编号+购买数量+状态 |
位置 | 输出到显示平台 |
名字 | 检验表 |
---|---|
描述 | 通过ID号和姓名进行用户的检验 |
定义 | 检验表=ID号+姓名 |
位置 | 输出到显示平台 |
5 系统接口分析
5.1用户功能模块与管理员功能模块之间的交互
用户功能模块与管理员功能模块交互:管理员可以对金融系统中的用户信息进行查询、用户注册时需要管理员进行审核、管理员也可以在后台添加用户、管理员可以注销用户账号,也可以封禁账户、管理员需要根据用户的购买、出售等操作来对用户信息进行增删查改;用户可以通过查询相关产品的信息来查询管理员、用户每次进行操作后,都会向管理员传递操作信息
5.2不同子模块之间的交互
银行卡管理与账户管理进行办理银行卡等交互;存款管理与银行卡管理进行查询交易记录等交换;理财产品管理与账号管理进行查询、购买、出售等交互;保险产品管理与账户管理进行查询、购买等交互;管理员理财产品管理与理财产品管理进行维护、管理、查询等交互;管理员保险产品管理与保险产品管理进行增删查改等交互;管理员账号管理与账户管理进行审核注册、注销账户、封禁账户等交互;管理员用户信息管理与账户管理进行查询信息停用银行卡等交互。
二、总体结构确认
1 系统组成确认
系统首先分为两个部分,即管理员管理模块和用户操作模块,用户管理模块包括用户账号管理子模块、用户银行卡管理子模块、用户存款管理子模块、用户理财产品管理子模块,这些模块为用户操作提供相关使用功能;管理员管理模块包括理财产品管理子模块、保险产品管理子模块、账户管理子模块、用户信息管理子模块组成,提供管理员操作各类对象的功能,同时提供一部分外部接口。
系统总体架构为以数据为中心的黑板体系结构,如下图所示。
用户通过客户端登陆后进入用户操作模块,使用其中功能对数据中心产生影响,管理员可以对数据进行操作,直接影响数据中心的数据,进而对用户产生影响。
2 软件功能确认
功能模块分为主功能模块和子功能模块,每个主功能模块包含多个子功能模块,主功能模块有两个,分别是用户功能模块和管理员功能模块。
用户管理模块具有账号管理、银行卡管理、存款管理、理财产品管理、保险产品管理能力,所以主功能模块用户功能模块包含子功能模块:账号管理功能模块、银行卡管理功能模块、存款管理功能模块、理财产品管理功能模块、保险产品管理功能模块。
管理员管理模块具有管理理财产品信息、管理保险产品信息、账户管理、用户信息管理能力,所以主功能模块管理员功能模块包含子功能模块:管理理财产品信息功能模块、管理保险产品信息功能模块、账户管理功能模块、用户信息管理功能模块。
同时对于使用流程我们设计为登录、进入使用者操作界面、选择操作模块、选择操作、提交信息完成操作、退出或继续等。
三、系统设计文档
1 软件功能设计
系统的逻辑结构为功能垂直的二层架构,模块结构图如下图所示:
整个系统的模块功能之间互不相交、互不影响,同时保证模块之间的功能相对独立(对于不同的使用者而言操作也是进行区分的)。
对于金融管理系统来看,根据系统的使用者不同主要分为管理员和用户。为了保证用户和管理员的分离操作,他们各自有自己的账户管理模块、银行卡管理模块、理财产品管理模块、保险管理模块,但是其中具有不同功能的方法,其对应着用户和管理员的不同的权限。
用户操作模块、管理员操作模块的下层,是进行区分的账户、银行卡、理财产品、保险管理的子模块,在更底层,为基础的操作类,为各个子模块提供相关的操作,其中这些操作类面向数据中心,同时为多个管理模块提供操作的接口,是一种分层次的网状架构。
用户视角下系统工作流程主要如下图所示:
用户输入账号密码后点击登录按钮,系统检测无误后成功登录,用户进入用户管理界面,此时用户可以选择进入哪个子模块进行相关操作,有四个模块可供用户进行选择,包括账号管理、银行卡管理、理财产品管理和保险管理,其中每个模块的功能逻辑模块如下图所示。
图1.6 用户银行卡管理子模块功能图
在操作时,例如用户选择银行卡管理子模块,在子模块界面选择转账、存款、办理新的银行卡、交易记录查询、查询信用卡办理资格等功能,系统将用户的选择数据发送给管理员,管理员对用户选择情况进行处理,系统将相应结果通过显示平台反馈给用户
用户选择保险产品功能,在跳转界面选择查询保险产品信息、购买保险产品、申请保险理赔等功能,系统将用户的选择数据发送给管理员,管理员对用户选择情况进行处理,最后将处理结果返回给系统,系统将相应结果通过显示平台反馈给用户;
用户在登录界面选择注册选项,进入注册界面,输入相关信息,系统将用户输入的信息传输给管理员进行审核,管理员也可以在后台进行手动添加用户,最后将注册完成信息发送给系统,系统将相关信息通过显示平台显示给用户。
管理员视角下系统操作流程图如下所示:
管理输入系统预留创建的账号密码后点击登录按钮,系统检测无误后成功登录,管理员进入管理员管理界面,此时管理员可以选择进入哪个子模块进行相关操作,有四个模块可供用户进行选择,包括账号管理、银行卡管理、理财产品管理和保险管理,其中每个模块的功能逻辑模块如下图所示。
在操作时,例如管理选择银行卡管理子模块,在子模块界面选择查询银行卡所有信息、冻结选定的银行卡、更新选定信用卡可用额度等功能,管理员对用户数据直接进行操作,可以按情况将功能分配到其他角色,根据不同情况进行处理,系统将相应结果通过数据变化的形式反馈给用户。
保险管理子模块,管理员在跳转界面选择对保险产品的增删查改等功能,通过对保险产品的管理,用户可以根据自身情况选择保险情况进行购买,最后将处理结果返回给系统,并记录在操作系统中,系统将相应结果通过显示平台反馈给用户查询。
理财产品管理子模块,管理员在跳转界面选择对理财产品的增删查改以及理财产品历史价格增加等功能,通过对理财产品的管理,影响到用户财产收益以及用户购买理财等情况,将处理结果返回给系统,并记录在操作系统中,系统将相应结果通过显示平台反馈给用户查询。
在用户账号管理模块中,管理员通过冻结用户、查询账户所有信息、更新信用分来对用户进行管理,影响到用户进行银行卡、信用卡的办理以及账户的使用。
2 数据库设计
2.1概念结构设计
根据系统功能模块设计与系统分析所示数据字典卡片进行确认实体(矩形)、属性(椭圆)、关系(菱形),再在属性中确定相应的主键和外键,最后绘制ER图,ER图展示如下
2.2 逻辑结构设计
根据ER图建立关系模式,具体描述如下:(其中划下划线为主键,斜体加黑为外键)
上述对象之间的关系如下:
-
一个客户可以办理多张银行卡,银行卡的类型分为储蓄卡、信用卡,一个客户可以办理多张信用卡和信用卡。
-
一个客户可以购买多个保险,同一类保险可以由多个客户购买,一个客户可以多次购买一类保险。每当客户购买一类保险时,产生一个持有保险记录。
-
一个客户可以购买多个理财产品,同一类理财产品可以由多个客户购买,一个客户可以多次购买一类理财产品。每当客户购买一类理财产品时,产生一个持有理财产品记录。
-
两张银行卡之间可以产生交易,每进行一次交易,产生一次交易记录。两张卡之间可以产生多次交易,形成多个交易记录。
通过对关系模式进行分析,所有关系模式都属于第三范式,不存在传递依赖和部分依赖。
2.3 物理结构设计
通过逻辑结构设计中的关系模式,进行转化为物理结构,转化结果如下:
-
客户(client)
(身份证号(c_id),姓名(c_name),电话号(c_tele),电子邮箱(c_e_mail),系统密码(c_password),信用分(c_credit_score),状态(c_status))
-
银行卡(bank_card)
(银行卡号(card_id),身份证号(c_id),办理时间(card_register_time),预留手机号(card_tele),种类(card_type),银行卡密码(card_password),余额 (card_balance),状态(card_status))
-
交易记录(trade_record)
(我方银行卡号(t_me),对面银行卡号(t_someone),交易时间(t_time),交易编号(t_id),交易金额(t_money),交易后余额(t_balance))
-
理财产品(financial)
(产品编号(fi_id),产品名称(fi_name),产品描述(fi_discribe),单价(fi_unit_price),理财年限(fi_year_limit))
-
持有理财(hold_financial)
(购买编号(hold_buy_id),产品编号(fi_id),身份证号(c_id),购买时间(hold_buy_time),购买数量(hold_buy_amount),购买价格(hold_buy_price),状态(hold_state),收益(hold_income))
-
理财产品历史价格(financial_history_price)
(理财产品编号(f_id),历史价格(fp_price),变动时间(fp_time))
-
保险(insure)
(保险编号(i_id),保险名称(i_name),适用人群(i_fit_crowds),保险项目(i_programs),保险金额(i_unit_price),保险年限(i_year_limit),保险所有时间(i_claims_times))
-
持有保险(hold_insure)
(购买编号(hold_buy_id),保险编号(i_id),身份证号(c_id),购买时间(hold_buy_time),购买数量(hold_buy_amount),状态(hold_state))
-
客户资产表(Assets)
(身份证号(c_id),资产编号(assets_id))
其中,检验表为了进行输入信息的检测建立;理财产品价格变动表是后台便于管理设计;客户资产表为了方便查询而建立,用于统计客户账户下持有的资产,基金与理财的历史价格不在原先的关系模式中,为了模拟基金价格变化,便于查询基金价格,在关系模式中加入基金与理财产品的历史价格变化表。
2.4 详细数据字典
通过总结概念模型、逻辑模型、物理模型,划分主键,设置字段类型、约束条件。完成数据字典的建立
字段标识 | 字段类型 | 约束 | 说明 |
---|---|---|---|
c_id | CHAR(22) | PRIMARY KEY | 身份证号 |
c_name | VARCHAR(60) | NOT NULL | 姓名 |
c_tele | CHAR(11) | UNIQUE NOT NULL | 电话号码 |
c_e_mail | VARCHAR(30) | UNIQUE | 电子邮箱 |
c_password | VARCHAR(20) | NOT NULL | 系统密码 |
c_credit_score | INT(3) | NOT NULL | 信用分 |
c_status | BINARY(1) | NOT NULL | 状态 |
字段标识 | 字段类型 | 约束 | 说明 | |
---|---|---|---|---|
c_id | CHAR(23) | NOT NULL | PRIMARY KEY | 身份证号 |
assets_id | CHAR(20) | NOT NULL | 姓名 |
字段标识 | 字段类型 | 约束 | 说明 |
---|---|---|---|
card_id | CHAR(19) | PRIMARY KEY | 银行卡号 |
c_id | CHAR(23) | FOREIGN KEY | 身份证号 |
card_register_time | timestamp | NOT NULL | 办理时间 |
card_tele | CHAR(11) | NOT NULL | 预留手机号 |
card_type | VARCHAR(10) | NOT NULL | 种类 |
card_balance | DECIMAL(22,2) | NOT NULL | 余额 |
card_password | VARCHAR(20) | NOT NULL | 银行卡密码 |
card_status | BINARY(1) | NOT NULL | 状态 |
字段标识 | 字段类型 | 约束 | 说明 | |
---|---|---|---|---|
t_time | Timestamp | NOT NULL | PRIMARY KEY | 交易时间 |
t_someone | CHAR(19) | NOT NULL | 对方银行卡号 | |
t_me | CHAR(19) | FOREIGN KEY | 我方银行卡号 | |
t_id | CHAR(20) | UNIQUE NOT NULL | 交易编号 | |
t_money | DECIMAL(22,2) | NOT NULL | 交易金额 | |
t_balance | DECIMAL(22,2) | NOT NULL | 余额 |
字段标识 | 字段类型 | 约束 | 说明 |
---|---|---|---|
fi_id | CHAR(20) | PRIMARY KEY | 产品编号 |
fi_name | VARCHAR(16) | NOT NULL | 产品名称 |
fi_discribe | TEXT | NOT NULL | 产品描述 |
fi_unit_price | DECIMAL(22,2) | NOT NULL | 单价 |
fi_year_limit | DECIMAL(3,1) | NOT NULL | 理财年限 |
字段标识 | 字段类型 | 约束 | 说明 | |
---|---|---|---|---|
fi_id | CHAR(20) | FOREIGN KEY | PRIMARY KEY | 理财产品编号 |
fp_time | timestamp | NOT NULL UNIQUE | 变动时间 | |
fp_price | VARCHAR(22,2) | NOT NULL | 历史价格 |
字段标识 | 字段类型 | 约束 | 说明 | |
---|---|---|---|---|
fi_id | CHAR(20) | FOREIGN KEY | PRIMARY KEY | 产品编号 |
c_id | CHAR(23) | FOREIGN KEY | 身份证号 | |
hold_buy_time | Timestamp | NOT NULL | 购买时间 | |
hold_buy_id | CHAR(100) | NOT NULL | 购买编号 | |
hold_buy_amount | DECIMAL(16) | NOT NULL | 购买数量 | |
hold_buy_price | DECIMAL(22,2) | NOT NULL | 购买价格 | |
hold_income | DECIMAL(22,2) | NOT NULL | 收益 | |
hold_state | VARYING(100) | NOT NULL | 状态 |
字段标识 | 字段类型 | 约束 | 说明 |
---|---|---|---|
i_id | CHAR(20) | PRIMARY KEY | 保险编号 |
i_name | VARCHAR(16) | NOT NULL UNIQUE | 保险名称 |
i_fit_crowds | TEXT | NOT NULL | 适用人群 |
i_programs | TEXT | NOT NULL | 保险项目 |
i_unit_price | DECIMAL(22,2) | NOT NULL | 保险金额 |
i_year_limit | DECIMAL(3,1) | NOT NULL | 保险年限 |
i_claims_times | INT(2) | NOT NULL | 保险理赔次数 |
字段标识 | 字段类型 | 约束 | 说明 | |
---|---|---|---|---|
i_id | CHAR(20) | FOREIGN KEY | PRIMARY KEY | 保险编号 |
c_id | CHAR(23) | FOREIGN KEY | 身份证号 | |
hold_buy_time | timestamp | NOT NULL | 购买时间 | |
hold_buy_id | CHAR(100) | NOT NULL UNIQUE | 购买编号 | |
hold_buy_amount | DECIMAL(16) | NOT NULL | 购买数量 | |
hold_state | VARYING(100) | NOT NULL | 状态 |
2.5 数据库安全
数据库的不安全因素:
非授权用户对数据库的恶意存取和破坏,一些黑客(Hacker)和犯罪分子在用户存取数据库时猎取用户名和用户口令,然后假冒合法用户偷取、修改甚至破坏用户数据;数据库中重要或者敏感的数据被泄露,黑客和敌对分子千方百计盗窃数据库中的重要数据, 一些机密信息被暴露;数据库安全环境的脆弱性,数据库的安全性与计算机系统的安全性紧密联系。
数据库安全控制:
金融管理系统根据用户标识鉴定用户身份,只有合法用户才准许进入金融管理系统;给用户和管理者以不同的角色,同时授予不同的权限,在执行操作时数据库会根据使用者的角色来控制权限,防止越权操作。数据库管理系统进行存取控制,只允许用户执行合法的操作;
对无存取权限的用户进行数据隐藏,一定程度提高数据的安全保护,对于没有权限的用户,无法看到隐藏部分信息,这一部分我们通过权限以及视图等功能进行了调整,同时在客户端中隐藏了这些操作类,对于用户权限以外的操作方式,我们对于用户的对应封装的操作类中不提供这些操作方法。
3 用户界面设计
3.1交互逻辑总览
本产品采用在线区分管理员和用户的方式操作金融管理系统,首先输入用户名和密码,并选择登录身份,系统通过云数据库验证后进入相应的功能前台,在前台选择不同的功能进入操作详情界面。管理员和普通用户都提供了账户管理、银行卡管理、理财管理和保险管理的功能入口,但受制于身份的不同,管理员和用户对于上述四个模块的操作权限范围不同,所能执行的功能也不同。
3.2详细界面设计
用户界面主要考虑到用户客户端为app,手机可操作空间相对较小,我们将大部分操作通过点击的方式进行一步步选择,而不是让用户进行输入,以提高可用性。
打开客户端后,登录界面由标题栏+输入框+操作按钮组成,用户可以在输入框中输入信息,选择登录身份进入系统,也可以点击创建用户跳转至注册详情界面。注册界面提供可编辑文本框给用户输入创建账号的信息。
用户和管理员进入功能界面,可以使用以下模块进行操作。用户管理界面和管理员管理界面如下图所示,功能界面由标题栏+操作按钮组成,标题栏提醒用户当前所在的操作前台的类别,操作按钮提供不同的金融系统功能入口。通过点击管理模块按键进行选择使用哪些管理模块功能。
此时用户可以进行点击来选择操作,也可以使用手机系统自带的回退键返回到上一步。管理员的操作界面与用户界面类似,此时用户和管理员可以选择其中的某个子模块进行相应操作,根据需求点击选择需要处理的模块进入具体操作选择的界面,以下为用户和管理员对银行卡进行管理的界面,如下图所示:
最后,通过对子模块给出的具体操作的选择,完成用户和管理员功能的选择过程,开始提示用户输入操作的信息,以完成用户或管理员所需功能的信息获取和处理,用户办理银行储蓄卡和用户对银行卡进行转账交易的示例图如下图所示。 通过可编辑输入框、选择按钮等控件提供便于用户操作输入的功能设计。并在执行相关操作后显示toast提示信息告知用户操作执行的成功与否。
用户修改账户信息的例图如下图所示:
最后,用户或管理员使用完当前选定的功能后,可以点击返回回到用户前台或管理员界面,此时用户或管理员可以选择退出系统或者继续下一步操作。
四、系统实现文档
开发工具平台选择
数据库工具平台选择Navicat premium:Navicat premium是一款数据库管理工具。将此工具连接数据库,可以从中看到各种数据库的详细信息。包括报错等等。也可以通过登陆数据库,进行各种操作。Navicat Premium是一个可多重连线资料库的管理工具,可以单一程式同时连线到 MySQL、SQLite、Oracle 及 PostgreSQL 资料库,让管理不同类型的资料库更加地方便。
界面显示工具平台选择Android studio:Android studio拥有稳定速度快的优势,Android studio会减小碰到假死、卡顿、内存占用高等一系列影响开发效率的问题几率;拥有功能强大的UI编辑器,集合了Eclipse+ADT的优点,并且能更实时地展示界面布局效果;拥有完善的插件管理功能,支持了多种插件,可直接在插件管理中下载所需的插件;Android studio拥有非常智能的功能,智能保存,智能补齐,在实际的编辑代码中熟练使用后,可极大提高代码编写效率;Android studio拥有完善的多种代码管理工具,不需要任何操作,直接支持SVN、GITHUB等主流的代码管理工具。
数据库语言选择SQL:SQL是一种非过程语言,它可以同时访问多条记录;它是所有关系型数据库的通用语言,也就是说,它是可移植的,只需稍微修改就可以用来操作其他数据库;SQL用于查询、插入、删除、修改数据和对象的命令非常简单
编码规范
2.1命名规范
1. Activity类以及布局文件命名
由于app跳转界面较多,我们对每个界面的实现进行命名控制,以区分不同的Activity类并能够较好的对应到相关的layout布局文件。
对于Activity类,我们根据使用者的身份等活动进行了区分,并规定使用驼峰命名法。命名规则为:使用者+操作模块+操作类型。例如:UserFinancialBuy、ManagerOpFinancialDelete、ManagerOpHome等。同时为了便于开发,我们约定将不同的Activity类根据逻辑模块放入不同的目录下。
对于不同Activity对应的layout文件,我们采用类似的命名方式,以使用者名称开头,操作模块和操作类型进行区分, 用下划线格式指明文件所在的层次和使用对象。例如:manager_op_insure_financial_layout_delete,user_card_query_layout,manager_home_layout等。
2. 控件命名与绑定
以button,textview为开头,指明对象绑定的控件类型,然后用下划线连接该控件所对应应该实现的功能。
Button button_new;
Button button_test;
Button button_query;
Button button_lost;
Button button_record;
Button button_put;
Button button_get;
Button button_trade;
Button button_update;
button_new = (Button)findViewById(R.id.user_card_home_make);
button_test = (Button)findViewById(R.id.user_card_home_test);
button_query = (Button)findViewById(R.id.user_card_home_query);
button_lost = (Button)findViewById(R.id.user_card_home_lost);
button_record = (Button)findViewById(R.id.user_card_home_record);
button_put = (Button)findViewById(R.id.user_card_home_put);
button_get = (Button)findViewById(R.id.user_card_home_get);
button_trade = (Button)findViewById(R.id.user_card_home_trade);
3. 方法命名
为了便于阅读,我们约定以小写字母开头,驼峰命名方式命名方法对方法名称命名,这与需要重写的方法名称命名方式统一。例如:
void setListeners()
void onCreate()
2.2编程规范
非必要不使用全局变量和类变量和静态变量,改为代码模块内的局部变量。代码执行顺序尽量与书写顺序一致,减少单一方法代码行数,改用函数式编程策略,提高代码复用性。
例如以下Activity类中的onCreate函数,
protected void onCreate( Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.user_card_home_layout);
username = getIntent().getStringExtra("username");
bind();
setListeners();
}
我们约定将绑定控件操作归纳为一个方法,在方法中进行空间绑定的操作,设置控件对应的监听器也是如此,使代码逻辑清晰明了。其中整个系统的逻辑实现置于监听器中,当对监听器进行相应的操作时,运行相关的代码,实现逻辑操作。
在setListener函数中,实现点击所对应的操作时,我们约定对代码逻辑关键实现处进行相应的注释,同时指定对于可能抛出的错误进行try-catch处理,最后对于报错等信息,可以通过toast提示使用者,在测试时可以使用log.d输出相应信息,以用户输出银行卡信息为例,代码示例如下所示:
void setListeners(){
confirm.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
bank_card_dao client_d = new bank_card_dao();
List\<bank_card\> list = null;
String card_id_put = card_id.getText().toString();
// 通过用户的c_id得到银行卡列表
// try-catch捕捉抛出的错误
try {
list = client_d.get_card_by_c_id(username);
} catch (SQLException e) {
e.printStackTrace();
}
int flag = 0;
// 设置迭代器
Iterator\<bank_card\> iterator = list.iterator();
while(iterator.hasNext())
{
// 输出银行卡的列表
bank_card b = iterator.next();
if(b.getCard_id().equals(card_id_put))
{
flag = 1;
try {
startPut(card_id_put);
} catch (SQLException e) {
e.printStackTrace();
}
break;
}
}
// 对出错进行toast提示用户
if(flag == 0){
Toast toast=Toast.*makeText*(UserCardPut.this, "这不是你的卡号", Toast.*LENGTH_SHORT*);
toast.show();
}
}
});
2.3协同规范
我们尝试了使用版本控制库进行版本控制。
我们对于在实际编码时由于多人分别进行编程,往往会出现编程时想法没有对应上的情况,出现不同的分工中出现代码协同上的问题,例如,对于数据库的操作处,初始设置的提供的数据库操作需要的参数与后期需求不一致,需要尽心修改的情况等。此时需要集体讨论得出一个被小组成员共同接受的一个规定,并由所有小组成员遵守、修改、记录下来,来实现项目在不同阶段的一致性。
我们约定实现过程主要为迭代开发,逐渐实现一个一个的功能模块,确保每一个新增的功能模块都能够正常使用,保证其正确性,不断扩展基本系统的功能。新增类需记录配置文件参数,及时与团队成员协同,例如对于新开发的模块,需要及时将模块信息记录到草稿中,进行相应的功能测试,实现后会将测试记录以及相关实现统一到所有人的项目文件中,以此确保所有开发人员的项目文件的统一。
最后,为了防止操作上的同步的失误,我们还每隔一段时间或者是得到新的迭代版本时,都进行一次项目版本的存档,以确保在项目出现问题时能够及时的回退。
五、测试文档
1 概述
1.1背景
金融管理系统对于安全性具有极高的要求,需要保证账户财产的安全、交易的安全、操作的安全等等,为提高金融管理效率和安全性,开发金融管理系统,并迎合智能手机普及化,有必要开发一款拥有良好人机接口的移动端金融管理系统,同时需要保证管理员和用户的手续办理效率和程序的安全可靠性,正确完成功能,不能出现差错。
1.2产品描述
本金融管理系统是给予安卓端的移动应用开发,已可实装至各种型号的安卓(或鸿蒙)系统的移动设备终端上,通过互联网验证账号密码连接至云端数据库,并区分管理员和用户可进行不同权限的操作。
1.3目的
金融系统管理员可以利用本产品进行对系统中账户,账户下的银行卡进行冻结等管理操作,也可将新上市的理财产品和保险信息上传至数据库并管理这些理财产品和保险,以供用户购买。同时,管理员还有权限查看所有数据库内的信息,并可以修改其中一小部分内容,如理财产品的价格变动等。
用户可以在此系统中创建自己的账户,并办理银行卡、根据信用办理信用卡等。通过存款、申请信用卡额度、购买理财产品等管理自己的资产,可以随时存取款,卖卖理财产品和保险,系统将提供少量的修改数据库的选项以保证数据库的安全性。
2 测试概要(测试方法、范围、测试环境、工具、周期)
2.1测试方法:
主要使用单元测试、白盒测试的方法进行软件的开发测试
2.2单元测试:
在开发前期,将数据流图中的每个功能模块分派给小组不同成员。其中数据库管理模块的测试工作最先开展,用于正确的连接数据库并给上层提供安全正确的操作接口。
在开发中期,分用户和管理员各4个模块进行开发,每开发一个模块进行单元测试并通过Navicat工具连接云数据库查看测试结果。
2.3白盒测试:
当所有模块全部开发并单元测试完毕后,联合所有模块,更具用户需求构造逻辑覆盖的测试方案,对整体系统进行白盒测试。
测试方案1:注册用户,登录用户,查询用户信息,办理储蓄卡,尝试办理信用卡,银行卡存款,银行卡查询,银行卡转账,交易记录查询,查询银行卡,查询理财产品,购买理财产品,卖出理财产品,查询保险产品,购买保险产品,申请保险理赔。
测试方案2:登录管理员(系统提供账号密码),查询某个账户信息,冻结某个账户,提高某个账户的信用分,查询某个银行卡信息,冻结某个银行卡信息,更新某个银行卡信用分,查询在售理财产品,新增一个理财产品,删除一个理财产品,更新一个理财产品的价格,查询在售保险,新增一个保险,删除一个保险,修改一个保险的使用人群等信息。
对于测试方案1,现对注册用户、登录用户、办理储蓄卡进行详细的测试说明如下。
注册用户:点击首页注册新用户按钮,注册一个新用户至云端数据库。
期望结果:点击注册后页面跳转至注册页面,用户填写信息后点击确认,系统判断信息是否合法给出注册的成功与否,成功注册则添加账户信息至数据库client表并初始设置信誉分为80,账号状态非冻结。
测试结果:点击后成功跳转,输入合法信息后可以成功注册至云端数据库,但输入不合法信息则无提示,系统未将错误信息提供给用户。
登录用户:用户在登录页面输入账号和密码信息后可登录。
预期结果:用户输入正确的账号密码再点击登录为用户按钮即可登录进入用户前台界面,如果账号不存在云端则反馈账号不存在,如果密码错误则反馈密码错误,点击登录为管理员则无法登录。
测试结果:正确账号成功登录,也反馈了账号不存在和密码错误的提示信息,在用户密码正确的情况下,错误的点击了管理员登录也提示账号不存在。本测试完美完成。
办理储蓄卡:用户可以办理储蓄卡
预期结果:申请成功,反馈卡号信息,数据库同步更新。
测试结果:符合要求。
2.4性能测试
开发系统:Andriod Studio 2021.3正式版
开发平台:Intel I5-9300H,Intel I5-8265U,Windows 10 64bit
测试平台:华为P30 pro
产品规模:3.08MB
产品性能:
平均启动时间0.7秒
平均编译时间3.2秒
平均打包时间32秒
平均内存占用16.6MB
3 动态测试结果与缺陷分析
3.1动态测试结果
测试用例每项10个,2个边缘数据,2个不合规数据
测试方案1:
测试情况(10) | 合格(10) | 待完善(9-6) | 缺陷(<=6) |
---|---|---|---|
注册用户 | ✔ | ||
登录用户 | ✔ | ||
查询用户信息 | ✔ | ||
办理储蓄卡 | ✔ | ||
尝试办理信用卡 | ✔ | ||
银行卡存款 | ✔ | ||
银行卡查询 | ✔ | ||
银行卡转账 | ✔ | ||
交易记录查询 | ✔ | ||
查询理财产品 | ✔ | ||
购买理财产品 | ✔ | ||
卖出理财产品 | ✔ | ||
查询保险产品 | ✔ | ||
购买保险产品 | ✔ | ||
申请保险理赔。 | ✔ |
测试方案2:
测试情况(10) | 合格(10) | 待完善(9-6) | 缺陷(<=6) |
---|---|---|---|
登录管理员 | ✔ | ||
查询某个账户信息 | ✔ | ||
冻结某个账户 | ✔ | ||
提高某个账户的信用分 | ✔ | ||
查询某个银行卡信息 | ✔ | ||
冻结某个银行卡信息 | ✔ | ||
更新某个银行卡信用分 | ✔ | ||
查询在售理财产品 | ✔ | ||
新增一个理财产品 | ✔ | ||
删除一个理财产品 | ✔ | ||
更新一个理财产品的价格 | ✔ | ||
查询在售保险 | ✔ | ||
新增一个保险 | ✔ | ||
删除一个保险 | ✔ | ||
修改一个保险的使用人群等信息。 | ✔ |
对于测试方案1的15个测试案例,共完全成功4个,存在少量鲁棒性缺陷的案例6个,未成功5个。
对于测试方案2的15个测试案例,共完全成功5个,存在少量鲁棒性缺陷的案例7个,未成功3个。
严重缺陷率为19.3%
3.2缺陷分析
部分功能因时间不足,安排不当而无法实现,选择减少非核心需求,造成未成功实现模块的严重缺陷。
大部分功能模块能够运作,但严重缺乏鲁棒性,系统对于边界数据和数据格式的审查和错误反馈性能很差,缺乏足够的功能逻辑指引。
登录界面,银行卡申请等实现了较强的鲁棒性,证明了前台实现信息安全处理的可能性和可行性。
4测试结论与建议(项目概况、测试时间 测试情况、结论性能汇总)
产品存在部分功能漏洞未能实现,成功实现的部分也存在数据安全性,操作鲁棒性,信息反馈灵敏度等性能缺陷。
软件性要求低,但功能缺少且实现功能鲁棒性低,安全性低,需要根据已有经验和学习流行技术提升软件性能和完善软件功能,注重易交互性和安全性。
六、总结
1.个人总结
王远卓:
这次软件综合实践,我们尝试了极限编程软件工程方法,不局限于一种固定的方法,高效快速的沟通,实现了系统版本初始版本的实现,完成了软件功能的不断迭代的实现,对于新的功能模块,我们及时的进行测试,确保其正确性。在编程遇到问题时,我们重视沟通解决问题的过程,对于出现的问题我们快速而有效的沟通,快速达成一致解决问题。
作为组长主要实现了数据库的连接,黑板架构的提出,数据库操作类的控制提高安全性等的提出,并编程完成了管理员各个功能模块与UI的实现,我认识到在小组合作中,小组之间进行高效合作的重要性,通过组员之间的高效的沟通,得到小组中最好的建议与方法,快速的达成一致并解决问题,这种效率是团队合作中及其重要的部分,也让我加深了对团队合作理解。通过这次实践,我更熟悉了软件系统实现的架构、部署以及其间的过程,对于软件开发的方法有了进一步的学习,增加了实践的经验。
周健杰:
在本次软件综合实践中,我负责绘制类图和部分数流图,在编程实现时完成了用户功能前台的交互逻辑和页面跳转,并实现了用户账户管理和银行卡管理的用户创建,信息修改与查看,银行卡办理和信用卡资质,并实现了银行卡的存取交易和转账以及对于的交易记录等。
在本次实践中,我充分体会到了软件工程在软件开发中的重要作用,需求报告、总体设计等编程前的准备对于编程的指导性和决定性作用。并且我意识到前期需求调查和方案的制定对于发现早期错误具有重要意义,及时修正早期错误可以避免错误的不断扩大。我会努力总结本次软件开发的宝贵经验,并将会在以后的工作项目中认真实践我在本次课设中学到的知识。
韩瑞乾:
在本次实践中,我首先重新复习了软件工程的相关知识,从软件需求分析到最后的程序分析测试,对整个流程有了较为全面的把握。我首先负责了本次实践的需求分析,剖析了银行金融系统的用户所需要的功能随后根据所确定的各种需求,进行更详细的设计。我还对项目所需的数据库进行了创建,使用了MySQL数据库搭建了金融系统数据库。在项目具体搭建中,我负责编写系统功能中各实体类,以及各实体与数据库之间的交互接口,并参与了部分主要功能的逻辑实现。本次实践中我最大的收获就是较为完整地参与了软件设计的整体过程,感受到了之前所学习的软件工程中各个设计方法的作用和重要性,使我更深刻地意识到了软件工程对于程序设计人员的重要性。
金桥:
在本次实验中,我学习到了数据库工具Navicat Premium的使用方法和运用visio studio来进行连接调用数据库的方法。在这次实验中,我学到了很多,不仅将自己学到的内容运用于实际,还在动手活动中提高自己的动手能力,并且在这个过程中对学到的理念进行运用,进而学习到更新的知识。从中获得的诸多收获,也是很可贵的,是非常有意义的,是一个让我把书本上的理论知识运用于实践中的好机会。在以前,我学的时候总是会感叹学的内容太难懂,现在回想起来,有些知识其实并不太难,它的关键在于怎么理解这些知识。它锻炼了我做项目的能力,提高了独立思考问题、自己动手操作的能力,在工作的过程中,复习了以前学习过的知识,并掌握了一些应用知识的技巧等。而且,实训中的项目作业也使我更加有团队精神。
2 组员自评分
王远卓:26分
周健杰:26分
韩瑞乾:26分
金桥:22分
评分总和:100
七、附录
1 数据库建表代码
CREATE TABLE `admin` (
`admin_name` char(22) DEFAULT NULL,
`admin_password` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `assets` (
`c_id` char(23) NOT NULL,
`asset_id` char(20) NOT NULL,
`amount` double(22,2) DEFAULT NULL,
PRIMARY KEY (`c_id`,`asset_id`),
CONSTRAINT `assets_c_id_fkey` FOREIGN KEY (`c_id`) REFERENCES `client` (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `bank_card` (
`card_id` char(19) NOT NULL,
`c_id` char(23) NOT NULL,
`card_register_time` varchar(30) NOT NULL DEFAULT '',
`card_tele` char(11) NOT NULL,
`card_type` varchar(10) NOT NULL,
`card_balance` decimal(22,2) NOT NULL,
`card_password` varchar(20) NOT NULL,
`card_status` varchar(1) NOT NULL,
`card_available` decimal(22,2) NOT NULL,
PRIMARY KEY (`card_id`),
KEY `bank_card_c_id_fkey` (`c_id`),
CONSTRAINT `bank_card_c_id_fkey` FOREIGN KEY (`c_id`) REFERENCES `client` (`c_id`),
CONSTRAINT `ck_card_balance` CHECK (((`card_balance` >= 0) or (`card_type` = _utf8mb3'信用卡')))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `client` (
`c_id` char(22) NOT NULL,
`c_name` varchar(60) NOT NULL,
`c_tele` char(11) NOT NULL,
`c_email` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`c_password` varchar(20) NOT NULL,
`c_credit_score` int(3) NOT NULL,
`c_status` varchar(1) NOT NULL,
PRIMARY KEY (`c_id`),
CONSTRAINT `ck_c_e_mail` CHECK ((`c_email` like _utf8mb3'%@%')),
CONSTRAINT `ck_c_password` CHECK ((length(`c_password`) >= 7))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `financial` (
`fi_id` char(20) NOT NULL,
`fi_name` varchar(16) NOT NULL,
`fi_discribe` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`fi_unit_price` decimal(22,2) NOT NULL,
`fi_year_limit` decimal(3,1) NOT NULL,
PRIMARY KEY (`fi_id`),
CONSTRAINT `ck_fi_unit_price` CHECK ((`fi_unit_price` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `financial_history_price` (
`fi_id` char(20) NOT NULL,
`fp_price` decimal(22,2) NOT NULL,
`fp_time` varchar(30) NOT NULL DEFAULT '',
PRIMARY KEY (`fi_id`,`fp_time`),
CONSTRAINT `fi_id_fkey` FOREIGN KEY (`fi_id`) REFERENCES `financial` (`fi_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `hold_financial` (
`fi_id` char(20) NOT NULL,
`c_id` char(23) NOT NULL,
`hold_buy_time` varchar(30) NOT NULL DEFAULT '',
`hold_buy_id` char(100) NOT NULL,
`hold_buy_amount` decimal(16,0) NOT NULL,
`hold_buy_price` decimal(22,2) NOT NULL,
`hold_income` decimal(22,2) NOT NULL DEFAULT (0),
`hold_state` varchar(100) NOT NULL,
PRIMARY KEY (`fi_id`,`c_id`,`hold_buy_time`),
UNIQUE KEY `hold_financial_hold_buy_id_key` (`hold_buy_id`),
KEY `hold_financial_c_id_fkey` (`c_id`),
CONSTRAINT `hold_financial_c_id_fkey` FOREIGN KEY (`c_id`) REFERENCES `client` (`c_id`),
CONSTRAINT `hold_financial_fi_id_fkey` FOREIGN KEY (`fi_id`) REFERENCES `financial` (`fi_id`),
CONSTRAINT `hold_financial_hold_buy_amount_check` CHECK ((`hold_buy_amount` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `hold_insure` (
`i_id` char(20) NOT NULL,
`c_id` char(23) NOT NULL,
`hold_buy_time` varchar(30) NOT NULL DEFAULT '',
`hold_buy_id` char(100) NOT NULL,
`hold_buy_amount` decimal(16,0) NOT NULL,
`hold_state` varchar(100) NOT NULL,
PRIMARY KEY (`i_id`,`hold_buy_time`,`c_id`),
KEY `hold_insure_c_id_fkey` (`c_id`),
CONSTRAINT `hold_insure_c_id_fkey` FOREIGN KEY (`c_id`) REFERENCES `client` (`c_id`),
CONSTRAINT `hold_insure_i_id_fkey` FOREIGN KEY (`i_id`) REFERENCES `insure` (`i_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `hold_insure_hold_buy_amount_check` CHECK ((`hold_buy_amount` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `insure` (
`i_id` char(20) NOT NULL,
`i_name` varchar(16) NOT NULL,
`i_fit_crowds` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`i_programs` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`i_unit_price` decimal(22,2) NOT NULL,
`i_year_limit` decimal(3,1) NOT NULL,
`i_claims_times` int(2) NOT NULL,
PRIMARY KEY (`i_id`),
KEY `i_id` (`i_id`),
CONSTRAINT `ck_i_unit_price` CHECK ((`i_unit_price` > 0)),
CONSTRAINT `ck_i_year_limit` CHECK ((`i_year_limit` > 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `trade_record` (
`t_time` varchar(30) NOT NULL DEFAULT '',
`t_me` char(19) NOT NULL,
`t_someone` char(19) NOT NULL,
`t_id` char(20) NOT NULL,
`t_balance` decimal(22,2) NOT NULL,
`t_money` decimal(22,2) NOT NULL,
PRIMARY KEY (`t_time`,`t_me`,`t_someone`),
UNIQUE KEY `trade_record_t_id_key` (`t_id`),
KEY `trade_t_me_fkey` (`t_me`),
CONSTRAINT `trade_t_me_fkey` FOREIGN KEY (`t_me`) REFERENCES `bank_card` (`card_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2 以账户操作为例核心代码
2.1 管理员冻结账户功能
package com.example.finance.Manager.OpClient;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.finance.Dao.client_dao;
import com.example.finance.R;
import com.example.finance.bean.client;
public class ManagerOpClientFreezeActivity extends AppCompatActivity {
// 声明控件变量
Button button_mopc_freeze_submit;
EditText text_id;
EditText text_status;
TextView text_showchange;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.manager_op_client_layout_freeze);
// 控件绑定
bindView();
// 设置监听器
setListener();
}
void bindView(){
button_mopc_freeze_submit = (Button)findViewById(R.id.button_mopc_freeze_submit);
text_id = (EditText)findViewById(R.id.text_mopc_freeze_id);
text_status = (EditText)findViewById(R.id.text_mopc_freeze_status);
text_showchange = (TextView)findViewById(R.id.text_mopc_freeze_show_status);
}
void setListener(){
button_mopc_freeze_submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// 获取控件中的信息
client result;
String client_id;
client_id = text_id.getText().toString();
String client_status;
client_status = text_status.getText().toString();
// 更新账户状态
client_dao ct = new client_dao();
ct.update_status_by_c_id(client_status,client_id);
// 输出操作后账户信息
result = (client) ct.get_client_by_id(client_id);
String msg;
msg = result.getC_id()+"\n"+
result.getC_name()+"\n"+
result.getC_tele()+"\n"+
result.getC_email()+"\n"+
result.getC_password()+"\n"+
String.valueOf(result.getC_credit_score())+"\n"+
result.getC_status();
text_showchange.setText(msg);
}
});
}
}
2.2 管理员查询账户
package com.example.finance.Manager.OpClient;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.finance.Dao.client_dao;
import com.example.finance.R;
import com.example.finance.bean.client;
public class ManagerOpClientQueryActivity extends AppCompatActivity {
// 声明控件变量
Button button_mopc_query_submit;
EditText text_id;
TextView text_msg;
String clientid;
client result;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.manager_op_client_layout_query);
// 控件绑定
bindView();
// 设置监听器
setListener();
}
void bindView(){
button_mopc_query_submit = (Button) findViewById(R.id.button_mopc_query_submit);
text_msg = (TextView)findViewById(R.id.text_mopc_query_show_msg) ;
text_id = (EditText) findViewById(R.id.text_mopc_query_id);
}
void setListener(){
button_mopc_query_submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// 获取控件中的信息
clientid = text_id.getText().toString();
client_dao ct = new client_dao();
result = (client) ct.get_client_by_id(clientid);
String msg;
msg = result.getC_id()+"\n"+
result.getC_name()+"\n"+
result.getC_tele()+"\n"+
result.getC_email()+"\n"+
result.getC_password()+"\n"+
String.valueOf(result.getC_credit_score())+"\n"+
result.getC_status();
text_msg.setText(msg);
}
});
}
}
2.3 管理员更新用户信用分
package com.example.finance.Manager.OpClient;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.finance.Dao.client_dao;
import com.example.finance.R;
import com.example.finance.bean.client;
public class ManagerOpClientUpdateActivity extends AppCompatActivity {
// 声明控件变量
Button button_mopc_update_submit;
EditText text_id;
EditText text_credits;
TextView text_showchange;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.manager_op_client_layout_update);
// 控件绑定
bindView();
// 设置监听器
setListener();
}
void bindView(){
button_mopc_update_submit = (Button)findViewById(R.id.button_mopc_update_submit);
text_id = (EditText)findViewById(R.id.text_mopc_update_id);
text_credits = (EditText)findViewById(R.id.text_mopc_update_credits);
text_showchange = (TextView)findViewById(R.id.text_mopc_update_show_credits);
}
void setListener(){
button_mopc_update_submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// 获取控件中的信息
client result;
String client_id;
client_id = text_id.getText().toString();
int client_credit;
client_credit = Integer.parseInt(text_credits.getText().toString());
// 更新账户信息
client_dao ct = new client_dao();
ct.update_score_by_c_id(client_credit,client_id);
// 输出操作后账户信息
result = (client) ct.get_client_by_id(client_id);
String msg;
msg = result.getC_id()+"\n"+
result.getC_name()+"\n"+
result.getC_tele()+"\n"+
result.getC_email()+"\n"+
result.getC_password()+"\n"+
String.valueOf(result.getC_credit_score())+"\n"+
result.getC_status();
text_showchange.setText(msg);
}
});
}
}
2.4 用户修改账户信息
package com.example.finance.User.acountForUser;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.example.finance.Dao.client_dao;
import com.example.finance.User.homeForUser.user_acount_acitivity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.example.finance.R;
import com.example.finance.bean.client;
public class UserChangeAcount extends AppCompatActivity {
// 声明控件变量
Button back;
TextView id,name,score,status;
EditText tele,email,password;
Button confirm;
String username;
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_acount_change_layout);
username = getIntent().getStringExtra("username");
// 绑定控件
bind();
// 设置监听器
setListeners();
// 输出信息
showInfo();
}
void bind(){
back = (Button)findViewById(R.id.user_from_acountchange_to_home);
id = (TextView) findViewById(R.id.user_account_change_c_id);
name = (TextView) findViewById(R.id.user_account_change_c_name);
score = (TextView) findViewById(R.id.user_account_change_c_creditScore);
status = (TextView) findViewById(R.id.user_account_change_c_status);
tele = (EditText) findViewById(R.id.user_account_change_c_tele);
email = (EditText) findViewById(R.id.user_account_change_c_email);
password = (EditText) findViewById(R.id.user_account_change_c_password);
confirm = (Button) findViewById(R.id.user_account_change_confirm);
}
void setListeners(){
confirm.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// 更新用户需要修改的信息
client_dao cd = new client_dao();
cd.update_email_by_c_id(email.getText().toString(), username);
cd.update_password_by_c_id(password.getText().toString(), username);
cd.update_tele_by_c_id(tele.getText().toString(),username);
}
});
back.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(UserChangeAcount.this, user_acount_acitivity.class);
intent.putExtra("username", username);
startActivity(intent);
}
});
}
void showInfo(){
client_dao client_d = new client_dao();
client bean = client_d.get_client_by_id(username);
id.setText(bean.getC_id());
name.setText(bean.getC_name());
tele.setText(bean.getC_tele());
email.setText(bean.getC_email());
password.setText(bean.getC_password());
score.setText(String.valueOf(bean.getC_credit_score()));
status.setText(bean.getC_status());
}
}
2.5 用户查询账户信息
package com.example.finance.User.acountForUser;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.example.finance.Dao.client_dao;
import com.example.finance.User.homeForUser.user_acount_acitivity;
import com.example.finance.R;
import com.example.finance.bean.client;
public class UserInfoAcount extends AppCompatActivity {
// 声明控件变量
Button back;
TextView id,name,tele,email,password,score,state;
String username;
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_acount_query_layout);
username = getIntent().getStringExtra("username");
// 绑定控件
bind();
// 设置监听器
setListeners();
// 输出信息
showInfo();
}
void bind()
{
back = (Button)findViewById(R.id.user_from_acount_query_to_home);
id = (TextView) findViewById(R.id.user_account_info_c_id);
name = (TextView) findViewById(R.id.user_account_info_c_name);
tele = (TextView) findViewById(R.id.user_account_info_c_tele);
email = (TextView) findViewById(R.id.user_account_info_c_email);
password = (TextView) findViewById(R.id.user_account_info_c_password);
score = (TextView) findViewById(R.id.user_account_info_c_creditScore);
state = (TextView) findViewById(R.id.user_account_info_c_status);
}
void setListeners()
{
back.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(UserInfoAcount.this, user_acount_acitivity.class);
intent.putExtra("username", username);
startActivity(intent);
}
});
}
void showInfo(){
client_dao client_d = new client_dao();
client bean = client_d.get_client_by_id(username);
id.setText(bean.getC_id());
name.setText(bean.getC_name());
tele.setText(bean.getC_tele());
email.setText(bean.getC_email());
password.setText(bean.getC_password());
score.setText(String.valueOf(bean.getC_credit_score()));
state.setText(bean.getC_status());
}
}
2.6 数据库操作账户类
package com.example.finance.Dao;
import com.example.finance.DBOpenHelper;
import com.example.finance.bean.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class client_dao {
public List<client> get_all_client() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<client> list = new ArrayList<client>();
try {
conn = DBOpenHelper.getConn();
String sql = "select * from bank_card";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
client ct = new client();
ct.setC_id(rs.getString("c_id"));
ct.setC_name(rs.getString("c_name"));
ct.setC_tele(rs.getString("c_tele"));
ct.setC_email(rs.getString("c_email"));
ct.setC_password(rs.getString("c_password"));
ct.setC_credit_score(rs.getInt("c_credit_score"));
ct.setC_status(rs.getString("c_status"));
list.add(ct);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return list;
}
public void add_client(client ct) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBOpenHelper.getConn();
String sql = "insert client"+"(c_id,c_name,c_tele,c_email " +
",c_password, c_credit_score, c_status)" +
"values (?,?,?,?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, ct.getC_id());
ps.setString(2, ct.getC_name());
ps.setString(3, ct.getC_tele());
ps.setString(4, ct.getC_email());
ps.setString(5, ct.getC_password());
ps.setInt(6, ct.getC_credit_score());
ps.setString(7, ct.getC_status());
ps.executeUpdate();
System.out.println("yes");
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
}
}
public void delete_card(String c_id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBOpenHelper.getConn();
String sql = "delete from client " +
"where c_id=?";
ps = conn.prepareStatement(sql);
ps.setString(1, c_id);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public client get_client_by_id(String c_id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
client ct = new client();
try {
conn = DBOpenHelper.getConn();
String sql = "select * from client where c_id=?";
ps = conn.prepareStatement(sql);
ps.setString(1, c_id);
rs = ps.executeQuery();
while (rs.next()) {
ct.setC_id(rs.getString("c_id"));
ct.setC_name(rs.getString("c_name"));
ct.setC_tele(rs.getString("c_tele"));
ct.setC_email(rs.getString("c_email"));
ct.setC_password(rs.getString("c_password"));
ct.setC_credit_score(rs.getInt("c_credit_score"));
ct.setC_status(rs.getString("c_status"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return ct;
}
public void update_password_by_c_id(String pwd, String c_id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
client ct = new client();
try {
conn = DBOpenHelper.getConn();
String sql = "update client set c_password=? where c_id = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, pwd);
ps.setString(2, c_id);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public void update_tele_by_c_id(String tele, String c_id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
client ct = new client();
try {
conn = DBOpenHelper.getConn();
String sql = "update client set c_tele=? where c_id = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, tele);
ps.setString(2, c_id);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public void update_email_by_c_id(String c_email, String c_id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
client card = new client();
try {
conn = DBOpenHelper.getConn();
String sql = "update client set c_email=? where c_id = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, c_email);
ps.setString(2, c_id);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public void update_status_by_c_id(String status, String c_id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
client card = new client();
try {
conn = DBOpenHelper.getConn();
String sql = "update client set c_status=? where c_id = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, status);
ps.setString(2, c_id);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public void update_score_by_c_id(int score, String c_id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBOpenHelper.getConn();
String sql = "update client set c_credit_score=? where c_id = ?";
ps = conn.prepareStatement(sql);
ps.setDouble(1, score);
ps.setString(2, c_id);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
2.7 账户基本类
package com.example.finance.bean;
public class client {
private String c_id;
private String c_name;
private String c_tele;
private String c_email;
private String c_password;
private int c_credit_score;
private String c_status;
public client(String c_id, String c_name, String c_tele, String c_email, String c_password, int c_credit_score, String c_status) {
this.c_id = c_id;
this.c_name = c_name;
this.c_tele = c_tele;
this.c_email = c_email;
this.c_password = c_password;
this.c_credit_score = c_credit_score;
this.c_status = c_status;
}
public client() {
}
public String getC_id() {
return c_id;
}
public void setC_id(String c_id) {
this.c_id = c_id;
}
public String getC_name() {
return c_name;
}
public void setC_name(String c_name) {
this.c_name = c_name;
}
public String getC_tele() {
return c_tele;
}
public void setC_tele(String c_tele) {
this.c_tele = c_tele;
}
public String getC_email() {
return c_email;
}
public void setC_email(String c_email) {
this.c_email = c_email;
}
public String getC_password() {
return c_password;
}
public void setC_password(String c_password) {
this.c_password = c_password;
}
public int getC_credit_score() {
return c_credit_score;
}
public void setC_credit_score(int c_credit_score) {
this.c_credit_score = c_credit_score;
}
public String getC_status() {
return c_status;
}
public void setC_status(String c_status) {
this.c_status = c_status;
}
}
2.8 用户修改账户信息布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="30dp">
<TextView
android:id="@+id/user_account_change_c_id_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="身份证"/>
<TextView
android:id="@+id/user_account_change_c_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="123131232"/>
<TextView
android:id="@+id/user_account_change_c_name_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="姓名"/>
<TextView
android:id="@+id/user_account_change_c_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="xiaohong"/>
<TextView
android:id="@+id/user_account_change_c_tele_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="电话"/>
<EditText
android:id="@+id/user_account_change_c_tele"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="1381313"/>
<TextView
android:id="@+id/user_account_change_c_email_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="邮箱"/>
<EditText
android:id="@+id/user_account_change_c_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="123@126"/>
<TextView
android:id="@+id/user_account_change_c_password_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="系统密码"/>
<EditText
android:id="@+id/user_account_change_c_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="*******"/>
<TextView
android:id="@+id/user_account_change_c_creditScore_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="信用分"/>
<TextView
android:id="@+id/user_account_change_c_creditScore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="80"/>
<TextView
android:id="@+id/user_account_change_c_status_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="账户状态"/>
<TextView
android:id="@+id/user_account_change_c_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="非冻结"/>
<Button
android:id="@+id/user_account_change_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确认修改"
android:layout_marginTop="80dp"/>
<Button
android:id="@+id/user_from_acountchange_to_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="返回"/>
</LinearLayout>
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://wangyuanzhuo.top/53-2/
Anna94 wants to trade nude pics with you
Touche. Outstanding arguments. Keep up the great effort. Scot Scheiblich
hidden cam
If some one wants to be updated with newest technologies after that he must be go to see this site and be up to date all the time. Rashad Boilard
Loveme
Very good article! We will be linking to this particularly great post on our site. Keep up the good writing. Alvaro Balch
adult dating
Thankyou for this rattling post, I am glad I discovered this site on yahoo. Isreal Washmuth
Loveme
I appreciate you sharing this blog post. Really looking forward to read more. Great. Haywood Mccrate
passwords
This website definitely has all of the information I needed concerning this subject and didn at know who to ask. Isaac Lamielle
bedava bitcoin
Perfectly written content, Really enjoyed looking through. Mauro Phare