目录
(1)项目可行性分析
(一)技术可行性:
(二)经济可行性:
(三)社会可行性:
(2)需求描述
功能模块图
用例图:
(3)界面原型
1.登录:
2.注册:
3.我的:
4.分类:
5.记录:
6.主页:
(4)数据库设计
(1)User表:
(2)Notes表:
(3)Type表:
E-r图如下:
数据库的sql文件:
(5)后端工程
common包:
R.java
config包:
CorsConfig.java
domain包:
Notes.java
Type.java
User.java
utils包:
PathUtils.java
controller包:
NotesController.java
TypeController.java
UploadController.java
UserController.java
service包:
NotesService
OssUploadService
TypeService
UserService
Impl包:
NotesServiceImpl.java
OssUploadServiceImpl.java
TypeServiceImpl.java
UserServiceImpl.java
(6)前端工程
接下来我们使用uniapp+springboot实现一个简单的前后端分离的小项目----个人备忘录系统,适合初学者学习,以下是详细步骤:
(1)项目可行性分析
(一)技术可行性:
1.uniapp是一个基于Vue.js框架的跨平台开发工具,可以在多个平台上实现一次开发多端运行。它提供了丰富的组件和插件,使得开发变得更加高效。
2.uniapp支持多个主流的移动端平台,如iOS和Android,以及微信小程序、H5等。这意味着你可以通过uniapp开发一个备忘录系统,并在多个平台上发布和使用。
3.Vue.js作为uniapp的底层框架,拥有活跃的开发社区和丰富的生态系统,可以提供大量的资源和支持。
(二)经济可行性:
1.uniapp的开发成本相对较低,因为它使用了一套代码可以覆盖多个平台的开发方式,减少了重复的工作量和开发时间。
2.由于uniapp支持多个主流平台,你可以在不同的平台上发布你的备忘录系统,扩大用户群体,增加潜在的收入来源。
3.uniapp的跨平台特性可以降低维护成本,因为你只需要维护一套代码,而不是针对每个平台都进行独立的开发和维护。
(三)社会可行性:
1.备忘录系统是一个常见且实用的应用,它可以帮助个人记录重要事项、提醒任务等。这种类型的应用在社会中有广泛的需求。
2.通过使用uniapp开发备忘录系统,你可以满足不同用户使用不同平台的需求,提高用户体验和满意度。
3.在移动互联网时代,人们越来越依赖手机和移动应用程序进行工作和生活管理。开发备忘录系统可以满足人们随时随地记录和查看备忘录的需求,符合社会的发展趋势。
(2)需求描述
个人备忘录系统主要有登录、注册、查看所有备忘录、创建新的备忘录、删除备忘录、修改备忘录、根据分类查询已完成或未完成的备忘录。
功能模块图
用例图:
(3)界面原型
主要界面如下:
1.登录:
2.注册:
3.我的:
4.分类:
5.记录:
6.主页:
(4)数据库设计
数据库主要有三个表:
(1)User表:
表名 | 类型 | 长度 | 注释 |
id | int | 255 | id |
username | varchar | 255 | 用户名 |
password | varchar | 255 | 密码 |
avatar | varchar | 255 | 头像 |
(2)Notes表:
表名 | 类型 | 长度 | 注释 |
id | int | 255 | id |
rid | int | 255 | 用户id |
detail | varchar | 255 | 内容 |
time | datetime | 255 | 截止时间 |
type | int | 255 | 类型 |
finish | int | 255 | 任务是否完成 |
(3)Type表:
表名 | 类型 | 长度 | 注释 |
typeid | int | 255 | 主键 |
type | varchar | 255 | 是什么类型 |
E-r图如下:
数据库的sql文件:
/*Navicat Premium Data TransferSource Server : mySQLSource Server Type : MySQLSource Server Version : 80019Source Host : localhost:3305Source Schema : memoTarget Server Type : MySQLTarget Server Version : 80019File Encoding : 65001Date: 25/12/2023 11:06:46
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for notes
-- ----------------------------
DROP TABLE IF EXISTS `notes`;
CREATE TABLE `notes` (`id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'note表的id',`rid` int(0) NOT NULL COMMENT '这个笔记是哪个人的',`detail` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '笔记的内容',`photo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户上传的图片,null或者0表示无',`time` datetime(0) NOT NULL COMMENT '笔记的创建时间',`type` int(0) NOT NULL COMMENT '笔记的类型',`finish` int(0) NOT NULL COMMENT '任务是否完成',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of notes
-- ----------------------------
INSERT INTO `notes` VALUES (31, 13, '软件设计师考试', 'http://s6422okdy.hn-bkt.clouddn.com/2023/12/23/e7bbeaecf4984a72af03d6d623a4f96c.jpg', '2023-11-04 00:04:28', 2, 1);
INSERT INTO `notes` VALUES (32, 13, '国奖答辩', NULL, '2023-10-16 20:26:27', 2, 1);
INSERT INTO `notes` VALUES (33, 13, 'hehang-blog数据库项目', NULL, '2024-01-07 20:26:56', 2, 1);
INSERT INTO `notes` VALUES (34, 13, '数据库详细设计报告', NULL, '2023-11-08 20:27:24', 2, 1);
INSERT INTO `notes` VALUES (35, 13, '数据库课设验收', NULL, '2023-11-22 20:28:02', 2, 1);
INSERT INTO `notes` VALUES (36, 13, '计算机组成原理期中考试', NULL, '2023-11-24 20:28:44', 2, 1);
INSERT INTO `notes` VALUES (37, 13, '计算机能力挑战赛C语言', NULL, '2023-11-25 08:00:00', 2, 1);
INSERT INTO `notes` VALUES (38, 13, '学生代表大会', '0', '2023-12-07 13:15:00', 3, 1);
INSERT INTO `notes` VALUES (39, 13, '闪聚支付springclound项目', NULL, '2023-12-19 18:30:21', 2, 1);
INSERT INTO `notes` VALUES (40, 13, '英语四级考试', NULL, '2023-12-16 09:00:00', 2, 1);
INSERT INTO `notes` VALUES (41, 13, '数据库课设详细设计文档', '0', '2024-01-07 23:59:59', 2, 0);
INSERT INTO `notes` VALUES (43, 13, '完成代码细节的修改', NULL, '2023-12-18 12:00:00', 2, 1);
INSERT INTO `notes` VALUES (44, 14, '记得吃药', '0', '2023-12-24 14:57:57', 8, 0);
INSERT INTO `notes` VALUES (45, 14, '写完uniapp期末课设的报告', '', '2023-12-24 14:08:58', 2, 1);
INSERT INTO `notes` VALUES (47, 13, '计算机能力挑战赛决赛\n地点:武汉纺织大学阳光校区', 'http://s6422okdy.hn-bkt.clouddn.com/2023/12/23/daa53bce645146d08531649be4308db4.jpg', '2023-12-09 09:00:00', 2, 1);-- ----------------------------
-- Table structure for type
-- ----------------------------
DROP TABLE IF EXISTS `type`;
CREATE TABLE `type` (`typeid` int(0) NOT NULL COMMENT '主键',`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '是什么类型',PRIMARY KEY (`typeid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of type
-- ----------------------------
INSERT INTO `type` VALUES (1, '日常');
INSERT INTO `type` VALUES (2, '学习');
INSERT INTO `type` VALUES (3, '工作');
INSERT INTO `type` VALUES (4, '娱乐');
INSERT INTO `type` VALUES (5, '社交');
INSERT INTO `type` VALUES (6, '家庭');
INSERT INTO `type` VALUES (7, '个人');
INSERT INTO `type` VALUES (8, '健康');
INSERT INTO `type` VALUES (9, '财务');-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(0) NOT NULL AUTO_INCREMENT COMMENT '用户的id',`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户名字',`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户密码',`avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户的头像',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (13, 'hehang', '123456', 'https://img2.baidu.com/it/u=3841326637,2519425910&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501');
INSERT INTO `user` VALUES (14, 'abcd', '123456', 'https://pic2.zhimg.com/v2-fc348d5e926116782149d2151dc09834.jpg');
INSERT INTO `user` VALUES (15, 'mynote', '123456', 'https://img2.baidu.com/it/u=3841326637,2519425910&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501');
INSERT INTO `user` VALUES (16, '1234', '123456', 'https://img2.baidu.com/it/u=3841326637,2519425910&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501');SET FOREIGN_KEY_CHECKS = 1;
(5)后端工程
首先打开IDEA,选择创建Spring Initializr,按照以下配置,jdk版本无法选择jdk1.8,先不管,进去以后可以改,具体操作可以看我的另一篇相关的博客
配置spring版本,先选择3.2.0,进入项目后再通过pom文件修改
进入项目后修改pom.xml文件为如下配置,我们在pom中手动修改了jdk版本为1.8,spring为2.7.8,这样兼容性比较好,修改后记得刷新maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.8</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>Memo-hehang</artifactId><version>0.0.1-SNAPSHOT</version><name>hehang</name><description>memo</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><!--七牛云OOS--><dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>[7.13.0, 7.13.99]</version></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.10.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>9</source><target>9</target></configuration></plugin></plugins></build></project>
然后我们修改resources文件夹下的application.yml,数据库连接修改成你自己的,七牛云的使用可以看我上一篇博客
server:port: 2023spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3305/memo?characterEncoding=utf-8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456mybatis-plus:global-config:db-config:id-type: auto
# configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 打开七牛云,找到密钥管理,把相关信息填写到下面3行
myoss:accessKey: yourAKsecretKey: yourSKbucket: yourbucket
接下来在项目下创建如下几个包:
common包:
R.java
在common文件下创建 R.java 类,主要用于封装返回给前端的数据:
package com.example.memohehang.common;import lombok.Data;import java.io.Serializable;/*** 统一返回类型*/
@Data
public class R implements Serializable
{private int code; // 200是正常,非200表示异常private String msg;private Object data;public static R success(Object data){return success(200, "操作成功", data);}public static R success(int code, String msg, Object data){R r = new R();r.setCode(code);r.setMsg(msg);r.setData(data);return r;}public static R error(int i, String msg){return error(400, msg, null);}public static R error(String msg, Object data){return error(400, msg, data);}public static R error(int code, String msg, Object data){R r = new R();r.setCode(code);r.setMsg(msg);r.setData(data);return r;}}
config包:
CorsConfig.java
在config包下创建 CorsConfig.java 类,用于解决前端跨域问题,在config.AllowedOrigin中填写你自己的前端端口,一般为8080,或者填 * ,允许所有
package com.example.memohehang.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.CorsConfiguration;//解决前端跨域问题
@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsFilter(){UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.addAllowedOrigin("http://localhost:8080");config.addAllowedHeader("*");config.addAllowedMethod("*");config.setAllowCredentials(true);source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}
domain包:
对应数据库的实体类
Notes.java
这里我们利用jsonformat注解进行时间格式化
package com.example.memohehang.domain;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Notes {@TableId(value = "id", type = IdType.AUTO)private Integer id;private Integer rid;// 内容private String detail;// 截止时间@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")private Date time;// 类型private Integer type;//图片private String photo;// 是否完成 0表示还没有 1表示完成了private Integer finish;}
Type.java
package com.example.memohehang.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Type
{private Integer typeid;private String type;
}
User.java
package com.example.memohehang.domain;import lombok.AllArgsConstructor;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User
{//主键自增@TableId(value = "id", type = IdType.AUTO)private Integer id;private String username;private String password;// 头像private String avatar;
}
utils包:
PathUtils.java
这是对上传的文件进行重命名,在后面的七牛云相关的service中会用到
package com.example.memohehang.utils;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;//对原始文件名进行修改文件名,并修改存放目录
public class PathUtils
{public static String generateFilePath(String fileName){//根据日期生成路径SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");String datePath = sdf.format(new Date());//uuid作为文件名String uuid = UUID.randomUUID().toString().replaceAll("-", "");//后缀和文件后缀一致int index = fileName.lastIndexOf(".");// test.jpg -> .jpgString fileType = fileName.substring(index);return new StringBuilder().append(datePath).append(uuid).append(fileType).toString();}
}
我一般写代码的顺序为:Controller----service----serviceImpl----mapper,在方法学一般先写调用体,根据调用写对应的实现,下面我们按照这个顺序来写:
controller包:
NotesController.java
package com.example.memohehang.controller;import com.example.memohehang.common.R;
import com.example.memohehang.domain.Notes;
import com.example.memohehang.service.NotesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;@Controller
@RequestMapping("/note")
public class NotesController {@Autowiredprivate NotesService notesService;// 添加@RequestMapping("/save")@ResponseBodypublic R save(@RequestBody Notes notes){System.out.println("添加备忘录:" + notes);return notesService.addNote(notes);}// 根据noteid查询对应的note@RequestMapping ("/selectByNote/{noteid}")@ResponseBodypublic R selectByNote(@PathVariable("noteid") Integer noteid){return notesService.selectByNote(noteid);}// 查询 只显示用户自己的@RequestMapping ("/selectAllByUserID/{userid}")@ResponseBodypublic R selectAllById(@PathVariable("userid") Integer userid,@RequestParam(defaultValue = "1") Integer currentPage){return notesService.selectAllById(userid,currentPage);}// 查询最近即将截止的未完成的备忘录的时间差@RequestMapping ("/selectTime/{userid}")@ResponseBodypublic R selectcutDownTime(@PathVariable("userid") Integer userid){return notesService.selectcutDownTime(userid);}// 分类查询@RequestMapping ("/selectByType/{userid}/{type}/{isFinish}")@ResponseBodypublic R selectByType(@PathVariable("userid") Integer userid, @PathVariable("type") Integer type,@PathVariable("isFinish") Integer isFinish,@RequestParam(defaultValue = "1") Integer currentPage){return notesService.selectByType(userid,type,isFinish,currentPage);}// 修改@RequestMapping("/update")@ResponseBodypublic R update(@RequestBody Notes notes){return notesService.update(notes);}// 删除@DeleteMapping("/delete/{id}")@ResponseBodypublic R delete(@PathVariable("id") Integer id){return notesService.delete(id);}}
TypeController.java
package com.example.memohehang.controller;import com.example.memohehang.common.R;
import com.example.memohehang.service.TypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;@Controller
@RequestMapping("/type")
public class TypeController
{@Autowiredprivate TypeService typeService;// 获取编号与类型的映射表@ResponseBody@GetMapping("/getMapping")public R typeMapping(){return typeService.typeMapping();}}
UploadController.java
package com.example.memohehang.controller;import com.example.memohehang.common.R;
import com.example.memohehang.service.OssUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;@RestController
public class UploadController
{@Autowiredprivate OssUploadService ossUploadService;@PostMapping("/upload")public R uploadImg(MultipartFile img){return ossUploadService.uploadImg(img);}
}
UserController.java
package com.example.memohehang.controller;import com.example.memohehang.common.R;
import com.example.memohehang.domain.User;
import com.example.memohehang.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;// 登录功能@RequestMapping(value = "/login", method = RequestMethod.POST)public R login(@RequestBody User user){return userService.login(user);}// 注册功能@RequestMapping(value = "/register", method = RequestMethod.POST)public R register(@RequestBody User user){return userService.register(user);}// 根据用户id查询@RequestMapping ("/selectUserById/{userid}")@ResponseBodypublic R selectUserById(@PathVariable("userid") Integer userid){return userService.selectUserById(userid);}}
我们用mybatisplus自带的查询函数即可完成所有的CRUD,因此我们不需要写SQL语句
service包:
NotesService
package com.example.memohehang.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.example.memohehang.common.R;
import com.example.memohehang.domain.Notes;
import com.example.memohehang.domain.User;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;public interface NotesService extends IService<Notes>
{/*** 添加备忘录* @param notes* @return*/public R addNote(Notes notes);/*** 根据noteid查询note* @param noteid* @return*/public R selectByNote(Integer noteid);/*** 查询 只显示用户自己的* @param userid* @param currentPage* @return*/public R selectAllById(Integer userid,Integer currentPage);/*** 查询最近即将截止的未完成的备忘录的时间差* @param userid* @return*/public R selectcutDownTime(Integer userid);/*** 分类查询* @param userid* @param type* @param isFinish* @param currentPage* @return*/public R selectByType(Integer userid, Integer type,Integer isFinish,Integer currentPage);/*** 修改* @param notes* @return*/public R update(Notes notes);/*** 删除* @param id* @return*/public R delete(Integer id);
}
OssUploadService
package com.example.memohehang.service;import com.example.memohehang.common.R;
import org.springframework.web.multipart.MultipartFile;public interface OssUploadService {//图片上传到七牛云R uploadImg(MultipartFile img);
}
TypeService
package com.example.memohehang.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.memohehang.common.R;
import com.example.memohehang.domain.Type;public interface TypeService extends IService<Type>
{/*** 获取所有类型* @return*/public R typeMapping();
}
UserService
package com.example.memohehang.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.memohehang.common.R;
import com.example.memohehang.domain.User;public interface UserService extends IService<User>
{/*** 登录* @param user* @return*/public R login(User user);/*** 注册* @param user* @return*/public R register(User user);/*** 根据id查询用户* @param userid* @return*/public R selectUserById(Integer userid);
}
接下来在service包中创建Impl,注意第一个 “ I ” 是大写的 “ i ”,第二个是小写的 “ L ”
Impl包:
NotesServiceImpl.java
package com.example.memohehang.service.Impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.memohehang.common.R;
import com.example.memohehang.domain.Notes;
import com.example.memohehang.mapper.NotesMapper;
import com.example.memohehang.service.NotesService;
import org.springframework.stereotype.Service;import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Service
public class NotesServiceImpl extends ServiceImpl<NotesMapper, Notes> implements NotesService
{private NotesMapper notesMapper;/*** 添加备忘录* @param notes* @return*/@Overridepublic R addNote(Notes notes){boolean b = save(notes);//调用mybatis-plusif (b){return R.success(200, "添加成功", null);}else{return R.error(405, "添加失败");}}/*** 根据noteid查询note* @param noteid* @return*/@Overridepublic R selectByNote(Integer noteid){QueryWrapper<Notes> wrapper = new QueryWrapper<>();wrapper.eq("id", noteid);List<Notes> note = list(wrapper);if (note == null){return R.error(400,"查询失败");}else{return R.success(note.get(0));}}/*** 查询 只显示用户自己的* @param userid* @param currentPage* @return*/@Overridepublic R selectAllById(Integer userid, Integer currentPage){Page page = new Page(currentPage, 20);// 查询条件 分页的基础上 再按照创建时间排序IPage pageData = page(page, new QueryWrapper<Notes>().orderByAsc("finish","time").eq("rid", userid));return R.success(pageData);}/*** 查询最近即将截止的未完成的备忘录的时间差* @param userid* @return*/@Overridepublic R selectcutDownTime(Integer userid){QueryWrapper<Notes> wrapper = new QueryWrapper<>();wrapper.eq("rid", userid).orderByAsc("finish", "time");List<Notes> note = list(wrapper);// 处理查询结果if (note != null && !note.isEmpty()){Notes firstUnfinishedNote = null;for (Notes n : note){if (n.getFinish() == 0){firstUnfinishedNote = n;break;}}if (firstUnfinishedNote != null){LocalDateTime currentTime = LocalDateTime.now();Date noteTime = firstUnfinishedNote.getTime();Instant instant = noteTime.toInstant();LocalDateTime noteLocalDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();Duration duration = Duration.between(currentTime, noteLocalDateTime);long days = duration.toDays();long hours = duration.toHoursPart();long minutes = duration.toMinutesPart();long seconds = duration.toSecondsPart();// 构造返回结果Map<String, Object> resultMap = new HashMap<>();resultMap.put("days", days);resultMap.put("hours", hours);resultMap.put("minutes", minutes);resultMap.put("seconds", seconds);System.out.println(resultMap);// 返回结果return R.success(200, "duration", resultMap);}else{return R.error(405, "没有找到未完成的备忘录");}}else{return R.error(405, "没有找到备忘录");}}/*** 分类查询* @param userid* @param type* @param isFinish* @param currentPage* @return*/@Overridepublic R selectByType(Integer userid, Integer type, Integer isFinish, Integer currentPage){Page page = new Page(currentPage, 20);IPage pageData = page(page, new QueryWrapper<Notes>().orderByAsc("time").eq("rid", userid).eq("finish", isFinish).eq("type", type));return R.success(pageData);}/*** 修改* @param notes* @return*/@Overridepublic R update(Notes notes){System.out.println("开始更新");System.out.println(notes);boolean b = update(notes, new QueryWrapper<Notes>().eq("id", notes.getId()));if (b){System.out.println("更新成功");return R.success(200, "更新成功", null);}System.out.println("更新失败");return R.error(405, "更新失败");}/*** 删除* @param id* @return*/@Overridepublic R delete(Integer id){System.out.println("user delete..." + id);boolean b = removeById(id);if (b){return R.success(200, "删除成功", null);}return R.error(405, "删除失败");}
}
OssUploadServiceImpl.java
注意这里需要修改外链回显链接
package com.example.memohehang.service.Impl;import com.example.memohehang.common.R;
import com.example.memohehang.service.OssUploadService;
import com.example.memohehang.utils.PathUtils;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;@Service
@Data//为成员变量生成get和set方法
@ConfigurationProperties(prefix = "myoss")
//把文件上传到七牛云
public class OssUploadServiceImpl implements OssUploadService {@Override//MultipartFile是spring提供的接口public R uploadImg(MultipartFile img) {//获取原始文件名String originalFilename = img.getOriginalFilename();// 获取文件大小long fileSize = img.getSize();//PathUtils.generateFilePath(originalFilename)表示把原始文件名转换成指定文件名String filePath = PathUtils.generateFilePath(originalFilename);//下面用于调用的uploadOss方法返回的必须是String类型String url = uploadOss(img,filePath);System.out.println("外链地址:"+url);//把得到的外链地址返回给前端return R.success(200,"操作成功",url);}//----------------------------------上传文件到七牛云----------------------------------------//注意要从application.yml读取属性数据,下面的3个成员变量的名字必须对应application.yml的myoss属性的三个子属性名字private String accessKey;private String secretKey;private String bucket;//上传文件的具体代码。MultipartFile是spring提供的接口,作用是实现文件上传private String uploadOss(MultipartFile imgFile, String filePath){//构造一个带指定 Region 对象的配置类。你的七牛云OSS创建的是哪个区域的,那么就调用Region的什么方法即可Configuration cfg = new Configuration(Region.huanan());cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本UploadManager uploadManager = new UploadManager(cfg);//打开七牛云,把鼠标悬浮在右上角的个人头像,然后就会看到'密钥管理',点击进入就有你的密钥,把其中的AK和SK复制到下面两行//String accessKey = "_ibGP9wytjLCAZPqcFaWQNxbw7fMUvofSOvOFFR3";//String secretKey = "QSOAU-cv3sSDGNfVNPF6iXz-PsP5X9QTrjFI9zYw";//String bucket = "hehang-blog";//为避免上面3行暴露信息,我们会把信息写到application.yml里面,然后添加ConfigurationProperties注解、3个成员变量即可读取//文件名,如果写成null的话,就以文件内容的hash值作为文件名String key = filePath;try {//byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");//ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes);//上面两行是官方写的(注释掉),下面那几行是我们写的//把前端传过来的文件转换成InputStream对象InputStream xxinputStream = imgFile.getInputStream();Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {//把前端传过来的xxinputStream图片上传到七牛云Response response = uploadManager.put(xxinputStream,key,upToken,null, null);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println("上传成功! 生成的key是: "+putRet.key);System.out.println("上传成功! 生成的hash是: "+putRet.hash);return "http://s6422okdy.hn-bkt.clouddn.com/"+key;//注意这个地方替换成自己的域名,http://不能掉} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}}catch (Exception e) {//ignore}return "上传失败";}
}
TypeServiceImpl.java
package com.example.memohehang.service.Impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.example.memohehang.common.R;
import com.example.memohehang.domain.Type;
import com.example.memohehang.mapper.TypeMapper;
import com.example.memohehang.service.TypeService;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.List;@Service
public class TypeServiceImpl extends ServiceImpl<TypeMapper, Type> implements TypeService
{/*** 获取所有类型* @return*/@Overridepublic R typeMapping(){List<Type> types = list();HashMap<Integer, String> hashMap = new HashMap<>();for (Type type : types){hashMap.put(type.getTypeid(), type.getType());}return R.success(hashMap);}
}
UserServiceImpl.java
package com.example.memohehang.service.Impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.example.memohehang.common.R;
import com.example.memohehang.domain.User;
import com.example.memohehang.mapper.UserMapper;
import com.example.memohehang.service.UserService;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService
{/*** 登录* @param user* @return*/@Overridepublic R login(User user){// 判断用户账号是否正确User one = getOne(new QueryWrapper<User>().eq("username", user.getUsername()).eq("password", user.getPassword()));if (one != null){return R.success(200,"登录成功", one);}else{return R.error(405, "账号或密码错误");}}@Overridepublic R register(User user){LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getUsername, user.getUsername());System.out.println(user);User tempUsername = getOne(queryWrapper);// 先判断一下用户是否存在 存在就返回falseif (tempUsername != null){return R.error(405,"账户已存在");}else{//网上随机找的一个图片user.setAvatar("https://img2.baidu.com/it/u=3841326637,2519425910&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501");// 反之加入save(user);return R.success(user);}}/*** 根据id查询用户* @param userid* @return*/@Overridepublic R selectUserById(Integer userid){// 判断用户账号是否正确User one = getOne(new QueryWrapper<User>().eq("id", userid));if (one != null){return R.success(200,"查询成功", one);}else{return R.error(405, "查询失败");}}
}
至此后端工程全部创建完毕,按照下图检查一下是否有缺少,全部完毕后就可以运行项目,利用apipost进行测试,或者前端创建完后直接集成测试