博主介绍:专注于Java(springboot ssm 等开发框架) vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作
☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟
我的博客空间发布了1500+毕设题目 方便大家学习使用
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人
更多项目地址 介绍 翰文编程CSDN博客 翰文编程-CSDN博客
文末下方有源码获取地址
4.2功能结构设计
本系统主要是基于数据的增加,修改,删除等操作,使用者能够通过提前设定的登录功能进入指定的操作区,这里对使用者设计的功能进行结构展示。
管理员功能结构图的绘制结果见图4-1。管理员登录进入本系统操作的功能包括管理基金,管理基金净值,管理基金自选,管理持有基金,管理交易记录,管理论坛帖子,管理公告等。
图4-1 管理员功能结构图
用户功能结构图的绘制结果见图4-2。用户登录进入本系统操作的功能包括购买基金,查看基金净值,查看基金经理,把基金添加自选,卖出持有基金,查看基金交易记录等。
图4-2 用户功能结构图
4.3数据库设计
如果说设计系统的功能很重要,那么设计该系统的数据库将更重要,毕竟系统服务于用户,数据库服务于系统,用户访问系统,操作系统的所有数据都要依赖于数据库,而系统的数据几乎都是保存在数据库中的,所以,一个高质量的程序,必然拥有一个安全,快速响应,稳定可靠的数据库。本系统的MySQL数据库可以通过SQL语言来实现对系统数据的管理,包括在指定表中插入数据,在规定的表中更改数据,以及删除指定表中的部分数据等操作。一般来说,像MySQL这样的关系型数据库,对于结构化查询语言SQL都能很好的进行支持。在编程中,通过合理运用SQL语言便能操作数据库的各种数据,真是非常方便快捷!
4.3.1 数据库概念设计
本节内容主要是使用图形的方式来描述数据库中的实体,每个实体的相应属性,还有实体之间的相互联系,常用的Visio工具即可满足绘制E-R图的需求。E-R图是由矩形,椭圆,菱形等图形元素组成,矩形框中主要写实体的名称,椭圆框中主要是登记该实体的属性,而菱形框中主要是登记实体之间的联系名称,最后使用实心线段把这些图形元素进行连接,即可完成E-R图的绘制。当初步得到一个E-R图时,需要进行检查,使用分析的方式去修改,重构E-R图,以达到消除数据冗余,或者是消除实体间联系冗余的目的。从而保持数据库的完整性,以及降低数据库维护上面的难度。
(1)使用Visio这样的常用的实体属性图绘制工具来绘制基金实体属性图,绘制结果见图4-3。
图4-3 基金实体属性图
(2)使用Visio这样的常用的实体属性图绘制工具来绘制用户实体属性图,绘制结果见图4-4。
图4-4 用户实体属性图
(3)使用Visio这样的常用的实体属性图绘制工具来绘制交易记录实体属性图,绘制结果见图4-5。
图4-5 交易记录实体属性图
(4)使用Visio这样的常用的实体属性图绘制工具来绘制管理员实体属性图,绘制结果见图4-6。
图4-6 管理员实体属性图
(5)绘制的上述实体间存在的联系见图4-7。
图4-7 实体间关系E-R图
4.3.2 数据库物理设计
本系统数据在数据库中都是通过各种二维表进行记录保存的,在数据库中设计这样的二维表也是比较重要的内容,因为它影响着数据的存储效率。在设计二维表也就是关系模型之前,一些有关二维表方面的常用概念需要进行充分了解。
关系:一张具体的数据表即表示关系,关系的名称与数据表的名称保持一致;
元组:数据表中,每行显示的数据即代表元组;
属性:数据表中,每列表示的数据即代表属性;
关键字:数据表中,为了与其他数据表进行区分,则需要在每张表中进行主键的设置;
通过上节内容可以知晓数据库中的各个实体,并通过一定方式把这些实体表示的内容进行数据表的转换,通常来说,每个实体都会对应一张具体的数据表,在本系统指定的数据库中创建命名好的数据库,才可以对数据表进行创建与设计。理财通数据表设计结果展示如下:
表4-1 论坛表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
forum_name | 帖子标题 | varchar(200) | 是 |
yonghu_id | 用户 | int(11) | 是 |
users_id | 管理员 | int(11) | 是 |
forum_content | 发布内容 | text | 是 |
super_ids | 父id | int(11) | 是 |
forum_types | 帖子类型 | int(11) | 是 |
forum_state_types | 帖子状态 | int(11) | 是 |
insert_time | 发帖时间 | timestamp | 是 |
update_time | 修改时间 | timestamp | 是 |
create_time | 创建时间 | timestamp | 是 |
表4-2 公告信息表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
gonggao_name | 公告名称 | varchar(200) | 是 |
gonggao_photo | 公告图片 | varchar(200) | 是 |
gonggao_types | 公告类型 | int(11) | 否 |
insert_time | 公告发布时间 | timestamp | 是 |
gonggao_content | 公告详情 | text | 是 |
create_time | 创建时间 | timestamp | 是 |
表4-3 交易记录表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
jijin_id | 基金 | int(11) | 是 |
yonghu_id | 用户 | int(11) | 是 |
jiaoyijilu_fenshu | 交易份数 | int(11) | 是 |
jiaoyijilu_sum_money | 总金额 | decimal(10,2) | 是 |
jiaoyijilu_types | 类型 | int(11) | 是 |
insert_time | 记录时间 | datetime | 是 |
create_time | 添加时间 | datetime | 是 |
表4-4 基金表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
jijinjingli_id | 基金经理 | int(11) | 是 |
jijin_uuid_number | 基金代码 | varchar(200) | 是 |
jijin_name | 基金名称 | varchar(200) | 是 |
jijin_photo | 基金照片 | varchar(200) | 是 |
jijin_types | 基金类型 | int(11) | 是 |
jijin_fengxian_types | 基金风险类型 | int(11) | 是 |
jijin_clicknum | 点击次数 | int(11) | 是 |
jijin_tuijian_types | 首页推荐 | int(11) | 是 |
jijin_content | 基金档案 | longtext | 是 |
shangxia_types | 是否上架 | int(11) | 是 |
jijin_delete | 逻辑删除 | int(11) | 是 |
insert_time | 基金发布时间 | datetime | 是 |
create_time | 添加时间 | datetime | 是 |
表4-5 基金经理表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
jijinjingli_name | 基金经理姓名 | varchar(200) | 是 |
jijinjingli_photo | 基金经理照片 | varchar(200) | 是 |
jijinjingli_gongzuo | 工作年限 | varchar(200) | 是 |
sex_types | 性别 | int(11) | 是 |
jijinjingli_renqi_text | 任期及回报 | text | 是 |
jijinjingli_content | 基金经理档案 | text | 是 |
insert_time | 添加时间 | timestamp | 是 |
create_time | 创建时间 | timestamp | 是 |
表4-6 持有基金表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
jijin_id | 基金 | int(11) | 是 |
yonghu_id | 用户 | int(11) | 是 |
fenshu | 持有份数 | int(11) | 是 |
buy_sum_money | 总购买金额 | decimal(10,2) | 是 |
sell_sum_money | 总卖出份额 | decimal(10,2) | 是 |
insert_time | 创建时间 | datetime | 是 |
create_time | 添加时间 | datetime | 是 |
表4-7 基金自选表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
jijin_id | 基金 | int(11) | 是 |
yonghu_id | 用户 | int(11) | 是 |
insert_time | 自选时间 | datetime | 是 |
create_time | 添加时间 | datetime | 是 |
表4-8 净值表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
jijin_id | 基金 | int(11) | 是 |
jingzhi_money | 净值 | decimal(10,2) | 是 |
insert_time | 日期 | date | 是 |
create_time | 创建时间 | timestamp | 是 |
表4-9 管理员表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | bigint(20) | 否 |
username | 用户名 | varchar(100) | 否 |
password | 密码 | varchar(100) | 否 |
role | 角色 | varchar(100) | 是 |
addtime | 新增时间 | timestamp | 否 |
表4-10 用户表
字段 | 注释 | 类型 | 空 |
id (主键) | 主键 | int(11) | 否 |
username | 账户 | varchar(200) | 是 |
password | 密码 | varchar(200) | 是 |
yonghu_name | 用户姓名 | varchar(200) | 是 |
yonghu_phone | 用户手机号 | varchar(200) | 是 |
yonghu_id_number | 用户身份证号 | varchar(200) | 是 |
yonghu_photo | 用户头像 | varchar(200) | 是 |
sex_types | 性别 | int(11) | 是 |
yonghu_email | 电子邮箱 | varchar(200) | 是 |
new_money | 余额 | decimal(10,2) | 是 |
create_time | 创建时间 | timestamp | 是 |
第五章 系统实现
这里主要是对系统设计实现进行描述,通过系统的设计和数据库的设计,通过编码后变成了可以进行操作的界面,让一切想法变成了结果,通过文字和具体程序操作界面的截图之间的配合,可以把功能更直观的描述起来。
5.1管理员功能实现
5.1.1 基金管理
管理员进入如图5-1所示的基金管理界面之后,管理员点击信息显示栏中最右侧的修改,删除,下架,上架按钮可依次完成基金信息的修改,删除,下架,上架等操作。
图5-1 基金管理界面
主要代码
@Autowired
private TokenService tokenService;
@Autowired
private DictionaryService dictionaryService;
//级联表service
@Autowired
private JijinjingliService jijinjingliService;
@Autowired
private YonghuService yonghuService;
@Autowired
private JingzhiService jingzhiService;
/**
* 后端列表
*/
@RequestMapping("/page")
public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永不会进入");
else if("用户".equals(role))
params.put("yonghuId",request.getSession().getAttribute("userId"));
params.put("jijinDeleteStart",1);params.put("jijinDeleteEnd",1);
if(params.get("orderBy")==null || params.get("orderBy")==""){
params.put("orderBy","id");
}
PageUtils page = jijinService.queryPage(params);
//字典表数据转换
List<JijinView> list =(List<JijinView>)page.getList();
for(JijinView c:list){
//修改对应字典表字段
dictionaryService.dictionaryConvert(c, request);
}
return R.ok().put("data", page);
}
/**
* 后端详情
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
JijinEntity jijin = jijinService.selectById(id);
if(jijin !=null){
//entity转view
JijinView view = new JijinView();
BeanUtils.copyProperties( jijin , view );//把实体数据重构到view中
//级联表
JijinjingliEntity jijinjingli = jijinjingliService.selectById(jijin.getJijinjingliId());
if(jijinjingli != null){
BeanUtils.copyProperties( jijinjingli , view ,new String[]{ "id", "createTime", "insertTime", "updateTime"});//把级联的数据添加到view中,并排除id和创建时间字段
view.setJijinjingliId(jijinjingli.getId());
}
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 后端保存
*/
@RequestMapping("/save")
public R save(@RequestBody JijinEntity jijin, HttpServletRequest request){
logger.debug("save方法:,,Controller:{},,jijin:{}",this.getClass().getName(),jijin.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永远不会进入");
Wrapper<JijinEntity> queryWrapper = new EntityWrapper<JijinEntity>()
.eq("jijinjingli_id", jijin.getJijinjingliId())
.eq("jijin_uuid_number", jijin.getJijinUuidNumber())
.eq("jijin_name", jijin.getJijinName())
.eq("jijin_types", jijin.getJijinTypes())
.eq("jijin_fengxian_types", jijin.getJijinFengxianTypes())
.eq("jijin_clicknum", jijin.getJijinClicknum())
.eq("jijin_tuijian_types", jijin.getJijinTuijianTypes())
.eq("shangxia_types", jijin.getShangxiaTypes())
.eq("jijin_delete", jijin.getJijinDelete())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
JijinEntity jijinEntity = jijinService.selectOne(queryWrapper);
if(jijinEntity==null){
Date date = new Date();
jijin.setJijinClicknum(1);
jijin.setShangxiaTypes(1);
jijin.setJijinDelete(1);
jijin.setInsertTime(date);
jijin.setCreateTime(date);
jijinService.insert(jijin);
//设置基金默认净值为1
JingzhiEntity jingzhiEntity = new JingzhiEntity();
jingzhiEntity.setCreateTime(date);
jingzhiEntity.setInsertTime(date);
jingzhiEntity.setJijinId(jijin.getId());
jingzhiEntity.setJingzhiMoney(1.0);
jingzhiService.insert(jingzhiEntity);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
/**
* 后端修改
*/
@RequestMapping("/update")
public R update(@RequestBody JijinEntity jijin, HttpServletRequest request){
logger.debug("update方法:,,Controller:{},,jijin:{}",this.getClass().getName(),jijin.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
// if(false)
// return R.error(511,"永远不会进入");
//根据字段查询是否有相同数据
Wrapper<JijinEntity> queryWrapper = new EntityWrapper<JijinEntity>()
.notIn("id",jijin.getId())
.andNew()
.eq("jijinjingli_id", jijin.getJijinjingliId())
.eq("jijin_uuid_number", jijin.getJijinUuidNumber())
.eq("jijin_name", jijin.getJijinName())
.eq("jijin_types", jijin.getJijinTypes())
.eq("jijin_fengxian_types", jijin.getJijinFengxianTypes())
.eq("jijin_clicknum", jijin.getJijinClicknum())
.eq("jijin_tuijian_types", jijin.getJijinTuijianTypes())
.eq("shangxia_types", jijin.getShangxiaTypes())
.eq("jijin_delete", jijin.getJijinDelete())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
JijinEntity jijinEntity = jijinService.selectOne(queryWrapper);
if("".equals(jijin.getJijinPhoto()) || "null".equals(jijin.getJijinPhoto())){
jijin.setJijinPhoto(null);
}
if(jijinEntity==null){
jijinService.updateById(jijin);//根据id更新
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Integer[] ids){
logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
ArrayList<JijinEntity> list = new ArrayList<>();
for(Integer id:ids){
JijinEntity jijinEntity = new JijinEntity();
jijinEntity.setId(id);
jijinEntity.setJijinDelete(2);
list.add(jijinEntity);
}
if(list != null && list.size() >0){
jijinService.updateBatchById(list);
}
return R.ok();
}
/**
* 批量上传
*/
@RequestMapping("/batchInsert")
public R save(String fileName){
logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);
try {
List<JijinEntity> jijinList = new ArrayList<>();//上传的东西
Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段
Date date = new Date();
int lastIndexOf = fileName.lastIndexOf(".");
if(lastIndexOf == -1){
return R.error(511,"该文件没有后缀");
}else{
String suffix = fileName.substring(lastIndexOf);
if(!".xls".equals(suffix)){
return R.error(511,"只支持后缀为xls的excel文件");
}else{
URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径
File file = new File(resource.getFile());
if(!file.exists()){
return R.error(511,"找不到上传文件,请联系管理员");
}else{
List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件
dataList.remove(0);//删除第一行,因为第一行是提示
for(List<String> data:dataList){
//循环
JijinEntity jijinEntity = new JijinEntity();
// jijinEntity.setJijinjingliId(Integer.valueOf(data.get(0))); //基金经理 要改的
// jijinEntity.setJijinUuidNumber(data.get(0)); //基金代码 要改的
// jijinEntity.setJijinName(data.get(0)); //基金名称 要改的
// jijinEntity.setJijinPhoto("");//照片
// jijinEntity.setJijinTypes(Integer.valueOf(data.get(0))); //基金类型 要改的
// jijinEntity.setJijinFengxianTypes(Integer.valueOf(data.get(0))); //基金风险类型 要改的
// jijinEntity.setJijinClicknum(Integer.valueOf(data.get(0))); //点击次数 要改的
// jijinEntity.setJijinTuijianTypes(Integer.valueOf(data.get(0))); //首页推荐 要改的
// jijinEntity.setJijinContent("");//照片
// jijinEntity.setShangxiaTypes(Integer.valueOf(data.get(0))); //是否上架 要改的
// jijinEntity.setJijinDelete(1);//逻辑删除字段
// jijinEntity.setInsertTime(date);//时间
// jijinEntity.setCreateTime(date);//时间
jijinList.add(jijinEntity);
//把要查询是否重复的字段放入map中
//基金代码
if(seachFields.containsKey("jijinUuidNumber")){
List<String> jijinUuidNumber = seachFields.get("jijinUuidNumber");
jijinUuidNumber.add(data.get(0));//要改的
}else{
List<String> jijinUuidNumber = new ArrayList<>();
jijinUuidNumber.add(data.get(0));//要改的
seachFields.put("jijinUuidNumber",jijinUuidNumber);
}
}
//查询是否重复
//基金代码
List<JijinEntity> jijinEntities_jijinUuidNumber = jijinService.selectList(new EntityWrapper<JijinEntity>().in("jijin_uuid_number", seachFields.get("jijinUuidNumber")).eq("jijin_delete", 1));
if(jijinEntities_jijinUuidNumber.size() >0 ){
ArrayList<String> repeatFields = new ArrayList<>();
for(JijinEntity s:jijinEntities_jijinUuidNumber){
repeatFields.add(s.getJijinUuidNumber());
}
return R.error(511,"数据库的该表中的 [基金代码] 字段已经存在 存在数据为:"+repeatFields.toString());
}
jijinService.insertBatch(jijinList);
return R.ok();
}
}
}
}catch (Exception e){
5.1.2 基金净值管理
管理员进入如图5-2所示的基金净值管理界面之后,管理员点击信息显示栏中最右侧的修改,删除按钮可依次完成基金净值信息的修改,删除等操作,管理员在当前界面也能添加基金净值,查询基金净值。
图5-2 基金净值管理界面
5.1.3 基金自选管理
管理员进入如图5-3所示的基金自选管理界面之后,管理员点击信息显示栏右侧的查看,删除按钮可依次完成基金自选信息的查看,删除等操作。
图5-3 基金自选管理界面
5.1.4 论坛管理
管理员进入如图5-4所示的论坛管理界面之后,管理员点击信息显示栏中最右侧的查看,查看帖子回复,删除按钮可依次完成论坛帖子信息的查看,查看帖子回复,删除等操作。
图5-4 论坛管理界面
5.2用户功能实现
5.2.1 基金信息
用户进入如图5-5所示的基金信息界面之后,用户把基金添加自选,查看基金的基金经理信息,购买本界面的基金等。
大家点赞、收藏、关注、评论啦 其他的定制服务 下方联系卡片↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 或者私信作者