docs: 更新项目文档,完善需求和技术细节
This commit is contained in:
@@ -2,6 +2,61 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const dbConnector = require('../utils/dbConnector');
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/addresses:
|
||||
* get:
|
||||
* summary: 获取用户收货地址列表
|
||||
* description: 获取当前用户的所有收货地址,按默认地址和创建时间排序
|
||||
* tags:
|
||||
* - 地址管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 成功获取收货地址列表
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 200
|
||||
* message:
|
||||
* type: string
|
||||
* example: 获取成功
|
||||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/Address'
|
||||
* 401:
|
||||
* description: 未授权访问
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 401
|
||||
* message:
|
||||
* type: string
|
||||
* example: 未授权访问
|
||||
* 500:
|
||||
* description: 服务器内部错误
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 500
|
||||
* message:
|
||||
* type: string
|
||||
* example: 服务器内部错误
|
||||
*/
|
||||
// 获取用户收货地址列表
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
@@ -29,12 +84,132 @@ router.get('/', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/addresses:
|
||||
* post:
|
||||
* summary: 添加收货地址
|
||||
* description: 为当前用户添加新的收货地址
|
||||
* tags:
|
||||
* - 地址管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - recipient
|
||||
* - phone
|
||||
* - province
|
||||
* - city
|
||||
* - district
|
||||
* - detail
|
||||
* properties:
|
||||
* recipient:
|
||||
* type: string
|
||||
* example: "张三"
|
||||
* description: 收货人姓名
|
||||
* phone:
|
||||
* type: string
|
||||
* example: "13800138000"
|
||||
* description: 收货人手机号
|
||||
* province:
|
||||
* type: string
|
||||
* example: "北京市"
|
||||
* description: 省份
|
||||
* city:
|
||||
* type: string
|
||||
* example: "北京市"
|
||||
* description: 城市
|
||||
* district:
|
||||
* type: string
|
||||
* example: "朝阳区"
|
||||
* description: 区/县
|
||||
* detail:
|
||||
* type: string
|
||||
* example: "xxx街道xxx号"
|
||||
* description: 详细地址
|
||||
* is_default:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* description: 是否为默认地址 (0-否, 1-是)
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 成功添加收货地址
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 200
|
||||
* message:
|
||||
* type: string
|
||||
* example: 添加成功
|
||||
* data:
|
||||
* type: object
|
||||
* properties:
|
||||
* address_id:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* 400:
|
||||
* description: 请求参数错误
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 400
|
||||
* message:
|
||||
* type: string
|
||||
* example: 收货人姓名、手机号和地址信息不能为空
|
||||
* 401:
|
||||
* description: 未授权访问
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 401
|
||||
* message:
|
||||
* type: string
|
||||
* example: 未授权访问
|
||||
* 500:
|
||||
* description: 服务器内部错误
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 500
|
||||
* message:
|
||||
* type: string
|
||||
* example: 服务器内部错误
|
||||
*/
|
||||
// 添加收货地址
|
||||
router.post('/', async (req, res) => {
|
||||
try {
|
||||
const { recipient, phone, province, city, district, detail, is_default } = req.body;
|
||||
const userId = req.user.id;
|
||||
|
||||
// 验证必填字段
|
||||
if (!recipient || !phone || !province || !city || !district || !detail) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '收货人姓名、手机号和地址信息不能为空'
|
||||
});
|
||||
}
|
||||
|
||||
// 如果设置为默认地址,先取消其他默认地址
|
||||
if (is_default) {
|
||||
await dbConnector.query(
|
||||
@@ -50,8 +225,8 @@ router.post('/', async (req, res) => {
|
||||
[userId, recipient, phone, province, city, district, detail, is_default || 0]
|
||||
);
|
||||
|
||||
res.status(201).json({
|
||||
code: 201,
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '添加成功',
|
||||
data: {
|
||||
address_id: result.insertId
|
||||
@@ -67,6 +242,125 @@ router.post('/', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/addresses/{id}:
|
||||
* put:
|
||||
* summary: 更新收货地址
|
||||
* description: 更新当前用户的指定收货地址
|
||||
* tags:
|
||||
* - 地址管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
* description: 地址ID
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* recipient:
|
||||
* type: string
|
||||
* example: "张三"
|
||||
* description: 收货人姓名
|
||||
* phone:
|
||||
* type: string
|
||||
* example: "13800138000"
|
||||
* description: 收货人手机号
|
||||
* province:
|
||||
* type: string
|
||||
* example: "北京市"
|
||||
* description: 省份
|
||||
* city:
|
||||
* type: string
|
||||
* example: "北京市"
|
||||
* description: 城市
|
||||
* district:
|
||||
* type: string
|
||||
* example: "朝阳区"
|
||||
* description: 区/县
|
||||
* detail:
|
||||
* type: string
|
||||
* example: "xxx街道xxx号"
|
||||
* description: 详细地址
|
||||
* is_default:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* description: 是否为默认地址 (0-否, 1-是)
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 成功更新收货地址
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 200
|
||||
* message:
|
||||
* type: string
|
||||
* example: 更新成功
|
||||
* 400:
|
||||
* description: 请求参数错误
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 400
|
||||
* message:
|
||||
* type: string
|
||||
* example: 收货人姓名、手机号和地址信息不能为空
|
||||
* 401:
|
||||
* description: 未授权访问
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 401
|
||||
* message:
|
||||
* type: string
|
||||
* example: 未授权访问
|
||||
* 404:
|
||||
* description: 地址不存在
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 404
|
||||
* message:
|
||||
* type: string
|
||||
* example: 地址不存在
|
||||
* 500:
|
||||
* description: 服务器内部错误
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 500
|
||||
* message:
|
||||
* type: string
|
||||
* example: 服务器内部错误
|
||||
*/
|
||||
// 更新收货地址
|
||||
router.put('/:id', async (req, res) => {
|
||||
try {
|
||||
@@ -74,13 +368,21 @@ router.put('/:id', async (req, res) => {
|
||||
const { recipient, phone, province, city, district, detail, is_default } = req.body;
|
||||
const userId = req.user.id;
|
||||
|
||||
// 检查地址是否存在
|
||||
const address = await dbConnector.query(
|
||||
// 验证必填字段
|
||||
if (!recipient || !phone || !province || !city || !district || !detail) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '收货人姓名、手机号和地址信息不能为空'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查地址是否存在且属于当前用户
|
||||
const existingAddress = await dbConnector.query(
|
||||
'SELECT * FROM addresses WHERE id = ? AND user_id = ?',
|
||||
[id, userId]
|
||||
);
|
||||
|
||||
if (address.length === 0) {
|
||||
if (existingAddress.length === 0) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '地址不存在'
|
||||
@@ -96,10 +398,11 @@ router.put('/:id', async (req, res) => {
|
||||
}
|
||||
|
||||
await dbConnector.query(
|
||||
`UPDATE addresses SET
|
||||
recipient = ?, phone = ?, province = ?, city = ?, district = ?, detail = ?, is_default = ?, updated_at = NOW()
|
||||
WHERE id = ? AND user_id = ?`,
|
||||
[recipient, phone, province, city, district, detail, is_default || 0, id, userId]
|
||||
`UPDATE addresses
|
||||
SET recipient = ?, phone = ?, province = ?, city = ?, district = ?, detail = ?,
|
||||
is_default = ?, updated_at = NOW()
|
||||
WHERE id = ?`,
|
||||
[recipient, phone, province, city, district, detail, is_default || 0, id]
|
||||
);
|
||||
|
||||
res.json({
|
||||
@@ -116,17 +419,99 @@ router.put('/:id', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/v1/addresses/{id}:
|
||||
* delete:
|
||||
* summary: 删除收货地址
|
||||
* description: 删除当前用户的指定收货地址
|
||||
* tags:
|
||||
* - 地址管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
* description: 地址ID
|
||||
* responses:
|
||||
* 200:
|
||||
* description: 成功删除收货地址
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 200
|
||||
* message:
|
||||
* type: string
|
||||
* example: 删除成功
|
||||
* 401:
|
||||
* description: 未授权访问
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 401
|
||||
* message:
|
||||
* type: string
|
||||
* example: 未授权访问
|
||||
* 404:
|
||||
* description: 地址不存在
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 404
|
||||
* message:
|
||||
* type: string
|
||||
* example: 地址不存在
|
||||
* 500:
|
||||
* description: 服务器内部错误
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* code:
|
||||
* type: integer
|
||||
* example: 500
|
||||
* message:
|
||||
* type: string
|
||||
* example: 服务器内部错误
|
||||
*/
|
||||
// 删除收货地址
|
||||
router.delete('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const userId = req.user.id;
|
||||
|
||||
await dbConnector.query(
|
||||
'DELETE FROM addresses WHERE id = ? AND user_id = ?',
|
||||
// 检查地址是否存在且属于当前用户
|
||||
const existingAddress = await dbConnector.query(
|
||||
'SELECT * FROM addresses WHERE id = ? AND user_id = ?',
|
||||
[id, userId]
|
||||
);
|
||||
|
||||
if (existingAddress.length === 0) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '地址不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 删除地址
|
||||
await dbConnector.query('DELETE FROM addresses WHERE id = ?', [id]);
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '删除成功'
|
||||
@@ -141,36 +526,4 @@ router.delete('/:id', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 设置默认地址
|
||||
router.put('/:id/default', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const userId = req.user.id;
|
||||
|
||||
// 先取消所有默认地址
|
||||
await dbConnector.query(
|
||||
'UPDATE addresses SET is_default = 0 WHERE user_id = ?',
|
||||
[userId]
|
||||
);
|
||||
|
||||
// 设置当前地址为默认
|
||||
await dbConnector.query(
|
||||
'UPDATE addresses SET is_default = 1, updated_at = NOW() WHERE id = ? AND user_id = ?',
|
||||
[id, userId]
|
||||
);
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '设置默认地址成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('设置默认地址失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user