赞
踩
目录
接下来我们使用uniapp+springboot实现一个简单的前后端分离的小项目----个人备忘录系统,适合初学者学习,全文大约5w字,全部免费,以下是详细步骤:
1.uniapp是一个基于Vue.js框架的跨平台开发工具,可以在多个平台上实现一次开发多端运行。它提供了丰富的组件和插件,使得开发变得更加高效。
2.uniapp支持多个主流的移动端平台,如iOS和Android,以及微信小程序、H5等。这意味着你可以通过uniapp开发一个备忘录系统,并在多个平台上发布和使用。
3.Vue.js作为uniapp的底层框架,拥有活跃的开发社区和丰富的生态系统,可以提供大量的资源和支持。
1.uniapp的开发成本相对较低,因为它使用了一套代码可以覆盖多个平台的开发方式,减少了重复的工作量和开发时间。
2.由于uniapp支持多个主流平台,你可以在不同的平台上发布你的备忘录系统,扩大用户群体,增加潜在的收入来源。
3.uniapp的跨平台特性可以降低维护成本,因为你只需要维护一套代码,而不是针对每个平台都进行独立的开发和维护。
1.备忘录系统是一个常见且实用的应用,它可以帮助个人记录重要事项、提醒任务等。这种类型的应用在社会中有广泛的需求。
2.通过使用uniapp开发备忘录系统,你可以满足不同用户使用不同平台的需求,提高用户体验和满意度。
3.在移动互联网时代,人们越来越依赖手机和移动应用程序进行工作和生活管理。开发备忘录系统可以满足人们随时随地记录和查看备忘录的需求,符合社会的发展趋势。
个人备忘录系统主要有登录、注册、查看所有备忘录、创建新的备忘录、删除备忘录、修改备忘录、根据分类查询已完成或未完成的备忘录。
主要界面如下:
数据库主要有三个表:
表名 | 类型 | 长度 | 注释 |
id | int | 255 | id |
username | varchar | 255 | 用户名 |
password | varchar | 255 | 密码 |
avatar | varchar | 255 | 头像 |
表名 | 类型 | 长度 | 注释 |
id | int | 255 | id |
rid | int | 255 | 用户id |
detail | varchar | 255 | 内容 |
time | datetime | 255 | 截止时间 |
type | int | 255 | 类型 |
finish | int | 255 | 任务是否完成 |
表名 | 类型 | 长度 | 注释 |
typeid | int | 255 | 主键 |
type | varchar | 255 | 是什么类型 |
- /*
- Navicat Premium Data Transfer
- Source Server : mySQL
- Source Server Type : MySQL
- Source Server Version : 80019
- Source Host : localhost:3305
- Source Schema : memo
- Target Server Type : MySQL
- Target Server Version : 80019
- File Encoding : 65001
- Date: 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;
首先打开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: 2023 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3305/memo?characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 123456 mybatis-plus: global-config: db-config: id-type: auto # configuration: # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打开七牛云,找到密钥管理,把相关信息填写到下面3行 myoss: accessKey: yourAK secretKey: yourSK bucket: yourbucket
接下来在项目下创建如下几个包:
在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.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 {
- @Bean
- public 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);
- }
- }
对应数据库的实体类
这里我们利用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;
-
-
- }
- 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;
- }
- 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;
- }
这是对上传的文件进行重命名,在后面的七牛云相关的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 -> .jpg
- String fileType = fileName.substring(index);
- return new StringBuilder().append(datePath).append(uuid).append(fileType).toString();
- }
- }
我一般写代码的顺序为:Controller----service----serviceImpl----mapper,在方法学一般先写调用体,根据调用写对应的实现,下面我们按照这个顺序来写:
- 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 {
- @Autowired
- private NotesService notesService;
-
-
- // 添加
- @RequestMapping("/save")
- @ResponseBody
- public R save(@RequestBody Notes notes)
- {
- System.out.println("添加备忘录:" + notes);
- return notesService.addNote(notes);
- }
-
-
- // 根据noteid查询对应的note
- @RequestMapping ("/selectByNote/{noteid}")
- @ResponseBody
- public R selectByNote(@PathVariable("noteid") Integer noteid)
- {
-
- return notesService.selectByNote(noteid);
- }
-
- // 查询 只显示用户自己的
- @RequestMapping ("/selectAllByUserID/{userid}")
- @ResponseBody
- public R selectAllById(@PathVariable("userid") Integer userid,@RequestParam(defaultValue = "1") Integer currentPage)
- {
- return notesService.selectAllById(userid,currentPage);
- }
-
- // 查询最近即将截止的未完成的备忘录的时间差
- @RequestMapping ("/selectTime/{userid}")
- @ResponseBody
- public R selectcutDownTime(@PathVariable("userid") Integer userid)
- {
- return notesService.selectcutDownTime(userid);
- }
-
-
-
- // 分类查询
- @RequestMapping ("/selectByType/{userid}/{type}/{isFinish}")
- @ResponseBody
- public 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")
- @ResponseBody
- public R update(@RequestBody Notes notes)
- {
- return notesService.update(notes);
- }
-
- // 删除
- @DeleteMapping("/delete/{id}")
- @ResponseBody
- public R delete(@PathVariable("id") Integer id)
- {
- return notesService.delete(id);
- }
-
-
-
- }
-
-
- 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
- {
- @Autowired
- private TypeService typeService;
-
- // 获取编号与类型的映射表
- @ResponseBody
- @GetMapping("/getMapping")
- public R typeMapping()
- {
- return typeService.typeMapping();
- }
-
- }
-
-
- 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
- {
- @Autowired
- private OssUploadService ossUploadService;
-
- @PostMapping("/upload")
- public R uploadImg(MultipartFile img)
- {
-
- return ossUploadService.uploadImg(img);
- }
- }
- 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 {
-
-
- @Autowired
- private 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}")
- @ResponseBody
- public R selectUserById(@PathVariable("userid") Integer userid)
- {
- return userService.selectUserById(userid);
- }
-
- }
-
-
-
我们用mybatisplus自带的查询函数即可完成所有的CRUD,因此我们不需要写SQL语句
- 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);
- }
-
-
- package com.example.memohehang.service;
-
- import com.example.memohehang.common.R;
- import org.springframework.web.multipart.MultipartFile;
-
- public interface OssUploadService {
- //图片上传到七牛云
- R uploadImg(MultipartFile img);
- }
- 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();
- }
-
-
- 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 ”
- 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
- */
- @Override
- public R addNote(Notes notes)
- {
- boolean b = save(notes);//调用mybatis-plus
- if (b)
- {
- return R.success(200, "添加成功", null);
- }
- else
- {
- return R.error(405, "添加失败");
- }
-
- }
-
- /**
- * 根据noteid查询note
- * @param noteid
- * @return
- */
- @Override
- public 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
- */
- @Override
- public 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
- */
- @Override
- public 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
- */
- @Override
- public 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
- */
- @Override
- public 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
- */
- @Override
- public 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, "删除失败");
- }
- }
-
-
注意这里需要修改外链回显链接
- 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 "上传失败";
- }
- }
-
-
- 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
- */
- @Override
- public 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);
- }
- }
-
-
- 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
- */
- @Override
- public 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, "账号或密码错误");
- }
- }
-
- @Override
- public R register(User user)
- {
- LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(User::getUsername, user.getUsername());
- System.out.println(user);
- User tempUsername = getOne(queryWrapper);
- // 先判断一下用户是否存在 存在就返回false
- if (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
- */
- @Override
- public 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, "查询失败");
- }
- }
- }
-
-
至此后端工程全部创建完毕,按照下图检查一下是否有缺少,注意Mapper可写也可以不写,因为我们不需要写SQL语句,不需要调用Mapper,全部完毕后就可以运行项目,利用apipost进行测试,或者前端创建完后直接集成测试
我们采用uniapp来写前端代码,按照以下步骤建立项目
输入项目名称,选择vue2
我们需要用到以下uniapp的组件,可以从uniapp组件库下载,链接为:组件使用的入门教程 | uni-app官网
对应的矢量图标可以在阿里巴巴矢量图库下载,链接为iconfont-阿里巴巴矢量图标库
然后我们在根目录下建立store文件夹,在此文件夹下建立index.js,用于存放一些函数
- export function getUserid() {
- let userid = uni.getStorageSync("userid");
- if (userid == null || userid === '')
- return '';
- else
- return userid;
- }
-
- export function getNoteid()
- {
- let noteid = uni.getStorageSync("noteid");
- if (noteid == null || noteid === '')
- return '';
- else
- return noteid;
- }
-
- export function getUsername()
- {
- let username = uni.getStorageSync("username");
- if (username == null || username === '')
- return '';
- else
- return username;
- }
-
-
- export function hasLogin() {
- let userid = uni.getStorageSync("userid");
- if (userid == null || userid === '') {
- return false;
- } else
- return true;
- }
-
- export function logout() {
- uni.removeStorageSync("userid");
- uni.removeStorageSync("noteid");
- uni.removeStorageSync("username");
- uni.redirectTo({
- url: "/pages/mine"
- });
- }
随后修改pages.json中修改相关页面配置文件,可以先创建相关页面后再进行此步骤,以免编译时报错
- {
- "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
- {
- "path": "pages/Main",
- "style": {
- "navigationBarTitleText": "个人备忘录"
- }
- }
- ,{
- "path" : "pages/Login",
- "style" :
- {
- "navigationBarTitleText": "登录",
- "enablePullDownRefresh": false
- }
-
- }
- ,{
- "path" : "pages/Main",
- "style" :
- {
- "navigationBarTitleText": "所有备忘录",
- "enablePullDownRefresh": false
- }
-
- },
- {
- "path" : "pages/mine",
- "style" :
- {
- "navigationBarTitleText": "个人中心",
- "enablePullDownRefresh": false
- }
-
- }
- ,{
- "path" : "pages/addNote",
- "style" :
- {
- "navigationBarTitleText": "添加/修改备忘录",
- "enablePullDownRefresh": false
- }
-
- }
- ,{
- "path" : "pages/catNote",
- "style" :
- {
- "navigationBarTitleText": "查询备忘录",
- "enablePullDownRefresh": false
- }
-
- }
- ,{
- "path" : "pages/Register",
- "style" :
- {
- "navigationBarTitleText": "注册",
- "enablePullDownRefresh": false
- }
-
- }
- ],
- "globalStyle": {
- "navigationBarTextStyle": "black",
- "navigationBarTitleText": "个人备忘录",
- "navigationBarBackgroundColor": "#F8F8F8",
- "backgroundColor": "#F8F8F8"
- },
- "tabBar": {
- "list": [
- {
- "text": "首页",
- "pagePath": "pages/Main",
- "iconPath": "static/images/首页.png",
- "selectedIconPath": "static/images/首页2.png"
- },
- {
- "text": "记录",
- "pagePath": "pages/addNote",
- "iconPath": "static/images/记录.png",
- "selectedIconPath": "static/images/记录1.png"
- },
- {
- "text": "分类",
- "pagePath": "pages/catNote",
- "iconPath": "static/images/分类.png",
- "selectedIconPath": "static/images/分类2.png"
- },
- {
- "text": "我的",
- "pagePath": "pages/mine",
- "iconPath": "static/images/我的.png",
- "selectedIconPath": "static/images/我的2.png"
- }
- ]
- },
- "uniIdRouter": {}
- }
然后再pages中建立以下页面文件,我这里没有创建同名目录
- <template>
- <view>
- <uni-card title="添加/修改笔记" extra="必填">
- <uni-section>
- <view class="example">
- <uni-forms>
- <uni-forms-item label="截止时间">
- <uni-datetime-picker type="datetime" return-type="timestamp" v-model="time"/>
- </uni-forms-item>
-
- <uni-forms-item label="分类">
- <select v-model="selectedType" class="select">
- <option v-for="(value, key) in types" :key="key" :value="key">{{ value }}</option>
- </select>
- </uni-forms-item>
-
- <uni-forms-item label="内容">
- <uni-section type="line" padding>
- <uni-easyinput type="textarea" autoHeight v-model="context" placeholder="请输入内容"></uni-easyinput>
- </uni-section>
- </uni-forms-item>
-
- <uni-forms-item label="完成?">
- <zero-switch v-model="finish"></zero-switch>
- </uni-forms-item>
-
- </uni-forms>
- <button type="primary" @click="saveNote()">提交</button>
- </view>
- </uni-section>
- </uni-card>
-
- <uni-card title="上传文件" extra="可选">
- <view>
- <div class="button-container">
- <button type="primary" @tap="chooseFile">选择文件</button>
- <button type="primary" @click="cancelChooseFile">取消选择</button>
- </div><br>
- <image class="myimg" v-if="this.filePath != null && this.filePath != '0'" :src="this.filePath"></image>
- <button type="primary" @tap="uploadFile">上传文件</button>
- </view>
- </uni-card>
-
-
- </view>
- </template>
-
- <script>
- import {getUserid,getNoteid} from "@/store/index.js"
- export default {
- data(){
- return{
- noteId: '',
- userId: '',
- time: '',
- selectedType: '',
- types: {},
- context: '',
- finish: false,
- note:{},
-
- filePath: null,
- fileUrl: null,
-
-
- };
- },
- onLoad() {
- this.noteId = getNoteid()//获取缓存中的noteid
- this.userId = getUserid()
-
- uni.request({
- url:`http://localhost:2023/type/getMapping`,
- method:"GET",
- success:(res)=>{
- // 将返回的备忘录类型数据赋值给types数组
- this.types = res.data.data
- }
- });
-
- if(this.noteId != null && this.noteId != '')
- {//noteId不为空查询对应的note
- uni.request({
- url: `http://localhost:2023/note/selectByNote/${this.noteId}`,
- method:"POST",
- success: (res) => {
- this.note = res.data.data
- //console.log(this.note);
- this.time = this.note.time
- this.selectedType = this.note.type
- this.context = this.note.detail
- this.finish = this.note.finish !== 0;
- //uni.removeStorageSync("noteid");
- this.filePath = this.note.photo;
- this.fileUrl = this.note.photo
-
- }
- })
- }
- },
-
- methods: {
-
- cancelChooseFile() {
- this.filePath = null;
- this.fileUrl = null;
- console.log('用户取消选择文件');
- },
- chooseFile() {
- uni.chooseImage({
- count: 1,
- success: (res) => {
- // 选择文件成功
- this.filePath = res.tempFilePaths[0];
- },
- fail: (error) => {
- // 选择文件失败
- console.error(error);
- },
- });
- },
- uploadFile() {
- uni.uploadFile({
- url: 'http://localhost:2023/upload',
- filePath: this.filePath,
- name: 'img',
- method:"POST",
- success: function (res) {
- // 上传成功
- console.log(res);
- let responseData = JSON.parse(res.data); // 解析字符串为JSON对象
- console.log(responseData);
- if(responseData.code === 200)
- {
- uni.showToast({
- title: "上传成功",
- icon: "success",
- duration: 2000
- });
- this.fileUrl = responseData.data;
- console.log( "上传后:"+ this.fileUrl);
- uni.setStorageSync("fileurl", this.fileUrl);
- }
- else
- {
- uni.showToast({
- title: "上传失败",
- icon: "error",
- duration: 2000
- });
- }
-
- }
- })
- console.log(this.filePath);
- },
-
-
-
- saveNote() {
- if(this.fileUrl === null || this.fileUrl === '0')
- {
- this.fileUrl = uni.getStorageSync("fileurl");
- }
- //this.noteId = uni.getStorageSync('noteid')
- if(this.noteId === null || this.noteId === '')
- {//添加note
- // 构造备忘录的请求参数
- console.log("添加:"+this.fileUrl);
- const note = {
- //id: this.noteId,
- rid: this.userId,
- detail: this.context,
- time: this.time,
- type: this.selectedType,
- finish: this.finish ? 1 : 0,
- photo: this.fileUrl ? this.fileUrl : 0
- }
- uni.request({
- url: 'http://localhost:2023/note/save',
- method: 'POST',
- data: note,
- success: (res) => {
- // 备忘录添加成功的处理逻辑
- if(res.data.code === 200)
- {
- uni.showToast({
- title: "添加成功",
- icon: "success",
- duration: 2000
- });
- }
- else
- {
- uni.showToast({
- title: "添加失败",
- icon: "error",
- duration: 2000
- });
- }
-
- }
- })
- }
- else
- {//更新note,更新完后要在缓存中移除noteid
- console.log("更新:" +this.fileUrl);
- const notes = {
- id: this.noteId,
- rid: this.userId,
- detail: this.context,
- time: this.time,
- type: this.selectedType,
- finish: this.finish ? 1 : 0,
- photo: this.fileUrl ? this.fileUrl : 0//因为mybatisplus不能更新为null
- }
- uni.request({
- url: 'http://localhost:2023/note/update',
- method: 'POST',
- data: notes,
- success: (res) => {
- // 备忘录更新成功的处理逻辑
- if(res.data.code === 200)
- {
- uni.showToast({
- title: "修改成功",
- icon: "success",
- duration: 2000
- });
- }
- else
- {
- uni.showToast({
- title: "修改失败",
- icon: "error",
- duration: 2000
- });
- }
-
- uni.removeStorageSync("noteid");
- this.userId = null;
-
- }
- })
-
- }
- uni.removeStorageSync("fileurl");
- uni.reLaunch({
- url:`/pages/Main`
- });
- },
-
-
-
- }
- }
- </script>
-
-
- <style lang="scss">
-
- .example {
- padding: 15px;
- background-color: #fff;
- }
-
- .segmented-control {
- margin-bottom: 15px;
- }
-
- .button-group {
- margin-top: 15px;
- display: flex;
- justify-content: space-around;
- }
-
- .form-item {
- display: flex;
- align-items: center;
- }
-
- .button {
- display: flex;
- align-items: center;
- height: 35px;
- margin-left: 10px;
- }
- .select{
- //display: flex;
- //align-items: center;
- height: 65rpx;
- width: 250rpx;
- background-color: #fff;
- border-radius: 10rpx;
-
-
- //margin-left: 10px;
- }
-
- .button-container {
- display: flex; /* 使用flex布局 */
- justify-content: center; /* 水平居中对齐按钮 */
- }
- .myimg{
- width: 600rpx;
- height: 400rpx;
- }
- </style>
- <template>
- <view>
- <uni-card title="分类查询">
- <uni-forms-item label="分类">
- <select v-model="selectedType" class="select">
- <option v-for="(value, key) in types" :key="key" :value="key" class="">{{ value }}</option>
- </select>
- </uni-forms-item>
- <uni-forms-item label="完成?">
- <zero-switch v-model="finish"></zero-switch>
- </uni-forms-item>
- <button type="primary" @click="findNotes()">查询</button>
- </uni-card>
-
- <uni-swipe-action>
- <view v-for="note in notes" :key="note.id" >
- <uni-swipe-action-item :right-options="options" :auto-close="false" @click="bindClick(note.id)">
- <uni-card title="" extra="">
- <view class="" @click="updateNote(note.id)">
- <p>截止日期:{{note.time}}</p><br>
- <p>内 容:{{note.detail}}</p><br>
- <p>任务类型:{{types[""+note.type]}}</p><br>
- <p><image class="myimg" v-if="note.photo != null && note.photo != '0'" :src='note.photo'></image></p><br>
- <p :class="{'finished': note.finish === 1, 'unfinished': note.finish !== 1}">
- 是否完成:{{ note.finish === 1 ? "完成" : "未完成" }}
- </p>
- </view>
- </uni-card>
- </uni-swipe-action-item>
- </view>
- </uni-swipe-action>
-
- </view>
- </template>
-
- <script>
- import {getUserid} from "@/store/index.js"
- export default {
- data() {
- return {
- userId: '',
- selectedType: '',
- finish: false,
-
- types: {},
- notes: {},
- currentPage: 0,
- total: 0,
- pageSize: 0,
- options:[
- {
- text: '删除',
- style: {
- backgroundColor: '#dd524d'
- }
- }
- ],
- };
- },
- onLoad() {
- this.userId = getUserid();
- uni.request({
- url:`http://localhost:2023/type/getMapping`,
- method:"GET",
- success:(res)=>{
- // 将返回的备忘录类型数据赋值给types数组
- this.types = res.data.data
- }
- });
- },
- methods:{
- findNotes()
- {
- const isfinish = this.finish ? 1 : 0
- uni.request({
- url:`http://localhost:2023/note/selectByType/${this.userId}/${this.selectedType}/${isfinish}?currentPage=${this.currentPage}`,
- method:"POST",
-
- success:(res)=>{
- this.notes = res.data.data.records
- this.currentPage = res.data.data.current
- this.total = res.data.data.total
- this.pageSize = res.data.data.size
-
- }
- });
- },
- onReachBottom(){
- this.pageSize += 1;
- this.findNotes();
- },
- bindClick(noteid) {
- uni.showModal({
- title: "是否确定删除",
- success: res => {
- if (res.confirm) {
- //删除
- uni.request({
- url:`http://localhost:2023/note/delete/${noteid}`,
- method:"DELETE",
-
- success:(res)=>{
- //删除成功
- uni.showToast({
- title: "删除成功",
- icon: "success",
- duration: 2000
- });
- uni.reLaunch({
- url:`/pages/catNote`
- });
- }
- });
- }
- }
- });
- },
- updateNote(id){
- uni.setStorageSync("noteid",id);
- uni.reLaunch({
- url:`/pages/addNote`
- });
- },
- }
- }
- </script>
-
- <style lang="scss">
- .select{
- //display: flex;
- //align-items: center;
- height: 65rpx;
- width: 250rpx;
- background-color: #fff;
- border-radius: 10rpx;
-
-
- //margin-left: 10px;
- }
- .select2{
- //display: flex;
- //align-items: center;
- height: 55rpx;
- width: 50rpx;
- background-color: #fff;
- border-radius: 10rpx;
-
-
- //margin-left: 10px;
- }
- .finished {
- color: green; /* 已完成的备忘录显示为绿色 */
- }
-
- .unfinished {
- color: red; /* 未完成的备忘录显示为红色 */
- }
- .myimg{
- width: 600rpx;
- height: 400rpx;
- }
- </style>
- <template>
- <uni-card title="个人备忘录" extra="">
- <view class="loginform">
- <uni-forms ref="form" :model="user" >
- <uni-forms-item label="账号" name="username" required>
- <uni-easyinput type="text" v-model="user.username" placeholder="请输入账号..." />
- </uni-forms-item>
- <uni-forms-item label="密码" name="password" required>
- <uni-easyinput type="password" v-model="user.password" placeholder="请输入密码..." />
- </uni-forms-item>
- </uni-forms>
- <button @tap="submitForm" class="submit">登录</button>
- <view class="noaccount">
- <view @tap="gotoRegister">没有账号,<text>注册</text>一个</view>
- </view>
- </view>
- </uni-card>
- </template>
-
- <script>
- import {getUserid} from "@/store/index.js"
- export default {
- data() {
- return {
- user: {
- id:"",
- username: "",
- password: "",
- avatar:""
- },
- };
- },
- methods:{
- submitForm() {
- this.$refs.form.validate().then((res) => {
- uni.request({
- url: `http://localhost:2023/user/login`,
- method: "POST",
- data: {
- username: this.user.username,
- password: this.user.password
- },
- success: (result) => {
- if (result.data.code === 200) {
- uni.showToast({
- title: "登录成功",
- icon: "success",
- duration: 2000
- });
- setTimeout(() => {
- this.user = result.data.data,
- uni.setStorageSync("userid", result.data.data.id);
- uni.setStorageSync("username", result.data.data.username);
- uni.reLaunch({
- url: "/pages/Main"
- })
- }, 2000);
-
- } else {
- uni.showToast({
- title: result.data.msg,
- icon: "error"
- });
- }
- }
- });
- });
- },
- gotoRegister()
- {
- uni.reLaunch({
- url: "/pages/Register"
- })
- }
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .loginform {
- margin: 6rpx;
-
- .submit {
- background-color: $uni-color-primary;
- color: white;
- }
-
- .noaccount {
- font-size: 30rpx;
- display: flex;
- justify-content: space-between;
- margin: 10rpx;
-
- text {
-
- color: red;
- }
- }
- }
- </style>
- <template>
- <view>
- <uni-notice-bar show-icon scrollable
- :text="this.msg"/>
-
- <uni-card title="最近一条待办的截止时间" extra="">
- <uni-section type="line" padding>
- <uni-countdown :font-size="30" :day="this.days" :hour="this.hours" :minute="this.minutes" :second="this.seconds" color="#FFFFFF" background-color="#007AFF" />
- </uni-section>
- </uni-card >
-
- <uni-swipe-action>
- <!-- 基础用法 -->
- <view v-for="note in notes" :key="note.id" >
- <uni-swipe-action-item :right-options="options" :auto-close="false" @click="bindClick(note.id)">
- <uni-card title="" extra="">
- <view class="" @click="updateNote(note.id)">
- <p>截止日期:{{note.time}}</p><br>
- <p>内 容:{{note.detail}}</p><br>
- <p>任务类型:{{typeMap[""+note.type]}}</p><br>
- <p><image class="myimg" v-if="note.photo != null && note.photo != '0'" :src='note.photo'></image></p><br>
- <p :class="{'finished': note.finish === 1, 'unfinished': note.finish !== 1}">
- 是否完成:{{ note.finish === 1 ? "完成" : "未完成" }}
- </p>
- </view>
- </uni-card>
- </uni-swipe-action-item>
- </view>
- </uni-swipe-action>
-
- </view>
- </template>
-
- <script>
- import {getUserid,getUsername} from "@/store/index.js"
- export default {
- data() {
- return {
- imgP:"https://img2.baidu.com/it/u=3841326637,2519425910&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501",
- options:[
- {
- text: '删除',
- style: {
- backgroundColor: '#dd524d'
- }
- }
- ],
-
- userid:0,
- user:{},
- notes: [],
- currentPage: 0,
- total: 0,
- pageSize: 0,
- typeMap:{},
- finish:0,
-
- msg:'',
- days:0,
- hours:0,
- minutes:0,
- seconds:0,
-
- };
- },
- methods:{
-
- showNotes(){
- uni.request({
- url:`http://localhost:2023/note/selectAllByUserID/${this.userid}?currentPage=${this.currentPage}`,
- method:"POST",
-
- success:(res)=>{
- this.notes = res.data.data.records
- this.currentPage = res.data.data.current
- this.total = res.data.data.total
- this.pageSize = res.data.data.size
-
- }
- });
-
- uni.request({
- url:`http://localhost:2023/type/getMapping`,
- method:"GET",
-
- success:(res)=>{
- this.typeMap = res.data.data;
-
- }
- });
-
- },
- updateNote(id){
- uni.setStorageSync("noteid",id);
- uni.reLaunch({
- url:`/pages/addNote`
- });
- },
- bindClick(noteid) {
- uni.showModal({
- title: "是否确定删除",
- success: res => {
- if (res.confirm) {
- //删除
- uni.request({
- url:`http://localhost:2023/note/delete/${noteid}`,
- method:"DELETE",
-
- success:(res)=>{
- //删除成功
- if(res.data.code === 200)
- {
- uni.showToast({
- title: "删除成功",
- icon: "success",
- duration: 2000
- });
- uni.reLaunch({
- url:`/pages/Main`
- });
- }
- else
- {
- uni.showToast({
- title: "删除失败",
- icon: "error",
- duration: 2000
- });
- }
-
- }
- });
- }
- }
- });
- },
- SetCountdown() {
- uni.request({
- url:`http://localhost:2023/note/selectTime/${this.userid}`,
- method:"GET",
-
- success:(res)=>{
- const { days, hours, minutes, seconds } = res.data.data
- this.days = parseInt(days)
- this.hours = parseInt(hours)
- this.minutes = parseInt(minutes)
- this.seconds = parseInt(seconds)
-
- }
- });
- },
-
- },
- onLoad(){
- this.userid = getUserid();
- this.showNotes();
- this.msg = '欢迎' + getUsername() + '回来,您有以下几条待办事件';
- this.SetCountdown();
- },
- onReachBottom(){
- this.pageSize += 1;
- this.showNotes();
- },
-
- }
- </script>
-
-
- <style lang="scss">
-
- .a0{
- //align-items: center;
- padding-left: 40rpx;
-
- }
- .a1{
- border: 1px solid #ccc;
- border-radius: 5rpx;
- width: 650rpx;
- //text-align: center;
- //display: flex;
- // justify-content: center;
- // align-items: center;
- padding-left: 10rpx;
- padding-top: 20rpx;
-
-
- }
- .content-box {
- flex: 1;
- /* #ifdef APP-NVUE */
- justify-content: center;
- /* #endif */
- height: 44px;
- line-height: 44px;
- padding: 0 15px;
- position: relative;
- background-color: #fff;
- border-bottom-color: #f5f5f5;
- border-bottom-width: 1px;
- border-bottom-style: solid;
- }
-
- .content-text {
- font-size: 15px;
- }
-
- .example-body {
- /* #ifndef APP-NVUE */
- display: flex;
- /* #endif */
- flex-direction: row;
- justify-content: center;
- padding: 10px 0;
- background-color: #fff;
- }
-
- .button {
- border-color: #e5e5e5;
- border-style: solid;
- border-width: 1px;
- padding: 4px 8px;
- border-radius: 4px;
- }
-
- .button-text {
- font-size: 15px;
- }
-
- .slot-button {
- /* #ifndef APP-NVUE */
- display: flex;
- height: 100%;
- /* #endif */
- flex: 1;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- padding: 0 20px;
- background-color: #ff5a5f;
- }
-
- .slot-button-text {
- color: #ffffff;
- font-size: 14px;
- }
- .finished {
- color: green; /* 已完成的备忘录显示为绿色 */
- }
-
- .unfinished {
- color: red; /* 未完成的备忘录显示为红色 */
- }
- .container {
- /* #ifndef APP-NVUE */
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- /* #endif */
- }
- .myimg{
- width: 600rpx;
- height: 400rpx;
- }
- </style>
-
-
-
- <template>
- <view class="mine">
- <!--顶部信息:头像,昵称,发文收藏和点赞数据-->
- <view class="top">
- <view class="userinfo">
- <view class="group">
- <view class="pic">
- <image v-if="user.avatar != null" :src="user.avatar"></image>
- <image v-else src="/static/tabs/member.png" mode="aspectFit"></image>
- </view>
- <view>
- <text v-if="user.username != null" v-text="user.username"></text>
- <text v-else class="login" @tap="gotoLogin" v-text="'点击登录'"></text>
- </view>
-
- </view>
- <view class="more">
- <text class="iconfont icon-a-10-you"></text>
- </view>
- </view>
- </view>
- <!-- 登录后的补充组件-->
- <view v-if="user.username !=null">
-
- <!--退出登录-->
- <view class="itemgroup">
- <view class="item">
- <view class="left" @tap="gotoLogout">
- <text class="iconfont icon-a-73-tuichu"></text>
- <text>退出登录</text>
- </view>
- <view>
- <text class="iconfont icon-a-10-you"></text>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
-
- <script>
- import {
- hasLogin,
- logout,
- getUserid
- } from '@/store/index.js'
-
- export default {
- data() {
- return {
- user: {
- username: null, //用户账号
- avatar: null, //个人照片
-
- }
- };
- },
-
- onLoad() {
- if (hasLogin()) {
- this.getUserInfo();
- }
- },
-
- methods: {
- gotoLogin() {
- //跳转到的登录页面
- uni.redirectTo({
- url:"/pages/Login"
- });
- },
-
- getUserInfo() {
- this.userid = getUserid();
- if (this.userid != null) {
- uni.request({
-
- url: `http://localhost:2023/user/selectUserById/${this.userid}`,
- method: "GET",
- success: (res) => {
- this.user = res.data.data;
- }
- });
- }
- },
-
-
- gotoLogout() {
- uni.showModal({
- title: "是否确定退出",
- success: res => {
- if (res.confirm) {
- logout();
- this.user = {
- username: null,
- avatar: null,
- }
- }
- }
- });
- }
-
- }
-
- }
- </script>
-
- <style lang="scss">
- .mine {
- margin: 30rpx 30rpx;
-
- .top {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-
- .userinfo {
- display: flex;
- flex: row;
- justify-content: space-between;
- align-items: center;
-
- .group {
- display: flex;
- align-items: center;
-
- .pic {
- width: 120rpx;
- height: 120rpx;
- border-radius: 50%;
- overflow: hidden;
- border: 2rpx solid red;
- margin-right: 10rpx;
-
- image {
- width: 100%;
- height: 100%;
- }
- }
-
- .login {
- margin-left: 16rpx;
- font-size: 40rpx;
- }
- }
-
- .more {
- .iconfont {
- font-size: 40rpx;
- }
- }
- }
-
- .bloginfo {
- display: flex;
- flex: row;
- margin-top: 20rpx;
-
- view {
- margin-right: 30rpx;
- font-size: 26rpx;
- }
- }
- }
-
- .itemgroup {
- border-top: 4rpx solid #f4f4f4;
- margin-top: 30rpx;
-
- .item {
- padding: 24rpx 0;
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .left {
- text {
- margin-right: 16rpx;
- font-size: 36rpx;
- }
- }
- }
- }
- }
- </style>
- <template>
- <uni-card>
- <view class="registerform">
- <uni-forms ref="form" :model="user" :rules="rules" :labelWidth="85">
- <uni-forms-item label="账号" name="username" required>
- <uni-easyinput type="text" v-model="user.username" placeholder="请输入账号" />
- </uni-forms-item>
- <uni-forms-item label="密码" name="password" required>
- <uni-easyinput type="password" v-model="user.password" placeholder="请输入密码" />
- </uni-forms-item>
- <uni-forms-item label="再次输入" name="passwordconfirm" required>
- <uni-easyinput type="password" v-model="user.passwordconfirm" placeholder="再次输入密码" />
- </uni-forms-item>
- </uni-forms>
- <button @tap="submitForm" class="submit">注册</button>
- </view>
- </uni-card>
- </template>
-
- <script>
-
- export default {
- data() {
- return {
- user: {},
- rules: {
- username: {
- rules: [{
- required: true,
- errorMessage: '请输入账号',
- },
- {
- minLength: 2,
- maxLength: 20,
- errorMessage: '账号长度在 {minLength}到 {maxLength}个字符 ',
- }
- ]
- },
- password: {
- rules: [{
- required: true,
- errorMessage: '请输入密码',
- },
- {
- minLength: 2,
- maxLength: 20,
- errorMessage: '密码长度在 {minLength}到 {maxLength}个字符 ',
- }
-
- ]
- },
- passwordconfirm: {
- rules: [{
- required: true,
- errorMessage: '请输入密码',
- },
- {
- minLength: 2,
- maxLength: 20,
- errorMessage: '密码长度在 {minLength}到 {maxLength}个字符 ',
- },
- {
- validateFunction: function(rule, value, data, callback) {
- if (value !== data.password) {
- callback("两次输入的密码不一致");
- }
- return true;
- }
- }
- ]
- },
-
- }
-
- };
- },
- methods: {
- submitForm() {
- this.$refs.form.validate().then((res) => {
-
- Reflect.deleteProperty(this.user, "passwordconfirm");
- // console.log('user 模型',this.user);
-
- uni.request({
- url: "http://localhost:2023/user/register",
- method: "POST",
- data: {
- username: this.user.username,
- password: this.user.password,
- },
- success: (result) => {
- if (result.data.msg) {
- uni.showToast({
- title: "用户注册成功",
- duration: 2000
- });
-
- //注册成功则转到登录页面
- setTimeout(() => {
- uni.redirectTo({
- url: "/pages/Login"
- });
- this.user = {};
- }, 2000);
- } else {
- uni.showToast({
- title: result.data.describe,
- duration: 2000,
- icon: "error"
- })
- }
-
- } //end of success
-
- });
- }).catch(err => {
- // console.log(err);
- })
- },
- }
-
- }
- </script>
-
- <style lang="scss" scoped>
- .registerform {
- margin: 6rpx;
-
- .submit {
- background-color: $uni-color-primary;
- color: white;
- }
- }
- </style>
到这里前后端代码已经全部完成,下面是运行的截图
到此全部结束啦,如果此文章对你有帮助,希望给一个关注+点赞+收藏
若需要源码可以私信我,免费分享
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。