15.寻光集后台管理系统-产品信息-数据部分

2022-12-02 16:11:53 浏览数 (1)

基本样式

先编写表格的基本样式

直接使用框架提供的表格组件:frontend/src/components/scTable/index.vue

代码语言:javascript复制
<el-main class="nopadding">
    <scTable ref="table" :apiObj="list.apiObj" row-key="id" remoteSort>
      <el-table-column label="货品编码" prop="product_id" width="300"></el-table-column>
      <el-table-column label="类别" prop="category" width="150"></el-table-column>
      <el-table-column label="品牌" prop="brand" width="250"></el-table-column>
      <el-table-column label="品名" prop="name" width="150"></el-table-column>
      <el-table-column label="产品单价" prop="price" width="150" sortable='custom'></el-table-column>
      <el-table-column label="库存数" prop="total_warehouse" width="150"></el-table-column>
      <el-table-column label="样图" width="160"></el-table-column>
      <el-table-column label="备注" prop="desc" width="160"></el-table-column>
      <el-table-column label="操作" fixed="right" align="center" width="160">
      </el-table-column>
    </scTable>
  </el-main>

在数据中直接写this.$API.products.list接口调用就可以了,组件内部会去发起数据请求

代码语言:javascript复制
data() {
    return {
      list: {
        apiObj: this.$API.products.list
      },
    }
  },

效果

组件中调用逻辑

代码语言:javascript复制
mounted() {
  ...
  //判断是否静态数据
  if(this.apiObj){
    this.getData();
  }else if(this.data){
    this.tableData = this.data;
    this.total = this.tableData.length
  }
},
代码语言:javascript复制
//获取数据
async getData(){
  this.loading = true;
  var reqData = {
    [config.request.page]: this.currentPage,
    [config.request.pageSize]: this.scPageSize,
    [config.request.prop]: this.prop,
    [config.request.order]: this.order
  }
  if(this.hidePagination){
    delete reqData[config.request.page]
    delete reqData[config.request.pageSize]
  }
  Object.assign(reqData, this.tableParams)

  try {
    var res = await this.apiObj.get(reqData);
  }catch(error){
    this.loading = false;
    this.emptyText = error.statusText;
    return false;
  }
  try {
    var response = config.parseData(res);
  }catch(error){
    this.loading = false;
    this.emptyText = "数据格式错误";
    return false;
  }
  if(response.code != config.successCode){
    this.loading = false;
    this.emptyText = response.msg;
  }else{
    this.emptyText = "暂无数据";
    if(this.hidePagination){
      this.tableData = response.data || [];
    }else{
      this.tableData = response.rows || [];
    }
    this.total = response.total || 0;
    this.summary = response.summary || {};
    this.loading = false;
  }
  this.$refs.scTable.setScrollTop(0)
  this.$emit('dataChange', res, this.tableData)
},

getData函数拆开来看

  1. 处理请求数据:当前页码每页条数排序规则
  2. 是否hidePagination(没有页码组件部分)
  3. 把请求参数合并成一个新的对象
代码语言:javascript复制
var reqData = {
  [config.request.page]: this.currentPage,
  [config.request.pageSize]: this.scPageSize,
  [config.request.prop]: this.prop,
  [config.request.order]: this.order
}
if(this.hidePagination){
  delete reqData[config.request.page]
  delete reqData[config.request.pageSize]
}
Object.assign(reqData, this.tableParams)
  1. 发起http请求
代码语言:javascript复制
try {
  var res = await this.apiObj.get(reqData);
}catch(error){
  this.loading = false;
  this.emptyText = error.statusText;
  return false;
}
  1. 根据配置的规则处理数据
代码语言:javascript复制
parseData: function (res) {                    
    return {
      data: res.data,        //分析无分页的数据字段结构
      rows: res.data.rows,    //分析行数据字段结构
      total: res.data.total,    //分析总数字段结构
      summary: res.data.summary,  //分析合计行字段结构
      msg: res.message,      //分析描述字段结构
      code: res.code        //分析状态字段结构
    }
  },
代码语言:javascript复制
try {
  var response = config.parseData(res);
}catch(error){
  this.loading = false;
  this.emptyText = "数据格式错误";
  return false;
}

我们在后端按照这个规则处理过数据了,拿到的json数据为

代码语言:javascript复制
{
  "data": {
    "page": 1,
    "pageSize": 20,
    "rows": [
      {
        "id": 1,
        "c_time": "2022-09-02T12:14:32.356282 08:00",
        "u_time": "2022-09-02T12:14:32.356417 08:00",
        "product_id": "0001",
        "category": "饮料",
        "brand": "可口可乐",
        "name": "可乐",
        "price": "3.00",
        "sample_png": "",
        "desc": "无"
      }
    ],
    "total": 1
  },
  "message": "",
  "code": 200,
  "next": null,
  "previous": null
}

它刚好和处理的方式一致,也就不会报出数据格式错误错误了

  1. 根据响应码和数据内容判断是否继续
代码语言:javascript复制
if(response.code != config.successCode){
  this.loading = false;
  this.emptyText = response.msg;
}else{
  this.emptyText = "暂无数据";
  if(this.hidePagination){
    this.tableData = response.data || [];
  }else{
    this.tableData = response.rows || [];
  }
  this.total = response.total || 0;
  this.summary = response.summary || {};
  this.loading = false;
}
  1. 子组件往父组件把拿到的数据传递出去
代码语言:javascript复制
this.$refs.scTable.setScrollTop(0)
this.$emit('dataChange', res, this.tableData)

文件操作

要展示样图的话,首先需要编写一个上传图片的接口

这个接口是一个通用的接口,所以单独新建一个file模块来编写

代码语言:javascript复制
python manage.py startapp file

然后把file移到apps中

backend/LightSeeking/settings.py中进行注册

编写models.py

代码语言:javascript复制
from django.db import models
from utils.models import BaseModel


class File(BaseModel):
    file = models.FileField(blank=False, null=False)

    class Meta:
        db_table = 'tb_files'
        verbose_name = '文件'
        verbose_name_plural = verbose_name

编写一个serializers.py

代码语言:javascript复制
from rest_framework import serializers
from file.models import File


class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        exclude = ('is_delete',)
        extra_kwargs = {
            'c_time': {
                'read_only': True
            }
        }

编写视图文件views.py

代码语言:javascript复制
from rest_framework.decorators import api_view
from rest_framework.response import Response
from file.serializers import FileSerializer


@api_view(["POST"])
def upload(request):
    """
    上传文件
    :param request:
    :return:
    """
    if request.method == "POST":
        serializer = FileSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(data=serializer.data, status=200)

编写路由文件urls.py

代码语言:javascript复制
from django.urls import path
from file import views

urlpatterns = [
    path("upload/", views.upload)
]

backend/LightSeeking/urls.py补上

代码语言:javascript复制
path('', include('file.urls'))

数据迁移

代码语言:javascript复制
python manage.py makemigrations
python manage.py migrate

迁移后会多一张表:

测试

使用postman发送图片进行测试

调用接口后,图片被存放到了backend/media/20221018144148.png

后面使用的时候将sample_png设置为/media/20221018144148.png

样图展示

对样图部分进行修改

代码语言:javascript复制
<el-table-column label="样图" width="160">
  <template v-slot="scope">
    <el-popover placement="top-start" trigger="hover">
      <template #reference>
        <el-image :src="baseURL scope.row.sample_png.replace(baseURL,'')" alt="无样图"
              class="scopeImg"
              style="width: 70px; height: 70px">
          <template #error>
            <div class="image-slot">
              <i class="el-icon-picture-outline"></i>
            </div>
          </template>
        </el-image>
      </template>
      <el-image :src="baseURL scope.row.sample_png.replace(baseURL,'')" alt="无样图"
            style="width: 300%; height: 300%"></el-image>
    </el-popover>
  </template>
</el-table-column>

其中baseURL为config.API_URL1,

拼接出来的地址为:http://127.0.0.1:8000/media/20221018144148.png

这样后还是无法查看到图片,还需要给urls配置静态文件访问地址

代码语言:javascript复制
from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/', include('users.urls')),
    path('', include('product.urls')),
    path('', include('warehouse.urls')),
    path('', include('file.urls')),
]   static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

最终效果

0 人点赞