当前位置: 首页 > article >正文

移动应用开发项目——图书影片管理系统【安卓项目|前后端】

就把图书影片管理系统叫做熊猫推荐吧~
源码相关请私信

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表与视图的设计

图书表

字段名数据类型含义说明空值情况
idint图书编号主关键字
namevarchar图书名字
authorvarchar图书作者

影视表、管理员表、书评表、影评表、电影图片表、演职员表、演职员参演表、推荐评论表、管理员表…

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 测试数据及结果

博主写这个项目时候也是小白,项目的封装等专业性不够,但是项目可以正常运行,希望大家可以交流一起学习


http://www.kler.cn/a/385862.html

相关文章:

  • PaoluGPT——千里挑一
  • 数据研发基础 | 什么是流批一体
  • 「Mac玩转仓颉内测版5」入门篇5 - Cangjie控制结构(上)
  • 直流保护电路设计及保护器件参数说明和选型
  • ElementUI的日期组件中禁止选择小时、分钟、秒
  • apk反编译修改教程系列-----apk应用反编译中AndroidManifest.xml详细代码释义解析 包含各种权限 代码含义【二】
  • Ubuntu /etc/sudo.conf is owned by uid 1000, should be 0 的一种解决方法
  • 掌握 .NET 8 中最小 API 的单元和集成测试:高质量代码的最佳实践
  • CTF —— 网络安全大赛
  • ABAP开发-12、Dialog屏幕开发_1
  • 设计模式-构建者
  • IO作业day4
  • redis:list列表命令和内部编码
  • jenkins使用slave节点进行node打包报错问题处理
  • 【JAVA毕业设计】基于Vue和SpringBoot的技术交流分享平台
  • C++ 游戏开发:打造高效、性能优越的游戏世界
  • 【观察】华为持续投入开源开放“结硕果”,openEuler走出操作系统“创新路”...
  • 怎么对 PDF 添加权限密码或者修改密码-免费软件分享
  • .NET中通过C#实现Excel与DataTable的数据互转
  • Docker使用相关记录
  • 【PGCCC】postgresql 缓存池并发设计
  • 如何准备验厂及验厂证书有效期
  • 开源模型应用落地-glm模型小试-glm-4-9b-chat-Gradio集成(三)
  • 什么是jQuery
  • 光耦合器在现代电子学中的关键应用
  • H5播放器EasyPlayer.js 流媒体播放器是否支持npm(yarn) install 安装?