经典前端+后端+表头+表身的开发实战参考简易模板【珍藏】

前端部分(Vue 3 + Element Plus)

1. 修改 MPS002HList.vue(主生产计划列表)

a. 添加查询表单

在模板中添加查询表单,包含产品料号、品名、规格和年月的输入项。

<template>   <div>     <!-- 查询表单 -->     <el-form :inline="true" :model="filters" class="demo-form-inline">       <el-form-item label="产品料号">         <el-input v-model="filters.bo_no" placeholder="请输入产品料号"></el-input>       </el-form-item>       <el-form-item label="品名">         <el-input v-model="filters.item_name" placeholder="请输入品名"></el-input>       </el-form-item>       <el-form-item label="规格">         <el-input v-model="filters.item_spec" placeholder="请输入规格"></el-input>       </el-form-item>       <el-form-item label="年月">         <el-date-picker           v-model="filters.mps_ym"           type="month"           placeholder="选择年月"           format="yyyy-MM"           value-format="yyyy-MM"         />       </el-form-item>       <el-form-item>         <el-button type="primary" @click="fetchMpsList">查询</el-button>         <el-button @click="resetFilters">重置</el-button>       </el-form-item>     </el-form>      <!-- 生产计划列表 -->     <el-table :data="mpsList" style="width: 100%" v-loading="loading">       <el-table-column prop="mps_no" label="单号" width="180">         <template #default="{ row }">           <el-button type="text" @click="showMpsDetails(row.mps_no)">             {{ row.mps_no }}           </el-button>         </template>       </el-table-column>       <el-table-column prop="mps_date" label="单据时间" width="180" />       <el-table-column prop="fa_no_name" label="厂别" width="180" />       <el-table-column prop="bo_no" label="产品料号" width="180" />       <el-table-column prop="bo_no_name" label="品名" width="180" />       <el-table-column prop="bo_no_spec" label="规格" width="180" />       <el-table-column prop="mps_ym" label="年月" width="100" />       <el-table-column prop="mps_qty" label="数量" width="100" />     </el-table>      <!-- 分页 -->     <el-pagination       v-if="mpsList.length"       background       :current-page="page"       :page-size="pageSize"       layout="total, prev, pager, next"       :total="total"       @current-change="handlePageChange"     />      <!-- 详情对话框 -->     <el-dialog :visible.sync="showDetails" width="80%">       <template #header>         <h3>主生产计划详情</h3>       </template>       <MPS002HDetail :mps_no="selectedMpsNo" />     </el-dialog>   </div> </template>

b. 修改脚本部分

setup 函数中,添加 filters 数据,并修改 fetchMpsList 函数以包含查询参数。

<script> import { ref, onMounted } from 'vue'; import { getMPS002 } from '@/api/mpsApp/MPS002HModel'; import MPS002HDetail from './MPS002HDetail.vue';  export default {   components: { MPS002HDetail },   setup() {     const mpsList = ref([]);     const page = ref(1);     const pageSize = ref(10);     const total = ref(0);     const loading = ref(false);     const showDetails = ref(false);     const selectedMpsNo = ref(null);      const filters = ref({       bo_no: '',       item_name: '',       item_spec: '',       mps_ym: '',     });      const fetchMpsList = async () => {       loading.value = true;       try {         const params = {           page: page.value,           page_size: pageSize.value,           bo_no: filters.value.bo_no,           item_name: filters.value.item_name,           item_spec: filters.value.item_spec,           mps_ym: filters.value.mps_ym,         };         const response = await getMPS002(params);         mpsList.value = response.data.results;         total.value = response.data.count;       } catch (error) {         console.error('Error fetching MPS002 list:', error);       } finally {         loading.value = false;       }     };      const resetFilters = () => {       filters.value = {         bo_no: '',         item_name: '',         item_spec: '',         mps_ym: '',       };       fetchMpsList();     };      const showMpsDetails = (mps_no) => {       selectedMpsNo.value = mps_no;       showDetails.value = true;     };      const handlePageChange = (newPage) => {       page.value = newPage;       fetchMpsList();     };      onMounted(fetchMpsList);      return {       mpsList,       page,       pageSize,       total,       loading,       showDetails,       selectedMpsNo,       filters,       fetchMpsList,       resetFilters,       showMpsDetails,       handlePageChange,     };   }, }; </script>

2. 修改 MPS002D1List.vue(物料需求明细列表)

a. 添加查询表单

<template>   <div>     <!-- 查询表单 -->     <el-form :inline="true" :model="filters" class="demo-form-inline">       <el-form-item label="料号">         <el-input v-model="filters.item_no" placeholder="请输入料号"></el-input>       </el-form-item>       <el-form-item label="品名">         <el-input v-model="filters.item_name" placeholder="请输入品名"></el-input>       </el-form-item>       <el-form-item label="规格">         <el-input v-model="filters.item_spec" placeholder="请输入规格"></el-input>       </el-form-item>       <el-form-item>         <el-button type="primary" @click="fetchMpsD1List">查询</el-button>         <el-button @click="resetFilters">重置</el-button>       </el-form-item>     </el-form>      <!-- 物料需求明细列表 -->     <el-table :data="mpsD1List" style="width: 100%" v-loading="loading">       <el-table-column prop="item_no" label="料号" width="180" />       <el-table-column prop="item_name" label="品名" width="180" />       <el-table-column prop="item_spec" label="规格" width="180" />       <el-table-column prop="item_qty" label="需求数量" width="180" />       <!-- 添加更多列 -->     </el-table>      <!-- 分页 -->     <el-pagination       v-if="mpsD1List.length"       background       :current-page="page"       :page-size="pageSize"       layout="total, prev, pager, next"       :total="total"       @current-change="handlePageChange"     />   </div> </template>

b. 修改脚本部分

<script> import { ref, onMounted } from 'vue'; import { getMPS002D1 } from '@/api/mpsApp/MPS002D1Model';  export default {   setup() {     const mpsD1List = ref([]);     const page = ref(1);     const pageSize = ref(10);     const total = ref(0);     const loading = ref(false);      const filters = ref({       item_no: '',       item_name: '',       item_spec: '',     });      const fetchMpsD1List = async () => {       loading.value = true;       try {         const params = {           page: page.value,           page_size: pageSize.value,           item_no: filters.value.item_no,           item_name: filters.value.item_name,           item_spec: filters.value.item_spec,         };         const response = await getMPS002D1(params);         mpsD1List.value = response.data.results;         total.value = response.data.count;       } catch (error) {         console.error('Error fetching MPS002D1 list:', error);       } finally {         loading.value = false;       }     };      const resetFilters = () => {       filters.value = {         item_no: '',         item_name: '',         item_spec: '',       };       fetchMpsD1List();     };      const handlePageChange = (newPage) => {       page.value = newPage;       fetchMpsD1List();     };      onMounted(fetchMpsD1List);      return {       mpsD1List,       page,       pageSize,       total,       loading,       filters,       fetchMpsD1List,       resetFilters,       handlePageChange,     };   }, }; </script>

后端部分(Django REST Framework)

为了支持前端的查询功能,需要在后端的视图中添加筛选功能。

1. 修改 MPS002HModel 的视图

from rest_framework import viewsets, filters from django_filters.rest_framework import DjangoFilterBackend from .models import MPS002HModel from .serializers import MPS002HSerializer  class MPS002HViewSet(viewsets.ModelViewSet):     queryset = MPS002HModel.objects.all().order_by('-mps_date')     serializer_class = MPS002HSerializer     filter_backends = [DjangoFilterBackend, filters.SearchFilter]     filterset_fields = ['mps_ym']     search_fields = ['bo_no__item_no', 'bo_no__item_name', 'bo_no__item_spec']

说明

  • filter_backends:使用 DjangoFilterBackendSearchFilter,可以实现精确过滤和模糊搜索。
  • filterset_fields:精确过滤的字段,这里包括 mps_ym
  • search_fields:模糊搜索的字段,包括关联的 bo_no(产品料号)的 item_noitem_nameitem_spec

2. 修改 MPS002D1Model 的视图

from rest_framework import viewsets, filters from django_filters.rest_framework import DjangoFilterBackend from .models import MPS002D1Model from .serializers import MPS002D1Serializer  class MPS002D1ViewSet(viewsets.ModelViewSet):     queryset = MPS002D1Model.objects.all()     serializer_class = MPS002D1Serializer     filter_backends = [DjangoFilterBackend, filters.SearchFilter]     search_fields = ['item_no__item_no', 'item_no__item_name', 'item_no__item_spec']

说明

  • search_fields:对于物料需求明细,可以根据 item_no(料号)、item_name(品名)、item_spec(规格)进行模糊搜索。

3. 安装和配置 django-filter

如果还没有安装 django-filter,需要先安装:

pip install django-filter

并在 settings.py 中添加:

REST_FRAMEWORK = {     'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] }

更新序列化器

确保您的序列化器包含必要的字段,以便前端能够正确接收数据。

MPS002HSerializer

from rest_framework import serializers from .models import MPS002HModel  class MPS002HSerializer(serializers.ModelSerializer):     fa_no_name = serializers.CharField(source='fa_no.fa_name', read_only=True)     bo_no_name = serializers.CharField(source='bo_no.item_name', read_only=True)     bo_no_spec = serializers.CharField(source='bo_no.item_spec', read_only=True)     bo_no = serializers.CharField(source='bo_no.item_no', read_only=True)      class Meta:         model = MPS002HModel         fields = ['id', 'mps_no', 'mps_date', 'fa_no', 'fa_no_name', 'bo_no', 'bo_no_name', 'bo_no_spec', 'mps_ym', 'mps_qty']

MPS002D1Serializer

from rest_framework import serializers from .models import MPS002D1Model  class MPS002D1Serializer(serializers.ModelSerializer):     item_name = serializers.CharField(source='item_no.item_name', read_only=True)     item_spec = serializers.CharField(source='item_no.item_spec', read_only=True)     item_no = serializers.CharField(source='item_no.item_no', read_only=True)      class Meta:         model = MPS002D1Model         fields = ['id', 'mps_no', 'item_no', 'item_name', 'item_spec', 'item_qty', 'rmk']

更新 API 请求

1. 更新前端 API 调用

在您的 API 请求文件中,确保查询参数能够正确传递。

MPS002HModel API

import request from '@/utils/request'; const baseUrl = '/mpsApp/MPS002HModel/';  export function getMPS002(params) {   return request({     url: baseUrl,     method: 'get',     params,   }); }

MPS002D1Model API

import request from '@/utils/request'; const baseUrl = '/mpsApp/MPS002D1Model/';  export function getMPS002D1(params) {   return request({     url: baseUrl,     method: 'get',     params,   }); }


总结

通过上述步骤,我们实现了:

  • 前端:在 MPS002HModelMPS002D1Model 的列表页面中添加了查询表单,可以根据指定的字段进行筛选,并将查询条件传递给后端。

  • 后端:在 Django REST Framework 的视图中,使用 django-filterSearchFilter 实现了对指定字段的精确过滤和模糊搜索。

  • 序列化器:更新了序列化器,以便在返回数据时包含关联字段的信息,如品名和规格。

  • API 请求:确保查询参数能够正确地通过前端 API 请求发送到后端。

这样,用户就可以在前端界面上根据产品料号、品名、规格和年月对主生产计划列表进行查询,也可以在物料需求明细列表中根据料号、品名、规格进行筛选。

发表评论

相关文章