Vue + TS + MySQL实战示例三:实现商品管理系统

发布于:2024-12-06 ⋅ 阅读:(39) ⋅ 点赞:(0)

在之前的实战示例中,我们搭建了项目基础架构并实现了用户认证功能。接下来,我们将基于此构建一个商品管理系统,涵盖商品的添加、查询、更新和删除操作,进一步深入探索Vue、TS和MySQL的协同应用。

一、创建商品数据模型

  1. 定义商品模型
    在项目的models文件夹中创建product.model.ts文件,用于定义商品的数据模型。示例代码如下:
import { Model, DataTypes, Optional } from'sequelize-typescript';
import sequelize from '../config/db.config';

interface ProductAttributes {
  id: number;
  name: string;
  description: string;
  price: number;
  quantity: number;
}

interface ProductCreationAttributes extends Optional<ProductAttributes, 'id'> {}

class Product extends Model<ProductAttributes, ProductCreationAttributes> {
  id!: number;
  name!: string;
  description!: string;
  price!: number;
  quantity!: number;
}

Product.init({
  id: {
    type: DataTypes.INTEGER.UNSIGNED,
    autoIncrement: true,
    primaryKey: true
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false
  },
  description: {
    type: DataTypes.TEXT,
    allowNull: false
  },
  price: {
    type: DataTypes.DECIMAL(10, 2),
    allowNull: false
  },
  quantity: {
    type: DataTypes.INTEGER.UNSIGNED,
    allowNull: false,
    defaultValue: 0
  }
}, {
  sequelize,
  tableName: 'products'
});

export default Product;

这个模型定义了商品的基本属性,包括idname(商品名称)、description(商品描述)、price(价格)和quantity(库存数量),并指定了相应的数据类型和约束条件。

  1. 同步商品模型到数据库
    main.ts文件中,确保添加以下代码来同步商品模型到数据库(与之前同步用户模型类似):
import Product from './models/product.model';

async function syncModels() {
  await sequelize.sync({ force: false });
  console.log('模型同步成功');
}

syncModels();

运行项目后,数据库中将创建名为products的表,用于存储商品信息。

二、创建商品管理组件

  1. 生成商品管理组件
    使用命令行工具生成一个名为ProductManagement.vue的组件:
vue generate component ProductManagement
  1. 编写商品管理组件模板
    ProductManagement.vue<template>标签内,构建商品管理的用户界面。以下是一个简单的示例,包含商品列表展示、添加商品表单和操作按钮:
<template>
  <div class="product-management-container">
    <h2>商品管理</h2>
    <!-- 商品添加表单 -->
    <form @submit.prevent="addProduct">
      <label for="name">商品名称:</label>
      <input type="text" id="name" v-model="newProduct.name" required />
      <label for="description">商品描述:</label>
      <textarea id="description" v-model="newProduct.description" required></textarea>
      <label for="price">价格:</label>
      <input type="number" step="0.01" id="price" v-model="newProduct.price" required />
      <label for="quantity">库存数量:</label>
      <input type="number" id="quantity" v-model="newProduct.quantity" required />
      <button type="submit">添加商品</button>
    </form>
    <!-- 商品列表 -->
    <ul>
      <li v-for="product in products" :key="product.id">
        {{ product.name }} - {{ product.price }}元 - 库存: {{ product.quantity }}
        <button @click="editProduct(product)">编辑</button>
        <button @click="deleteProduct(product.id)">删除</button>
      </li>
    </ul>
  </div>
</template>

在这个模板中,我们使用v-for指令循环展示商品列表,每个商品项显示名称、价格、库存数量以及编辑和删除按钮。同时,提供了一个添加商品的表单,用于输入新商品的信息。

  1. 编写商品管理组件逻辑
    <script lang="ts">标签内,编写商品管理组件的逻辑代码。首先,导入必要的依赖,包括axiosProduct模型:
import axios from 'axios';
import Product from '@/models/product.model';

export default {
  name: 'ProductManagement',
  data() {
    return {
      products: [] as Product[],
      newProduct: {
        name: '',
        description: '',
        price: 0,
        quantity: 0
      }
    };
  },
  methods: {
    // 获取商品列表
    async getProducts() {
      try {
        const response = await axios.get('/api/products');
        this.products = response.data;
      } catch (error) {
        console.error('获取商品列表失败:', error);
      }
    },
    // 添加商品
    async addProduct() {
      try {
        const productToAdd: Product = {
          name: this.newProduct.name,
          description: this.newProduct.description,
          price: this.newProduct.price,
          quantity: this.newProduct.quantity
        };
        await axios.post('/api/products', productToAdd);
        this.newProduct = {
          name: '',
          description: '',
          price: 0,
          quantity: 0
        };
        this.getProducts();
      } catch (error) {
        console.error('添加商品失败:', error);
      }
    },
    // 编辑商品(这里可以根据需求进一步实现编辑功能,目前只简单打印商品信息)
    editProduct(product: Product) {
      console.log('编辑商品:', product);
    },
    // 删除商品
    async deleteProduct(productId: number) {
      try {
        await axios.delete(`/api/products/${productId}`);
        this.getProducts();
      } catch (error) {
        console.error('删除商品失败:', error);
      }
    }
  },
  mounted() {
    this.getProducts();
  }
};

mounted生命周期钩子中,调用getProducts方法获取初始的商品列表。getProducts方法使用axios.get请求后端的/api/products接口获取商品数据,并将其赋值给products数组,用于在前端展示。addProduct方法用于添加新商品,将用户输入的商品信息组成Product对象,发送axios.post请求到后端添加商品,添加成功后清空表单并重新获取商品列表。editProduct方法目前只是简单打印商品信息,后续可以根据需求完善编辑功能。deleteProduct方法根据商品id发送axios.delete请求到后端删除商品,删除成功后重新获取商品列表。

三、后端API实现(商品相关操作)

  1. 创建商品API路由文件
    在后端的routes文件夹中创建product.routes.js文件,用于定义商品相关的API路由。

  2. 实现获取商品列表路由
    product.routes.js文件中,编写获取商品列表路由的处理逻辑:

const express = require('express');
const router = express.Router();
const Product = require('../models/product.model');

router.get('/products', async (req, res) => {
  try {
    const products = await Product.findAll();
    res.status(200).json(products);
  } catch (error) {
    console.error('获取商品列表失败:', error);
    res.status(500).json({ message: '获取商品列表失败,请稍后重试' });
  }
});

这个路由处理函数使用Product.findAll方法从数据库中查询所有商品记录,并将结果以JSON格式返回给前端。

  1. 实现添加商品路由
    继续在product.routes.js文件中编写添加商品路由的处理逻辑:
router.post('/products', async (req, res) => {
  try {
    const { name, description, price, quantity } = req.body;
    const newProduct = await Product.create({
      name,
      description,
      price,
      quantity
    });
    res.status(201).json(newProduct);
  } catch (error) {
    console.error('添加商品失败:', error);
    res.status(500).json({ message: '添加商品失败,请稍后重试' });
  }
});

从请求体中获取商品信息,使用Product.create方法创建新的商品记录并保存到数据库中,然后将新创建的商品对象返回给前端。

  1. 实现删除商品路由
    product.routes.js文件中添加删除商品路由的处理逻辑:
router.delete('/products/:id', async (req, res) => {
  try {
    const productId = req.params.id;
    const result = await Product.destroy({ where: { id: productId } });
    if (result === 0) {
      return res.status(404).json({ message: '商品不存在' });
    }
    res.status(204).send();
  } catch (error) {
    console.error('删除商品失败:', error);
    res.status(500).json({ message: '删除商品失败,请稍后重试' });
  }
});

根据请求参数中的商品id,使用Product.destroy方法从数据库中删除对应的商品记录。如果删除的行数为0,表示商品不存在,返回相应的状态码和消息;否则,返回成功删除的状态码(204表示无内容返回)。

  1. 注册商品路由到应用程序
    在后端应用程序的入口文件(如app.jsindex.js)中,将product.routes.js文件中定义的路由注册到应用程序中:
const productRoutes = require('./routes/product.routes');

app.use('/api', productRoutes);

通过以上步骤,我们实现了一个简单的商品管理系统,包括商品数据模型的定义、前端商品管理组件的创建以及后端API的实现。用户可以在前端添加、查看、编辑(部分功能待完善)和删除商品,数据通过与MySQL数据库的交互进行持久化存储。在后续的实战示例中,我们可以进一步优化这个系统,例如添加商品图片上传、搜索功能、权限控制等,使其更加完善和实用。希望本示例对你在Vue + TS + MySQL项目开发中的学习有所帮助,如果你有任何疑问或建议,欢迎在评论区留言。