优化表结构 添加swagger接口文档

master
liwa 3 years ago
parent a05800ea8b
commit fd0502ece3

@ -17,6 +17,17 @@
<java.version>17</java.version>
</properties>
<dependencies>
<!-- https://doc.xiaominfo.com/knife4j/documentation/get_start.html-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

@ -7,8 +7,8 @@ create table if not exists `huas-project-yangwp`.product
price decimal(10, 2) not null,
in_cart tinyint(1) default 0 not null comment '是否在购物车中,0表示不在,1表示在',
quantity int default 0 not null comment '购物车中的商品数量,如果商品不在购物车中,那么数量为0',
created_at datetime not null,
updated_at datetime not null,
created_at datetime ,
updated_at datetime ,
is_deleted tinyint(1) default 0 not null
)
charset = utf8mb3;
@ -20,8 +20,8 @@ CREATE TABLE `user`
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`location` varchar(255),
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`created_at` datetime ,
`updated_at` datetime ,
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8;
@ -35,8 +35,8 @@ CREATE TABLE `cart_item`
`user_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`quantity` int(11) NOT NULL DEFAULT '0' COMMENT '购物车中的商品数量',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`created_at` datetime ,
`updated_at` datetime ,
PRIMARY KEY (`id`),
FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`product_id`) REFERENCES `product` (`id`)
@ -51,8 +51,8 @@ CREATE TABLE `order`
`product_id` int(11) NOT NULL,
`quantity` int(11) NOT NULL COMMENT '购买的商品数量',
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`created_at` datetime ,
`updated_at` datetime ,
PRIMARY KEY (`id`),
FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`product_id`) REFERENCES `product` (`id`)

@ -0,0 +1,23 @@
package com.ywp.shoppingcartbackend.Config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.servers.Server;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.addServersItem(new Server().url("http://localhost:9998"))
.info(new Info().title("丽娃购物车商城系统")
.description("丽娃购物车商城文档")
.contact(new Contact().name("liwa").email("111@qq.com").url("https://github.com/zhubaiali"))
.version("1.0"));
}
}

@ -14,7 +14,9 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:63342")
//设置允许跨域请求的域名
//当**Credentials为true时**Origin不能为星号需为具体的ip地址【如果接口不带cookie,ip无需设成具体ip】
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);

@ -5,6 +5,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@MapperScan("com.ywp.shoppingcartbackend.mapper")
@EnableScheduling

@ -8,6 +8,8 @@ import com.ywp.shoppingcartbackend.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
* @author asus
* @description userService
@ -28,7 +30,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
throw new IllegalArgumentException("Username already exists: " + user.getUsername());
}
// 否则,将用户信息保存到数据库
user.setCreatedAt(new Date());
user.setUpdatedAt(new Date());
this.save(user);
return user;
}

@ -0,0 +1,8 @@
import axios from 'axios';
const instance = axios.create({
baseURL: 'http://localhost:9998',
timeout: 1000
});
export default instance;

@ -1,51 +1,68 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import React, { useState, useEffect } from "react";
import axios from "../axios";
const CartPage = ({ userId }) => {
const [cartItems, setCartItems] = useState([]);
const [cartItems, setCartItems] = useState([]);
useEffect(() => {
const fetchCartItems = async () => {
const response = await axios.get(`/user/${userId}/cart`);
setCartItems(response.data);
};
useEffect(() => {
const fetchCartItems = async () => {
const response = await axios.get(`/user/${userId}/cart`);
setCartItems(response.data);
};
fetchCartItems();
}, [userId]);
fetchCartItems();
}, [userId]);
const addToCart = async (productId, quantity) => {
const response = await axios.post(`/user/${userId}/cart/add/${productId}`, { quantity });
setCartItems(prevItems => [...prevItems, response.data]);
};
const addToCart = async (productId, quantity) => {
const response = await axios.post(`/user/${userId}/cart/add/${productId}`, {
quantity,
});
setCartItems((prevItems) => [...prevItems, response.data]);
};
const decreaseQuantity = async (productId, quantity) => {
const response = await axios.post(`/user/${userId}/cart/decrease/${productId}`, { quantity });
if (response.status === 204) {
setCartItems(prevItems => prevItems.filter(item => item.productId !== productId));
} else {
setCartItems(prevItems => prevItems.map(item => item.productId === productId ? response.data : item));
}
};
const decreaseQuantity = async (productId, quantity) => {
const response = await axios.post(
`/user/${userId}/cart/decrease/${productId}`,
{ quantity }
);
if (response.status === 204) {
setCartItems((prevItems) =>
prevItems.filter((item) => item.productId !== productId)
);
} else {
setCartItems((prevItems) =>
prevItems.map((item) =>
item.productId === productId ? response.data : item
)
);
}
};
const removeFromCart = async (productId) => {
await axios.post(`/user/${userId}/cart/remove/${productId}`);
setCartItems(prevItems => prevItems.filter(item => item.productId !== productId));
};
const removeFromCart = async (productId) => {
await axios.post(`/user/${userId}/cart/remove/${productId}`);
setCartItems((prevItems) =>
prevItems.filter((item) => item.productId !== productId)
);
};
return (
<div>
<h1>购物车</h1>
{cartItems.map(item => (
<div key={item.id}>
<h2>{item.productName}</h2>
<p>数量: {item.quantity}</p>
<button onClick={() => addToCart(item.productId, 1)}>增加数量</button>
<button onClick={() => decreaseQuantity(item.productId, 1)}>减少数量</button>
<button onClick={() => removeFromCart(item.productId)}>从购物车移除</button>
</div>
))}
return (
<div>
<h1>购物车</h1>
{cartItems.map((item) => (
<div key={item.id}>
<h2>{item.productName}</h2>
<p>数量: {item.quantity}</p>
<button onClick={() => addToCart(item.productId, 1)}>增加数量</button>
<button onClick={() => decreaseQuantity(item.productId, 1)}>
减少数量
</button>
<button onClick={() => removeFromCart(item.productId)}>
从购物车移除
</button>
</div>
);
))}
</div>
);
};
export default CartPage;

@ -1,36 +1,44 @@
import React, { useState } from 'react';
import axios from 'axios';
import React, { useState } from "react";
import axios from "../axios";
const LoginPage = ({ onLogin }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = async (event) => {
event.preventDefault();
try {
const response = await axios.post('/user/login', { username, password });
onLogin(response.data);
} catch (error) {
alert('登录失败,请检查你的用户名和密码');
}
};
const handleSubmit = async (event) => {
event.preventDefault();
try {
const response = await axios.post("/user/login", { username, password });
onLogin(response.data);
} catch (error) {
alert("登录失败,请检查你的用户名和密码");
}
};
return (
<div>
<h1>登录</h1>
<form onSubmit={handleSubmit}>
<label>
用户名:
<input type="text" value={username} onChange={e => setUsername(e.target.value)} />
</label>
<label>
密码:
<input type="password" value={password} onChange={e => setPassword(e.target.value)} />
</label>
<button type="submit">登录</button>
</form>
</div>
);
return (
<div>
<h1>登录</h1>
<form onSubmit={handleSubmit}>
<label>
用户名:
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</label>
<label>
密码:
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</label>
<button type="submit">登录</button>
</form>
</div>
);
};
export default LoginPage;

@ -1,36 +1,38 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import React, { useState, useEffect } from "react";
import axios from "../axios";
const OrderPage = ({ userId }) => {
const [orders, setOrders] = useState([]);
const [orders, setOrders] = useState([]);
useEffect(() => {
const fetchOrders = async () => {
const response = await axios.get(`/user/${userId}/order`);
setOrders(response.data);
};
useEffect(() => {
const fetchOrders = async () => {
const response = await axios.get(`/user/${userId}/order`);
setOrders(response.data);
};
fetchOrders();
}, [userId]);
fetchOrders();
}, [userId]);
const deleteOrder = async (orderId) => {
await axios.delete(`/user/${userId}/order/${orderId}`);
setOrders(prevOrders => prevOrders.filter(order => order.id !== orderId));
};
const deleteOrder = async (orderId) => {
await axios.delete(`/user/${userId}/order/${orderId}`);
setOrders((prevOrders) =>
prevOrders.filter((order) => order.id !== orderId)
);
};
return (
<div>
<h1>订单</h1>
{orders.map(order => (
<div key={order.id}>
<h2>订单 ID: {order.id}</h2>
<p>商品 ID: {order.productId}</p>
<p>数量: {order.quantity}</p>
<button onClick={() => deleteOrder(order.id)}>删除订单</button>
</div>
))}
return (
<div>
<h1>订单</h1>
{orders.map((order) => (
<div key={order.id}>
<h2>订单 ID: {order.id}</h2>
<p>商品 ID: {order.productId}</p>
<p>数量: {order.quantity}</p>
<button onClick={() => deleteOrder(order.id)}>删除订单</button>
</div>
);
))}
</div>
);
};
export default OrderPage;

@ -1,30 +1,30 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import React, { useState, useEffect } from "react";
import axios from "../axios";
const ProductPage = () => {
const [products, setProducts] = useState([]);
const [products, setProducts] = useState([]);
useEffect(() => {
const fetchProducts = async () => {
const response = await axios.get(`/product`);
setProducts(response.data.records);
};
useEffect(() => {
const fetchProducts = async () => {
const response = await axios.get(`/product`);
setProducts(response.data.records);
};
fetchProducts();
}, []);
fetchProducts();
}, []);
return (
<div>
<h1>产品</h1>
{products.map(product => (
<div key={product.id}>
<h2>产品 ID: {product.id}</h2>
<p>产品名称: {product.name}</p>
<p>产品描述: {product.description}</p>
</div>
))}
return (
<div>
<h1>产品</h1>
{products.map((product) => (
<div key={product.id}>
<h2>产品 ID: {product.id}</h2>
<p>产品名称: {product.name}</p>
<p>产品描述: {product.description}</p>
</div>
);
))}
</div>
);
};
export default ProductPage;

Loading…
Cancel
Save