当前位置:   article > 正文

uniapp+springboot 实现前后端分离的个人备忘录系统【超详细】_uniapp springboot

uniapp springboot

目录

(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)前端工程

index.js

pages.json

addNote.vue

 catNote.vue

 Login.vue

 Main.vue

 mine.vue

Register.vue


接下来我们使用uniapp+springboot实现一个简单的前后端分离的小项目----个人备忘录系统,适合初学者学习,全文大约5w字,全部免费,以下是详细步骤:

(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文件:
  1. /*
  2. Navicat Premium Data Transfer
  3. Source Server : mySQL
  4. Source Server Type : MySQL
  5. Source Server Version : 80019
  6. Source Host : localhost:3305
  7. Source Schema : memo
  8. Target Server Type : MySQL
  9. Target Server Version : 80019
  10. File Encoding : 65001
  11. Date: 25/12/2023 11:06:46
  12. */
  13. SET NAMES utf8mb4;
  14. SET FOREIGN_KEY_CHECKS = 0;
  15. -- ----------------------------
  16. -- Table structure for notes
  17. -- ----------------------------
  18. DROP TABLE IF EXISTS `notes`;
  19. CREATE TABLE `notes` (
  20. `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'note表的id',
  21. `rid` int(0) NOT NULL COMMENT '这个笔记是哪个人的',
  22. `detail` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '笔记的内容',
  23. `photo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户上传的图片,null或者0表示无',
  24. `time` datetime(0) NOT NULL COMMENT '笔记的创建时间',
  25. `type` int(0) NOT NULL COMMENT '笔记的类型',
  26. `finish` int(0) NOT NULL COMMENT '任务是否完成',
  27. PRIMARY KEY (`id`) USING BTREE
  28. ) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
  29. -- ----------------------------
  30. -- Records of notes
  31. -- ----------------------------
  32. 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);
  33. INSERT INTO `notes` VALUES (32, 13, '国奖答辩', NULL, '2023-10-16 20:26:27', 2, 1);
  34. INSERT INTO `notes` VALUES (33, 13, 'hehang-blog数据库项目', NULL, '2024-01-07 20:26:56', 2, 1);
  35. INSERT INTO `notes` VALUES (34, 13, '数据库详细设计报告', NULL, '2023-11-08 20:27:24', 2, 1);
  36. INSERT INTO `notes` VALUES (35, 13, '数据库课设验收', NULL, '2023-11-22 20:28:02', 2, 1);
  37. INSERT INTO `notes` VALUES (36, 13, '计算机组成原理期中考试', NULL, '2023-11-24 20:28:44', 2, 1);
  38. INSERT INTO `notes` VALUES (37, 13, '计算机能力挑战赛C语言', NULL, '2023-11-25 08:00:00', 2, 1);
  39. INSERT INTO `notes` VALUES (38, 13, '学生代表大会', '0', '2023-12-07 13:15:00', 3, 1);
  40. INSERT INTO `notes` VALUES (39, 13, '闪聚支付springclound项目', NULL, '2023-12-19 18:30:21', 2, 1);
  41. INSERT INTO `notes` VALUES (40, 13, '英语四级考试', NULL, '2023-12-16 09:00:00', 2, 1);
  42. INSERT INTO `notes` VALUES (41, 13, '数据库课设详细设计文档', '0', '2024-01-07 23:59:59', 2, 0);
  43. INSERT INTO `notes` VALUES (43, 13, '完成代码细节的修改', NULL, '2023-12-18 12:00:00', 2, 1);
  44. INSERT INTO `notes` VALUES (44, 14, '记得吃药', '0', '2023-12-24 14:57:57', 8, 0);
  45. INSERT INTO `notes` VALUES (45, 14, '写完uniapp期末课设的报告', '', '2023-12-24 14:08:58', 2, 1);
  46. 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);
  47. -- ----------------------------
  48. -- Table structure for type
  49. -- ----------------------------
  50. DROP TABLE IF EXISTS `type`;
  51. CREATE TABLE `type` (
  52. `typeid` int(0) NOT NULL COMMENT '主键',
  53. `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '是什么类型',
  54. PRIMARY KEY (`typeid`) USING BTREE
  55. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
  56. -- ----------------------------
  57. -- Records of type
  58. -- ----------------------------
  59. INSERT INTO `type` VALUES (1, '日常');
  60. INSERT INTO `type` VALUES (2, '学习');
  61. INSERT INTO `type` VALUES (3, '工作');
  62. INSERT INTO `type` VALUES (4, '娱乐');
  63. INSERT INTO `type` VALUES (5, '社交');
  64. INSERT INTO `type` VALUES (6, '家庭');
  65. INSERT INTO `type` VALUES (7, '个人');
  66. INSERT INTO `type` VALUES (8, '健康');
  67. INSERT INTO `type` VALUES (9, '财务');
  68. -- ----------------------------
  69. -- Table structure for user
  70. -- ----------------------------
  71. DROP TABLE IF EXISTS `user`;
  72. CREATE TABLE `user` (
  73. `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '用户的id',
  74. `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户名字',
  75. `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户密码',
  76. `avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户的头像',
  77. PRIMARY KEY (`id`) USING BTREE
  78. ) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
  79. -- ----------------------------
  80. -- Records of user
  81. -- ----------------------------
  82. 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');
  83. INSERT INTO `user` VALUES (14, 'abcd', '123456', 'https://pic2.zhimg.com/v2-fc348d5e926116782149d2151dc09834.jpg');
  84. 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');
  85. 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');
  86. 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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.7.8</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.example</groupId>
  12. <artifactId>Memo-hehang</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>hehang</name>
  15. <description>memo</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.mybatis.spring.boot</groupId>
  26. <artifactId>mybatis-spring-boot-starter</artifactId>
  27. <version>2.3.0</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.mybatis.spring.boot</groupId>
  31. <artifactId>mybatis-spring-boot-starter</artifactId>
  32. <version>2.3.0</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-starter-data-jpa</artifactId>
  37. </dependency>
  38. <dependency>
  39. <groupId>com.mysql</groupId>
  40. <artifactId>mysql-connector-j</artifactId>
  41. <scope>runtime</scope>
  42. </dependency>
  43. <dependency>
  44. <groupId>org.projectlombok</groupId>
  45. <artifactId>lombok</artifactId>
  46. <optional>true</optional>
  47. </dependency>
  48. <dependency>
  49. <groupId>org.springframework.boot</groupId>
  50. <artifactId>spring-boot-starter-test</artifactId>
  51. <scope>test</scope>
  52. </dependency>
  53. <dependency>
  54. <groupId>com.baomidou</groupId>
  55. <artifactId>mybatis-plus-boot-starter</artifactId>
  56. <version>3.4.2</version>
  57. </dependency>
  58. <!--七牛云OOS-->
  59. <dependency>
  60. <groupId>com.qiniu</groupId>
  61. <artifactId>qiniu-java-sdk</artifactId>
  62. <version>[7.13.0, 7.13.99]</version>
  63. </dependency>
  64. <dependency>
  65. <groupId>com.google.code.gson</groupId>
  66. <artifactId>gson</artifactId>
  67. <version>2.10.1</version>
  68. </dependency>
  69. </dependencies>
  70. <build>
  71. <plugins>
  72. <plugin>
  73. <groupId>org.springframework.boot</groupId>
  74. <artifactId>spring-boot-maven-plugin</artifactId>
  75. <configuration>
  76. <excludes>
  77. <exclude>
  78. <groupId>org.projectlombok</groupId>
  79. <artifactId>lombok</artifactId>
  80. </exclude>
  81. </excludes>
  82. </configuration>
  83. </plugin>
  84. <plugin>
  85. <groupId>org.apache.maven.plugins</groupId>
  86. <artifactId>maven-compiler-plugin</artifactId>
  87. <configuration>
  88. <source>9</source>
  89. <target>9</target>
  90. </configuration>
  91. </plugin>
  92. </plugins>
  93. </build>
  94. </project>

然后我们修改resources文件夹下的application.yml,数据库连接修改成你自己的,七牛云的使用可以看我上一篇博客

  1. server:
  2. port: 2023
  3. spring:
  4. datasource:
  5. driver-class-name: com.mysql.cj.jdbc.Driver
  6. url: jdbc:mysql://localhost:3305/memo?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
  7. username: root
  8. password: 123456
  9. mybatis-plus:
  10. global-config:
  11. db-config:
  12. id-type: auto
  13. # configuration:
  14. # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  15. # 打开七牛云,找到密钥管理,把相关信息填写到下面3行
  16. myoss:
  17. accessKey: yourAK
  18. secretKey: yourSK
  19. bucket: yourbucket

接下来在项目下创建如下几个包:

common包: 
R.java

在common文件下创建 R.java 类,主要用于封装返回给前端的数据:

  1. package com.example.memohehang.common;
  2. import lombok.Data;
  3. import java.io.Serializable;
  4. /**
  5. * 统一返回类型
  6. */
  7. @Data
  8. public class R implements Serializable
  9. {
  10. private int code; // 200是正常,非200表示异常
  11. private String msg;
  12. private Object data;
  13. public static R success(Object data)
  14. {
  15. return success(200, "操作成功", data);
  16. }
  17. public static R success(int code, String msg, Object data)
  18. {
  19. R r = new R();
  20. r.setCode(code);
  21. r.setMsg(msg);
  22. r.setData(data);
  23. return r;
  24. }
  25. public static R error(int i, String msg)
  26. {
  27. return error(400, msg, null);
  28. }
  29. public static R error(String msg, Object data)
  30. {
  31. return error(400, msg, data);
  32. }
  33. public static R error(int code, String msg, Object data)
  34. {
  35. R r = new R();
  36. r.setCode(code);
  37. r.setMsg(msg);
  38. r.setData(data);
  39. return r;
  40. }
  41. }
config包: 
CorsConfig.java

在config包下创建 CorsConfig.java 类,用于解决前端跨域问题,在config.AllowedOrigin中填写你自己的前端端口,一般为8080,或者填 * ,允许所有

  1. package com.example.memohehang.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.filter.CorsFilter;
  5. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  6. import org.springframework.web.cors.CorsConfiguration;
  7. //解决前端跨域问题
  8. @Configuration
  9. public class CorsConfig {
  10. @Bean
  11. public CorsFilter corsFilter()
  12. {
  13. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  14. CorsConfiguration config = new CorsConfiguration();
  15. config.addAllowedOrigin("http://localhost:8080");
  16. config.addAllowedHeader("*");
  17. config.addAllowedMethod("*");
  18. config.setAllowCredentials(true);
  19. source.registerCorsConfiguration("/**", config);
  20. return new CorsFilter(source);
  21. }
  22. }
domain包:

对应数据库的实体类

Notes.java

这里我们利用jsonformat注解进行时间格式化

  1. package com.example.memohehang.domain;
  2. import com.baomidou.mybatisplus.annotation.IdType;
  3. import com.baomidou.mybatisplus.annotation.TableId;
  4. import com.fasterxml.jackson.annotation.JsonFormat;
  5. import lombok.AllArgsConstructor;
  6. import lombok.Data;
  7. import lombok.NoArgsConstructor;
  8. import java.util.Date;
  9. @Data
  10. @AllArgsConstructor
  11. @NoArgsConstructor
  12. public class Notes {
  13. @TableId(value = "id", type = IdType.AUTO)
  14. private Integer id;
  15. private Integer rid;
  16. // 内容
  17. private String detail;
  18. // 截止时间
  19. @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
  20. private Date time;
  21. // 类型
  22. private Integer type;
  23. //图片
  24. private String photo;
  25. // 是否完成 0表示还没有 1表示完成了
  26. private Integer finish;
  27. }
Type.java
  1. package com.example.memohehang.domain;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class Type
  9. {
  10. private Integer typeid;
  11. private String type;
  12. }
User.java
  1. package com.example.memohehang.domain;
  2. import lombok.AllArgsConstructor;
  3. import com.baomidou.mybatisplus.annotation.IdType;
  4. import com.baomidou.mybatisplus.annotation.TableId;
  5. import lombok.Data;
  6. import lombok.NoArgsConstructor;
  7. @Data
  8. @AllArgsConstructor
  9. @NoArgsConstructor
  10. public class User
  11. {
  12. //主键自增
  13. @TableId(value = "id", type = IdType.AUTO)
  14. private Integer id;
  15. private String username;
  16. private String password;
  17. // 头像
  18. private String avatar;
  19. }
utils包:
PathUtils.java

这是对上传的文件进行重命名,在后面的七牛云相关的service中会用到

  1. package com.example.memohehang.utils;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. import java.util.UUID;
  5. //对原始文件名进行修改文件名,并修改存放目录
  6. public class PathUtils
  7. {
  8. public static String generateFilePath(String fileName)
  9. {
  10. //根据日期生成路径
  11. SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
  12. String datePath = sdf.format(new Date());
  13. //uuid作为文件名
  14. String uuid = UUID.randomUUID().toString().replaceAll("-", "");
  15. //后缀和文件后缀一致
  16. int index = fileName.lastIndexOf(".");
  17. // test.jpg -> .jpg
  18. String fileType = fileName.substring(index);
  19. return new StringBuilder().append(datePath).append(uuid).append(fileType).toString();
  20. }
  21. }

 我一般写代码的顺序为:Controller----service----serviceImpl----mapper,在方法学一般先写调用体,根据调用写对应的实现,下面我们按照这个顺序来写:

controller包:
NotesController.java
  1. package com.example.memohehang.controller;
  2. import com.example.memohehang.common.R;
  3. import com.example.memohehang.domain.Notes;
  4. import com.example.memohehang.service.NotesService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.web.bind.annotation.*;
  8. @Controller
  9. @RequestMapping("/note")
  10. public class NotesController {
  11. @Autowired
  12. private NotesService notesService;
  13. // 添加
  14. @RequestMapping("/save")
  15. @ResponseBody
  16. public R save(@RequestBody Notes notes)
  17. {
  18. System.out.println("添加备忘录:" + notes);
  19. return notesService.addNote(notes);
  20. }
  21. // 根据noteid查询对应的note
  22. @RequestMapping ("/selectByNote/{noteid}")
  23. @ResponseBody
  24. public R selectByNote(@PathVariable("noteid") Integer noteid)
  25. {
  26. return notesService.selectByNote(noteid);
  27. }
  28. // 查询 只显示用户自己的
  29. @RequestMapping ("/selectAllByUserID/{userid}")
  30. @ResponseBody
  31. public R selectAllById(@PathVariable("userid") Integer userid,@RequestParam(defaultValue = "1") Integer currentPage)
  32. {
  33. return notesService.selectAllById(userid,currentPage);
  34. }
  35. // 查询最近即将截止的未完成的备忘录的时间差
  36. @RequestMapping ("/selectTime/{userid}")
  37. @ResponseBody
  38. public R selectcutDownTime(@PathVariable("userid") Integer userid)
  39. {
  40. return notesService.selectcutDownTime(userid);
  41. }
  42. // 分类查询
  43. @RequestMapping ("/selectByType/{userid}/{type}/{isFinish}")
  44. @ResponseBody
  45. public R selectByType(@PathVariable("userid") Integer userid, @PathVariable("type") Integer type,@PathVariable("isFinish") Integer isFinish,@RequestParam(defaultValue = "1") Integer currentPage)
  46. {
  47. return notesService.selectByType(userid,type,isFinish,currentPage);
  48. }
  49. // 修改
  50. @RequestMapping("/update")
  51. @ResponseBody
  52. public R update(@RequestBody Notes notes)
  53. {
  54. return notesService.update(notes);
  55. }
  56. // 删除
  57. @DeleteMapping("/delete/{id}")
  58. @ResponseBody
  59. public R delete(@PathVariable("id") Integer id)
  60. {
  61. return notesService.delete(id);
  62. }
  63. }
TypeController.java
  1. package com.example.memohehang.controller;
  2. import com.example.memohehang.common.R;
  3. import com.example.memohehang.service.TypeService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.web.bind.annotation.*;
  7. @Controller
  8. @RequestMapping("/type")
  9. public class TypeController
  10. {
  11. @Autowired
  12. private TypeService typeService;
  13. // 获取编号与类型的映射表
  14. @ResponseBody
  15. @GetMapping("/getMapping")
  16. public R typeMapping()
  17. {
  18. return typeService.typeMapping();
  19. }
  20. }
UploadController.java
  1. package com.example.memohehang.controller;
  2. import com.example.memohehang.common.R;
  3. import com.example.memohehang.service.OssUploadService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.PostMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import org.springframework.web.multipart.MultipartFile;
  8. @RestController
  9. public class UploadController
  10. {
  11. @Autowired
  12. private OssUploadService ossUploadService;
  13. @PostMapping("/upload")
  14. public R uploadImg(MultipartFile img)
  15. {
  16. return ossUploadService.uploadImg(img);
  17. }
  18. }
 UserController.java
  1. package com.example.memohehang.controller;
  2. import com.example.memohehang.common.R;
  3. import com.example.memohehang.domain.User;
  4. import com.example.memohehang.service.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.web.bind.annotation.*;
  7. @RestController
  8. @RequestMapping("/user")
  9. public class UserController {
  10. @Autowired
  11. private UserService userService;
  12. // 登录功能
  13. @RequestMapping(value = "/login", method = RequestMethod.POST)
  14. public R login(@RequestBody User user)
  15. {
  16. return userService.login(user);
  17. }
  18. // 注册功能
  19. @RequestMapping(value = "/register", method = RequestMethod.POST)
  20. public R register(@RequestBody User user)
  21. {
  22. return userService.register(user);
  23. }
  24. // 根据用户id查询
  25. @RequestMapping ("/selectUserById/{userid}")
  26. @ResponseBody
  27. public R selectUserById(@PathVariable("userid") Integer userid)
  28. {
  29. return userService.selectUserById(userid);
  30. }
  31. }

我们用mybatisplus自带的查询函数即可完成所有的CRUD,因此我们不需要写SQL语句

 service包:
NotesService
  1. package com.example.memohehang.service;
  2. import com.baomidou.mybatisplus.extension.service.IService;
  3. import com.example.memohehang.common.R;
  4. import com.example.memohehang.domain.Notes;
  5. import com.example.memohehang.domain.User;
  6. import org.springframework.web.bind.annotation.PathVariable;
  7. import org.springframework.web.bind.annotation.RequestBody;
  8. import org.springframework.web.bind.annotation.RequestParam;
  9. public interface NotesService extends IService<Notes>
  10. {
  11. /**
  12. * 添加备忘录
  13. * @param notes
  14. * @return
  15. */
  16. public R addNote(Notes notes);
  17. /**
  18. * 根据noteid查询note
  19. * @param noteid
  20. * @return
  21. */
  22. public R selectByNote(Integer noteid);
  23. /**
  24. * 查询 只显示用户自己的
  25. * @param userid
  26. * @param currentPage
  27. * @return
  28. */
  29. public R selectAllById(Integer userid,Integer currentPage);
  30. /**
  31. * 查询最近即将截止的未完成的备忘录的时间差
  32. * @param userid
  33. * @return
  34. */
  35. public R selectcutDownTime(Integer userid);
  36. /**
  37. * 分类查询
  38. * @param userid
  39. * @param type
  40. * @param isFinish
  41. * @param currentPage
  42. * @return
  43. */
  44. public R selectByType(Integer userid, Integer type,Integer isFinish,Integer currentPage);
  45. /**
  46. * 修改
  47. * @param notes
  48. * @return
  49. */
  50. public R update(Notes notes);
  51. /**
  52. * 删除
  53. * @param id
  54. * @return
  55. */
  56. public R delete(Integer id);
  57. }
OssUploadService
  1. package com.example.memohehang.service;
  2. import com.example.memohehang.common.R;
  3. import org.springframework.web.multipart.MultipartFile;
  4. public interface OssUploadService {
  5. //图片上传到七牛云
  6. R uploadImg(MultipartFile img);
  7. }
TypeService
  1. package com.example.memohehang.service;
  2. import com.baomidou.mybatisplus.extension.service.IService;
  3. import com.example.memohehang.common.R;
  4. import com.example.memohehang.domain.Type;
  5. public interface TypeService extends IService<Type>
  6. {
  7. /**
  8. * 获取所有类型
  9. * @return
  10. */
  11. public R typeMapping();
  12. }
UserService
  1. package com.example.memohehang.service;
  2. import com.baomidou.mybatisplus.extension.service.IService;
  3. import com.example.memohehang.common.R;
  4. import com.example.memohehang.domain.User;
  5. public interface UserService extends IService<User>
  6. {
  7. /**
  8. * 登录
  9. * @param user
  10. * @return
  11. */
  12. public R login(User user);
  13. /**
  14. * 注册
  15. * @param user
  16. * @return
  17. */
  18. public R register(User user);
  19. /**
  20. * 根据id查询用户
  21. * @param userid
  22. * @return
  23. */
  24. public R selectUserById(Integer userid);
  25. }

接下来在service包中创建Impl,注意第一个 “ I ” 是大写的 “ i ”,第二个是小写的 “ L ”

Impl包:
NotesServiceImpl.java
  1. package com.example.memohehang.service.Impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.core.metadata.IPage;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  6. import com.example.memohehang.common.R;
  7. import com.example.memohehang.domain.Notes;
  8. import com.example.memohehang.mapper.NotesMapper;
  9. import com.example.memohehang.service.NotesService;
  10. import org.springframework.stereotype.Service;
  11. import java.time.Duration;
  12. import java.time.Instant;
  13. import java.time.LocalDateTime;
  14. import java.time.ZoneId;
  15. import java.util.Date;
  16. import java.util.HashMap;
  17. import java.util.List;
  18. import java.util.Map;
  19. @Service
  20. public class NotesServiceImpl extends ServiceImpl<NotesMapper, Notes> implements NotesService
  21. {
  22. private NotesMapper notesMapper;
  23. /**
  24. * 添加备忘录
  25. * @param notes
  26. * @return
  27. */
  28. @Override
  29. public R addNote(Notes notes)
  30. {
  31. boolean b = save(notes);//调用mybatis-plus
  32. if (b)
  33. {
  34. return R.success(200, "添加成功", null);
  35. }
  36. else
  37. {
  38. return R.error(405, "添加失败");
  39. }
  40. }
  41. /**
  42. * 根据noteid查询note
  43. * @param noteid
  44. * @return
  45. */
  46. @Override
  47. public R selectByNote(Integer noteid)
  48. {
  49. QueryWrapper<Notes> wrapper = new QueryWrapper<>();
  50. wrapper.eq("id", noteid);
  51. List<Notes> note = list(wrapper);
  52. if (note == null)
  53. {
  54. return R.error(400,"查询失败");
  55. }
  56. else
  57. {
  58. return R.success(note.get(0));
  59. }
  60. }
  61. /**
  62. * 查询 只显示用户自己的
  63. * @param userid
  64. * @param currentPage
  65. * @return
  66. */
  67. @Override
  68. public R selectAllById(Integer userid, Integer currentPage)
  69. {
  70. Page page = new Page(currentPage, 20);
  71. // 查询条件 分页的基础上 再按照创建时间排序
  72. IPage pageData = page(page, new QueryWrapper<Notes>().orderByAsc("finish","time").eq("rid", userid));
  73. return R.success(pageData);
  74. }
  75. /**
  76. * 查询最近即将截止的未完成的备忘录的时间差
  77. * @param userid
  78. * @return
  79. */
  80. @Override
  81. public R selectcutDownTime(Integer userid)
  82. {
  83. QueryWrapper<Notes> wrapper = new QueryWrapper<>();
  84. wrapper.eq("rid", userid).orderByAsc("finish", "time");
  85. List<Notes> note = list(wrapper);
  86. // 处理查询结果
  87. if (note != null && !note.isEmpty())
  88. {
  89. Notes firstUnfinishedNote = null;
  90. for (Notes n : note)
  91. {
  92. if (n.getFinish() == 0)
  93. {
  94. firstUnfinishedNote = n;
  95. break;
  96. }
  97. }
  98. if (firstUnfinishedNote != null)
  99. {
  100. LocalDateTime currentTime = LocalDateTime.now();
  101. Date noteTime = firstUnfinishedNote.getTime();
  102. Instant instant = noteTime.toInstant();
  103. LocalDateTime noteLocalDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
  104. Duration duration = Duration.between(currentTime, noteLocalDateTime);
  105. long days = duration.toDays();
  106. long hours = duration.toHoursPart();
  107. long minutes = duration.toMinutesPart();
  108. long seconds = duration.toSecondsPart();
  109. // 构造返回结果
  110. Map<String, Object> resultMap = new HashMap<>();
  111. resultMap.put("days", days);
  112. resultMap.put("hours", hours);
  113. resultMap.put("minutes", minutes);
  114. resultMap.put("seconds", seconds);
  115. System.out.println(resultMap);
  116. // 返回结果
  117. return R.success(200, "duration", resultMap);
  118. }
  119. else
  120. {
  121. return R.error(405, "没有找到未完成的备忘录");
  122. }
  123. }
  124. else
  125. {
  126. return R.error(405, "没有找到备忘录");
  127. }
  128. }
  129. /**
  130. * 分类查询
  131. * @param userid
  132. * @param type
  133. * @param isFinish
  134. * @param currentPage
  135. * @return
  136. */
  137. @Override
  138. public R selectByType(Integer userid, Integer type, Integer isFinish, Integer currentPage)
  139. {
  140. Page page = new Page(currentPage, 20);
  141. IPage pageData = page(page, new QueryWrapper<Notes>().orderByAsc("time").eq("rid", userid).eq("finish", isFinish).eq("type", type));
  142. return R.success(pageData);
  143. }
  144. /**
  145. * 修改
  146. * @param notes
  147. * @return
  148. */
  149. @Override
  150. public R update(Notes notes)
  151. {
  152. System.out.println("开始更新");
  153. System.out.println(notes);
  154. boolean b = update(notes, new QueryWrapper<Notes>().eq("id", notes.getId()));
  155. if (b)
  156. {
  157. System.out.println("更新成功");
  158. return R.success(200, "更新成功", null);
  159. }
  160. System.out.println("更新失败");
  161. return R.error(405, "更新失败");
  162. }
  163. /**
  164. * 删除
  165. * @param id
  166. * @return
  167. */
  168. @Override
  169. public R delete(Integer id)
  170. {
  171. System.out.println("user delete..." + id);
  172. boolean b = removeById(id);
  173. if (b)
  174. {
  175. return R.success(200, "删除成功", null);
  176. }
  177. return R.error(405, "删除失败");
  178. }
  179. }
OssUploadServiceImpl.java

注意这里需要修改外链回显链接

  1. package com.example.memohehang.service.Impl;
  2. import com.example.memohehang.common.R;
  3. import com.example.memohehang.service.OssUploadService;
  4. import com.example.memohehang.utils.PathUtils;
  5. import com.google.gson.Gson;
  6. import com.qiniu.common.QiniuException;
  7. import com.qiniu.http.Response;
  8. import com.qiniu.storage.Configuration;
  9. import com.qiniu.storage.Region;
  10. import com.qiniu.storage.UploadManager;
  11. import com.qiniu.storage.model.DefaultPutRet;
  12. import com.qiniu.util.Auth;
  13. import lombok.Data;
  14. import org.springframework.boot.context.properties.ConfigurationProperties;
  15. import org.springframework.stereotype.Service;
  16. import org.springframework.web.multipart.MultipartFile;
  17. import java.io.InputStream;
  18. @Service
  19. @Data//为成员变量生成get和set方法
  20. @ConfigurationProperties(prefix = "myoss")
  21. //把文件上传到七牛云
  22. public class OssUploadServiceImpl implements OssUploadService {
  23. @Override
  24. //MultipartFile是spring提供的接口
  25. public R uploadImg(MultipartFile img) {
  26. //获取原始文件名
  27. String originalFilename = img.getOriginalFilename();
  28. // 获取文件大小
  29. long fileSize = img.getSize();
  30. //PathUtils.generateFilePath(originalFilename)表示把原始文件名转换成指定文件名
  31. String filePath = PathUtils.generateFilePath(originalFilename);
  32. //下面用于调用的uploadOss方法返回的必须是String类型
  33. String url = uploadOss(img,filePath);
  34. System.out.println("外链地址:"+url);
  35. //把得到的外链地址返回给前端
  36. return R.success(200,"操作成功",url);
  37. }
  38. //----------------------------------上传文件到七牛云----------------------------------------
  39. //注意要从application.yml读取属性数据,下面的3个成员变量的名字必须对应application.yml的myoss属性的三个子属性名字
  40. private String accessKey;
  41. private String secretKey;
  42. private String bucket;
  43. //上传文件的具体代码。MultipartFile是spring提供的接口,作用是实现文件上传
  44. private String uploadOss(MultipartFile imgFile, String filePath){
  45. //构造一个带指定 Region 对象的配置类。你的七牛云OSS创建的是哪个区域的,那么就调用Region的什么方法即可
  46. Configuration cfg = new Configuration(Region.huanan());
  47. cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
  48. UploadManager uploadManager = new UploadManager(cfg);
  49. //打开七牛云,把鼠标悬浮在右上角的个人头像,然后就会看到'密钥管理',点击进入就有你的密钥,把其中的AK和SK复制到下面两行
  50. //String accessKey = "_ibGP9wytjLCAZPqcFaWQNxbw7fMUvofSOvOFFR3";
  51. //String secretKey = "QSOAU-cv3sSDGNfVNPF6iXz-PsP5X9QTrjFI9zYw";
  52. //String bucket = "hehang-blog";
  53. //为避免上面3行暴露信息,我们会把信息写到application.yml里面,然后添加ConfigurationProperties注解、3个成员变量即可读取
  54. //文件名,如果写成null的话,就以文件内容的hash值作为文件名
  55. String key = filePath;
  56. try {
  57. //byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
  58. //ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes);
  59. //上面两行是官方写的(注释掉),下面那几行是我们写的
  60. //把前端传过来的文件转换成InputStream对象
  61. InputStream xxinputStream = imgFile.getInputStream();
  62. Auth auth = Auth.create(accessKey, secretKey);
  63. String upToken = auth.uploadToken(bucket);
  64. try {
  65. //把前端传过来的xxinputStream图片上传到七牛云
  66. Response response = uploadManager.put(xxinputStream,key,upToken,null, null);
  67. //解析上传成功的结果
  68. DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
  69. System.out.println("上传成功! 生成的key是: "+putRet.key);
  70. System.out.println("上传成功! 生成的hash是: "+putRet.hash);
  71. return "http://s6422okdy.hn-bkt.clouddn.com/"+key;//注意这个地方替换成自己的域名,http://不能掉
  72. } catch (QiniuException ex) {
  73. Response r = ex.response;
  74. System.err.println(r.toString());
  75. try {
  76. System.err.println(r.bodyString());
  77. } catch (QiniuException ex2) {
  78. //ignore
  79. }
  80. }
  81. }catch (Exception e) {
  82. //ignore
  83. }
  84. return "上传失败";
  85. }
  86. }
TypeServiceImpl.java
  1. package com.example.memohehang.service.Impl;
  2. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  3. import com.example.memohehang.common.R;
  4. import com.example.memohehang.domain.Type;
  5. import com.example.memohehang.mapper.TypeMapper;
  6. import com.example.memohehang.service.TypeService;
  7. import org.springframework.stereotype.Service;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. @Service
  11. public class TypeServiceImpl extends ServiceImpl<TypeMapper, Type> implements TypeService
  12. {
  13. /**
  14. * 获取所有类型
  15. * @return
  16. */
  17. @Override
  18. public R typeMapping()
  19. {
  20. List<Type> types = list();
  21. HashMap<Integer, String> hashMap = new HashMap<>();
  22. for (Type type : types)
  23. {
  24. hashMap.put(type.getTypeid(), type.getType());
  25. }
  26. return R.success(hashMap);
  27. }
  28. }
UserServiceImpl.java
  1. package com.example.memohehang.service.Impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5. import com.example.memohehang.common.R;
  6. import com.example.memohehang.domain.User;
  7. import com.example.memohehang.mapper.UserMapper;
  8. import com.example.memohehang.service.UserService;
  9. import org.springframework.stereotype.Service;
  10. import java.util.List;
  11. @Service
  12. public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService
  13. {
  14. /**
  15. * 登录
  16. * @param user
  17. * @return
  18. */
  19. @Override
  20. public R login(User user)
  21. {
  22. // 判断用户账号是否正确
  23. User one = getOne(new QueryWrapper<User>()
  24. .eq("username", user.getUsername())
  25. .eq("password", user.getPassword())
  26. );
  27. if (one != null)
  28. {
  29. return R.success(200,"登录成功", one);
  30. }
  31. else
  32. {
  33. return R.error(405, "账号或密码错误");
  34. }
  35. }
  36. @Override
  37. public R register(User user)
  38. {
  39. LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
  40. queryWrapper.eq(User::getUsername, user.getUsername());
  41. System.out.println(user);
  42. User tempUsername = getOne(queryWrapper);
  43. // 先判断一下用户是否存在 存在就返回false
  44. if (tempUsername != null)
  45. {
  46. return R.error(405,"账户已存在");
  47. }
  48. else
  49. {
  50. //网上随机找的一个图片
  51. user.setAvatar("https://img2.baidu.com/it/u=3841326637,2519425910&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501");
  52. // 反之加入
  53. save(user);
  54. return R.success(user);
  55. }
  56. }
  57. /**
  58. * 根据id查询用户
  59. * @param userid
  60. * @return
  61. */
  62. @Override
  63. public R selectUserById(Integer userid)
  64. {
  65. // 判断用户账号是否正确
  66. User one = getOne(new QueryWrapper<User>()
  67. .eq("id", userid)
  68. );
  69. if (one != null)
  70. {
  71. return R.success(200,"查询成功", one);
  72. }
  73. else
  74. {
  75. return R.error(405, "查询失败");
  76. }
  77. }
  78. }

至此后端工程全部创建完毕,按照下图检查一下是否有缺少,注意Mapper可写也可以不写,因为我们不需要写SQL语句,不需要调用Mapper,全部完毕后就可以运行项目,利用apipost进行测试,或者前端创建完后直接集成测试

(6)前端工程

我们采用uniapp来写前端代码,按照以下步骤建立项目

输入项目名称,选择vue2

我们需要用到以下uniapp的组件,可以从uniapp组件库下载,链接为:组件使用的入门教程 | uni-app官网

对应的矢量图标可以在阿里巴巴矢量图库下载,链接为iconfont-阿里巴巴矢量图标库

然后我们在根目录下建立store文件夹,在此文件夹下建立index.js,用于存放一些函数

index.js
  1. export function getUserid() {
  2. let userid = uni.getStorageSync("userid");
  3. if (userid == null || userid === '')
  4. return '';
  5. else
  6. return userid;
  7. }
  8. export function getNoteid()
  9. {
  10. let noteid = uni.getStorageSync("noteid");
  11. if (noteid == null || noteid === '')
  12. return '';
  13. else
  14. return noteid;
  15. }
  16. export function getUsername()
  17. {
  18. let username = uni.getStorageSync("username");
  19. if (username == null || username === '')
  20. return '';
  21. else
  22. return username;
  23. }
  24. export function hasLogin() {
  25. let userid = uni.getStorageSync("userid");
  26. if (userid == null || userid === '') {
  27. return false;
  28. } else
  29. return true;
  30. }
  31. export function logout() {
  32. uni.removeStorageSync("userid");
  33. uni.removeStorageSync("noteid");
  34. uni.removeStorageSync("username");
  35. uni.redirectTo({
  36. url: "/pages/mine"
  37. });
  38. }

随后修改pages.json中修改相关页面配置文件,可以先创建相关页面后再进行此步骤,以免编译时报错

pages.json
  1. {
  2. "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
  3. {
  4. "path": "pages/Main",
  5. "style": {
  6. "navigationBarTitleText": "个人备忘录"
  7. }
  8. }
  9. ,{
  10. "path" : "pages/Login",
  11. "style" :
  12. {
  13. "navigationBarTitleText": "登录",
  14. "enablePullDownRefresh": false
  15. }
  16. }
  17. ,{
  18. "path" : "pages/Main",
  19. "style" :
  20. {
  21. "navigationBarTitleText": "所有备忘录",
  22. "enablePullDownRefresh": false
  23. }
  24. },
  25. {
  26. "path" : "pages/mine",
  27. "style" :
  28. {
  29. "navigationBarTitleText": "个人中心",
  30. "enablePullDownRefresh": false
  31. }
  32. }
  33. ,{
  34. "path" : "pages/addNote",
  35. "style" :
  36. {
  37. "navigationBarTitleText": "添加/修改备忘录",
  38. "enablePullDownRefresh": false
  39. }
  40. }
  41. ,{
  42. "path" : "pages/catNote",
  43. "style" :
  44. {
  45. "navigationBarTitleText": "查询备忘录",
  46. "enablePullDownRefresh": false
  47. }
  48. }
  49. ,{
  50. "path" : "pages/Register",
  51. "style" :
  52. {
  53. "navigationBarTitleText": "注册",
  54. "enablePullDownRefresh": false
  55. }
  56. }
  57. ],
  58. "globalStyle": {
  59. "navigationBarTextStyle": "black",
  60. "navigationBarTitleText": "个人备忘录",
  61. "navigationBarBackgroundColor": "#F8F8F8",
  62. "backgroundColor": "#F8F8F8"
  63. },
  64. "tabBar": {
  65. "list": [
  66. {
  67. "text": "首页",
  68. "pagePath": "pages/Main",
  69. "iconPath": "static/images/首页.png",
  70. "selectedIconPath": "static/images/首页2.png"
  71. },
  72. {
  73. "text": "记录",
  74. "pagePath": "pages/addNote",
  75. "iconPath": "static/images/记录.png",
  76. "selectedIconPath": "static/images/记录1.png"
  77. },
  78. {
  79. "text": "分类",
  80. "pagePath": "pages/catNote",
  81. "iconPath": "static/images/分类.png",
  82. "selectedIconPath": "static/images/分类2.png"
  83. },
  84. {
  85. "text": "我的",
  86. "pagePath": "pages/mine",
  87. "iconPath": "static/images/我的.png",
  88. "selectedIconPath": "static/images/我的2.png"
  89. }
  90. ]
  91. },
  92. "uniIdRouter": {}
  93. }

 然后再pages中建立以下页面文件,我这里没有创建同名目录

addNote.vue
  1. <template>
  2. <view>
  3. <uni-card title="添加/修改笔记" extra="必填">
  4. <uni-section>
  5. <view class="example">
  6. <uni-forms>
  7. <uni-forms-item label="截止时间">
  8. <uni-datetime-picker type="datetime" return-type="timestamp" v-model="time"/>
  9. </uni-forms-item>
  10. <uni-forms-item label="分类">
  11. <select v-model="selectedType" class="select">
  12. <option v-for="(value, key) in types" :key="key" :value="key">{{ value }}</option>
  13. </select>
  14. </uni-forms-item>
  15. <uni-forms-item label="内容">
  16. <uni-section type="line" padding>
  17. <uni-easyinput type="textarea" autoHeight v-model="context" placeholder="请输入内容"></uni-easyinput>
  18. </uni-section>
  19. </uni-forms-item>
  20. <uni-forms-item label="完成?">
  21. <zero-switch v-model="finish"></zero-switch>
  22. </uni-forms-item>
  23. </uni-forms>
  24. <button type="primary" @click="saveNote()">提交</button>
  25. </view>
  26. </uni-section>
  27. </uni-card>
  28. <uni-card title="上传文件" extra="可选">
  29. <view>
  30. <div class="button-container">
  31. <button type="primary" @tap="chooseFile">选择文件</button>
  32. <button type="primary" @click="cancelChooseFile">取消选择</button>
  33. </div><br>
  34. <image class="myimg" v-if="this.filePath != null && this.filePath != '0'" :src="this.filePath"></image>
  35. <button type="primary" @tap="uploadFile">上传文件</button>
  36. </view>
  37. </uni-card>
  38. </view>
  39. </template>
  40. <script>
  41. import {getUserid,getNoteid} from "@/store/index.js"
  42. export default {
  43. data(){
  44. return{
  45. noteId: '',
  46. userId: '',
  47. time: '',
  48. selectedType: '',
  49. types: {},
  50. context: '',
  51. finish: false,
  52. note:{},
  53. filePath: null,
  54. fileUrl: null,
  55. };
  56. },
  57. onLoad() {
  58. this.noteId = getNoteid()//获取缓存中的noteid
  59. this.userId = getUserid()
  60. uni.request({
  61. url:`http://localhost:2023/type/getMapping`,
  62. method:"GET",
  63. success:(res)=>{
  64. // 将返回的备忘录类型数据赋值给types数组
  65. this.types = res.data.data
  66. }
  67. });
  68. if(this.noteId != null && this.noteId != '')
  69. {//noteId不为空查询对应的note
  70. uni.request({
  71. url: `http://localhost:2023/note/selectByNote/${this.noteId}`,
  72. method:"POST",
  73. success: (res) => {
  74. this.note = res.data.data
  75. //console.log(this.note);
  76. this.time = this.note.time
  77. this.selectedType = this.note.type
  78. this.context = this.note.detail
  79. this.finish = this.note.finish !== 0;
  80. //uni.removeStorageSync("noteid");
  81. this.filePath = this.note.photo;
  82. this.fileUrl = this.note.photo
  83. }
  84. })
  85. }
  86. },
  87. methods: {
  88. cancelChooseFile() {
  89. this.filePath = null;
  90. this.fileUrl = null;
  91. console.log('用户取消选择文件');
  92. },
  93. chooseFile() {
  94. uni.chooseImage({
  95. count: 1,
  96. success: (res) => {
  97. // 选择文件成功
  98. this.filePath = res.tempFilePaths[0];
  99. },
  100. fail: (error) => {
  101. // 选择文件失败
  102. console.error(error);
  103. },
  104. });
  105. },
  106. uploadFile() {
  107. uni.uploadFile({
  108. url: 'http://localhost:2023/upload',
  109. filePath: this.filePath,
  110. name: 'img',
  111. method:"POST",
  112. success: function (res) {
  113. // 上传成功
  114. console.log(res);
  115. let responseData = JSON.parse(res.data); // 解析字符串为JSON对象
  116. console.log(responseData);
  117. if(responseData.code === 200)
  118. {
  119. uni.showToast({
  120. title: "上传成功",
  121. icon: "success",
  122. duration: 2000
  123. });
  124. this.fileUrl = responseData.data;
  125. console.log( "上传后:"+ this.fileUrl);
  126. uni.setStorageSync("fileurl", this.fileUrl);
  127. }
  128. else
  129. {
  130. uni.showToast({
  131. title: "上传失败",
  132. icon: "error",
  133. duration: 2000
  134. });
  135. }
  136. }
  137. })
  138. console.log(this.filePath);
  139. },
  140. saveNote() {
  141. if(this.fileUrl === null || this.fileUrl === '0')
  142. {
  143. this.fileUrl = uni.getStorageSync("fileurl");
  144. }
  145. //this.noteId = uni.getStorageSync('noteid')
  146. if(this.noteId === null || this.noteId === '')
  147. {//添加note
  148. // 构造备忘录的请求参数
  149. console.log("添加:"+this.fileUrl);
  150. const note = {
  151. //id: this.noteId,
  152. rid: this.userId,
  153. detail: this.context,
  154. time: this.time,
  155. type: this.selectedType,
  156. finish: this.finish ? 1 : 0,
  157. photo: this.fileUrl ? this.fileUrl : 0
  158. }
  159. uni.request({
  160. url: 'http://localhost:2023/note/save',
  161. method: 'POST',
  162. data: note,
  163. success: (res) => {
  164. // 备忘录添加成功的处理逻辑
  165. if(res.data.code === 200)
  166. {
  167. uni.showToast({
  168. title: "添加成功",
  169. icon: "success",
  170. duration: 2000
  171. });
  172. }
  173. else
  174. {
  175. uni.showToast({
  176. title: "添加失败",
  177. icon: "error",
  178. duration: 2000
  179. });
  180. }
  181. }
  182. })
  183. }
  184. else
  185. {//更新note,更新完后要在缓存中移除noteid
  186. console.log("更新:" +this.fileUrl);
  187. const notes = {
  188. id: this.noteId,
  189. rid: this.userId,
  190. detail: this.context,
  191. time: this.time,
  192. type: this.selectedType,
  193. finish: this.finish ? 1 : 0,
  194. photo: this.fileUrl ? this.fileUrl : 0//因为mybatisplus不能更新为null
  195. }
  196. uni.request({
  197. url: 'http://localhost:2023/note/update',
  198. method: 'POST',
  199. data: notes,
  200. success: (res) => {
  201. // 备忘录更新成功的处理逻辑
  202. if(res.data.code === 200)
  203. {
  204. uni.showToast({
  205. title: "修改成功",
  206. icon: "success",
  207. duration: 2000
  208. });
  209. }
  210. else
  211. {
  212. uni.showToast({
  213. title: "修改失败",
  214. icon: "error",
  215. duration: 2000
  216. });
  217. }
  218. uni.removeStorageSync("noteid");
  219. this.userId = null;
  220. }
  221. })
  222. }
  223. uni.removeStorageSync("fileurl");
  224. uni.reLaunch({
  225. url:`/pages/Main`
  226. });
  227. },
  228. }
  229. }
  230. </script>
  231. <style lang="scss">
  232. .example {
  233. padding: 15px;
  234. background-color: #fff;
  235. }
  236. .segmented-control {
  237. margin-bottom: 15px;
  238. }
  239. .button-group {
  240. margin-top: 15px;
  241. display: flex;
  242. justify-content: space-around;
  243. }
  244. .form-item {
  245. display: flex;
  246. align-items: center;
  247. }
  248. .button {
  249. display: flex;
  250. align-items: center;
  251. height: 35px;
  252. margin-left: 10px;
  253. }
  254. .select{
  255. //display: flex;
  256. //align-items: center;
  257. height: 65rpx;
  258. width: 250rpx;
  259. background-color: #fff;
  260. border-radius: 10rpx;
  261. //margin-left: 10px;
  262. }
  263. .button-container {
  264. display: flex; /* 使用flex布局 */
  265. justify-content: center; /* 水平居中对齐按钮 */
  266. }
  267. .myimg{
  268. width: 600rpx;
  269. height: 400rpx;
  270. }
  271. </style>
 catNote.vue
  1. <template>
  2. <view>
  3. <uni-card title="分类查询">
  4. <uni-forms-item label="分类">
  5. <select v-model="selectedType" class="select">
  6. <option v-for="(value, key) in types" :key="key" :value="key" class="">{{ value }}</option>
  7. </select>
  8. </uni-forms-item>
  9. <uni-forms-item label="完成?">
  10. <zero-switch v-model="finish"></zero-switch>
  11. </uni-forms-item>
  12. <button type="primary" @click="findNotes()">查询</button>
  13. </uni-card>
  14. <uni-swipe-action>
  15. <view v-for="note in notes" :key="note.id" >
  16. <uni-swipe-action-item :right-options="options" :auto-close="false" @click="bindClick(note.id)">
  17. <uni-card title="" extra="">
  18. <view class="" @click="updateNote(note.id)">
  19. <p>截止日期:{{note.time}}</p><br>
  20. <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;容:{{note.detail}}</p><br>
  21. <p>任务类型:{{types[""+note.type]}}</p><br>
  22. <p><image class="myimg" v-if="note.photo != null && note.photo != '0'" :src='note.photo'></image></p><br>
  23. <p :class="{'finished': note.finish === 1, 'unfinished': note.finish !== 1}">
  24. 是否完成:{{ note.finish === 1 ? "完成" : "未完成" }}
  25. </p>
  26. </view>
  27. </uni-card>
  28. </uni-swipe-action-item>
  29. </view>
  30. </uni-swipe-action>
  31. </view>
  32. </template>
  33. <script>
  34. import {getUserid} from "@/store/index.js"
  35. export default {
  36. data() {
  37. return {
  38. userId: '',
  39. selectedType: '',
  40. finish: false,
  41. types: {},
  42. notes: {},
  43. currentPage: 0,
  44. total: 0,
  45. pageSize: 0,
  46. options:[
  47. {
  48. text: '删除',
  49. style: {
  50. backgroundColor: '#dd524d'
  51. }
  52. }
  53. ],
  54. };
  55. },
  56. onLoad() {
  57. this.userId = getUserid();
  58. uni.request({
  59. url:`http://localhost:2023/type/getMapping`,
  60. method:"GET",
  61. success:(res)=>{
  62. // 将返回的备忘录类型数据赋值给types数组
  63. this.types = res.data.data
  64. }
  65. });
  66. },
  67. methods:{
  68. findNotes()
  69. {
  70. const isfinish = this.finish ? 1 : 0
  71. uni.request({
  72. url:`http://localhost:2023/note/selectByType/${this.userId}/${this.selectedType}/${isfinish}?currentPage=${this.currentPage}`,
  73. method:"POST",
  74. success:(res)=>{
  75. this.notes = res.data.data.records
  76. this.currentPage = res.data.data.current
  77. this.total = res.data.data.total
  78. this.pageSize = res.data.data.size
  79. }
  80. });
  81. },
  82. onReachBottom(){
  83. this.pageSize += 1;
  84. this.findNotes();
  85. },
  86. bindClick(noteid) {
  87. uni.showModal({
  88. title: "是否确定删除",
  89. success: res => {
  90. if (res.confirm) {
  91. //删除
  92. uni.request({
  93. url:`http://localhost:2023/note/delete/${noteid}`,
  94. method:"DELETE",
  95. success:(res)=>{
  96. //删除成功
  97. uni.showToast({
  98. title: "删除成功",
  99. icon: "success",
  100. duration: 2000
  101. });
  102. uni.reLaunch({
  103. url:`/pages/catNote`
  104. });
  105. }
  106. });
  107. }
  108. }
  109. });
  110. },
  111. updateNote(id){
  112. uni.setStorageSync("noteid",id);
  113. uni.reLaunch({
  114. url:`/pages/addNote`
  115. });
  116. },
  117. }
  118. }
  119. </script>
  120. <style lang="scss">
  121. .select{
  122. //display: flex;
  123. //align-items: center;
  124. height: 65rpx;
  125. width: 250rpx;
  126. background-color: #fff;
  127. border-radius: 10rpx;
  128. //margin-left: 10px;
  129. }
  130. .select2{
  131. //display: flex;
  132. //align-items: center;
  133. height: 55rpx;
  134. width: 50rpx;
  135. background-color: #fff;
  136. border-radius: 10rpx;
  137. //margin-left: 10px;
  138. }
  139. .finished {
  140. color: green; /* 已完成的备忘录显示为绿色 */
  141. }
  142. .unfinished {
  143. color: red; /* 未完成的备忘录显示为红色 */
  144. }
  145. .myimg{
  146. width: 600rpx;
  147. height: 400rpx;
  148. }
  149. </style>

 Login.vue
  1. <template>
  2. <uni-card title="个人备忘录" extra="">
  3. <view class="loginform">
  4. <uni-forms ref="form" :model="user" >
  5. <uni-forms-item label="账号" name="username" required>
  6. <uni-easyinput type="text" v-model="user.username" placeholder="请输入账号..." />
  7. </uni-forms-item>
  8. <uni-forms-item label="密码" name="password" required>
  9. <uni-easyinput type="password" v-model="user.password" placeholder="请输入密码..." />
  10. </uni-forms-item>
  11. </uni-forms>
  12. <button @tap="submitForm" class="submit">登录</button>
  13. <view class="noaccount">
  14. <view @tap="gotoRegister">没有账号,<text>注册</text>一个</view>
  15. </view>
  16. </view>
  17. </uni-card>
  18. </template>
  19. <script>
  20. import {getUserid} from "@/store/index.js"
  21. export default {
  22. data() {
  23. return {
  24. user: {
  25. id:"",
  26. username: "",
  27. password: "",
  28. avatar:""
  29. },
  30. };
  31. },
  32. methods:{
  33. submitForm() {
  34. this.$refs.form.validate().then((res) => {
  35. uni.request({
  36. url: `http://localhost:2023/user/login`,
  37. method: "POST",
  38. data: {
  39. username: this.user.username,
  40. password: this.user.password
  41. },
  42. success: (result) => {
  43. if (result.data.code === 200) {
  44. uni.showToast({
  45. title: "登录成功",
  46. icon: "success",
  47. duration: 2000
  48. });
  49. setTimeout(() => {
  50. this.user = result.data.data,
  51. uni.setStorageSync("userid", result.data.data.id);
  52. uni.setStorageSync("username", result.data.data.username);
  53. uni.reLaunch({
  54. url: "/pages/Main"
  55. })
  56. }, 2000);
  57. } else {
  58. uni.showToast({
  59. title: result.data.msg,
  60. icon: "error"
  61. });
  62. }
  63. }
  64. });
  65. });
  66. },
  67. gotoRegister()
  68. {
  69. uni.reLaunch({
  70. url: "/pages/Register"
  71. })
  72. }
  73. }
  74. }
  75. </script>
  76. <style lang="scss" scoped>
  77. .loginform {
  78. margin: 6rpx;
  79. .submit {
  80. background-color: $uni-color-primary;
  81. color: white;
  82. }
  83. .noaccount {
  84. font-size: 30rpx;
  85. display: flex;
  86. justify-content: space-between;
  87. margin: 10rpx;
  88. text {
  89. color: red;
  90. }
  91. }
  92. }
  93. </style>
 Main.vue
  1. <template>
  2. <view>
  3. <uni-notice-bar show-icon scrollable
  4. :text="this.msg"/>
  5. <uni-card title="最近一条待办的截止时间" extra="">
  6. <uni-section type="line" padding>
  7. <uni-countdown :font-size="30" :day="this.days" :hour="this.hours" :minute="this.minutes" :second="this.seconds" color="#FFFFFF" background-color="#007AFF" />
  8. </uni-section>
  9. </uni-card >
  10. <uni-swipe-action>
  11. <!-- 基础用法 -->
  12. <view v-for="note in notes" :key="note.id" >
  13. <uni-swipe-action-item :right-options="options" :auto-close="false" @click="bindClick(note.id)">
  14. <uni-card title="" extra="">
  15. <view class="" @click="updateNote(note.id)">
  16. <p>截止日期:{{note.time}}</p><br>
  17. <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;容:{{note.detail}}</p><br>
  18. <p>任务类型:{{typeMap[""+note.type]}}</p><br>
  19. <p><image class="myimg" v-if="note.photo != null && note.photo != '0'" :src='note.photo'></image></p><br>
  20. <p :class="{'finished': note.finish === 1, 'unfinished': note.finish !== 1}">
  21. 是否完成:{{ note.finish === 1 ? "完成" : "未完成" }}
  22. </p>
  23. </view>
  24. </uni-card>
  25. </uni-swipe-action-item>
  26. </view>
  27. </uni-swipe-action>
  28. </view>
  29. </template>
  30. <script>
  31. import {getUserid,getUsername} from "@/store/index.js"
  32. export default {
  33. data() {
  34. return {
  35. imgP:"https://img2.baidu.com/it/u=3841326637,2519425910&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501",
  36. options:[
  37. {
  38. text: '删除',
  39. style: {
  40. backgroundColor: '#dd524d'
  41. }
  42. }
  43. ],
  44. userid:0,
  45. user:{},
  46. notes: [],
  47. currentPage: 0,
  48. total: 0,
  49. pageSize: 0,
  50. typeMap:{},
  51. finish:0,
  52. msg:'',
  53. days:0,
  54. hours:0,
  55. minutes:0,
  56. seconds:0,
  57. };
  58. },
  59. methods:{
  60. showNotes(){
  61. uni.request({
  62. url:`http://localhost:2023/note/selectAllByUserID/${this.userid}?currentPage=${this.currentPage}`,
  63. method:"POST",
  64. success:(res)=>{
  65. this.notes = res.data.data.records
  66. this.currentPage = res.data.data.current
  67. this.total = res.data.data.total
  68. this.pageSize = res.data.data.size
  69. }
  70. });
  71. uni.request({
  72. url:`http://localhost:2023/type/getMapping`,
  73. method:"GET",
  74. success:(res)=>{
  75. this.typeMap = res.data.data;
  76. }
  77. });
  78. },
  79. updateNote(id){
  80. uni.setStorageSync("noteid",id);
  81. uni.reLaunch({
  82. url:`/pages/addNote`
  83. });
  84. },
  85. bindClick(noteid) {
  86. uni.showModal({
  87. title: "是否确定删除",
  88. success: res => {
  89. if (res.confirm) {
  90. //删除
  91. uni.request({
  92. url:`http://localhost:2023/note/delete/${noteid}`,
  93. method:"DELETE",
  94. success:(res)=>{
  95. //删除成功
  96. if(res.data.code === 200)
  97. {
  98. uni.showToast({
  99. title: "删除成功",
  100. icon: "success",
  101. duration: 2000
  102. });
  103. uni.reLaunch({
  104. url:`/pages/Main`
  105. });
  106. }
  107. else
  108. {
  109. uni.showToast({
  110. title: "删除失败",
  111. icon: "error",
  112. duration: 2000
  113. });
  114. }
  115. }
  116. });
  117. }
  118. }
  119. });
  120. },
  121. SetCountdown() {
  122. uni.request({
  123. url:`http://localhost:2023/note/selectTime/${this.userid}`,
  124. method:"GET",
  125. success:(res)=>{
  126. const { days, hours, minutes, seconds } = res.data.data
  127. this.days = parseInt(days)
  128. this.hours = parseInt(hours)
  129. this.minutes = parseInt(minutes)
  130. this.seconds = parseInt(seconds)
  131. }
  132. });
  133. },
  134. },
  135. onLoad(){
  136. this.userid = getUserid();
  137. this.showNotes();
  138. this.msg = '欢迎' + getUsername() + '回来,您有以下几条待办事件';
  139. this.SetCountdown();
  140. },
  141. onReachBottom(){
  142. this.pageSize += 1;
  143. this.showNotes();
  144. },
  145. }
  146. </script>
  147. <style lang="scss">
  148. .a0{
  149. //align-items: center;
  150. padding-left: 40rpx;
  151. }
  152. .a1{
  153. border: 1px solid #ccc;
  154. border-radius: 5rpx;
  155. width: 650rpx;
  156. //text-align: center;
  157. //display: flex;
  158. // justify-content: center;
  159. // align-items: center;
  160. padding-left: 10rpx;
  161. padding-top: 20rpx;
  162. }
  163. .content-box {
  164. flex: 1;
  165. /* #ifdef APP-NVUE */
  166. justify-content: center;
  167. /* #endif */
  168. height: 44px;
  169. line-height: 44px;
  170. padding: 0 15px;
  171. position: relative;
  172. background-color: #fff;
  173. border-bottom-color: #f5f5f5;
  174. border-bottom-width: 1px;
  175. border-bottom-style: solid;
  176. }
  177. .content-text {
  178. font-size: 15px;
  179. }
  180. .example-body {
  181. /* #ifndef APP-NVUE */
  182. display: flex;
  183. /* #endif */
  184. flex-direction: row;
  185. justify-content: center;
  186. padding: 10px 0;
  187. background-color: #fff;
  188. }
  189. .button {
  190. border-color: #e5e5e5;
  191. border-style: solid;
  192. border-width: 1px;
  193. padding: 4px 8px;
  194. border-radius: 4px;
  195. }
  196. .button-text {
  197. font-size: 15px;
  198. }
  199. .slot-button {
  200. /* #ifndef APP-NVUE */
  201. display: flex;
  202. height: 100%;
  203. /* #endif */
  204. flex: 1;
  205. flex-direction: row;
  206. justify-content: center;
  207. align-items: center;
  208. padding: 0 20px;
  209. background-color: #ff5a5f;
  210. }
  211. .slot-button-text {
  212. color: #ffffff;
  213. font-size: 14px;
  214. }
  215. .finished {
  216. color: green; /* 已完成的备忘录显示为绿色 */
  217. }
  218. .unfinished {
  219. color: red; /* 未完成的备忘录显示为红色 */
  220. }
  221. .container {
  222. /* #ifndef APP-NVUE */
  223. position: absolute;
  224. left: 0;
  225. right: 0;
  226. top: 0;
  227. bottom: 0;
  228. /* #endif */
  229. }
  230. .myimg{
  231. width: 600rpx;
  232. height: 400rpx;
  233. }
  234. </style>
 mine.vue
  1. <template>
  2. <view class="mine">
  3. <!--顶部信息:头像,昵称,发文收藏和点赞数据-->
  4. <view class="top">
  5. <view class="userinfo">
  6. <view class="group">
  7. <view class="pic">
  8. <image v-if="user.avatar != null" :src="user.avatar"></image>
  9. <image v-else src="/static/tabs/member.png" mode="aspectFit"></image>
  10. </view>
  11. <view>
  12. <text v-if="user.username != null" v-text="user.username"></text>
  13. <text v-else class="login" @tap="gotoLogin" v-text="'点击登录'"></text>
  14. </view>
  15. </view>
  16. <view class="more">
  17. <text class="iconfont icon-a-10-you"></text>
  18. </view>
  19. </view>
  20. </view>
  21. <!-- 登录后的补充组件-->
  22. <view v-if="user.username !=null">
  23. <!--退出登录-->
  24. <view class="itemgroup">
  25. <view class="item">
  26. <view class="left" @tap="gotoLogout">
  27. <text class="iconfont icon-a-73-tuichu"></text>
  28. <text>退出登录</text>
  29. </view>
  30. <view>
  31. <text class="iconfont icon-a-10-you"></text>
  32. </view>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import {
  40. hasLogin,
  41. logout,
  42. getUserid
  43. } from '@/store/index.js'
  44. export default {
  45. data() {
  46. return {
  47. user: {
  48. username: null, //用户账号
  49. avatar: null, //个人照片
  50. }
  51. };
  52. },
  53. onLoad() {
  54. if (hasLogin()) {
  55. this.getUserInfo();
  56. }
  57. },
  58. methods: {
  59. gotoLogin() {
  60. //跳转到的登录页面
  61. uni.redirectTo({
  62. url:"/pages/Login"
  63. });
  64. },
  65. getUserInfo() {
  66. this.userid = getUserid();
  67. if (this.userid != null) {
  68. uni.request({
  69. url: `http://localhost:2023/user/selectUserById/${this.userid}`,
  70. method: "GET",
  71. success: (res) => {
  72. this.user = res.data.data;
  73. }
  74. });
  75. }
  76. },
  77. gotoLogout() {
  78. uni.showModal({
  79. title: "是否确定退出",
  80. success: res => {
  81. if (res.confirm) {
  82. logout();
  83. this.user = {
  84. username: null,
  85. avatar: null,
  86. }
  87. }
  88. }
  89. });
  90. }
  91. }
  92. }
  93. </script>
  94. <style lang="scss">
  95. .mine {
  96. margin: 30rpx 30rpx;
  97. .top {
  98. display: flex;
  99. flex-direction: column;
  100. justify-content: space-between;
  101. .userinfo {
  102. display: flex;
  103. flex: row;
  104. justify-content: space-between;
  105. align-items: center;
  106. .group {
  107. display: flex;
  108. align-items: center;
  109. .pic {
  110. width: 120rpx;
  111. height: 120rpx;
  112. border-radius: 50%;
  113. overflow: hidden;
  114. border: 2rpx solid red;
  115. margin-right: 10rpx;
  116. image {
  117. width: 100%;
  118. height: 100%;
  119. }
  120. }
  121. .login {
  122. margin-left: 16rpx;
  123. font-size: 40rpx;
  124. }
  125. }
  126. .more {
  127. .iconfont {
  128. font-size: 40rpx;
  129. }
  130. }
  131. }
  132. .bloginfo {
  133. display: flex;
  134. flex: row;
  135. margin-top: 20rpx;
  136. view {
  137. margin-right: 30rpx;
  138. font-size: 26rpx;
  139. }
  140. }
  141. }
  142. .itemgroup {
  143. border-top: 4rpx solid #f4f4f4;
  144. margin-top: 30rpx;
  145. .item {
  146. padding: 24rpx 0;
  147. display: flex;
  148. justify-content: space-between;
  149. align-items: center;
  150. .left {
  151. text {
  152. margin-right: 16rpx;
  153. font-size: 36rpx;
  154. }
  155. }
  156. }
  157. }
  158. }
  159. </style>
Register.vue

  1. <template>
  2. <uni-card>
  3. <view class="registerform">
  4. <uni-forms ref="form" :model="user" :rules="rules" :labelWidth="85">
  5. <uni-forms-item label="账号" name="username" required>
  6. <uni-easyinput type="text" v-model="user.username" placeholder="请输入账号" />
  7. </uni-forms-item>
  8. <uni-forms-item label="密码" name="password" required>
  9. <uni-easyinput type="password" v-model="user.password" placeholder="请输入密码" />
  10. </uni-forms-item>
  11. <uni-forms-item label="再次输入" name="passwordconfirm" required>
  12. <uni-easyinput type="password" v-model="user.passwordconfirm" placeholder="再次输入密码" />
  13. </uni-forms-item>
  14. </uni-forms>
  15. <button @tap="submitForm" class="submit">注册</button>
  16. </view>
  17. </uni-card>
  18. </template>
  19. <script>
  20. export default {
  21. data() {
  22. return {
  23. user: {},
  24. rules: {
  25. username: {
  26. rules: [{
  27. required: true,
  28. errorMessage: '请输入账号',
  29. },
  30. {
  31. minLength: 2,
  32. maxLength: 20,
  33. errorMessage: '账号长度在 {minLength}到 {maxLength}个字符 ',
  34. }
  35. ]
  36. },
  37. password: {
  38. rules: [{
  39. required: true,
  40. errorMessage: '请输入密码',
  41. },
  42. {
  43. minLength: 2,
  44. maxLength: 20,
  45. errorMessage: '密码长度在 {minLength}到 {maxLength}个字符 ',
  46. }
  47. ]
  48. },
  49. passwordconfirm: {
  50. rules: [{
  51. required: true,
  52. errorMessage: '请输入密码',
  53. },
  54. {
  55. minLength: 2,
  56. maxLength: 20,
  57. errorMessage: '密码长度在 {minLength}到 {maxLength}个字符 ',
  58. },
  59. {
  60. validateFunction: function(rule, value, data, callback) {
  61. if (value !== data.password) {
  62. callback("两次输入的密码不一致");
  63. }
  64. return true;
  65. }
  66. }
  67. ]
  68. },
  69. }
  70. };
  71. },
  72. methods: {
  73. submitForm() {
  74. this.$refs.form.validate().then((res) => {
  75. Reflect.deleteProperty(this.user, "passwordconfirm");
  76. // console.log('user 模型',this.user);
  77. uni.request({
  78. url: "http://localhost:2023/user/register",
  79. method: "POST",
  80. data: {
  81. username: this.user.username,
  82. password: this.user.password,
  83. },
  84. success: (result) => {
  85. if (result.data.msg) {
  86. uni.showToast({
  87. title: "用户注册成功",
  88. duration: 2000
  89. });
  90. //注册成功则转到登录页面
  91. setTimeout(() => {
  92. uni.redirectTo({
  93. url: "/pages/Login"
  94. });
  95. this.user = {};
  96. }, 2000);
  97. } else {
  98. uni.showToast({
  99. title: result.data.describe,
  100. duration: 2000,
  101. icon: "error"
  102. })
  103. }
  104. } //end of success
  105. });
  106. }).catch(err => {
  107. // console.log(err);
  108. })
  109. },
  110. }
  111. }
  112. </script>
  113. <style lang="scss" scoped>
  114. .registerform {
  115. margin: 6rpx;
  116. .submit {
  117. background-color: $uni-color-primary;
  118. color: white;
  119. }
  120. }
  121. </style>

到这里前后端代码已经全部完成,下面是运行的截图

到此全部结束啦,如果此文章对你有帮助,希望给一个关注+点赞+收藏

若需要源码可以私信我,免费分享

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/263251
推荐阅读
相关标签
  

闽ICP备14008679号