为了学习英语,我开发了一个单词对战系统

简介: 本系统主要由Android、服务端、数据管理端构成。客户端的页面实现通过网络与服务器REST API接口通信获取 MySQL数据。本人重点参与网上单词对战系统客户端、服务器以及数据库的设计、开发、测试工作。

一,系统介绍


随着“互联网+”的大潮兴起,移动应用受热捧。


其中,Android应用借其强大的用户基础及其应用时的便捷而深受欢迎。在此基础上,以Android为载体的单词对战平台,可以满足复习单词的需求。因此,结合以上优势设计并实现基于Android的单词对战APP,符合我国互联网精准化问答和个性化服务的趋势。现如今随着消费方式的升级,学习单词的方式也变得多种多样,随着计算机与信息技术的发展,学习单词也由线下发展到了线上管理,越来越多的人选择利用计算机以及网络信息技术进行线上的单词学习,线上管理的好处在于可以实时统计以及查看信息,并且可以持久化到硬件设备中,数据管理方便,成本低,是如今信息管理的首选,本文就以Android为基础,设计并开发自己的系统,一个基于Android的单词对战系统。


本系统主要由Android、服务端、数据管理端构成。客户端的页面实现通过网络与服务器REST API接口通信获取 MySQL数据。本人重点参与网上单词对战系统客户端、服务器以及数据库的设计、开发、测试工作。


基于Android的单词对战系统主要实现了以下功能:


(1)用户管理。主要实现了基于Android的单词对战系统的用户管理功能。

(2)对战管理。主要实现了基于Android的单词对战系统的对战管理功能。

(3)单词管理。主要实现了基于Android的单词对战系统的单词管理功能。

(4)好友管理。主要实现了基于Android的单词对战系统的好友管理功能。

(5)故事管理。主要实现了基于Android的单词对战系统的故事管理功能。(6)类型管理。主要实现了基于Android的单词对战系统的类型管理功能。

(7)系统管理。主要实现了基于Android的单词对战系统的系统管理功能。


微信图片_20221010161653.png


二,系统演示


在基于Android的单词对战系统的首页中,可以看到信息和公告。首页包括登陆窗口、信息窗口等。实现的方法是。首页主要方便管理员进行首页展示。客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet。


后台管理系统主要用于基于Android的单词对战系统的管理员进行后台管理, 后端管理对于control的处理关键就是:DispatcherServlet的handlerMappings集合中根据请求的URL匹配每一个handlerMapping对象中的某个handler,匹配成功之后将会返回这个handler的处理连接handlerExecutionChain对象。而这个handlerExecutionChain对象中将会包含用户自定义的多个handlerInterceptor对象。


微信图片_20221010161700.png


微信图片_20221010161704.png


微信图片_20221010161709.png


微信图片_20221010161714.png


微信图片_20221010161718.png


微信图片_20221010161723.png


微信图片_20221010161727.png


微信图片_20221010161732.png


三,核心代码演示


@Aspect
@Component
public class OperLogAspect {
    private ThreadLocal<Long> startTime = new ThreadLocal<>();
    @Autowired
    private OperRecordService operRecordService;
    @Pointcut("@annotation(com.egao.common.core.annotation.OperLog)")
    public void operLog() {
    }
    @Before("operLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
    }
    @AfterReturning(pointcut = "operLog()", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {
        saveLog(joinPoint, result, null);
    }
    @AfterThrowing(value = "operLog()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
        saveLog(joinPoint, null, e);
    }
    private void saveLog(JoinPoint joinPoint, Object result, Exception e) {
        // 获取reques对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (attributes == null ? null : attributes.getRequest());
        // 构建操作日志
        OperRecord operRecord = new OperRecord();
        operRecord.setUserId(getLoginUserId());
        if (startTime.get() != null) operRecord.setSpendTime(System.currentTimeMillis() - startTime.get());
        if (request != null) {
            operRecord.setRequestMethod(request.getMethod());
            operRecord.setUrl(request.getRequestURI());
            operRecord.setIp(UserAgentGetter.getIp(request));
        }
        // 记录异常信息
        if (e != null) {
            operRecord.setState(1);
            operRecord.setComments(StrUtil.sub(e.toString(), 0, 2000));
        }
        // 记录模块名、操作功能、请求方法、请求参数、返回结果
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        operRecord.setOperMethod(joinPoint.getTarget().getClass().getName() + "." + signature.getName());
        Method method = signature.getMethod();
        if (method != null) {
            OperLog operLog = method.getAnnotation(OperLog.class);
            if (operLog != null) {
                operRecord.setModel(operLog.value());
                operRecord.setDescription(operLog.desc());
                if (operLog.param() && request != null) {
                    operRecord.setParam(StrUtil.sub(JSON.toJSONString(request.getParameterMap()), 0, 2000));
                }
                if (operLog.result() && result != null) {
                    operRecord.setResult(StrUtil.sub(JSON.toJSONString(result), 0, 2000));
                }
            }
        }
        operRecordService.saveAsync(operRecord);
    }
    /**
     * 获取当前登录的userId
     */
    private Integer getLoginUserId() {
        Subject subject = SecurityUtils.getSubject();
        if (subject == null) return null;
        Object object = subject.getPrincipal();
        if (object instanceof User) return ((User) object).getUserId();
        return null;
    }
}


/**
 * 业务异常
 * Created by xiaomeng 
 */
public class BusinessException extends IException {
    private static final long serialVersionUID = 5450935008012318697L;
    public BusinessException() {
        super();
    }
    public BusinessException(String message) {
        super(message);
    }
    public BusinessException(Integer code, String message) {
        super(code, message);
    }
    @Override
    public Integer getCode() {
        Integer code = super.getCode();
        if (code == null) {
            code = 500;
        }
        return code;
    }
    @Override
    public String getMessage() {
        String message = super.getMessage();
        if (message == null) {
            message = "系统错误";
        }
        return message;
    }
}


public class ParameterException extends IException {
    private static final long serialVersionUID = 7993671808524980055L;
    public ParameterException() {
        super();
    }
    public ParameterException(String message) {
        super(message);
    }
    public ParameterException(Integer code, String message) {
        super(code, message);
    }
    @Override
    public Integer getCode() {
        Integer code = super.getCode();
        if (code == null) {
            code = 400;
        }
        return code;
    }
    @Override
    public String getMessage() {
        String message = super.getMessage();
        if (message == null) {
            message = "参数错误";
        }
        return message;
    }
}


@Controller
@RequestMapping("/sys/dict")
public class DictionaryController extends BaseController {
    @Autowired
    private DictionaryService dictionaryService;
    @RequiresPermissions("sys:dict:view")
    @RequestMapping()
    public String view() {
        return "system/dictionary.html";
    }
    /**
     * 分页查询字典
     */
    @OperLog(value = "字典管理", desc = "分页查询")
    @RequiresPermissions("sys:dict:list")
    @ResponseBody
    @RequestMapping("/page")
    public PageResult<Dictionary> page(HttpServletRequest request) {
        PageParam<Dictionary> pageParam = new PageParam<>(request);
        return new PageResult<>(dictionaryService.page(pageParam, pageParam.getWrapper()).getRecords(), pageParam.getTotal());
    }
    /**
     * 查询全部字典
     */
    @OperLog(value = "字典管理", desc = "查询全部")
    @RequiresPermissions("sys:dict:list")
    @ResponseBody
    @RequestMapping("/list")
    public JsonResult list(HttpServletRequest request) {
        PageParam<Dictionary> pageParam = new PageParam<>(request);
        return JsonResult.ok().setData(dictionaryService.list(pageParam.getOrderWrapper()));
    }
    /**
     * 根据id查询字典
     */
    @OperLog(value = "字典管理", desc = "根据id查询")
    @RequiresPermissions("sys:dict:list")
    @ResponseBody
    @RequestMapping("/get")
    public JsonResult get(Integer id) {
        return JsonResult.ok().setData(dictionaryService.getById(id));
    }
    /**
     * 添加字典
     */
    @OperLog(value = "字典管理", desc = "添加", param = false, result = true)
    @RequiresPermissions("sys:dict:save")
    @ResponseBody
    @RequestMapping("/save")
    public JsonResult save(Dictionary dictionary) {
        if (dictionaryService.count(new QueryWrapper<Dictionary>().eq("dict_code", dictionary.getDictCode())) > 0) {
            return JsonResult.error("字典标识已存在");
        }
        if (dictionaryService.count(new QueryWrapper<Dictionary>().eq("dict_name", dictionary.getDictName())) > 0) {
            return JsonResult.error("字典名称已存在");
        }
        if (dictionaryService.save(dictionary)) {
            return JsonResult.ok("添加成功");
        }
        return JsonResult.error("添加失败");
    }
    /**
     * 修改字典
     */
    @OperLog(value = "字典管理", desc = "修改", param = false, result = true)
    @RequiresPermissions("sys:dict:update")
    @ResponseBody
    @RequestMapping("/update")
    public JsonResult update(Dictionary dictionary) {
        if (dictionaryService.count(new QueryWrapper<Dictionary>().eq("dict_code", dictionary.getDictCode())
                .ne("dict_id", dictionary.getDictId())) > 0) {
            return JsonResult.error("字典代码已存在");
        }
        if (dictionaryService.count(new QueryWrapper<Dictionary>().eq("dict_name", dictionary.getDictName())
                .ne("dict_id", dictionary.getDictId())) > 0) {
            return JsonResult.error("字典名称已存在");
        }
        if (dictionaryService.updateById(dictionary)) {
            return JsonResult.ok("修改成功");
        }
        return JsonResult.error("修改失败");
    }
    /**
     * 删除字典
     */
    @OperLog(value = "字典管理", desc = "删除", result = true)
    @RequiresPermissions("sys:dict:remove")
    @ResponseBody
    @RequestMapping("/remove")
    public JsonResult remove(Integer id) {
        if (dictionaryService.removeById(id)) {
            return JsonResult.ok("删除成功");
        }
        return JsonResult.error("删除失败");
    }
    /**
     * 批量添加字典
     */
    @OperLog(value = "字典管理", desc = "批量添加", param = false, result = true)
    @RequiresPermissions("sys:dict:save")
    @ResponseBody
    @RequestMapping("/saveBatch")
    public JsonResult saveBatch(@RequestBody List<Dictionary> list) {
        // 对集合本身进行非空和重复校验
        StringBuilder sb = new StringBuilder();
        sb.append(CoreUtil.listCheckBlank(list, "dictCode", "字典标识"));
        sb.append(CoreUtil.listCheckBlank(list, "dictName", "字典名称"));
        sb.append(CoreUtil.listCheckRepeat(list, "dictCode", "字典标识"));
        sb.append(CoreUtil.listCheckRepeat(list, "dictName", "字典名称"));
        if (sb.length() != 0) return JsonResult.error(sb.toString());
        // 数据库层面校验
        if (dictionaryService.count(new QueryWrapper<Dictionary>().in("dict_code",
                list.stream().map(Dictionary::getDictCode).collect(Collectors.toList()))) > 0) {
            return JsonResult.error("字典标识已存在");
        }
        if (dictionaryService.count(new QueryWrapper<Dictionary>().in("dict_name",
                list.stream().map(Dictionary::getDictName).collect(Collectors.toList()))) > 0) {
            return JsonResult.error("字典名称已存在");
        }
        if (dictionaryService.saveBatch(list)) {
            return JsonResult.ok("添加成功");
        }
        return JsonResult.error("添加失败");
    }
    /**
     * 批量删除字典
     */
    @OperLog(value = "字典管理", desc = "批量删除", result = true)
    @RequiresPermissions("sys:dict:remove")
    @ResponseBody
    @RequestMapping("/removeBatch")
    public JsonResult removeBatch(@RequestBody List<Integer> ids) {
        if (dictionaryService.removeByIds(ids)) {
            return JsonResult.ok("删除成功");
        }
        return JsonResult.error("删除失败");
    }
}



四,数据库演示


数据库采用的mysql,具体的数据表设计如下:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for danci
-- ----------------------------
DROP TABLE IF EXISTS `danci`;
CREATE TABLE `danci`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `danci` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '单词',
  `fanyi` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '中文翻译',
  `ciyi` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '词义',
  `liju` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '例句',
  `image` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片',
  `leixing` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '类型',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of danci
-- ----------------------------
INSERT INTO `danci` VALUES (1, 'apple', '苹果', '一种水果名字叫苹果', 'This is a apple', 'http://localhost:8081/getFileURL/file/20210513/home_bg.jpg', '水果');
INSERT INTO `danci` VALUES (2, 'banner', '香蕉', '一种黄色长条状的水果', 'This is a banner', 'http://localhost:8081/getFileURL/file/20210513/ic_bg_one.jpg', '类型1');
-- ----------------------------
-- Table structure for duizhan
-- ----------------------------
DROP TABLE IF EXISTS `duizhan`;
CREATE TABLE `duizhan`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `yaoqingren` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邀请人',
  `beiyaoqingren` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '被邀请人',
  `shifoutongyidz` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '是否同意对战',
  `yqrchuci` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邀请人出词',
  `byqrshiyi` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '被邀请人解释',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of duizhan
-- ----------------------------
INSERT INTO `duizhan` VALUES (3, '123', '1234', '0', '', '');
-- ----------------------------
-- Table structure for gushi
-- ----------------------------
DROP TABLE IF EXISTS `gushi`;
CREATE TABLE `gushi`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题',
  `content` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '内容',
  `zuozhe` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '作者',
  `createtime` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of gushi
-- ----------------------------
INSERT INTO `gushi` VALUES (1, '邀请好友', ' B是生活中最常见的液体 D物质俗称苏打', '阿瑟东', '2020-01-01 00:00:00');
INSERT INTO `gushi` VALUES (2, '山核桃仁 ', ' B是生活中最常见的液体 D物质俗称苏打', '作者', '2020-01-01 00:00:00');
-- ----------------------------
-- Table structure for haoyou
-- ----------------------------
DROP TABLE IF EXISTS `haoyou`;
CREATE TABLE `haoyou`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `yhid` int(0) NULL DEFAULT NULL COMMENT '用户id',
  `yonghuname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
  `haoyouming` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '好友名',
  `haoyouid` int(0) NULL DEFAULT NULL COMMENT '好友id',
  `shifouty` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '是否同意',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of haoyou
-- ----------------------------
INSERT INTO `haoyou` VALUES (1, 123, '123', '1234', 3, '1');
INSERT INTO `haoyou` VALUES (2, 123, '567', '123', 3, '1');
-- ----------------------------
-- Table structure for leixing
-- ----------------------------
DROP TABLE IF EXISTS `leixing`;
CREATE TABLE `leixing`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `leixing` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '类型',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of leixing
-- ----------------------------
INSERT INTO `leixing` VALUES (1, '类型1');
INSERT INTO `leixing` VALUES (2, '水果');
-- ----------------------------
-- Table structure for sys_dictionary
-- ----------------------------
DROP TABLE IF EXISTS `sys_dictionary`;
CREATE TABLE `sys_dictionary`  (
  `dict_id` int(0) NOT NULL AUTO_INCREMENT COMMENT '字典id',
  `dict_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典标识',
  `dict_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典名称',
  `sort_number` int(0) NOT NULL DEFAULT 1 COMMENT '排序号',
  `comments` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
  `deleted` int(0) NOT NULL DEFAULT 0 COMMENT '是否删除,0否,1是',
  `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  PRIMARY KEY (`dict_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典' ROW_FORMAT = Dynamic;


根据模块图,基于Android的单词对战系统一共有一下七个模块:

用户管理模块:在基于Android的单词对战系统中,首次登陆的用户选择普通用户或管理员,输入自己的姓名及密码方可登陆。管理员可以实现修改用户和删除用户,查看用户增加用户等功能。管理员可以通过后台管理系统进行后台管理,普通用户可以操作APP进行单词对战操作。


目录
相关文章
|
4月前
|
机器学习/深度学习 人工智能 搜索推荐
【颠覆传统】解锁记忆新姿势:多模态AI单词助记神器——让单词学习变得生动有趣,打造个性化学习新体验!
【8月更文挑战第21天】多模态AI单词助记模型融合文本、语音与图像,增强英语单词记忆效果。设计上利用多感官刺激提升信息处理与记忆效率。技术栈包括React.js前端、Node.js后端、PyTorch深度学习框架等。实现过程涵盖数据准备、前端开发、后端服务搭建、深度学习模型构建及用户反馈循环。应用显示该模型显著提高学习兴趣与记忆效率,尤其对视觉和听觉学习者有益,个性化推荐系统进一步优化学习体验。
163 0
|
7月前
|
人工智能 自然语言处理
【AIGC】英语小助手Lingo:基于大语言模型的学习英语小帮手
【5月更文挑战第11天】英语小助手Lingo:基于大语言模型的学习英语小帮手
351 7
|
机器学习/深度学习 人工智能 自然语言处理
用二十段话介绍下ChatGPT
用二十段话介绍下ChatGPT
|
人工智能 程序员
英语不好能不能学编程?
就像有人不懂日语,也照样能打通很多日文游戏。不懂英语至少会用翻译软件吧?先记住语法和报错最常涉及的那些单词,if 、while 、for 、class 、def 、error 、type 之类,足够你写出完整的程序。英语好不是学习编程的先决条件。
|
人工智能 自然语言处理
利用ChatGPT场景化学习英语听说读写
利用ChatGPT场景化学习英语听说读写
271 0
利用ChatGPT场景化学习英语听说读写
|
存储 Python
基于python实现英语学习系统(附完整代码)
基于python实现英语学习系统(附完整代码)
329 0
基于python实现英语学习系统(附完整代码)
|
XML 安全 程序员
英语不好可以学编程吗?
对于IT程序员来说,日常的开发工作所需要的单词也就那些,,相当于初中英语水平,只要拿出上学时一半的精力来学习,再加上实际运用,很快就能学会,哪怕死记硬背也实在不算什么难事。
513 0
英语不好可以学编程吗?
|
自然语言处理 程序员
程序员英语高效学习法
大多数程序员的英语是软肋,包括我在内。自己也曾经试过多种方法来学习英语,但最后都是不了了之,现在回想起来,
程序员英语高效学习法
|
机器学习/深度学习 人工智能 自然语言处理
在语音识别这件事上,汉语比英语早一年超越人类水平(附论文)
几天前,微软语音识别实现了历史性突破,英语的语音转录达到专业速录员水平,机器之心也独家专访了专访微软首席语音科学家黄学东 ,了解到词错率仅 5.9% 背后的「秘密武器」——CNTK。但微软的成果是在英语水平上的,从部分读者留言中我们了解到对汉语语音识别的前沿成果不太了解,这篇文章将向大家介绍国内几家公司在汉语识别上取得的成果。
381 0
在语音识别这件事上,汉语比英语早一年超越人类水平(附论文)

热门文章

最新文章