Merge branch 'bjxz-dev' of http://139.9.66.234:18023/kun/mobile-workflow into bjxz-dev
This commit is contained in:
commit
83f717ec05
@ -21,7 +21,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { showItem } from '@/utils/tool.js'
|
import { showItem } from '@/utils/tool.js'
|
||||||
import WFormItem from './WFormItem.vue'
|
import WFormItem from './WFormItem.vue'
|
||||||
|
import { CompareFuncs } from "./form/compare/CompareOptions.js";
|
||||||
//import FormComponents from '@/components/form/ComponentsExport.js'
|
//import FormComponents from '@/components/form/ComponentsExport.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -38,7 +38,10 @@
|
|||||||
config: { //表单联动相关配置
|
config: { //表单联动相关配置
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {}
|
return {
|
||||||
|
ruleType: "SIMPLE",
|
||||||
|
rules: [],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
jsonConf: { //表单json配置,用来渲染表单
|
jsonConf: { //表单json配置,用来渲染表单
|
||||||
@ -60,7 +63,7 @@
|
|||||||
rules() {
|
rules() {
|
||||||
const formRule = {}
|
const formRule = {}
|
||||||
this.formFields.forEach(v => {
|
this.formFields.forEach(v => {
|
||||||
if (v.props.required) {
|
if (v.props.required && v.perm !== 'H') {
|
||||||
formRule[v.id] = {
|
formRule[v.id] = {
|
||||||
rules: [{
|
rules: [{
|
||||||
required: true,
|
required: true,
|
||||||
@ -76,11 +79,23 @@
|
|||||||
this.jsonConf.forEach(field => this.loadInnerField(field, fields))
|
this.jsonConf.forEach(field => this.loadInnerField(field, fields))
|
||||||
console.log(JSON.stringify(fields),666)
|
console.log(JSON.stringify(fields),666)
|
||||||
return fields
|
return fields
|
||||||
|
},
|
||||||
|
formItemMap() {
|
||||||
|
const map = new Map()
|
||||||
|
this.loadFormItemMap(this.jsonConf, map)
|
||||||
|
return map
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
//缓存下原始权限设置
|
||||||
|
formPermHis: {},
|
||||||
|
compareFunc: {},
|
||||||
|
//缓存旧值
|
||||||
|
oldFormData: {},
|
||||||
|
//缓存所有用到的条件字段
|
||||||
|
conditionFields: new Set(),
|
||||||
|
execute: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onReady() {
|
onReady() {
|
||||||
@ -103,6 +118,179 @@
|
|||||||
// call(false)
|
// call(false)
|
||||||
console.log('表单错误信息:', err);
|
console.log('表单错误信息:', err);
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
loadFormItemMap(forms, map) {
|
||||||
|
forms.forEach(item => {
|
||||||
|
if (item.name === 'TableList') {
|
||||||
|
map.set(item.id, item)
|
||||||
|
this.loadFormItemMap(item.props.columns, map)
|
||||||
|
} else if (item.name === 'SpanLayout') {
|
||||||
|
this.loadFormItemMap(item.props.items, map)
|
||||||
|
} else {
|
||||||
|
map.set(item.id, item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//解析表单联动规则
|
||||||
|
parserRule(cdRule) {
|
||||||
|
const condition = cdRule.condition
|
||||||
|
//在这里可以实现一个算法,按条件层级去解析,不需要解析所有条件,先不实现
|
||||||
|
if (cdRule.children.length > 0) {
|
||||||
|
for (let i = 0; i < cdRule.children.length; i++) {
|
||||||
|
const result = this.parserRule(cdRule.children[i])
|
||||||
|
if (cdRule.logic) {
|
||||||
|
//如果是且关系,有一个为假就是假
|
||||||
|
if (!result) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//如果是或关系,有一个为真就是真
|
||||||
|
if (result) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//遍历完了返回最终结果
|
||||||
|
return cdRule.logic
|
||||||
|
} else {
|
||||||
|
//解析条件
|
||||||
|
try {
|
||||||
|
return this.compare(condition)
|
||||||
|
} catch (e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async doActions(actions) {
|
||||||
|
(actions || []).forEach(action => {
|
||||||
|
//执行预设的动作
|
||||||
|
switch (action.type) {
|
||||||
|
case 'SHOW':
|
||||||
|
action.targets.forEach(tg => this.showField(tg));
|
||||||
|
break;
|
||||||
|
case 'HIDE':
|
||||||
|
action.targets.forEach(tg => this.hideField(tg));
|
||||||
|
break;
|
||||||
|
case 'DISABLE':
|
||||||
|
action.targets.forEach(tg => this.disableField(tg));
|
||||||
|
break;
|
||||||
|
case 'UPDATE':
|
||||||
|
action.targets.forEach(tg => this.updateField(tg, action.value));
|
||||||
|
break;
|
||||||
|
case 'ENABLE':
|
||||||
|
action.targets.forEach(tg => this.enableField(tg, action.value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
analyseFormRule() {
|
||||||
|
if (this.config.ruleType === 'SIMPLE') {
|
||||||
|
this.analyseRules()
|
||||||
|
} else {
|
||||||
|
this.analyseJsRules()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async analyseJsRules() {
|
||||||
|
if (!(this.execute instanceof Function)) {
|
||||||
|
this.execute = new Function(`${this.config.ruleJs || 'function doChange(){}'}\r\n return doChange`)
|
||||||
|
this.execute = this.execute()
|
||||||
|
}
|
||||||
|
this.execute(this._value, this.formItemMap)
|
||||||
|
},
|
||||||
|
async analyseRules() {
|
||||||
|
(this.config.rules || []).forEach((rule, i) => {
|
||||||
|
//解析表单联动条件
|
||||||
|
const result = this.parserRule(rule.condition)
|
||||||
|
console.log(`解析规则 ${(i + 1)}: ${result}`)
|
||||||
|
this.doActions(result ? rule.action.with : rule.action.other)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
compare(condition) {
|
||||||
|
//要判断组件类型,再取其值
|
||||||
|
const source = this._value[condition.field]
|
||||||
|
//动态调用函数
|
||||||
|
let compareType = null
|
||||||
|
switch (condition.fieldType) {
|
||||||
|
case 'AmountInput':
|
||||||
|
case 'NumberInput':
|
||||||
|
case 'Score':
|
||||||
|
case 'CalcFormula':
|
||||||
|
compareType = 'numCompare';
|
||||||
|
break;
|
||||||
|
case 'TextInput':
|
||||||
|
case 'TextareaInput':
|
||||||
|
case 'SelectInput':
|
||||||
|
case 'Location':
|
||||||
|
case 'Provinces':
|
||||||
|
compareType = 'strCompare'
|
||||||
|
break;
|
||||||
|
case 'MultipleSelect':
|
||||||
|
compareType = 'strArrCompare';
|
||||||
|
break;
|
||||||
|
case 'DateTime':
|
||||||
|
compareType = 'timeCompare';
|
||||||
|
break;
|
||||||
|
case 'DateTimeRange':
|
||||||
|
compareType = 'timeArrCompare';
|
||||||
|
break;
|
||||||
|
case 'DeptPicker':
|
||||||
|
case 'UserPicker':
|
||||||
|
compareType = 'orgCompare';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CompareFuncs[compareType][condition.compare](source,
|
||||||
|
condition.fixed ? condition.compareVal :
|
||||||
|
this._value[condition.compareVal[0]])
|
||||||
|
},
|
||||||
|
isRequired(item) {
|
||||||
|
return this.rules[item.id] !== undefined
|
||||||
|
},
|
||||||
|
hideField(id) {
|
||||||
|
const field = this.formItemMap.get(id)
|
||||||
|
if (field) {
|
||||||
|
field.perm = 'H'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showField(id) {
|
||||||
|
const field = this.formItemMap.get(id)
|
||||||
|
if (field) {
|
||||||
|
field.perm = this.formPermHis[id] || 'E'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disableField(id) {
|
||||||
|
const field = this.formItemMap.get(id)
|
||||||
|
if (field) {
|
||||||
|
field.perm = 'R'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enableField(id) {
|
||||||
|
const field = this.formItemMap.get(id)
|
||||||
|
if (field) {
|
||||||
|
field.perm = 'E'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateField(id, val) {
|
||||||
|
const field = this.formItemMap.get(id)
|
||||||
|
if (field) {
|
||||||
|
this._value[id] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
modelValue: {
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
handler() {
|
||||||
|
console.log(this.modelValue)
|
||||||
|
if (this.config) {
|
||||||
|
if (Object.keys(this.formPermHis).length === 0) {
|
||||||
|
this.formItemMap.forEach(item => {
|
||||||
|
this.formPermHis[item.id] = item.perm
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.analyseFormRule()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue']
|
emits: ['update:modelValue']
|
||||||
|
|||||||
108
components/form/compare/CompareOptions.js
Normal file
108
components/form/compare/CompareOptions.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
//字符串比较选项
|
||||||
|
|
||||||
|
const strCompareOptions = [
|
||||||
|
{name: '等于', symbol: 'EQ', compare: (a, b) => a == b[0]},
|
||||||
|
{name: '不等于', symbol: 'NEQ', compare: (a, b) => a != b[0]},
|
||||||
|
{name: '为其之一', symbol: 'IN', compare: (a, b) => (b || []).includes(a)},
|
||||||
|
{name: '不为其之一', symbol: 'NIN', compare: (a, b) => !(b || []).includes(a)},
|
||||||
|
{name: '含有', symbol: 'LIKE', compare: (a, b) => (b || '').includes(a)},
|
||||||
|
]
|
||||||
|
|
||||||
|
const strArrCompareOptions = [
|
||||||
|
{name: '包含', symbol: 'HS', compare: (a, b) => checkElementsExistInArray(b, a)},
|
||||||
|
{name: '不包含', symbol: 'NHS', compare: (a, b) => !checkElementsExistInArray(b, a)},
|
||||||
|
]
|
||||||
|
|
||||||
|
const numCompareOptions = [
|
||||||
|
{name: '大于', symbol: 'GT', compare: (a, b) => a > b},
|
||||||
|
{name: '小于', symbol: 'LT', compare: (a, b) => a < b},
|
||||||
|
{name: '等于', symbol: 'EQ', compare: (a, b) => a == b},
|
||||||
|
{name: '不等于', symbol: 'NEQ', compare: (a, b) => a != b},
|
||||||
|
{name: '大于等于', symbol: 'GT_EQ', compare: (a, b) => a >= b},
|
||||||
|
{name: '小于等于', symbol: 'LT_EQ', compare: (a, b) => a <= b},
|
||||||
|
{name: '在内或相等', symbol: 'IN_EQ', compare: (a, b) => a >= b[0] && a <= b[1]},
|
||||||
|
{name: '在内或不等', symbol: 'IN_NEQ', compare: (a, b) => a == b},
|
||||||
|
{name: '为其之一', symbol: 'IN', compare: (a, b) => (b || []).includes(a)},
|
||||||
|
{name: '不为其之一', symbol: 'NIN', compare: (a, b) => !(b || []).includes(a)},
|
||||||
|
]
|
||||||
|
|
||||||
|
const orgCompareOptions = [
|
||||||
|
{name: '是', symbol: 'EQ', compare: (a, b) => a[0].id == b[0].id},
|
||||||
|
{name: '不是', symbol: 'NEQ', compare: (a, b) => a[0].id != b[0].id},
|
||||||
|
{name: '为其之一', symbol: 'IN', compare: (a, b) => checkElementsExistInArray(a, b, 'id')},
|
||||||
|
{name: '含有', symbol: 'HS', compare: (a, b) => checkElementsExistInArray(b, a, 'id')},
|
||||||
|
{name: '不含有', symbol: 'NHS', compare: (a, b) => !checkElementsExistInArray(b, a, 'id')},
|
||||||
|
]
|
||||||
|
|
||||||
|
const timeCompareOptions = [
|
||||||
|
{name: '在之前', symbol: 'LT', compare: (a, b) => isBefore(a, b[0])},
|
||||||
|
{name: '在之后', symbol: 'GT', compare: (a, b) => isAfter(a, b[0])},
|
||||||
|
{name: '在其中', symbol: 'IN', compare: (a, b) => isBefore(b[0], a) && isAfter(b[1], a)},
|
||||||
|
]
|
||||||
|
|
||||||
|
const timeArrCompareOptions = [
|
||||||
|
{name: '包含', symbol: 'HS', compare: (a, b) => isBefore(a[0], b[0]) && isAfter(a[1], b[0])},
|
||||||
|
{name: '不包含', symbol: 'NHS', compare: (a, b) => isBefore(a[0], b[0]) || isAfter(b[0], a[1])},
|
||||||
|
]
|
||||||
|
|
||||||
|
function isBefore(a, b){
|
||||||
|
return new Date(a).getTime() >= new Date(a).getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAfter(a, b){
|
||||||
|
return new Date(a).getTime() <= new Date(a).getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
//加载比较函数对象
|
||||||
|
function getCompareFucs(){
|
||||||
|
let cpFuncs = {
|
||||||
|
strCompare:{},
|
||||||
|
strArrCompare:{},
|
||||||
|
numCompare:{},
|
||||||
|
orgCompare:{},
|
||||||
|
timeCompare:{},
|
||||||
|
timeArrCompare:{}
|
||||||
|
}
|
||||||
|
strCompareOptions.forEach(v => cpFuncs.strCompare[v.symbol] = v.compare)
|
||||||
|
strArrCompareOptions.forEach(v => cpFuncs.strArrCompare[v.symbol] = v.compare)
|
||||||
|
numCompareOptions.forEach(v => cpFuncs.numCompare[v.symbol] = v.compare)
|
||||||
|
orgCompareOptions.forEach(v => cpFuncs.orgCompare[v.symbol] = v.compare)
|
||||||
|
timeCompareOptions.forEach(v => cpFuncs.timeCompare[v.symbol] = v.compare)
|
||||||
|
timeArrCompareOptions.forEach(v => cpFuncs.timeArrCompare[v.symbol] = v.compare)
|
||||||
|
return cpFuncs
|
||||||
|
}
|
||||||
|
|
||||||
|
//校验数组A是否包含在B内
|
||||||
|
export function checkElementsExistInArray(A, B, key) {
|
||||||
|
if (A.length === 0 || B.length === 0){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (let i = 0; i < A.length; i++) {
|
||||||
|
let found = false;
|
||||||
|
for (let j = 0; j < B.length; j++) {
|
||||||
|
if (key){
|
||||||
|
if (A[i][key] == B[j][key]) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if (A[i] == B[j]) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CompareFuncs = getCompareFucs()
|
||||||
|
|
||||||
|
export default {
|
||||||
|
strCompareOptions, strArrCompareOptions,
|
||||||
|
numCompareOptions, orgCompareOptions,
|
||||||
|
timeCompareOptions, timeArrCompareOptions
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user