移动应用开发项目——图书影片管理系统【安卓项目|前后端】
就把图书影片管理系统叫做熊猫推荐吧~
源码相关请私信
1. 问题描述
随着现代生活节奏的不断加快,许多人在阅读了大量书籍或观看了许多电影后,依然感到与他人沟通时所拥有的知识有限。为了帮助用户分享自己的见解、发现新的知识,我们设计了一个全新的平台。该平台旨在帮助人们分享和发现书籍、电影等内容,并促进用户之间的互动。
现代社会中,评论已成为人们互动和交流的重要方式。在本项目中,用户之间可以进行多种形式的互动。例如,用户在平台上发现自己喜爱的书籍或电影后,可以点击查看详细信息,并在下方发表自己的评论,寻找志同道合的朋友。平台内容的生成始于用户主动分享的书单、电影推荐及个人评论。这些内容构成了多个基础节点,随着平台技术功能的支持(如最受关注的书籍、最受欢迎的评论或平台推荐等),这些节点之间逐渐建立联系,从而形成了内容的基本网络。
对于被动型用户(即仅浏览内容、不主动创作的用户)而言,平台同样提供了价值,他们可以通过浏览其他用户的评论和推荐,发现符合自己兴趣的书籍或电影。
2. 需求分析
在信息化时代,知识的不断更新与扩展已经成为人们日常生活中不可忽视的一部分。与通过专业网站或搜索引擎获取知识的传统方式不同,本项目为用户提供了一种新的知识拓展路径。这条路径不仅具备内在的逻辑联系,而且具有更广泛的跨领域性。其核心在于:知识扩展并不以专业分类为基础,而是以“人”为中心。
即使是几位有相同兴趣的人,他们对相同书单或电影的感受也可能不同。通过本平台,用户可以将自己的感受转化为评论与他人分享,这种基于差异化的评论为其他用户提供了新的知识扩展线索,激发更多的发散性思维。因此,本平台倡导的“先求同,再求异”模式,成为用户进行知识扩展的重要方式。
与传统的网上书店推荐书籍的方式不同,本项目强调评论和人际关系的作用,这不仅能更好地满足用户探索新知识的需求,还能在知识学习上取得更加显著的效果。
3. 概要设计
3.1 系统架构
熊猫推荐系统可以分为两大主要部分:安卓端和管理端。
-
安卓端:用户通过手机访问系统时,会触发一系列操作。系统从数据库中获取数据,并渲染成安卓端的界面进行展示,提供互动体验。
-
管理端:管理端是面向管理员的后台系统,根据安卓端用户的需求,管理人员可以通过管理端修改数据库中的数据,确保系统内容的实时更新。
系统架构的设计采用了以下技术组合:
- Android客户端:基于Android 2.2(AS2.2)开发,利用Eclipse开发环境进行构建。
- PC端后台管理系统:采用Vue框架与SpringBoot进行开发,前端界面使用VueElementUI进行美化和增强用户体验。
- 数据库:使用MySQL数据库,根据功能对数据进行分区管理,以优化性能。
数据库的设计将数据划分为多个独立的表格,每个表格对应系统的一个功能模块。这种分区策略能够有效减轻数据库的负载,提高系统的响应速度与稳定性。
3.2流程图
3.3 UML建模设计
包括系统涉众图、业务过程图、用例图、顺序图、时序图、类图
3.4 E-R图
3.5 表的设计
3.5.1关系模型
关系名 | 属性及码 | 其他约束条件 |
---|---|---|
用户 | 用户编号、姓名、类型、等级、密码 | 1、属性都不为空2、类型为用户 |
图书 | 图书编号、书名、作者、出版社、出版日期、价格、国际标准书号、类型、评分、内容简介、作者简介、宣传图 | 1、属性都不为空2、类型为“新书速递、最受关注图书、电子书”其中一种 3、评分5以内 |
… | … | … |
3.5.2表与视图的设计
图书表
字段名 | 数据类型 | 含义说明 | 空值情况 |
---|---|---|---|
id | int | 图书编号 | 主关键字 |
name | varchar | 图书名字 | 否 |
author | varchar | 图书作者 | 否 |
… | … | … | … |
影视表、管理员表、书评表、影评表、电影图片表、演职员表、演职员参演表、推荐评论表、管理员表…
4. 详细设计
4.1 熊猫图书模块
熊猫图书模块是用户获取图书信息和进行互动的核心部分。用户可以通过该模块查看市面上最新出版的图书,了解其详细信息,并参与评论与评分。模块的主要功能包括:
- 新书速递:展示市面上最新出版的图书详情,包括书名、作者、简介等。用户可以查看书籍信息,发表自己的读后感受,并参与评分。
- 图书详情页:用户点击书籍时,进入该书的详细页面,展示该书的详细内容,如书籍简介、作者信息、评分等,以及用户评论。
4.1.1 设计思路
4.1.2 关键代码
安卓端关键代码
- 加载新书速递:此代码片段展示了如何在安卓端加载和展示新书速递列表。数据通过
BaseAdapter
适配器渲染在列表中,用户可以点击某本书进入图书详情页。
// 加载新书速递
private void initNewBook() {
BaseAdapter ba = new BaseAdapter() {
@Override
public int getCount() {
return newbookInfo.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String[] strs = newbookInfo.get(position);
String name = strs[1];
String logo = strs[11];
String like = strs[2];
LinearLayout menu_item = (LinearLayout) LayoutInflater.from(getActivity()).inflate(R.layout.home_menu_item, null);
int width = Utils.getScreenWidth(getActivity()) * 7 / 15;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, width);
ImageView iv = (ImageView) menu_item.findViewById(R.id.image);
iv.setLayoutParams(params);
imageLoader.thumbnailExcute(iv, logo);
TextView cname = (TextView) menu_item.findViewById(R.id.name);
cname.setText(name);
TextView slike = (TextView) menu_item.findViewById(R.id.like);
slike.setText(like);
return menu_item;
}
};
menu_ll.setAdapter(ba);
menu_ll.setSelector(new ColorDrawable(Color.TRANSPARENT));
menu_ll.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
String[] strs = newbookInfo.get(arg2);
String id = strs[0];
Intent intent = new Intent(getActivity(), Menushow.class);
intent.putExtra("menu_id", id);
startActivity(intent);
}
});
}
- 获取新书速递数据:通过
NetInfoUtil
获取最新的图书信息,包括书名、作者、价格等数据。
public static List<String[]> getNewBook() {
try {
cacheConnect();
cachedos.writeUTF(Constant.GET_NEW_BOOK);
message = cachedin.readUTF();
} catch (Exception e) {
e.printStackTrace();
} finally {
cacheDisConnect();
}
return StrListChange.StrToList(message);
}
图书详情页面核心代码
- 请求图书详情:通过
Handler
接收并处理来自后台服务器的图书详细信息,更新图书详情页面。
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle = msg.getData();
String[] str = bundle.getStringArray("str");
String process = bundle.getString("process", null);
if (str != null) {
if (!str.equals(Constant.NO_MESSAGE)) {
loadReady(str);
}
}
imageDownLoader.cancelTask();
}
};
new Thread() {
@Override
public void run() {
try {
String[] str = null;
String mmsg = NetInfoUtil.getMenuDetC(menu_id);
str = mmsg.split("<#>");
Bundle bundle = new Bundle();
bundle.putStringArray("str", str);
Message msg = new Message();
msg.setData(bundle);
mHandler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
- 获取图书详细信息:服务器端根据传入的
menuId
获取相应的图书详细信息。
public static String getMenuDetC(String menuId) {
String message = null;
try {
cacheConnect();
cachedos.writeUTF(Constant.SEAECH_MENU_YEARS + menuId);
message = cachedin.readUTF();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
cacheDisConnect();
}
return message;
}
服务器端关键代码
- 获取新书速递:服务器端根据数据库查询返回最新的图书信息,并通过缓存与客户端交互。
public static String getNewBook() {
Connection con = getConnection();
Statement st = null;
ResultSet rs = null;
PreparedStatement pst = null;
ResultSet prs = null;
try {
st = con.createStatement();
String sql = "select id from book where type = '新书速递' order by id limit 6";
rs = st.executeQuery(sql);
pst = con.prepareStatement("select name,author,publisher,year,price,isbn,type,score,contentInfo,authorInfo,image from book where id=?");
StringBuffer sb = new StringBuffer();
while (rs.next()) {
int id = rs.getInt(1);
pst.setInt(1, id);
prs = pst.executeQuery();
if (prs.next()) {
String name = prs.getString(1);
String author = prs.getString(2);
String publisher = prs.getString(3);
String year = prs.getString(4);
String price = prs.getString(5);
String isbn = prs.getString(6);
String type = prs.getString(7);
String score = prs.getString(8);
String contentInfo = prs.getString(9);
String authorInfo = prs.getString(10);
String logo = prs.getString(11);
sb.append(id + "<#>" + name + "<#>" + author + "<#>" + publisher + "<#>" + year + "<#>" + price + "<#>" + isbn + "<#>" + type + "<#>" + score + "<#>" + contentInfo + "<#>" + authorInfo + "<#>" + logo + "<%>");
}
}
if (sb.length() > 0) {
return sb.substring(0, sb.length() - 3);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {prs.close();} catch (SQLException e) {e.printStackTrace();}
try {rs.close();} catch (Exception e) {e.printStackTrace();}
try {st.close();} catch (SQLException e) {e.printStackTrace();}
try {con.close();} catch (SQLException e) {e.printStackTrace();}
}
return Constant.NO_MESSAGE;
}
- 根据图书ID查询图书详情:根据传入的
bookId
查询数据库中的图书信息,并将其拼接成特定格式返回。
public static String searchBookYears(String bookId) {
Connection con = getConnection();
Statement st = null;
ResultSet rs = null;
try {
st = con.createStatement();
String sql = "select id,name,author,publisher,year,price,isbn,type,score,contentInfo,authorInfo,image from book where id =" + bookId;
rs = st.executeQuery(sql);
StringBuffer message = new StringBuffer();
while (rs.next()) {
for (int i = 1; i <= 12; i++) {
message.append(rs.getString(i) + "<#>");
}
if (message.length() > 0) {
return message.substring(0, message.length() - 3).toString();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {rs.close();} catch (Exception e) {e.printStackTrace();}
try {st.close();} catch (SQLException e) {e.printStackTrace();}
try {con.close();} catch (SQLException e) {e.printStackTrace();}
}
return Constant.NO_MESSAGE;
}
4.1.3 界面
熊猫图书模块
书籍详情页
图书评论页
4.2 熊猫影视模块
…
4.3 熊猫推荐后台管理
<template>
<el-card>
<el-row :gutter="20" class="search" style="margin-bottom: 20px">
<el-col :span="17"> <h2 style="margin: 0">用户列表</h2> </el-col>
<el-col :span="5">
<el-input v-model="select" placeholder="请输入筛选关键词" />
</el-col>
<el-col :span="2"><el-button type="primary">搜索</el-button></el-col>
</el-row>
<el-table :stripe="true" border :data="data" style="width: 100%;height:550px">
<el-table-column type="selection" width="50" />
<el-table-column type="index" :index="calcIdx" width="80" />
<el-table-column prop="id" label="ID" width="200" />
<el-table-column prop="name" label="姓名" width="200" />
<el-table-column prop="type" label="用户类型" width="200" />
<el-table-column prop="memlevel" label="会员等级" width="200" />
<el-table-column label="操作" width="160">
<template slot-scope="scope">
<el-button type="text" @click="Update(scope.row)">修改</el-button>
<el-button
type="text"
style="margin-left: 30px"
@click="DeleteYes(scope.row.id)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="pageSize"
layout="total, prev, pager, next, jumper"
:total="tableData.length"
>
</el-pagination>
<el-dialog title="用户信息" :visible.sync="dialogFormVisible">
<el-form :model="user">
<el-form-item label="ID:" :label-width="formLabelWidth">
<el-input v-model="user.id" autocomplete="off" disabled></el-input>
</el-form-item>
<el-form-item label="姓名:" :label-width="formLabelWidth">
<el-input v-model="user.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="用户类型:" :label-width="formLabelWidth">
<el-select
v-model="user.type"
placeholder="请选择用户类型"
style="width: 100%"
>
<el-option label="超级管理员" value="超级管理员"></el-option>
<el-option label="用户" value="用户"></el-option>
</el-select>
</el-form-item>
<el-form-item label="会员等级:" :label-width="formLabelWidth">
<el-input v-model="user.memlevel" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="determineUpdate">确 定</el-button>
</div>
</el-dialog>
<el-dialog
title="删除提示"
:visible.sync="dialogFormVisible1"
style="width: 500px; margin-left: 550px; margin-top: 100px"
>
<div>您确定要删除吗?</div>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible1 = false">取 消</el-button>
<el-button type="primary" @click="Delete">确 定</el-button>
</div>
</el-dialog>
</el-card>
</template>
queryData() {
this.tempData = [];
this.tableData = [];
this.$http.post("api/doubanuser/queryAllUsers").then((resp) => {
console.log(resp);
this.tableData = resp.data;
this.tempData = resp.data;
});
},
添加用户:
addUser() {
console.log(this.user);
this.$http
.post("api/doubanuser/insertUser", {
id: this.user.id,
name: this.user.name,
type: this.user.type,
memlevel: this.user.memlevel,
password: "123456",
})
.then((resp) => {
this.$notify({
title: "添加成功",
message: "用户添加成功!",
type: "success",
});
});
}
…
5 测试数据及结果
…
博主写这个项目时候也是小白,项目的封装等专业性不够,但是项目可以正常运行,希望大家可以交流一起学习