前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >15.寻光集后台管理系统-产品信息-数据部分

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

作者头像
zx钟
发布2022-12-02 16:11:53
3340
发布2022-12-02 16:11:53
举报
文章被收录于专栏:测试游记测试游记测试游记

基本样式

先编写表格的基本样式

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

<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接口调用就可以了,组件内部会去发起数据请求

data() {
    return {
      list: {
        apiObj: this.$API.products.list
      },
    }
  },

效果

组件中调用逻辑

mounted() {
  ...
  //判断是否静态数据
  if(this.apiObj){
    this.getData();
  }else if(this.data){
    this.tableData = this.data;
    this.total = this.tableData.length
  }
},
//获取数据
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. 把请求参数合并成一个新的对象
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请求
try {
  var res = await this.apiObj.get(reqData);
}catch(error){
  this.loading = false;
  this.emptyText = error.statusText;
  return false;
}
  1. 根据配置的规则处理数据
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        //分析状态字段结构
    }
  },
try {
  var response = config.parseData(res);
}catch(error){
  this.loading = false;
  this.emptyText = "数据格式错误";
  return false;
}

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

{
  "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. 根据响应码和数据内容判断是否继续
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. 子组件往父组件把拿到的数据传递出去
this.$refs.scTable.setScrollTop(0)
this.$emit('dataChange', res, this.tableData)

文件操作

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

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

python manage.py startapp file

然后把file移到apps中

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

编写models.py

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

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

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

from django.urls import path
from file import views

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

backend/LightSeeking/urls.py补上

path('', include('file.urls'))

数据迁移

python manage.py makemigrations
python manage.py migrate

迁移后会多一张表:

测试

使用postman发送图片进行测试

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

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

样图展示

对样图部分进行修改

<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配置静态文件访问地址

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)

最终效果

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本样式
  • 效果
  • 组件中调用逻辑
  • 文件操作
    • 数据迁移
      • 测试
      • 样图展示
        • 最终效果
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档