学习抖音哲玄《大前端全栈实践》课程之领域模型架构搭建
前言
本文是根据抖音哲玄《大前端全栈实践》课程学习的笔记,我们知道,在大多数后台管理系统中,有很多结构一样,只是数据不一样的布局,如何让这些重复性的工作变得更加轻松,简单,让程序员解放双手,留时间去做不一样的事。这就需要我们去全面思考,小到从项目文件的建立应该怎么样命名,放置,如果我们从一开始就规范自己,也方便后续的迭代。大到怎么构建数据结构,以数据驱动页面,这就需要我们有很强的数据构造和清洗能力,将和业务相关的数据抽取出来。里程碑3中讲解了如何以一份DSL描述文件,去生成不同后台管理系统的重复性页面。
model目录
|-- elpise
|--app
|--model
|--business
|--project
|--jd.js
|--pdd.js
|--taobao.js
|--model.js
|--course
|--project
|--bilibili.js
|--douyin.js
|--model.js
|--index.js
model目录解析
model为模型的意思,我们可以将模型进行分类,将页面结构,功能重复多的系统归为一个大类,如图中的business和course两大类,business和course下面建立project文件夹存放不同系统的DSL描述文件。DSL文件描述结构让如下:
const dashboardModel = {
//模板类型,不同模板类型对应不一样的模板数据结构
mode: "dashboard",
name: "", //名称
desc: "", //描述
icon: "", //icon
homePage: "", //首页(项目配置)
//头部菜单
menu: [
{
key: "", //菜单唯一描述
name: "", //菜单名称
menuType: "", //枚举值:group/module
//当menuType===group时,可填
subMenu: [
{
//可递归
},
],
//当menuType===module时,可填
moduleType: "", //枚举值:sider/iframe/custom/schema
//当moduleType===sider时,可填
siderConfig: {
menu: [
{
//可递归menuItem
},
],
},
//当moduleType===iframe时,可填
iframeConfig: {
path: "", //iframe路径
},
//当moduleType===custom时,可填
customConfig: {
path: "", //自定义路由路径
},
//当moduleType===schema时,可填
schemaConfig: {
api: "", //数据源API(遵循RESTFUL 规范)
schema: {
type: "object",
properties: {
key: {
...schema, //标准schema配置
type: "", //字段类型
label: "", //字段中间名
//字段在table中的相关配置
tableOption: {
...elTableColumnConfig,//标准el-table-column配置
toFixed:0,//保留小数点后几位
visiable: true,//默认为true(false或不配置时,表示不在表单中显示)
},
//字段在search-bar中的相关配置
searchOption: {
...eleComponentConfig,//标准el-component-column配置
comType: '',//配置组件类型input/select/......
default: '',//默认值
//comType === 'select'
enumList: [],//下拉框可选项
//comType === 'dynamicSelect'
api:''
}
},
},
},
//table相关配置
tableConfig: {
headerButtons: [{
label: '',//按钮中文名
eventKey: '',//按钮事件名
eventOption: {},//按钮事件具体配置
...elButtonConfig,//标准el-button配置
}],
rowButtons: [{
label: '', //按钮中文名
eventKey: "",//按钮事件名
eventOption: {
//当eventKey === 'remove'
params: {
//paramKey = 参数的键值
paramKey: rowValueKey
//rowValue = 参数值 (当格式为 schema:tableKey 的时候,到table中找相应的字段)
}
},//按钮事件具体配置
...elButtonConfig,//标准el-button配置
}]
},
//search-bar相关配置
searchConfig: {},
//模块组件
components: {}
},
},
],
};
export default dashboardModel;
根据model文件,最后我们想要生产如下数据结构
解析model配置并返回组织且继承后的数据结构
[ { model:${model} project:{ proj1:${proj1}, proj2:${proj2} } },...]
此项目中
const originalList = [ { model: { key: 'business', model: 'dashboard', name: '电商系统', menu: [ { key: 'product', name: '商品管理', menuType: 'module', moduleType: 'schema', schemaConfig: { api: '/api/proj/product', schema: { type: 'object', properties: { product_id: { type: 'string', label: '商品ID', tableOption: { width: 300, 'show-overflow-tooltip': true } }, product_name: { type: 'string', label: '商品名称', tableOption: { width: 200 }, searchOption: { comType: 'dynamicSelect', api: '/api/proj/product_enum/list' } }, price: { type: 'number', label: '价格', tableOption: { width: 200 }, searchOption: { comType: 'select', enumList: [ { label: '200以下', value: -1 }, { label: '100以下', value: 1 }, { label: '100-200', value: 2 } ]
}
},
inventory: {
type: 'number',
label: '库存',
tableOption: {
width: 200
}
},
create_time: {
type: 'string',
label: '创建时间',
tableOption: {},
searchOption: {
comType: 'dateRange'
}
}
}
},
tableConfig: {
headerButtons: [
{
label: '新增商品',
eventKey: 'showComponent',
type: 'primary',
plain: true
}
],
rowButtons: [
{
label: '修改',
eventKey: 'showComponent',
type: 'warning'
},
{
label: '删除',
eventKey: 'remove',
eventOption: {
params: {
product_id: 'schema::product_id'
}
},
type: 'danger'
}
]
}
}
},
{
key: 'order',
name: '订单管理',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
},
{
key: 'client',
name: '客户管理',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
}
]
},
project: {
jd: {
key: 'jd',
modleKey: 'business',
name: '京东',
desc: '京东电商系统',
homePage: '/schema?proj_key=jd&key=product',
menu: [
{
key: 'shop-setting',
name: '店铺设置',
menuType: 'group',
subMenu: [
{
key: 'info-setting',
name: '店铺信息',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: 'todo'
}
},
{
key: 'quality-setting',
name: '店铺资质',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: {
path: 'http://www.baidu'
}
},
{
key: 'categories',
name: '分类数据',
menuType: 'group',
subMenu: [
{
key: 'category-1',
name: '一级分类',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
},
{
key: 'category-2',
name: '二级分类',
menuType: 'module',
moduleType: 'iframe',
customConfig: {
path: '/http://www.baidu'
}
},
{
key: 'tags',
name: '标签',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
}
]
}
]
}
]
},
pdd: {
key: 'pdd',
modleKey: 'business',
name: '拼多多',
desc: '拼多多电商系统',
homePage: '/schema?proj_key=pdd&key=product',
menu: [
{
key: 'product',
name: '商品管理(拼多多)'
},
{
key: 'client',
name: '客户管理(拼多多)',
moduleType: 'schema',
schemaConfig: {
api: '/api/client',
schema: {}
}
},
{
key: 'data',
name: '数据分析',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'analysis',
name: '电商罗盘',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
},
{
key: 'sider-search',
name: '信息查询',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: {
path: 'http://www.baidu.com'
}
},
{
key: 'categories',
name: '分类数据',
menuType: 'group',
subMenu: [
{
key: 'category-1',
name: '一级分类',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
},
{
key: 'category-2',
name: '二级分类',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: {
path: 'http://www.baidu.com'
}
},
{
key: 'tags',
name: '标签',
menuType: 'module',
moduleType: 'schema',
schemaConfig: {
api: '/api/client',
schema: {}
}
}
]
}
]
}
},
{
key: 'search',
name: '信息查询',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: {
path: 'http://www.baidu.com'
}
}
]
},
taobao: {
key: 'taobao',
modleKey: 'business',
name: '淘宝',
desc: '淘宝电商系统',
homePage: '/schema?proj_key=taobao&key=product',
menu: [
{
key: 'order',
moduleType: 'iframe',
iframeConfig: {
path: 'http://www.baidu.com'
}
},
{
key: 'operation',
name: '运营活动',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'coupon',
name: '优惠券',
moduleType: 'custom',
menuType: 'module',
customcOnfig: {
path: '/todo'
}
},
{
key: 'limited',
name: '限量购',
moduleType: 'custom',
menuType: 'module',
customcOnfig: {
path: '/todo'
}
},
{
key: 'festival',
name: '节日活动',
moduleType: 'custom',
menuType: 'module',
customcOnfig: {
path: '/todo'
}
}
]
}
}
]
}
}
},
{
model: {
key: 'course',
model: 'dashboard',
name: '课程系统',
menu: [
{
key: 'video',
name: '视频管理',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
},
{
key: 'user',
name: '用户管理',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
}
]
},
project: {
bilibili: {
key: 'bilibili',
modleKey: 'course',
name: 'B站课堂',
desc: 'B站课程管理系统',
homePage: '/todo?proj_key=bilibili&key=video',
menu: [
{
key: 'video',
name: '视频管理(B站)'
},
{
key: 'user',
name: '用户管理(B站)'
},
{
key: 'resource',
name: '课程资料',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'pdf',
name: 'PDF',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
},
{
key: 'excel',
name: 'EXCEL',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
},
{
key: 'ppt',
name: 'PPT',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
}
]
}
}
]
},
douyin: {
key: 'douyin',
modleKey: 'course',
name: '抖音课堂',
desc: '抖音课程管理系统',
homePage: '/todo?proj_key=douyin&key=video',
menu: [
{
key: 'traffic',
name: '流量管理',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'user-traffic',
name: '用户流量',
menuType: 'module',
moduleType: 'custom',
customConfig: {
path: '/todo'
}
}
]
}
}
]
}
}
}
]
最后我们需要处理修改,继承(保留),新增的情况, 因为project继承model,所以需要处理修改和新增内容的情况
//project有的键值,model也有=>修改(重载)
//project有的键值,model没有=>新增
//model有的键值,project没有=>保留(继承)
以下是处理以后的数据
const arr = [ { model: { key: 'business', model: 'dashboard', name: '电商系统', menu: [ { key: 'product', name: '商品管理', menuType: 'module', moduleType: 'schema', schemaConfig: { api: '/api/proj/product', schema: { type: 'object', properties: { product_id: { type: 'string', label: '商品ID', tableOption: { width: 300, 'show-overflow-tooltip': true } }, product_name: { type: 'string', label: '商品名称', tableOption: { width: 200 }, searchOption: { comType: 'dynamicSelect', api: '/api/proj/product_enum/list' } }, price: { type: 'number', label: '价格', tableOption: { width: 200 }, searchOption: { comType: 'select', enumList: [ { label: '200以下', value: -1 }, { label: '100以下', value: 1 }, { label: '100-200', value: 2 } ]
}
},
inventory: {
type: 'number',
label: '库存',
tableOption: { width: 200 }
},
create_time: {
type: 'string',
label: '创建时间',
tableOption: {},
searchOption: { comType: 'dateRange' }
}
}
},
tableConfig: {
headerButtons: [
{
label: '新增商品',
eventKey: 'showComponent',
type: 'primary',
plain: true
}
],
rowButtons: [
{ label: '修改', eventKey: 'showComponent', type: 'warning' },
{
label: '删除',
eventKey: 'remove',
eventOption: { params: { product_id: 'schema::product_id' } },
type: 'danger'
}
]
}
}
},
{
key: 'order',
name: '订单管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'client',
name: '客户管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
}
]
},
project: {
jd: {
key: 'jd',
model: 'dashboard',
name: '京东',
menu: [
{
key: 'product',
name: '商品管理',
menuType: 'module',
moduleType: 'schema',
schemaConfig: {
api: '/api/proj/product',
schema: {
type: 'object',
properties: {
product_id: {
type: 'string',
label: '商品ID',
tableOption: { width: 300, 'show-overflow-tooltip': true }
},
product_name: {
type: 'string',
label: '商品名称',
tableOption: { width: 200 },
searchOption: {
comType: 'dynamicSelect',
api: '/api/proj/product_enum/list'
}
},
price: {
type: 'number',
label: '价格',
tableOption: { width: 200 },
searchOption: {
comType: 'select',
enumList: [
{ label: '200以下', value: -1 },
{ label: '100以下', value: 1 },
{ label: '100-200', value: 2 }
]
}
},
inventory: {
type: 'number',
label: '库存',
tableOption: { width: 200 }
},
create_time: {
type: 'string',
label: '创建时间',
tableOption: {},
searchOption: { comType: 'dateRange' }
}
}
},
tableConfig: {
headerButtons: [
{
label: '新增商品',
eventKey: 'showComponent',
type: 'primary',
plain: true
}
],
rowButtons: [
{ label: '修改', eventKey: 'showComponent', type: 'warning' },
{
label: '删除',
eventKey: 'remove',
eventOption: {
params: { product_id: 'schema::product_id' }
},
type: 'danger'
}
]
}
}
},
{
key: 'order',
name: '订单管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'client',
name: '客户管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'shop-setting',
name: '店铺设置',
menuType: 'group',
subMenu: [
{
key: 'info-setting',
name: '店铺信息',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: 'todo' }
},
{
key: 'quality-setting',
name: '店铺资质',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: { path: 'http://www.baidu' }
},
{
key: 'categories',
name: '分类数据',
menuType: 'group',
subMenu: [
{
key: 'category-1',
name: '一级分类',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'category-2',
name: '二级分类',
menuType: 'module',
moduleType: 'iframe',
customConfig: { path: '/http://www.baidu' }
},
{
key: 'tags',
name: '标签',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
}
]
}
]
}
],
modleKey: 'business',
desc: '京东电商系统',
homePage: '/schema?proj_key=jd&key=product'
},
pdd: {
key: 'pdd',
model: 'dashboard',
name: '拼多多',
menu: [
{
key: 'product',
name: '商品管理(拼多多)',
menuType: 'module',
moduleType: 'schema',
schemaConfig: {
api: '/api/proj/product',
schema: {
type: 'object',
properties: {
product_id: {
type: 'string',
label: '商品ID',
tableOption: { width: 300, 'show-overflow-tooltip': true }
},
product_name: {
type: 'string',
label: '商品名称',
tableOption: { width: 200 },
searchOption: {
comType: 'dynamicSelect',
api: '/api/proj/product_enum/list'
}
},
price: {
type: 'number',
label: '价格',
tableOption: { width: 200 },
searchOption: {
comType: 'select',
enumList: [
{ label: '200以下', value: -1 },
{ label: '100以下', value: 1 },
{ label: '100-200', value: 2 }
]
}
},
inventory: {
type: 'number',
label: '库存',
tableOption: { width: 200 }
},
create_time: {
type: 'string',
label: '创建时间',
tableOption: {},
searchOption: { comType: 'dateRange' }
}
}
},
tableConfig: {
headerButtons: [
{
label: '新增商品',
eventKey: 'showComponent',
type: 'primary',
plain: true
}
],
rowButtons: [
{ label: '修改', eventKey: 'showComponent', type: 'warning' },
{
label: '删除',
eventKey: 'remove',
eventOption: {
params: { product_id: 'schema::product_id' }
},
type: 'danger'
}
]
}
}
},
{
key: 'order',
name: '订单管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'client',
name: '客户管理(拼多多)',
menuType: 'module',
moduleType: 'schema',
customConfig: { path: '/todo' },
schemaConfig: { api: '/api/client', schema: {} }
},
{
key: 'data',
name: '数据分析',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'analysis',
name: '电商罗盘',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'sider-search',
name: '信息查询',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: { path: 'http://www.baidu.com' }
},
{
key: 'categories',
name: '分类数据',
menuType: 'group',
subMenu: [
{
key: 'category-1',
name: '一级分类',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'category-2',
name: '二级分类',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: { path: 'http://www.baidu.com' }
},
{
key: 'tags',
name: '标签',
menuType: 'module',
moduleType: 'schema',
schemaConfig: { api: '/api/client', schema: {} }
}
]
}
]
}
},
{
key: 'search',
name: '信息查询',
menuType: 'module',
moduleType: 'iframe',
iframeConfig: { path: 'http://www.baidu.com' }
}
],
modleKey: 'business',
desc: '拼多多电商系统',
homePage: '/schema?proj_key=pdd&key=product'
},
taobao: {
key: 'taobao',
model: 'dashboard',
name: '淘宝',
menu: [
{
key: 'product',
name: '商品管理',
menuType: 'module',
moduleType: 'schema',
schemaConfig: {
api: '/api/proj/product',
schema: {
type: 'object',
properties: {
product_id: {
type: 'string',
label: '商品ID',
tableOption: { width: 300, 'show-overflow-tooltip': true }
},
product_name: {
type: 'string',
label: '商品名称',
tableOption: { width: 200 },
searchOption: {
comType: 'dynamicSelect',
api: '/api/proj/product_enum/list'
}
},
price: {
type: 'number',
label: '价格',
tableOption: { width: 200 },
searchOption: {
comType: 'select',
enumList: [
{ label: '200以下', value: -1 },
{ label: '100以下', value: 1 },
{ label: '100-200', value: 2 }
]
}
},
inventory: {
type: 'number',
label: '库存',
tableOption: { width: 200 }
},
create_time: {
type: 'string',
label: '创建时间',
tableOption: {},
searchOption: { comType: 'dateRange' }
}
}
},
tableConfig: {
headerButtons: [
{
label: '新增商品',
eventKey: 'showComponent',
type: 'primary',
plain: true
}
],
rowButtons: [
{ label: '修改', eventKey: 'showComponent', type: 'warning' },
{
label: '删除',
eventKey: 'remove',
eventOption: {
params: { product_id: 'schema::product_id' }
},
type: 'danger'
}
]
}
}
},
{
key: 'order',
name: '订单管理',
menuType: 'module',
moduleType: 'iframe',
customConfig: { path: '/todo' },
iframeConfig: { path: 'http://www.baidu.com' }
},
{
key: 'client',
name: '客户管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'operation',
name: '运营活动',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'coupon',
name: '优惠券',
moduleType: 'custom',
menuType: 'module',
customcOnfig: { path: '/todo' }
},
{
key: 'limited',
name: '限量购',
moduleType: 'custom',
menuType: 'module',
customcOnfig: { path: '/todo' }
},
{
key: 'festival',
name: '节日活动',
moduleType: 'custom',
menuType: 'module',
customcOnfig: { path: '/todo' }
}
]
}
}
],
modleKey: 'business',
desc: '淘宝电商系统',
homePage: '/schema?proj_key=taobao&key=product'
}
}
},
{
model: {
key: 'course',
model: 'dashboard',
name: '课程系统',
menu: [
{
key: 'video',
name: '视频管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'user',
name: '用户管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
}
]
},
project: {
bilibili: {
key: 'bilibili',
model: 'dashboard',
name: 'B站课堂',
menu: [
{
key: 'video',
name: '视频管理(B站)',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'user',
name: '用户管理(B站)',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'resource',
name: '课程资料',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'pdf',
name: 'PDF',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'excel',
name: 'EXCEL',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'ppt',
name: 'PPT',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
}
]
}
}
],
modleKey: 'course',
desc: 'B站课程管理系统',
homePage: '/todo?proj_key=bilibili&key=video'
},
douyin: {
key: 'douyin',
model: 'dashboard',
name: '抖音课堂',
menu: [
{
key: 'video',
name: '视频管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'user',
name: '用户管理',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
},
{
key: 'traffic',
name: '流量管理',
menuType: 'module',
moduleType: 'sider',
siderConfig: {
menu: [
{
key: 'user-traffic',
name: '用户流量',
menuType: 'module',
moduleType: 'custom',
customConfig: { path: '/todo' }
}
]
}
}
],
modleKey: 'course',
desc: '抖音课程管理系统',
homePage: '/todo?proj_key=douyin&key=video'
}
}
}
]
以下是通过DSL生成的页面,分别是schemaView,siderView,iframeView