1. 自定义模型
可以快速扩展现有的业务表数据,例如:文章内容字段不满足,可以通过 文章栏目
来绑定模型,还有 会员管理
的 会员扩展信息。
[!tip] 核心设计思想,主从表
一对一
[!tip] 这里选择的是
文章
类型模型,只会在内容管理模块生效
1.1. 其他数据库导入模型
1.1.1. 使用对应数据库的模板
1.1.2. 手动创建
如果是非mysql数据库,但模型中json的sql项为mysql语法(开启数据库忽略大小写)
- 在数据库中手动创建表,表名需要为MDIY_MODEL_ + 代码生成器业务表名,字段和代码生成器中拖拽的保持一致
- 将模型json中的sql项置为空串 "sql": "", 再导入模型即可
[!tip] 不支持不同数据库之间的模型json导入;eg:mysql服务下的自定义模型json,无法导入到其他数据库服务的自定义模型
栏目绑定模型
在栏目下新增文章就会多出一个
文章扩展
的tab选项卡
1.2. JavaScript 工具类
参考 src/main/webapp/static/mdiy/index.js
[!tip] 具体参考
范例
中的描述
2. 范例
2.1. 扩展一张表的信息
先通过 代码生成器
拖拽出需要的表单项,导入 自定义模型
2.1.1. 后台获取自定义模型信息
基于后台UI规范通过 Tabs 标签页 控件实现
下面代码片段来自 会员插件
的 src/main/webapp/WEB-INF/manager/people-user/form.ftl
页面
库
<script src="${base}/static/mdiy/index.js"></script>
HTML片段
...
<el-tabs v-model="activeName">
<el-tab-pane label="基本信息" name="基本信息">
...
</el-tab-pane>
<el-tab-pane label="扩展信息" name="扩展信息">
<!--关键点1-->
<!-- 后台 使用自定义组件渲染模型 -->
<ms-mdiy-form v-if="modelId!=null" ref="modelForm" type="model" :model-id="modelId" :id="form.peopleId+''"></ms-mdiy-form>
</el-tab-pane>
</el-tabs>
...
JavaScript片段
<script>
var form = new Vue({
el: '#form',
data: function() {
// data 代码片段
return {
//关键点2:定义自定义模型变量
modelId:null,
};
},
methods: {
// save 代码片段
save: function() {
// 关键点3、判断自定义模型的表单是否通过校验
var formValid = false;
if(that.$refs.modelForm) {
await that.$refs.modelForm.$refs.form.$refs.form.validate((valid,fields) => {
formValid = valid;
})
if(!formValid) {
that.activeName = '扩展信息';
return;
}
}
//保存用户信息
ms.http.post(url, data).then(function(data) {
if (data.result) {
// 关键点4,自定义模型保存
// 注意:也可参考下方前台保存关键点4的数据一次保存
if(that.$refs.modelForm) {
that.$refs.modelForm.$refs.form.form.linkId = res.data.id;
that.$refs.modelForm.getForm().save(function (resModel) {
if(resModel.result){
//模型保存成功
}else {
//模型保存失败
}
});
}
});
}
},
created: function() {
// created 代码片段
var that = this;
//关键点5,加载自定义模型,modelName:模型名称,linkId:
this.$nextTick(function (){
ms.http.get(ms.manager + "/mdiy/model/get.do", {"modelName":"扩展会员信息"}).then(function (res) {
if (res.result && res.data) {
that.modelId = res.data.id;
}
});
})
}
});
</script>
[!tip] 注意代码片段中提示的
关键点
1到5
2.1.2. 前台获取自定义模型
下面代码片段来自 政务版
的 src\main\webapp\template\1\out\people\content-form.htm
会员投稿页面
<!-- 引入自定义js -->
<script src="${base}/static/mdiy/index.js"></script>
<div id="app" v-cloak >
...
<!-- 关键点1 定义渲染的dom节点 -->
<div v-if="item.title!='文章编辑'" id="peopleContentModel" ref="modelForm">
<!--会自动渲染代码生成器的表单-->
</div>
...
</div>
<script>
// vue实例的名称必须是form
var form = new Vue({
el: '#app',
})
data:{
···
// 关键点2
peopleContentModel:{} // 存储模型对象
···
}
methods:{
···
save:function (){
// 关键点3 自定义模型规则验证
if (that.peopleContentModel && !that.peopleContentModel.validate()) {
this.activeName = 'custom-name';
return;
}
···
let data = JSON.parse(JSON.stringify(that.form));
// 关键点4 组织模型数据传递到后台,一次保存
// 注意 如果需要主数据与模型数据一次保存,确保后端服务主业务保存时,并调用模型保存接口modelDataBiz.saveOrUpdate(linkid);
if (that.peopleContentModel) {
data.modelData= that.peopleContentModel.getFormData()
data.modelData = JSON.stringify(data.modelData);
}
ms.http.post(url, data).then(function (data) {
if (data.result) {
}
})
···
}
changeModel: function (categoryId) {
// 关键点5 渲染模型以及获取模型数据
// 注意 前台出于数据安全考虑未提供通用的模型以及模型数据获取接口,需要开发者自行新增接口,可参考后台模型数据获取接口;必须在前台的action限制模型类型
that.$nextTick(function () {
// 重新设置模型获取数据url
var modelDateUrlGet;
if (that.form.id) {
modelDateUrlGet = {
"url": "/people/cms/content/model/data.do",
"params": {"linkId": that.form.id, "modelId": _category[0].mdiyModelId}
}
}
//ms.mdiy.model.getModelData(domid,模型对象(模型id或模型名称),模型数据请求参数,模型数据获取地址)
// 具体可查看该方法上的参数注释说明
ms.mdiy.model.getModelData('peopleContentModel', { "id": _category[0].mdiyModelId }, modelDateUrlGet, '/people/cms/content/model/get.do').then(function(obj) {
that.peopleContentModel = obj;
});
})
}
}
···
</script>
// 前台自定义模型获取示例
public ResultData get(ModelEntity modelEntity, HttpServletResponse response, HttpServletRequest request) {
···
// 设置当前业务可获取的自定义模型类型
String modelType = DictUtil.getDictValue("自定义模型类型","文章");
if(StringUtils.isBlank(modelType)){
return ResultData.build().error("自定义模型类型名称为文章的字典不存在")
}
modelEntity.setModelType(modelType);
modelEntity.setModelCustomType(ModelCustomTypeEnum.MODEL.getLabel());
ModelEntity model = modelBiz.getOne(new QueryWrapper<>(modelEntity));
···
return ResultData.build().success(model);
}
// 前台自定义模型数据示例
public ResultData data(String modelId,String linkId,HttpServletResponse response,HttpServletRequest request,ModelMap modelMap){
···
// 检查SQL注入
SqlInjectionUtil.filterContent(modelId);
SqlInjectionUtil.filterContent(linkId);
// 设置当前业务可获取的自定义模型类型
ModelEntity model = modelBiz.getOne(new LambdaQueryWrapper<ModelEntity>().eq(ModelEntity::getId, modelId).eq(ModelEntity::getModelCustomType, ModelCustomTypeEnum.MODEL.getLabel())
.eq(ModelEntity::getModelType, DictUtil.getDictValue("自定义模型类型","文章")));
···
return ResultData.build().success(modelDataBiz.getModelDataByLinkId(model,linkId));
}
// 业务主数据与模型数据一次保存,如 在文章保存的biz业务中
@Transactional(rollbackFor = Exception.class)
public boolean saveOrUpdate(ContentEntity content) {
// 保存文章数据
boolean flag = contentDao.insertOrUpdate(content);
// 保存模型数据 在其他业务场景同样只需调用模型保存方法即可,参数为主数据的id
// 注意: 前端模型数据必须要调用 xxx.getFormData()获取,才能使用这个方法
modelDataBiz.saveOrUpdate(content.getId());
return flag;
}
[!tip] 注意代码片段中提示的
关键点
1到5
2.2. 文章内容扩展
文章扩展是另外一种业务场景,是通过 栏目
绑定扩展模型,间接的通过业务代码实现文章内容扩展
具体参考 MCms手册常见问题中标签问题 相关案例