后端
package com.atguigu.schedule.common;
/**
* 全局统一响应的JSON格式处理类
*/
public class Result<T> {
// 返回码
private Integer code;
// 返回消息
private String message;
// 返回数据
private T data;
public Result() {
}
// 返回数据
protected static <T> Result<T> build(T data) {
Result<T> result = new Result<T>();
if (data != null)
result.setData(data);
return result;
}
public static <T> Result<T> build(T body, Integer code, String message) {
Result<T> result = build(body);
result.setCode(code);
result.setMessage(message);
return result;
}
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = build(body);
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMessage());
return result;
}
/**
* 操作成功
*
* @param data baseCategory1List
* @param <T>
* @return
*/
public static <T> Result<T> ok(T data) {
Result<T> result = build(data);
return build(data, ResultCodeEnum.SUCCESS);
}
public Result<T> message(String msg) {
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code) {
this.setCode(code);
return this;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
package com.atguigu.schedule.common;
public enum ResultCodeEnum {
SUCCESS(200,"success"),
USERNAEM_ERROR(501,"usernameError"),
PASSWORD_ERROR(503,"passwordError"),
NOTLOGIN(504,"notlogin"),
USERNAME_USED(505,"usernameUsed");
private Integer code;
private String message;
private ResultCodeEnum(Integer code ,String message){
this.code= code;
this.message = message;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}
package com.atguigu.schedule.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().info(
new Info()
.title("日程系统API")
.version("1.0")
.description("日程系统API"));
}
@Bean
public GroupedOpenApi loginAPI() {
return GroupedOpenApi.builder().group("用户登录管理").
pathsToMatch(
"/user/**"
).
build();
}
@Bean
public GroupedOpenApi apartmentAPI() {
return GroupedOpenApi.builder().group("日程信息管理").
pathsToMatch(
"/schedule/**"
).build();
}
}
package com.atguigu.schedule.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
package com.atguigu.schedule.controller;
import com.atguigu.schedule.common.Result;
import com.atguigu.schedule.pojo.SysSchedule;
import com.atguigu.schedule.service.SysScheduleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/*
* 增加日程的请求 /schedule/add
* 查询日程的请求 /schedule/find
* 修改日程的请求 /schedule/update
* 删除日程的请求 /schedule/remove
* */
@Tag(name = "用户日程管理")
@RestController
@RequestMapping("/schedule")
public class SysScheduleController {
@Resource
private SysScheduleService scheduleService;
@Operation(summary = "删除日程")
@GetMapping("delete")
protected Result<Integer> removeSchedule(@RequestParam Integer sid) {
// 调用服务层方法 删除数据
// 响应 成功信息
return Result.ok(scheduleService.removeSchedule(sid));
}
@Operation(summary = "更新日程")
@PostMapping("update")
protected Result<Integer> updateSchedule(@RequestBody SysSchedule sysSchedule) {
// 调用服务层方法,将信息更新进入数据
return Result.ok(scheduleService.updateSchedule(sysSchedule));
}
@Operation(summary = "新增日程")
@GetMapping("add")
protected Result<Integer> addDefaultSchedule(@RequestParam Integer uid) {
// 调用服务层方法,向数据库中 增加一条 空记录
return Result.ok(scheduleService.addDefault(uid));
}
@Operation(summary = "获取日程列表")
@GetMapping("getScheduleList")
protected Result<List<SysSchedule>> getScheduleList(@RequestParam Integer uid) {
// 查询用户的所有日程
List<SysSchedule> itemList = scheduleService.findItemListByUid(uid);
return Result.ok(itemList);
}
}
package com.atguigu.schedule.controller;
import com.atguigu.schedule.common.Result;
import com.atguigu.schedule.common.ResultCodeEnum;
import com.atguigu.schedule.pojo.SysUser;
import com.atguigu.schedule.service.SysUserService;
import com.atguigu.schedule.util.MD5Util;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "用户登录注册管理")
@RestController
@RequestMapping("/user")
public class SysUserController {
@Resource
private SysUserService sysUserService;
/**
* 注册时,接收要注册的用户名,校验用户名是否被占用的业务接口
*/
@Operation(summary = "校验用户名是否被占用")
@GetMapping("checkUsernameUsed")
protected Result<Boolean> checkUsernameUsed(@RequestParam("username") String username) {
// 调用服务层业务处理方法查询该用于名是否有对应的用户
SysUser sysUser = sysUserService.getSysUserByUsername(username);
Result<Boolean> result = Result.build(true, ResultCodeEnum.USERNAME_USED);
if (sysUser == null) {
result = Result.ok(false);
}
return result;
}
/**
* 接收用登录请求,完成的登录业务接口
*/
@Operation(summary = "用户登录")
@PostMapping("login")
protected Result login(@RequestBody SysUser sysUser) {
//2 调用服务层方法,根据用户名查询用户信息
SysUser loginUser = sysUserService.getSysUserByUsername(sysUser.getUsername());
Result result = null;
if (null == loginUser) {
result = Result.build(null, ResultCodeEnum.USERNAEM_ERROR);
} else if (!MD5Util.encrypt(sysUser.getUserPwd()).equals(loginUser.getUserPwd())) {
result = Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
} else {
// 登录程序,将用户uid和username响应给客户端
result = Result.ok(loginUser);
}
System.out.println("已登录!");
return result;
}
/**
* 接收用户注册请求的业务处理方法( 业务接口 不是java中的interface )
*/
@Operation(summary = "用户注册")
@PostMapping("register")
public Result register(@RequestBody SysUser registerUser) {
//将参数放入一个SysUser对象中,在调用register方法时传入
int rows = sysUserService.regist(registerUser);
// 根据注册结果(成功 失败) 做页面跳转
Result result = Result.ok(null);
if (rows < 1) {
result = Result.build(null, ResultCodeEnum.USERNAME_USED);
}
return result;
}
/**
* 获取用户列表
*/
@Operation(summary = "获取用户列表")
@GetMapping("getUserList")
public Result<List<SysUser>> getUserList() {
return Result.ok(sysUserService.getUserList());
}
}
package com.atguigu.schedule.mapper;
import com.atguigu.schedule.pojo.SysSchedule;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SysScheduleMapper extends BaseMapper<SysSchedule> {
}
package com.atguigu.schedule.mapper;
import com.atguigu.schedule.pojo.SysUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SysUserMapper extends BaseMapper<SysUser> {
}
package com.atguigu.schedule.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName("sys_schedule")
public class SysSchedule implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "sid", type = IdType.AUTO)
private Integer sid;
@TableField(value = "uid")
private Integer uid;
@TableField(value = "title")
private String title;
@TableField(value = "completed")
private Integer completed;
}
package com.atguigu.schedule.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import java.io.Serializable;
import java.util.Objects;
@AllArgsConstructor // 添加了全参构造
@NoArgsConstructor // 添加了无参构造
@Data //getter setter equals hashcode toString
public class SysUser implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "uid", type = IdType.AUTO)
private Integer uid;
@TableField(value = "username")
private String username;
@TableField(value = "user_pwd")
private String userPwd;
}
package com.atguigu.schedule.service.impl;
import com.atguigu.schedule.mapper.SysScheduleMapper;
import com.atguigu.schedule.mapper.SysUserMapper;
import com.atguigu.schedule.pojo.SysSchedule;
import com.atguigu.schedule.service.SysScheduleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysScheduleServiceImpl implements SysScheduleService {
@Resource
private SysScheduleMapper sysScheduleMapper;
@Override
public List<SysSchedule> findItemListByUid(Integer uid) {
LambdaQueryWrapper<SysSchedule> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysSchedule::getUid, uid);
sysScheduleMapper.selectList(wrapper);
return sysScheduleMapper.selectList(wrapper);
}
@Override
public Integer addDefault(Integer uid) {
SysSchedule schedule = new SysSchedule();
schedule.setTitle("默认日程");
schedule.setUid(uid);
schedule.setCompleted(0);
return sysScheduleMapper.insert(schedule);
}
@Override
public Integer updateSchedule(SysSchedule schedule) {
return sysScheduleMapper.updateById(schedule);
}
@Override
public Integer removeSchedule(Integer sid) {
return sysScheduleMapper.deleteById(sid);
}
}
package com.atguigu.schedule.service.impl;
import com.atguigu.schedule.mapper.SysUserMapper;
import com.atguigu.schedule.pojo.SysUser;
import com.atguigu.schedule.service.SysUserService;
import com.atguigu.schedule.util.MD5Util;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysUserServiceImpl implements SysUserService {
@Resource
private SysUserMapper userMapper;
@Override
public int regist(SysUser sysUser) {
// 将用户的明文密码转换为密文密码
sysUser.setUserPwd(MD5Util.encrypt(sysUser.getUserPwd()));
//将sysUser信息存入数据库
return userMapper.insert(sysUser);
}
@Override
public SysUser getSysUserByUsername(String username) {
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysUser::getUsername, username);
return userMapper.selectOne(wrapper);
}
@Override
public List<SysUser> getUserList() {
return userMapper.selectList(null);
}
}
package com.atguigu.schedule.service;
import com.atguigu.schedule.pojo.SysSchedule;
import java.util.List;
public interface SysScheduleService {
List<SysSchedule> findItemListByUid(Integer uid);
Integer addDefault(Integer uid);
Integer updateSchedule(SysSchedule schedule);
Integer removeSchedule(Integer sid);
}
package com.atguigu.schedule.service;
import com.atguigu.schedule.pojo.SysUser;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 该接口定义了以sys_user表格为核心的业务处理功能
*/
public interface SysUserService {
/**
* 注册用户的方法
* @param sysUser 要注册的用户名和明文密码以SysUser对象的形式接收
* @return 注册成功返回1 注册失败返回0
*/
int regist(SysUser sysUser);
/**
* 根据用户名获得完整用户信息的方法
* @param username 要查询的用户名
* @return 如果找到了返回SysUser对象,找不到返回null
*/
SysUser getSysUserByUsername(String username);
List<SysUser> getUserList();
}
package com.atguigu.schedule.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public final class MD5Util {
public static String encrypt(String strSrc) {
try {
char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] bytes = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
bytes = md.digest();
int j = bytes.length;
char[] chars = new char[j * 2];
int k = 0;
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
chars[k++] = hexChars[b >>> 4 & 0xf];
chars[k++] = hexChars[b & 0xf];
}
return new String(chars);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("MD5加密出错");
}
}
}
package com.atguigu.schedule;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin
@SpringBootApplication
@EnableScheduling
@MapperScan("com.atguigu.schedule.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
server:
port: 8080
spring:
#配置jackson日期格式和时区
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/schedule_system?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2b8
username: root
password: root
hikari:
connection-test-query: SELECT 1 # 自动检测连接
connection-timeout: 60000 #数据库连接超时时间,默认30秒
idle-timeout: 500000 #空闲连接存活最大时间,默认600000(10分钟)
max-lifetime: 540000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
maximum-pool-size: 12 #连接池最大连接数,默认是10
minimum-idle: 10 #最小空闲连接数量
pool-name: SPHHikariPool # 连接池名称
#用于打印框架生成的sql语句,便于调试
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: is_deleted # 全局逻辑删除的实体字段名(配置后可以忽略不配置步骤二)
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu</groupId>
<artifactId>schedule-system-atguigu</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 包含spring test相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- knife4j文档 -->
<!-- 官方文档:https://doc.xiaominfo.com/docs/quick-start -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
参考:尚硅谷全新JavaWeb教程,企业主流javaweb技术栈
前端
按顺序
<script setup>
/* 导入pinia中的user数据 */
import { defineUser } from '../store/userStore.js'
import { defineSchedule } from '../store/scheduleStore.js'
let sysUser = defineUser()
let schedule = defineSchedule();
/* 导入编程式路由 */
import { useRouter } from 'vue-router'
let router = useRouter()
/* 退出登录接口 */
function logout() {
// 清除userPina 和schedulepinia
sysUser.$reset()
schedule.$reset()
// 通过路由回到登录页
router.push("/login")
}
</script>
<template>
<div>
<h1 class="ht">欢迎使用日程管理系统</h1>
<div class="optionDiv" v-if="sysUser.username != ''">
欢迎{{ sysUser.username }}!!!
<button class="b1b" @click="logout()">登出</button>
</div>
</div>
</template>
<style scoped>
.ht {
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.b1s {
border: 2px solid powderblue;
border-radius: 4px;
width: 60px;
background-color: antiquewhite;
}
.b1b {
border: 2px solid powderblue;
border-radius: 4px;
width: 100px;
background-color: antiquewhite;
}
.optionDiv {
width: 500px;
float: right;
}
</style>
<script setup>
/* 导入pinia中的user数据 */
import { defineUser } from '../store/userStore.js'
let sysUser = defineUser()
/* 获取 编程式路由对象 */
import { useRouter } from 'vue-router'
let router = useRouter();
/* 导入axios请求对象 */
import request from '../utils/request.js'
// 导入ref,reactive处理响应式数据的方法
import { ref, reactive } from 'vue'
// 响应式数据,保存用户输入的表单信息
let loginUser = reactive({
username: '',
userPwd: ''
})
// 响应式数据,保存校验的提示信息
let usernameMsg = ref('')
let userPwdMsg = ref('')
// 校验用户名的方法
function checkUsername() {
// 定义正则
var usernameReg = /^[a-zA-Z0-9]{5,10}$/
// 校验用户名
if (!usernameReg.test(loginUser.username)) {
// 格式不合法
usernameMsg.value = "格式有误"
return false
}
usernameMsg.value = "ok"
return true
}
// 校验密码的方法
function checkUserPwd() {
// 定义正则
var passwordReg = /^[0-9]{6}$/
// 校验密码
if (!passwordReg.test(loginUser.userPwd)) {
// 格式不合法
userPwdMsg.value = "格式有误"
return false
}
userPwdMsg.value = "ok"
return true
}
// 登录的函数
async function login() {
console.log("发送异步请求")
let { data } = await request.post("/user/login", loginUser)
console.log(data.data)
if (data.code == 200) {
alert("登录成功")
// 更新pinia数据
sysUser.uid = data.data.uid
sysUser.username = data.data.username
// 跳转到日程查询页
router.push("/showSchedule")
} else if (data.code == 501) {
alert("用户名有误,请重新输入")
} else if (data.code == 503) {
alert("密码有误,请重新输入")
} else {
alert("出现未知名错误")
}
}
// 清除表单信息的方法
function clearForm() {
loginUser.username = ''
loginUser.userPwd = ''
usernameMsg.value = ''
userPwdMsg.value = ''
}
</script>
<template>
<div>
<h3 class="ht">请登录</h3>
<table class="tab" cellspacing="0px">
<tr class="ltr">
<td>请输入账号</td>
<td>
<input class="ipt" type="text" v-model="loginUser.username" @blur="checkUsername()">
<span id="usernameMsg" v-text="usernameMsg"></span>
</td>
</tr>
<tr class="ltr">
<td>请输入密码</td>
<td>
<input class="ipt" type="password" v-model="loginUser.userPwd" @blur="checkUserPwd()">
<span id="userPwdMsg" v-text="userPwdMsg"></span>
</td>
</tr>
<tr class="ltr">
<td colspan="2" class="buttonContainer">
<input class="btn1" type="button" @click="login()" value="登录">
<input class="btn1" type="button" @click="clearForm()" value="重置">
<router-link to="/regist">
<button class="btn1">去注册</button>
</router-link>
</td>
</tr>
</table>
</div>
</template>
<style scoped>
.ht {
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.tab {
width: 500px;
border: 5px solid cadetblue;
margin: 0px auto;
border-radius: 5px;
font-family: 幼圆;
}
.ltr td {
border: 1px solid powderblue;
}
.ipt {
border: 0px;
width: 50%;
}
.btn1 {
border: 2px solid powderblue;
border-radius: 4px;
width: 80px;
background-color: antiquewhite;
}
#usernameMsg,
#userPwdMsg {
color: gold;
}
.buttonContainer {
text-align: center;
}
</style>
<script setup>
import { ref, reactive } from 'vue'
/* 导入发送请求的axios对象 */
import request from '../utils/request'
import { useRouter } from 'vue-router'
const router = useRouter()
let registUser = reactive({
username: "",
userPwd: ""
})
let usernameMsg = ref('')
let userPwdMsg = ref('')
let reUserPwdMsg = ref('')
let reUserPwd = ref('')
async function checkUsername() {
//校验格式
let usernameReg = /^[a-zA-Z0-9]{5,10}$/
if (!usernameReg.test(registUser.username)) {
usernameMsg.value = "格式有误"
return false
}
// 发送异步请求 继续校验用户名是否被占用
let { data } = await request.get(`user/checkUsernameUsed?username=${registUser.username}`)
console.log(data)
if (data.code != 200) {
usernameMsg.value = "用户名占用"
return false
}
usernameMsg.value = "可用"
return true
}
function checkUserPwd() {
let userPwdReg = /^[0-9]{6}$/
if (!userPwdReg.test(registUser.userPwd)) {
userPwdMsg.value = "格式有误"
return false
}
userPwdMsg.value = "OK"
return true
}
function checkReUserPwd() {
let userPwdReg = /^[0-9]{6}$/
if (!userPwdReg.test(reUserPwd.value)) {
reUserPwdMsg.value = "格式有误"
return false
}
if (registUser.userPwd != reUserPwd.value) {
reUserPwdMsg.value = "两次密码不一致"
return false
}
reUserPwdMsg.value = "OK"
return true
}
// 注册的方法
async function regist() {
// 校验所有的输入框是否合法
let flag1 = await checkUsername()
let flag2 = await checkUserPwd()
let flag3 = await checkReUserPwd()
if (flag1 && flag2 && flag3) {
let { data } = await request.post("user/register", registUser)
if (data.code == 200) {
// 注册成功跳转 登录页
alert("注册成功,快去登录吧")
router.push("/login")
} else {
alert("抱歉,用户名被抢注了")
}
} else {
alert("校验不通过,请求再次检查数据")
}
}
function clearForm() {
registUser.username = ""
registUser.userPwd = ""
usernameMsg.value = ""
userPwdMsg.value = ""
reUserPwd.value = ""
reUserPwdMsg.value = ""
}
</script>
<template>
<div>
<h3 class="ht">请注册</h3>
<table class="tab" cellspacing="0px">
<tr class="ltr">
<td>请输入账号</td>
<td>
<input class="ipt" id="usernameInput" type="text" name="username" v-model="registUser.username"
@blur="checkUsername()">
<span id="usernameMsg" class="msg" v-text="usernameMsg"></span>
</td>
</tr>
<tr class="ltr">
<td>请输入密码</td>
<td>
<input class="ipt" id="userPwdInput" type="password" name="userPwd" v-model="registUser.userPwd"
@blur="checkUserPwd()">
<span id="userPwdMsg" class="msg" v-text="userPwdMsg"></span>
</td>
</tr>
<tr class="ltr">
<td>确认密码</td>
<td>
<input class="ipt" id="reUserPwdInput" type="password" v-model="reUserPwd" @blur="checkReUserPwd()">
<span id="reUserPwdMsg" class="msg" v-text="reUserPwdMsg"></span>
</td>
</tr>
<tr class="ltr">
<td colspan="2" class="buttonContainer">
<input class="btn1" type="button" @click="regist()" value="注册">
<input class="btn1" type="button" @click="clearForm()" value="重置">
<router-link to="/login">
<button class="btn1">去登录</button>
</router-link>
</td>
</tr>
</table>
</div>
</template>
<style scoped>
.ht {
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.tab {
width: 500px;
border: 5px solid cadetblue;
margin: 0px auto;
border-radius: 5px;
font-family: 幼圆;
}
.ltr td {
border: 1px solid powderblue;
}
.ipt {
border: 0px;
width: 50%;
}
.btn1 {
border: 2px solid powderblue;
border-radius: 4px;
width: 80px;
background-color: antiquewhite;
}
.msg {
color: gold;
}
.buttonContainer {
text-align: center;
}
</style>
<script setup>
/* 引入axios */
import request from '../utils/request.js'
/* 引入pinia数据 */
import { defineSchedule } from '../store/scheduleStore.js'
import { defineUser } from '../store/userStore.js'
let schedule = defineSchedule();
let sysUser = defineUser()
/* 引入挂载生命周期 */
import { onMounted, onUpdated, ref, reactive } from 'vue';
// 第一次挂载就立刻向后端发送请求,获取最新数据
onMounted(async function () {
// 加载完毕后,立刻调用查询数据的方法
showSchedule()
})
async function showSchedule() {
let { data } = await request.get("/schedule/getScheduleList",
{
params: {
"uid":
sysUser.uid
}
})
console.log(data.data)
schedule.itemList = data.data
}
// 新增日程
async function addItem() {
// 立刻向后端发送一个请求,让后端先为当前用户在数据库中增加一个默认格式的空数据
let { data } = await request.get("/schedule/add", { params: { "uid": sysUser.uid } })
if (data.code == 200) {
// 然后调用刷新页面数据方法,立刻获取最新数据
showSchedule()
} else {
alert("添加异常!")
}
}
// 更新日程的方法
async function updateItem(index) {
// 根据索引获取元素
// 将元素通过 JSON串的形式 发送给服务端
if (confirm("确定修改该条数据?")) {
let { data } = await request.post("/schedule/update", schedule.itemList[index])
if (data.code = 200) {
// 服务端修改完毕后,刷新页面数据
showSchedule()
} else {
alert("更新异常")
}
}
}
// 删除日程的方法
async function removeItem(index) {
// 弹窗提示是否删除
if (confirm("确定要删除该条数据?")) {
// 根据索引获取要删除的item的id
let sid = schedule.itemList[index].sid
// 向服务端发送请求删除元素
let { data } = await request.get("/schedule/delete", { params: { "sid": sid } })
//根据业务码判断删除是否成功
if (data.code == 200) {
// 删除成功,更新数据
showSchedule()
} else {
// 删除失败,提示失败
alert("删除失败")
}
}
}
</script>
<template>
<div>
<h3 class="ht">您的日程如下</h3>
<table class="tab" cellspacing="0px">
<tr class="ltr">
<th>编号</th>
<th>内容</th>
<th>进度</th>
<th>操作</th>
</tr>
<tr class="ltr" v-for="item, index in schedule.itemList" :key="index">
<td v-text="index + 1">
</td>
<td>
<input type="input" v-model="item.title">
</td>
<td>
<input type="radio" value="1" v-model="item.completed"> 已完成
<input type="radio" value="0" v-model="item.completed"> 未完成
</td>
<td class="buttonContainer">
<button class="btn1" @click="removeItem(index)">删除</button>
<button class="btn1" @click="updateItem(index)">保存修改</button>
</td>
</tr>
<tr class="ltr buttonContainer">
<td colspan="4">
<button class="btn1" @click="addItem()">新增日程</button>
</td>
</tr>
</table>
<!-- {{schedule}} -->
</div>
</template>
<style scoped>
.ht {
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.tab {
width: 80%;
border: 5px solid cadetblue;
margin: 0px auto;
border-radius: 5px;
font-family: 幼圆;
}
.ltr td {
border: 1px solid powderblue;
}
.ipt {
border: 0px;
width: 50%;
}
.btn1 {
border: 2px solid powderblue;
border-radius: 4px;
width: 100px;
background-color: antiquewhite;
}
#usernameMsg,
#userPwdMsg {
color: gold;
}
.buttonContainer {
text-align: center;
}
</style>
import { createRouter, createWebHashHistory } from 'vue-router'
import pinia from '../store/pinia.js'
import { defineUser } from '../store/userStore.js'
let sysUser = defineUser(pinia)
import Login from '../components/Login.vue'
import Regist from '../components/Regist.vue'
import ShowScedule from '../components/ShowSchedule.vue'
let router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/",
component: Login
},
{
path: "/login",
component: Login
},
{
path: "/showSchedule",
component: ShowScedule
},
{
path: "/regist",
component: Regist
}
]
})
/* 配置路由的前置守卫,在登录状态下才可以范文showSchedule.vue */
router.beforeEach((to, from, next) => {
// 如果是查看日程
if (to.path == "/showSchedule") {
// 如果尚未的登录
if (sysUser.username == '') {
alert("您尚未登录,请登录后再查看日程")
next("/login")
} else {
// 已经登录 放行
next()
}
// 其他资源 放行
} else {
next()
}
})
export default router
// 导入pinia组件
import {createPinia} from 'pinia'
// 创建pinia对象
let pinia = createPinia()
// 导出默认的pinia
export default pinia
import {defineStore} from 'pinia'
export const defineSchedule = defineStore('scheduleList',{
state:()=>{
return {
itemList:[
]
}
},
getters :{
},
actions:{
}
})
import {defineStore} from 'pinia'
export const defineUser = defineStore('loginUser',{
state:()=>{
return {
uid:0,
username:''
}
},
getters :{
}
})
import axios from 'axios'
// 创建instance实例
const instance = axios.create({
baseURL: 'http://localhost:8080/'
})
// 添加请求拦截
instance.interceptors.request.use(
// 设置请求头配置信息
config => {
//处理指定的请求头
return config
},
// 设置请求错误处理函数
error => {
return Promise.reject(error)
}
)
// 添加响应拦截器
instance.interceptors.response.use(
// 设置响应正确时的处理函数
response => {
return response
},
// 设置响应异常时的处理函数
error => {
return Promise.reject(error)
}
)
// 默认导出
export default instance
<script setup>
import Header from './components/Header.vue'
</script>
<template>
<div>
<Header></Header>
<!-- 用于路由切换视图使用 -->
<router-view></router-view>
</div>
</template>
<style scoped></style>
import { createApp } from 'vue'
import App from './App.vue'
// 导入路由
import router from './routers/router.js'
// 导入pinia对象
import pinia from './store/pinia.js'
let app =createApp(App)
// 全局使用路由
app.use(router)
// 全局使用pinia
app.use(pinia)
app.mount('#app')
其余默认