一、前言介绍:
本次设计任务是要设计一个基于协同过滤算法的电影推荐系统,通过这个系统能够满足电影推荐的管理功能。系统的主要包括首页,个人中心,用户管理,电影分类管理,免费电影管理,付费电影管理,电影订单管理,电影论坛,系统管理等功能。
管理员可以根据系统给定的账号进行登录,登录后可以进入电影推荐系统对个性化智能电影推荐所有模块进行管理。包括查看和修改自己的个人信息以及登录密码。
该系统为每一个用户都分配了一个用户账号,用户通过账号的登录可以在系统中查看个性化智能电影推荐信息及对个人信息进行修改等功能。
二、系统设计:
2.1 系统设计原则:
本电影推荐系统采用 Java 技术,Mysql 数据库开发,充分保证了系统稳定性、完整性。
电影推荐系统设计与实现的设计思路如下:
1.操作简单方便,页面布局简单清晰、界面安全良好:,便于查询电影推荐系统的相关信息。
2.即时可视性:电影推荐系统的信息处理将在相应的位置即时可用,以实现“即时发布、即时生效”的系统功能。
功能完善:个人中心,用户管理,电影分类管理,免费电影管理,付费电影管理,电影订单管理,我的电影管理,电影论坛,系统管理等功能等模块的修改和维护。
2.2 系统结构设计:
系统设计是把本系统的各项功能需求进行细化,而转换为软件系统表示的一个设计过程,在对目标系统的研究分析之后,做出整个系统平台的总体规划,进而对用例中各个对象进一步地合理精细设计。为降低整个系统的复杂度,而使其更加便于修改,提高代码的可读性,我们会将系统模块化,模块间保持相对独立,且每个模块只完成一个子功能,并且与其他模块通过简单的接口链接,即高内聚低耦合原则,而使整个系统能够拥有一个高性能的结构,这边是系统概要设计最重要的目的。在之前的需求分析的基础上,本电影推荐系统结构,如下图所示。
2.3 协同过滤算法:
协同过滤算法是一种较为著名和常用的推荐算法,它基于对用户历史行为数据的挖掘发现用户的喜好偏向,并预测用户可能喜好的产品进行推荐。也就是常见的“猜你喜欢”,和“购买了该商品的人也喜欢”等功能。它的主要实现由:
●根据和你有共同喜好的人给你推荐
●根据你喜欢的物品给你推荐相似物品
●根据以上条件综合推荐
因此可以得出常用的协同过滤算法分为两种,基于用户的协同过滤算法(user-based collaboratIve filtering),以及基于物品的协同过滤算法(item-based collaborative filtering)。特点可以概括为“人以类聚,物以群分”,并据此进行预测和推荐。
三、数据设计:
在查询时,应保证所有满足条件的记录都能查到。数据库记录通常在几百条以上,如有遗漏将会对客户的统计造成影响。一般操作的响应时间应该在 1-2 秒内。采用菜单界面,对会员比较友好。通过 E-R 图来设计并展示数据的概念模型,
3.1 用户实体属性:
3.2 电影实体属性:
3.3 数据逻辑设计:
四、功能截图:
4.1 登录注册:
4.2 用户首页:
4.2.1 首页:
电影推荐系统,在系统首页可以查看首页,免费电影,付费电影,电影论坛,电影资讯,个人中心等内容,并进行详细操作。
4.2.2 免费电影:
免费电影,在免费电影页面可以查看电影编号,电影分类,评分,开映时间,时长,导演,主演,点击次数等信息,并进行赞一下,踩一下,点我收藏等操作
4.2.3 付费电影:
付费电影,在免费电影页面可以查看电影编号,电影分类,评分,开映时间,时长,导演,主演,点击次数等信息,并进行赞一下,踩一下,点我收藏等操作
查看详情!进行预览播放视频!收藏 点餐 踩等功能!收藏越多权重越高
详情查看以及评论等操作
4.2.4 电影论坛:
4.2.5 电影资讯:
4.2.6 个人中心:
个人中心,在个人中心页面通过填写用户名,姓名,密码,性别,年龄,手机号等内容进行更新信息,还可以根据需要对我的发布,我的收藏进行相对应操作
4.3 用户后端:
4.3.1 个人信息:
4.3.2 电影订单:
4.4 管理员后端:
可以对首页,个人中心,用户管理,电影分类管理,免费电影管理,付费电影管理,电影订单管理、电影论坛,系统管理等功能进行相应的操作
4.4.1 用户管理:
用户管理,在用户管理页面可以对索引,用户名,姓名,性别,年龄,手机号等内容进行详情,修改和删除操作
4.4.2 电影分类:
4.4.3 免费电影:
免费电影管理,在免费电影管理页面可以对索引,电影编号,电影名称,视频,海报,评分,开映时间,时长,主演,导演等内容进行详情,修改,查看评论和删除操作
4.4.4 付费电影:
付费电影管理,在付费电影管理页面可以对索引,电影编号,电影名称,预告片,价格,海报,评分,开映时间,时长,主演,导演等内容进行详情,修改,查看评论和删除操作
4.4.5 电影订单:
电影订单管理,在电影订单管理页面可以对 索引,订单编号,电影编号,电影名称,价格,用户名,姓名,手机号,购买时间,是否支付等内容进行详情,我的电影,修改和删除等操作
4.4.7 电影论坛:
4.4.8 系统管理:
4.4.9 首页轮播图:
五、代码实现:
5.1 用户登录:
form.on('submit(login)', function(data) {
data = data.field;
if (vue.roles.length!=1) {
if (!data.role) {
layer.msg('请选择登录用户类型', {
time: 2000,
icon: 5
});
return false;
}
} else {
data.role = vue.roles[0].tableName;
}
http.request(data.role + '/login', 'get', data, function(res) {
layer.msg('登录成功', {
time: 2000,
icon: 6
});
// 登录凭证
localStorage.setItem('Token', res.token);
var roleName = "";
if(typeof(jquery('#role:checked').attr('title')) == "undefined") {
roleName = vue.roles[0].roleName;
} else {
roleName = jquery('#role:checked').attr('title');
}
localStorage.setItem('role', roleName);
// 当前登录用户角色
localStorage.setItem('userTable', data.role);
localStorage.setItem('sessionTable', data.role);
// 用户名称
localStorage.setItem('adminName', data.username);
http.request(data.role + '/session', 'get', {}, function(res) {
// 用户id
localStorage.setItem('userid', res.data.id);
if(res.data.vip) {
localStorage.setItem('vip', res.data.vip);
}
// 路径访问设置
window.location.href = '../../index.html';
})
});
return false
});
复制代码
5.2 文件上传;
/**
* 上传文件
*/
@RequestMapping("/upload")
public R upload(@RequestParam("file") MultipartFile file, String type,HttpServletRequest request) throws Exception {
if (file.isEmpty()) {
throw new EIException("上传文件不能为空");
}
String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
String fileName = new Date().getTime()+"."+fileExt;
File dest = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
file.transferTo(dest);
// FileUtils.copyFile(dest, new File("D:\\ssmpiv99\\src\\main\\webapp\\upload"+"/"+fileName)); /**修改了路径以后请将该行最前面的//注释去掉**/
if(StringUtils.isNotBlank(type) && type.equals("1")) {
ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
if(configEntity==null) {
configEntity = new ConfigEntity();
configEntity.setName("faceFile");
configEntity.setValue(fileName);
} else {
configEntity.setValue(fileName);
}
configService.insertOrUpdate(configEntity);
}
return R.ok().put("file", fileName);
}
复制代码
5.3 电影订单:
/**
* 电影订单
* 后端接口
* @author
* @email
* @date 2022-08-06 21:42:07
*/
@RestController
@RequestMapping("/dianyingdingdan")
public class DianyingdingdanController {
@Autowired
private DianyingdingdanService dianyingdingdanService;
/**
* 前端列表
*/
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params,DianyingdingdanEntity dianyingdingdan,
HttpServletRequest request){
EntityWrapper<DianyingdingdanEntity> ew = new EntityWrapper<DianyingdingdanEntity>();
PageUtils page = dianyingdingdanService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, dianyingdingdan), params), params));
return R.ok().put("data", page);
}
/**
* 列表
*/
@RequestMapping("/lists")
public R list( DianyingdingdanEntity dianyingdingdan){
EntityWrapper<DianyingdingdanEntity> ew = new EntityWrapper<DianyingdingdanEntity>();
ew.allEq(MPUtil.allEQMapPre( dianyingdingdan, "dianyingdingdan"));
return R.ok().put("data", dianyingdingdanService.selectListView(ew));
}
/**
* 查询
*/
@RequestMapping("/query")
public R query(DianyingdingdanEntity dianyingdingdan){
EntityWrapper< DianyingdingdanEntity> ew = new EntityWrapper< DianyingdingdanEntity>();
ew.allEq(MPUtil.allEQMapPre( dianyingdingdan, "dianyingdingdan"));
DianyingdingdanView dianyingdingdanView = dianyingdingdanService.selectView(ew);
return R.ok("查询电影订单成功").put("data", dianyingdingdanView);
}
/**
* 前端详情
*/
@RequestMapping("/detail/{id}")
public R detail(@PathVariable("id") Long id){
DianyingdingdanEntity dianyingdingdan = dianyingdingdanService.selectById(id);
return R.ok().put("data", dianyingdingdan);
}
/**
* 前端保存
*/
@RequestMapping("/add")
public R add(@RequestBody DianyingdingdanEntity dianyingdingdan, HttpServletRequest request){
dianyingdingdan.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
//ValidatorUtils.validateEntity(dianyingdingdan);
dianyingdingdanService.insert(dianyingdingdan);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody DianyingdingdanEntity dianyingdingdan, HttpServletRequest request){
//ValidatorUtils.validateEntity(dianyingdingdan);
dianyingdingdanService.updateById(dianyingdingdan);//全部更新
return R.ok();
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] ids){
dianyingdingdanService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
}
复制代码
5.4 协同过滤算法主要实现:
/**
* 协同算法(按收藏推荐)
*/
@RequestMapping("/autoSort")
public R autoSort2(@RequestParam Map<String, Object> params,MianfeidianyingEntity mianfeidianying, HttpServletRequest request){
String userId = request.getSession().getAttribute("userId").toString();
String inteltypeColumn = "dianyingfenlei";
List<StoreupEntity> storeups = storeupService.selectList(new EntityWrapper<StoreupEntity>().eq("type", 1).eq("userid", userId).eq("tablename", "mianfeidianying").orderBy("addtime", false));
List<String> inteltypes = new ArrayList<String>();
Integer limit = params.get("limit")==null?10:Integer.parseInt(params.get("limit").toString());
List<MianfeidianyingEntity> mianfeidianyingList = new ArrayList<MianfeidianyingEntity>();
//去重
if(storeups!=null && storeups.size()>0) {
for(StoreupEntity s : storeups) {
mianfeidianyingList.addAll(mianfeidianyingService.selectList(new EntityWrapper<MianfeidianyingEntity>().eq(inteltypeColumn, s.getInteltype())));
}
}
EntityWrapper<MianfeidianyingEntity> ew = new EntityWrapper<MianfeidianyingEntity>();
params.put("sort", "id");
params.put("order", "desc");
PageUtils page = mianfeidianyingService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, mianfeidianying), params), params));
List<MianfeidianyingEntity> pageList = (List<MianfeidianyingEntity>)page.getList();
if(mianfeidianyingList.size()<limit) {
int toAddNum = (limit-mianfeidianyingList.size())<=pageList.size()?(limit-mianfeidianyingList.size()):pageList.size();
for(MianfeidianyingEntity o1 : pageList) {
boolean addFlag = true;
for(MianfeidianyingEntity o2 : mianfeidianyingList) {
if(o1.getId().intValue()==o2.getId().intValue()) {
addFlag = false;
break;
}
}
if(addFlag) {
mianfeidianyingList.add(o1);
if(--toAddNum==0) break;
}
}
}
page.setList(mianfeidianyingList);
return R.ok().put("data", page);
}
复制代码
六、项目总结:
历经六个月左右的时间,本次的毕业设计已画上了句号。原本以为完成一个系统会很顺利,因为在之前课上,也曾动手操作过相关的模块编写,但当真正接触到一个完整的系统时,发现并没有想象地那么简单。首先,以前实践过的只是单独的模块,而这次,是一个庞大的系统,许多细节不容忽视,有时候稍不留意的一个小错误,会致使整个系统都运行不起来,而查找错误的过程又漫长且艰辛,这也正是经验不足所导致的。在整个系统开发过程中,也查阅了很多书籍和相关资料,这让我不但巩固了原本的知识,同时还学习到了一些新的知识,这让我受益匪浅。
此次系统从整体看来,已基本达到预期的设计目的,能够实现基本的功能,但相较于市场的一些优秀网站而言,还是有许多不足的地方。遗憾的是,由于时间的有限,已经不允许再投入更多的时间和精力进行研究开发。相信在以后的工作中,我会接触到更多相关的知识,会更丰富自身的经验,我希望到时能够在此基础上完成一个丰富完整的学习网站,这将对我有很大的意义。
通过这次的毕业设计,我学到了很多,除了学识方面的知识,在态度上也有了很大的转变,细心和耐心是整个开发过程中最重要的两件事。我也在跟随着系统的完善而成长,这次毕业设计考核地也不单单是所学的知识,也同样在衡量着面对困难时的态度。
评论