constant/formList.js
export const operationFormDesc = (_this) => {
return {
rule: {
type: 'cascader',
label: '违规情况',
layout: 12,
required: true,
attrs: {
'collapse-tags': true,
props: {
lazy: true,
// multiple: true,
/** ** 【主要代码】懒加载 ****/
lazyLoad: (node, resolve) => {
/**
* 【懒加载 - 当前应用场景】
* 当前表单项支持新增、修改, "违规情况" 是一个级联选择器
* 级联选择器(懒加载):
* 1. 一级列表(level: 0):规则大类(从字典获取)
* 2. 二级列表(level: 1):规则子类(根据一级列表当前值调用接口获取)
*
* 【新增 - 懒加载】
* 二级列表的数据根据接口获取
*
* 【编辑 - 懒加载 】
* 1. 首先获取详情数据回显:回显数据时,由于懒加载,当前二级列表是没有数据,所以需要根据一级列表当前值调用接口获取二级列表数据(如果一级数据有值,就会自动根据当前一级数据调用接口获取对应的二级数据列表 ----- 【注意】前提是先有的一级数据(初始数据),再有的一级列表,才会自动获取二级数据);
* 2. form 表单详情接口调用完之后,获取到初始数据,然后渲染级联选择器一级数据 → 懒加载自动调用获取二级数据列表接口;
* 3. 但是不知道为啥会调用两次二级数据接口,所以 用 ruleFirstClickList 将已经调用过二级数据列表的一级数据存起来,判断一下,如果当前一级数据已经调用过二级数据列表,resolve 返回空数组。
*
*/
const { level, data } = node
if (level === 0) {
/**
* 获取规则大类(一级列表)
* 取字典数据
*/
const nodes = (_this.$common.getDic('rule_first') || []).map((item) => {
return {
value: item.value,
label: item.label,
leaf: false
}
})
/**
* 【弹框 - 编辑场景】
* - 侦听 isGetDetailEnd 是否结束(即:详情接口是否调用完成 - 获取到初始数据)
* - 结束后再 resolve 返回字典列表数据 nodes
*/
if (_this.dialogType === 'edit') {
const timer = setInterval(() => {
if (_this.isGetDetailEnd) {
// 根据 isGetDetailEnd 判断详情接口是否调用完成
resolve(nodes)
clearInterval(timer)
}
}, 100)
return
}
/**
* 【弹框 - 非编辑场景 - 即新增场景】
* - 直接返回字典列表数据 nodes
*/
resolve(nodes)
} else if (level === 1) {
/**
* 【获取二级列表数据】
* - 调用接口
*/
getRuleSecondList(data.value).then((res) => {
_this.$common.CheckCode(res, null, () => {
const nodes =
res.data?.map((item) => {
return {
value: item.dmbh,
label: item.dmmc,
leaf: true
}
}) || []
_this.ruleSecondOptions && _this.ruleSecondOptions.push(...nodes) // 将二级数据列表推入二级数据列表数组中,便于翻译(当行代码与当前文章无关,可不看)
/**
* 【弹框 - 编辑场景】
* - 已经加载过二级数据的一级数据,resolve 返回空数组
*/
resolve(
_this.dialogType === 'edit' && _this.ruleFirstClickList.includes(data.value)
? []
: nodes // 其他情况 resolve 接口返回数据
)
/**
* 【弹框 - 编辑场景】
* - 将已经加载过二级数据的一级数据 push 到 ruleFirstClickList 数组中
*/
if (_this.dialogType === 'edit') {
_this.ruleFirstClickList.push(data.value)
}
})
})
} else {
resolve([])
}
}
}
}
}
}
}
index.vue
<template>
<el-dialog
:title="title"
:visible.sync="dialogVisible"
width="60%"
top="8vh"
:before-close="handleClose"
:close-on-click-modal="dialogType === 'detail'"
>
<ele-form
ref="submitRef"
inline
form-btn-size="mini"
:disabled="dialogType === 'detail'"
:form-data="formData"
:form-desc="formDesc"
:is-show-back-btn="false"
/>
<span v-if="dialogType !== 'detail'" slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" @click="submitHandler"> 提交 el-button>
<el-button size="mini" @click="handleClose">关闭el-button>
span>
el-dialog>
template>
<script>
import { mapGetters } from 'vuex'
import _ from 'lodash.clonedeep'
import { addScore, editScore, getScore } from '@/api/twelve-points'
import { operationFormDesc } from '../constant/formList'
export default {
name: 'OperationDialog',
components: {},
props: {},
data() {
return {
dialogVisible: false,
dialogType: '',
rowData: {},
formData: {
rule: []
},
detailInfo: {},
ruleSecondOptions: [],
ruleFirstClickList: [],
isGetDetailEnd: false,
editFirst: false,
editRuleFirst: false
}
},
computed: {
...mapGetters(['glbmOptions', 'sysConfigData']),
title() {
const obj = {
add: '新增记分',
edit: '修改记分',
detail: '记分详情'
}
return obj[this.dialogType]
},
formDesc() {
return this.dialogVisible ? operationFormDesc(this) : {}
},
submitAx() {
const obj = {
add: addScore,
edit: editScore
}
return obj[this.dialogType]
}
},
watch: {
dialogVisible() {
this.$refs.submitRef &&
this.$refs.submitRef.$refs.form &&
this.$refs.submitRef.$refs.form.clearValidate()
}
},
created() {},
methods: {
open(type, rowData = {}) {
this.rowData = _(rowData)
this.dialogType = type
if (type !== 'add') {
this.getDetail(rowData.jfbh)
}
this.dialogVisible = true
},
getDetail(jfbh) {
getScore(jfbh)
.then((res) => {
this.$common.CheckCode(res, null, () => {
this.detailInfo = res.data || {}
const { data = {} } = res
this.editFirst = true
for (const key in this.formDesc) {
if (key === 'sjfssjStr') {
this.$set(this.formData, key, data['sjfssj'])
} else if (['rule'].includes(key)) {
const arr = [data.ruleFirst, data.ruleSecond]
this.$set(this.formData, 'rule', arr)
} else {
this.$set(this.formData, key, data[key])
}
}
this.editFirst = false
this.editRuleFirst = true
})
})
.finally(() => {
this.isGetDetailEnd = true
})
},
submitHandler() {
this.$refs.submitRef.validate().then((valid) => {
this.$confirm('确认提交记分?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
const { jfdwView, jfrView, ...params } = this.formData
const { jfbh, jfdw, jfr } = this.detailInfo
if (this.dialogType === 'edit') {
params.jfbh = jfbh
params.jfdw = jfdw
params.jfr = jfr
}
this.submitAx(params).then((res) => {
this.$common.CheckCode(res, '提交成功', () => {
this.$emit('update')
this.handleClose()
})
})
})
.catch(() => {
this.$message('取消提交')
})
})
},
handleClose() {
this.rowData = {}
this.ruleSecondOptions = []
this.ruleFirstClickList = []
this.isGetDetailEnd = false
this.editFirst = false
this.editRuleFirst = false
for (const key in this.formData) {
if (this.formData[key] && this.formData[key].constructor === Array) {
this.formData[key] = []
} else if (this.formData[key] && this.formData[key].constructor === Object) {
this.formData[key] = {}
} else {
this.formData[key] = ''
}
}
this.dialogVisible = false
}
}
}
script>
<style lang='scss' scoped>
@import '@/styles/dialog-scss.scss';
style>