ec50n9
2023/02/12阅读:30主题:嫩青
uni-cloud 实现简易商品后台管理
实现方案
采用uni-cloud技术方案实现一个PC端的基础信息管理后台,包含商品分类、商品和SKU管理。
由于是面向PC端而且使用uni-cloud技术方案的,便采用uni-admin
后台管理模板作为起始模板,使用OpenDB
规范,搭配DB Schema
+schema2code
代码生成系统快速完成管理后台的开发。
实现过程
在OpenDB
的表模板中已经有一套电商系统的表模板了,但是表的部分字段定义的不够完整,还需要自己动手作进一步完善。
初始化表
初始化时所需要的表如下:

选择这几张表,然后点击创建选中的opendb表,然后再HBuilder中进行表的初始化即可,按照步骤初始化之后可以看到如下几张表:

这时候的表功能还是不全的,比如商品分类表的树结构、商品表和商品分类表之间的关联也没有做好,想要使用schema2code
快速生成管理页面的话还需要手动作一些调整。
商品分类
表结构
由于商品分类一般是三级分类,是一个树结构。大概实现过程就是在数据表中加上一个parent_id
字段,用于存储父节点的id
,如果节点是根节点的话,则parent_id
则为空。
修改admin0210/uniCloud/database/opendb-mall-categories.schema.json
,增加以下两个字段:

其中一个是分类的标识(也可以说是id
,相较于默认的_id
更有意义),另一个则是用于存储父id的字段,用于确定该节点的父节点。
这样就可以实现一个简单的树结构了,接下来使用schema2code
工具快速生成对应的页面代码了。
列表页面
默认生成的页面类似于这样:

但是商品分类是一个树结构的,还应该有新建一级分类和分类的新建子分类的功能,所以还需要对编辑页面进一步修改,具体步骤如下:
-
把新增按钮改为新增一级分类按钮,用于创建 parent_id
为空的分类 -
表格的操作列中增加一个新建子分类按钮,用于在该分类下创建子分类 -
如果分类含有子分类,则隐藏该分类的删除按钮 -
如果分类为三级分类,则隐藏该分类的新建子分类按钮
-
-
移除各列的排序功能,默认使用sort字段排序 -
创建 list2tree
函数,用于将列表数据转换为树结构并展示在列表中
以下是需要完成的效果:

以下是具体功能的实现方法:
新建一级分类
首先是把顶部栏右侧原有的新建按钮移除了,然后再在左侧增加一个新建一级分类按钮:

因为这个按钮直接跳转到./add
页面,接下来就只需要在./add
页面中将表单中的parent_id
设置为空,且不允许编辑即可:


新建子分类
每个分类(三级分类除外)下面都可以创建子分类,实现起来也很简单,在列表的每一项后面加一个子分类管理即可,点击新建子分类之后,跳转到./add
页面时带上当前分类的id,然后在./add
页面中获取传过来的parent_id
并手动设置到表单上即可:


列表转换为树结构
这一步比较麻烦,从api中获取到的数据是一个列表结构,但是为了方便编辑的话我们还需要对这个列表进行重新排序,使得它具备以下功能:
-
父子节点能挨在一起,并且同级节点按照 sort
字段从小到大排序 -
判断每个节点是否有子节点,如果有的话则隐藏该节点的删除按钮 -
判断节点的层级,如果节点是三级节点,则不可再创建子节点,即隐藏新建子分类按钮 -
根据节点的层级,在节点名称前面加上一些字符串,方便用户理解节点的层级关系
这些功能都可以通过一个函数来进行转换实现:
// 转换函数
list2treeList(list) {
// 临时记录表,收集具有相同 parent_id 的节点
const record = new Map()
// 遍历列表,将 parent_id 相同的节点放在同一个列表中
list.forEach(item => {
if (!record.get(item.parent_id)) {
record.set(item.parent_id, [])
}
record.get(item.parent_id).push(item)
})
// 转换结果
const treeList = []
// 获取所有根节点并遍历,即 parent_id 为空的节点
record.get('').forEach(i => {
// 根节点可以创建子节点,所以这个属性为 true
i.can_add_child = true
// 添加到转换结果中去
treeList.push(i)
// 获取所有 parent_id 为这个节点的子节点
const children = record.get(i.category_id)
if (children) {
// 有子节点,遍历子节点,这一层遍历的节点为二级节点
children.forEach(j => {
// 二级节点的名字前都加上短的字符串前缀
j.name = '* * | ' + j.name
// 二级节点也可以创建子节点
j.can_add_child = true
// 存到结果列表中去
treeList.push(j)
// 获取该节点下单子节点,即三级节点
const subChildren = record.get(j.category_id)
if (subChildren) {
subChildren.forEach(k => {
// 三级节点有更长的前缀
k.name = '* * * * | ' + k.name
// 三级节点不会有子节点,可以删除
k.can_del = true
treeList.push(k)
})
} else {
// 没有子节点,可以显示删除按钮给用户
j.can_del = true
}
})
} else {
// 没有子节点,可以显示删除按钮给用户
i.can_del = true
}
})
// 返回结果
return treeList
}
在获取到数据之后,调用以上函数转换一下,将转换结果设置到表格中即可:



这样就实现好树列表了。
商品管理
多表关联选择
商品的数据表有几个需要注意的地方,首先是商品需要有一个分类,也就是category_id
字段,该字段和商品分类表进行关联,所以想要实现与商品分类的关联选择的话,需要加上以下配置:

生成效果:

单个或多个图片选择并上传
还有就是商品的缩略图和商品详情页的banner图,因为是图片,需要调用文件选择器来实现文件选择,好在schema2code
提供了快捷简便的生成工具,只需要这样配置:

效果:

上架时间和最后修改时间
在这里其实上架时间和最后修改时间都是自动赋值的,不需要人为干预。在创建商品的时候,移除自动生成的时间编辑:

由于在表配置中设置了这两个字段的默认值:

所以在提交的表单中设置这两个值为null
,接口就会自动设置这两个值为当前服务端的时间戳:

而在编辑页面保存的时候,我们也需要更新last_modify_date
。根据官方文档可知,时间戳可以通过new Date().getTime()
来获取,因此只需要在表单提交之前更改last_modify_date
为当前时间就可以了:

库存管理
关联商品表
因为库存中有一个商品id的字段,用于存储是哪个商品的库存。比较好的做法是可以直接通过选择框进行选择,好在schema2code
也提供了快速生成的功能,只需要以下配置:

实现效果:

上面的做法只能在库存列表中显示商品名字,如果想更进一步的展示商品的图标的话,比如这样:

就需要对查询代码进行一些修改了:


价格精度
为了保证价格的精度,采用了int
类型进行存储,所以存储到数据库的价格应该是以分为单位的:

但是在展示给用户看的时候,用分作为单位则不是很好理解,所以需要转换为以元为单位:


以上。
作者介绍