微信小程序|考试系统|基于微信小程序和SpringBoot+VUE的智能在线考试系统毕业设计

简介: 微信小程序|考试系统|基于微信小程序和SpringBoot+VUE的智能在线考试系统毕业设计

项目编号:BS-GX-067

一,项目简介

随着计算机技术的不断发展,我们的日常生活和工作都与计算机技术的关系越来越密切。计算机技术的发展改变了我们日常的生活和工作习惯,也改变了社会的发展速度,使得我们的生活更加便利和高效。伴随着计算机技术发展起来的互联网技术将我们的生活带领进信息化时代,改变了我们的学习和工作环境,例如我们经常面对的考试也随着互联网技术的发展产生了改变,伴随着信息技术的发展,在线无纸化的考试系统应运而生,不仅彻底改变了传统纸质考试的习惯和环境,更是提高了考试效率,保证了考试效果,达到了考试目的[1]。传统的纸质考试具有很多局限性和不足,主要包括以下几点:

1.传统纸质考试需要较多的人力资源和时间资源进行题目的设定,同时题目的难易程度和考核价值水平很难达到基本的要求;

2.传统纸质考试的阅卷采用人工的方式,人工阅卷难免会出现阅卷差错或者分数合算差错,这也会对考试的效果造成影响;

3.传统纸质考试的人工阅卷模式也会浪费大量的人力资源和时间资源,不能保证工作效率和工作质量;

4.传统纸质考试对考试的总结能力较差,不能够全面具体的分析考试结果,教师也很难得到基本的考试结果分析的数据信息,而这些数据信息是提高教学质量和教学效果的关键因素;

5.传统纸质考试对考试时间以及考试纪律的要求不能达到统一,这也会影响到考试的公平性。根据以上分析的传统纸质考试的不足之处,新型的结合计算机技术以及互联网技术的在线考试系统应运而生,不仅通过一种新的技术解决了传统纸质考试的基本问题,还提供了一种新的考试思路和考试理念,纠正了传统纸质考试的弊端,提供更加合理有效的考试过程。

二,环境介绍

三,技术说明

后端系统 前端系统 微信小程序
spring-boot 2.1.6.RELEASE vue 采用新版,使用了vue-cli4搭建的系统 iView 主题样式
spring-boot-security 用户登录验证 element-ui 最流行的vue UI框架
undertow web容器 vue-element-admin 模版
mybatis/mybatis_plus echarts 图表统计
hikari 速度最快的数据库连接池 ueditor 题目编辑器

四,功能列表

4.1 学生系统功能

模块 介绍
登录 用户名、密码
注册 年级、用户名、密码
任务中心 管理员发布的年级任务,每个学生只能做一次
考试 题干支持文本、图片、数学公式、表格等,学生答题支持:文本
固定试卷 可重复练习、自行批改的试卷
时段试卷 在时间限制内,可重复练习、自行批改的试卷
考试记录 查看答卷记录和试卷信息
错题本 答错题目会自动进入错题本,显示题目基本信息
个人信息 显示学生个人资料
更新信息 修改个人资料、头像
个人动态 显示用户最近的个人动态
消息中心 用于接收管理员发送的消息

4.2 管理系统功能

模块 介绍
登录 用户名、密码
主页 试卷总数、题目总数、用户活跃度、题目月数量
学生列表 显示系统所有的学生,新增、修改、删除、禁用
管理员列表 显示系统所有的管理员,新增、修改、删除、禁用
学科列表 学科查询、修改、删除
学科创编 创建学科
试卷列表 试卷查询、修改、删除
试卷创编 创建的试卷为时段试卷、固定试卷、任务试卷
题目列表 题目查询、修改、删除
题目创建 题目支持单选题、多选题、判断题、填空题、简答题,题干支持文本、图片、表格、数学公式
任务列表 任务查询、修改、删除
消息列表 显示已发送的消息,消息已读人数等信息
消息发送 发送消息给多个用户
用户日志 显示所有用户日志
个人资料 显示管理员用户名、真实姓名
时间线 显示管理员创建时间
修改资料 修改姓名、手机号

4.3 小程序功能

模块 介绍
登录 用户登录登出功能,登录会自动绑定微信账号,登出会解绑
注册 年级、用户名、密码
任务中心 管理员发布的年级任务,每个学生只能做一次
考试 题干支持文本、图片、数学公式、表格等,学生答题支持:文本
固定试卷 可重复练习、自行批改的试卷
时段试卷 在时间限制内,可重复练习、自行批改的试卷
考试记录 查看答卷记录和试卷信息
错题本 答错题目会自动进入错题本,显示题目基本信息
个人信息 显示学生个人资料
更新信息 修改个人资料、头像
个人动态 显示用户最近的个人动态
消息中心 用于接收管理员发送的消息

五,数据库设计

仅展示部分数据库字段设计

5.1 试卷表

字段名 类型 注释
id int
name varchar 试卷名称
subject_id int 学科
paper_type int 试卷类型( 1.固定试卷 4.时段试卷 6.任务试卷 )
grade_level int 年级
score int 试卷总分(千分制)
question_count int 题目数量
suggest_time int 建议时长(分钟)
limit_start_time datetime 时段试卷 开始时间
limit_end_time datetime 时段试卷 结束时间
frame_text_content_id int 试卷框架 内容为JSON
create_user int
create_time datetime
deleted bit
task_exam_id int

5.2 试卷答案表

字段名 类型 注释
id int
exam_paper_id int
paper_name varchar 试卷名称
paper_type int 试卷类型( 1.固定试卷 4.时段试卷 6.任务试卷 )
subject_id int 学科
system_score int 系统判定得分
user_score int 最终得分(千分制)
paper_score int 试卷总分
question_correct int 做对题目数量
question_count int 题目总数量
do_time int 做题时间(秒)
status int 试卷状态(1待判分 2完成)
create_user int 学生
create_time datetime 提交时间
task_exam_id int

5.3 题目表

字段名 类型 注释
id int
question_type int 1.单选题 2.多选题 3.判断题 4.填空题 5.简答题
subject_id int 学科
score int 题目总分(千分制)
grade_level int 级别
difficult int 题目难度
correct text 正确答案
info_text_content_id int 题目 填空、 题干、解析、答案等信息
create_user int 创建人
status int 1.正常
create_time datetime 创建时间
deleted bit

5.4 学科表

字段名 类型 注释
id int
name varchar 语文 数学 英语 等
level int 年级 (1-12) 小学 初中 高中 大学
level_name varchar 一年级、二年级等
item_order int 排序
deleted bit

5.5 用户表

字段名 类型 注释
id int
user_uuid varchar
user_name varchar 用户名
password varchar
real_name varchar 真实姓名
age int
sex int 1.男 2女
birth_day datetime
user_level int 学生年级(1-12)
phone varchar
role int 1.学生 3.管理员
status int 1.启用 2禁用
image_path varchar 头像地址
create_time datetime
modify_time datetime
last_active_time datetime
deleted bit 是否删除
wx_open_id varchar 微信openId

5.6 用户日志表

字段名 类型 注释
id int
user_id int 用户id
user_name varchar 用户名
real_name varchar 真实姓名
content text 内容
create_time datetime 时间

其他表的设计省略............

六,系统展示

6.1 后台管理

主页

用户管理

试卷管理

题目管理

添加题目

添加试卷

任务管理

教育管理

成绩管理

6.2 学生端

首页登录与注册

学生端首页

试卷中心

考试记录

错题本

个人中心

6.3 小程序端

登录与注册

首页

试卷考试

考试记录

我的

七,核心代码展示

@Service
public class TaskExamServiceImpl extends BaseServiceImpl<TaskExam> implements TaskExamService {
    protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();
    private final TaskExamMapper taskExamMapper;
    private final TextContentService textContentService;
    private final ExamPaperMapper examPaperMapper;
    @Autowired
    public TaskExamServiceImpl(TaskExamMapper taskExamMapper, TextContentService textContentService, ExamPaperMapper examPaperMapper) {
        super(taskExamMapper);
        this.taskExamMapper = taskExamMapper;
        this.textContentService = textContentService;
        this.examPaperMapper = examPaperMapper;
    }
    @Override
    public PageInfo<TaskExam> page(TaskPageRequestVM requestVM) {
        return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "id desc").doSelectPageInfo(() ->
                taskExamMapper.page(requestVM)
        );
    }
    @Override
    @Transactional
    public void edit(TaskRequestVM model, User user) {
        ActionEnum actionEnum = (model.getId() == null) ? ActionEnum.ADD : ActionEnum.UPDATE;
        TaskExam taskExam = null;
        if (actionEnum == ActionEnum.ADD) {
            Date now = new Date();
            taskExam = modelMapper.map(model, TaskExam.class);
            taskExam.setCreateUser(user.getId());
            taskExam.setCreateUserName(user.getUserName());
            taskExam.setCreateTime(now);
            taskExam.setDeleted(false);
            //保存任务结构
            TextContent textContent = textContentService.jsonConvertInsert(model.getPaperItems(), now, p -> {
                TaskItemObject taskItemObject = new TaskItemObject();
                taskItemObject.setExamPaperId(p.getId());
                taskItemObject.setExamPaperName(p.getName());
                return taskItemObject;
            });
            textContentService.insertByFilter(textContent);
            taskExam.setFrameTextContentId(textContent.getId());
            taskExamMapper.insertSelective(taskExam);
        } else {
            taskExam = taskExamMapper.selectByPrimaryKey(model.getId());
            modelMapper.map(model, taskExam);
            TextContent textContent = textContentService.selectById(taskExam.getFrameTextContentId());
            //清空试卷任务的试卷Id,后面会统一设置
            List<Integer> paperIds = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class)
                    .stream()
                    .map(d -> d.getExamPaperId())
                    .collect(Collectors.toList());
            examPaperMapper.clearTaskPaper(paperIds);
            //更新任务结构
            textContentService.jsonConvertUpdate(textContent, model.getPaperItems(), p -> {
                TaskItemObject taskItemObject = new TaskItemObject();
                taskItemObject.setExamPaperId(p.getId());
                taskItemObject.setExamPaperName(p.getName());
                return taskItemObject;
            });
            textContentService.updateByIdFilter(textContent);
            taskExamMapper.updateByPrimaryKeySelective(taskExam);
        }
        //更新试卷的taskId
        List<Integer> paperIds = model.getPaperItems().stream().map(d -> d.getId()).collect(Collectors.toList());
        examPaperMapper.updateTaskPaper(taskExam.getId(), paperIds);
        model.setId(taskExam.getId());
    }
    @Override
    public TaskRequestVM taskExamToVM(Integer id) {
        TaskExam taskExam = taskExamMapper.selectByPrimaryKey(id);
        TaskRequestVM vm = modelMapper.map(taskExam, TaskRequestVM.class);
        TextContent textContent = textContentService.selectById(taskExam.getFrameTextContentId());
        List<ExamResponseVM> examResponseVMS = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class).stream().map(tk -> {
            ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(tk.getExamPaperId());
            ExamResponseVM examResponseVM = modelMapper.map(examPaper, ExamResponseVM.class);
            examResponseVM.setCreateTime(DateTimeUtil.dateFormat(examPaper.getCreateTime()));
            return examResponseVM;
        }).collect(Collectors.toList());
        vm.setPaperItems(examResponseVMS);
        return vm;
    }
    @Override
    public List<TaskExam> getByGradeLevel(Integer gradeLevel) {
        return taskExamMapper.getByGradeLevel(gradeLevel);
    }
}
@Service
public class AuthenticationServiceImpl implements AuthenticationService {
    private final UserService userService;
    private final SystemConfig systemConfig;
    @Autowired
    public AuthenticationServiceImpl(UserService userService, SystemConfig systemConfig) {
        this.userService = userService;
        this.systemConfig = systemConfig;
    }
    /**
     * @param username username
     * @param password password
     * @return boolean
     */
    @Override
    public boolean authUser(String username, String password) {
        User user = userService.getUserByUserName(username);
        return authUser(user, username, password);
    }
    @Override
    public boolean authUser(User user, String username, String password) {
        if (user == null) {
            return false;
        }
        String encodePwd = user.getPassword();
        if (null == encodePwd || encodePwd.length() == 0) {
            return false;
        }
        String pwd = pwdDecode(encodePwd);
        return pwd.equals(password);
    }
    @Override
    public String pwdEncode(String password) {
        return RsaUtil.rsaEncode(systemConfig.getPwdKey().getPublicKey(), password);
    }
    @Override
    public String pwdDecode(String encodePwd) {
        return RsaUtil.rsaDecode(systemConfig.getPwdKey().getPrivateKey(), encodePwd);
    }
}
<view class="exam-page">
  <view class="view-wrap">
    <view class="exam-count-down">{{remainTimeStr}}</view>
  </view>
  <view class="view-wrap-hidden">
  </view>
  <view>
    <view class="exam-name-title">
      <h1>{{form.name}}</h1>
    </view>
    <form bindsubmit='formSubmit'>
      <i-panel title="{{titleItem.name}}" wx:for="{{form.titleItems}}" wx:for-item="titleItem" wx:key="{{titleItem.name}}" i-class="exam-panel-title">
        <i-cell-group i-class="exam-cell">
          <i-cell wx:for="{{titleItem.questionItems}}" wx:key="{{titleItem.id}}" wx:for-item="questionItem">
            <view wx:if="{{questionItem.questionType === 1}}">
              <rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" />
              <radio-group class="radio-group" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}">
                <label class="radio" wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="radioItem" class="exam-radio-item-label">
                  <radio color="#2d8cf0" value="{{radioItem.prefix}}" checked="{{radioItem.checked}}" class="exam-item-left" />
                  <rich-text nodes="{{radioItem.prefix}}. {{radioItem.content}}" class="exam-item-left" />
                </label>
              </radio-group>
            </view>
            <view wx:elif="{{questionItem.questionType === 2}}">
              <rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" class="exam-item-left" style="line-height:35px" />
              <checkbox-group class="exam-item-left" style="margin-left:10px" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}">
                <label wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="radioItem" class="exam-radio-item-label">
                  <checkbox color="#2d8cf0" value="{{radioItem.prefix}}" checked="{{radioItem.checked}}" class="exam-item-left" />
                  <rich-text nodes="{{radioItem.prefix}}. {{radioItem.content}}" class="exam-item-left" />
                </label>
              </checkbox-group>
            </view>
            <view wx:elif="{{questionItem.questionType === 3}}">
              <rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" class="exam-item-left" style="line-height:35px" />
              <radio-group class="radio-group" class="exam-item-left" style="margin-left:10px" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}">
                <label class="radio" wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="radioItem" class="exam-radio-item-label">
                  <radio color="#2d8cf0" value="{{radioItem.prefix}}" checked="{{radioItem.checked}}" class="exam-item-left" />
                  <rich-text nodes="{{radioItem.content}}" class="exam-item-left" />
                </label>
              </radio-group>
            </view>
            <view wx:elif="{{questionItem.questionType === 4}}">
              <rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" />
              <view class="exam-input-contain" wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="inputItem" wx:for-index="idx">
                <view class="exam-input-contain-label">{{inputItem.prefix}}</view>
                <input class="exam-input-contain-content" maxlength="-1" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}_{{idx}}" />
              </view>
            </view>
            <view wx:else>
              <rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" />
              <view class="exam-textarea-contain">
                <textarea placeholder="答案" maxlength="-1" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}"></textarea>
              </view>
            </view>
          </i-cell>
        </i-cell-group>
      </i-panel>
      <view>
        <button class="i-btn  i-btn-primary i-btn-square" form-type='submit'>提交</button>
      </view>
      <i-action-sheet visible="true" visible="{{timeOutShow}}" mask-closable="{{ false }}">
        <view slot="header" style="padding: 16px">
          <view class="exam-timeout-title">考试试卷结束,请提交试卷!</view>
          <button class="i-btn  i-btn-primary i-btn-square" form-type='submit'>提交</button>
        </view>
      </i-action-sheet>
    </form>
    <i-modal title="考试结果" visible="{{modalShow}}" bind:ok="returnRecord" bind:cancel="returnRecord">
      <view>得分:{{result}}</view>
    </i-modal>
    <i-spin size="large" fix wx:if="{{ spinShow }}"></i-spin>
    <i-message id="message" />
  </view>
</view>

八,项目部署

8.1 目录结构

获取到源码进行解压后,文件列表如下:

8.2 导入数据库

打开Navicat(或者其他数据库连接工具也可),导入资料中的sql文件。

8.3 后端源码部署

8.3.1 导入源码

打开idea,新建工程【可以任意目录】。把解压后的xzs目录复制到创建好的idea工程中。进行导入。

导入进来之后,idea会进行编译。编译之后没有出现错误说明导入成功。

8.3.2 修改配置文件

修改数据库连接配置,在application-dev.yml配置文件中修改成自己的数据库名和自己的密码。

8.3.3 启动项目

SpringBoot的程序启动类,相信大部分小伙伴们都知道该怎么启动。不过在这里还是要写一下,以防个别小伙伴不知道。在src下找到XzsApplication启动类,在该类中进行右键运行即可。最后查看控制台有没有报错信息。没有报错信息,启动成功。

上面说明启动成功

8.4 管理员端和学生端部署

管理员端和学生端部署操作都是一样的,在这里以管理员端为例进行演示。

打开vscode【用其他前端开发工具打开也可】,导入资料中的vue目录下的xzs-admin工程,学生端是xzs-student。打开vscode的终端,进行安装依赖和启动项目。

8.4.1 安装依赖

命令:npm install

8.4.2 启动项目

命令:npm run serve

运行成功,端口号8002

8.5 小程序端部署

8.5.1 微信小程序开发工具下载与安装

开发工具的官方下载地址为:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html

不支持Windows XP和Windows 7系统,建议使用WIN10。我这里选择Windows 64版本的安装包。

安装过程比较简单,不用设置什么,按照提示来就行了。下面是每一步详细截图

8.5.2 项目部署

打开微信开发工具---> 选择导入--->找到资料中的wx目录,导入xzs_student

到这一步会提示,输入appId,如果自己有就写自己的,没有的话,点击测试,使用测试号

导入进来之后,会自动提示是否运行,选择【信任并运行】

运行成功 。到此整个项目部署就已经完成了

九,项目总结

该项目是PC端+小程序端。Java做为后端支持。代码结构规整,源码容易阅读,功能完善,非常适合做为毕设来使用。

相关文章
|
5月前
|
小程序 JavaScript 搜索推荐
基于springboot的考研互助小程序
本项目基于SpringBoot开发考研互助小程序,整合优质资源,提供真题、视频、学习计划等功能,构建交流社区,助力考生高效备考,促进教育公平与信息化发展。
|
8月前
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
633 0
|
12月前
|
小程序 JavaScript Java
基于SpringBoot的智慧停车场微信小程序源码分享
智慧停车场微信小程序主要包含管理端和小程序端。管理端包括停车场管理,公告信息管理,用户信息管理,预定信息管理,用户反馈管理等功能。小程序端包括登录注册,预约停车位,停车导航,停车缴费,用户信息,车辆信息,钱包充值,意见反馈等功能。
562 5
基于SpringBoot的智慧停车场微信小程序源码分享
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
568 1
|
移动开发 安全 JavaScript
SpringBoot接入微信JSSDK,看这篇妥妥的
这篇教程详细介绍了如何在Spring Boot项目中接入微信JSSDK,实现H5页面的自定义分享和调用相册选取图片等功能。文章首先通过对比理想与现实的分享效果,引出了接入微信JSSDK的必要性。接着,作者提供了GitHub和Gitee上的项目源码链接,并逐步讲解了整个接入过程的关键步骤,包括配置文件、主要类和方法的实现细节,以及必要的微信公众号设置。此外,还特别强调了几个常见问题及其解决方案,如域名绑定、IP白名单设置和签名验证等。最后,通过实际测试验证了功能的正确性。适合初学者快速上手微信JSSDK接入。
429 8
SpringBoot接入微信JSSDK,看这篇妥妥的
|
存储 安全 Java
打造智能合同管理系统:SpringBoot与电子签章的完美融合
【10月更文挑战第7天】 在数字化转型的浪潮中,电子合同管理系统因其高效、环保和安全的特点,正逐渐成为企业合同管理的新宠。本文将分享如何利用SpringBoot框架实现一个集电子文件签字与合同管理于一体的智能系统,探索技术如何助力合同管理的现代化。
696 4
|
小程序 前端开发 Java
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
JavaDog Chat v1.0.0 是一款基于 SpringBoot、MybatisPlus 和 uniapp 的简易聊天软件,兼容 H5、小程序和 APP,提供丰富的注释和简洁代码,适合初学者。主要功能包括登录注册、消息发送、好友管理及群组交流。
399 1
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。
482 0
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
403 0
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
小程序 前端开发 JavaScript
【项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序
【避坑宝】是一款企业黑红名单吐槽小程序,旨在帮助打工人群体辨别企业优劣。该平台采用SpringBoot+MybatisPlus+uniapp+uview2等技术栈构建,具备丰富的注释与简洁的代码结构,非常适合实战练习与学习。通过小程序搜索“避坑宝”即可体验。
458 0
【项目实战】SpringBoot+uniapp+uview2打造一个企业黑红名单吐槽小程序