Browse Source

逻辑显示完成70%

old
wangqing 4 years ago
parent
commit
1916f4accb
  1. 40
      src/assets/styles/index.scss
  2. 30
      src/components/parser/Parser.vue
  3. 43
      src/layout/example.vue
  4. 23
      src/utils/convert.js
  5. 50
      src/utils/expression.js
  6. 63
      src/views/form/ProjectForm.vue
  7. 6
      src/views/form/editor.vue
  8. 175
      src/views/form/logic.vue

40
src/assets/styles/index.scss

@ -3,6 +3,7 @@
@import './transition.scss'; @import './transition.scss';
@import './element-ui.scss'; @import './element-ui.scss';
@import './btn.scss'; @import './btn.scss';
body { body {
height: 100%; height: 100%;
margin: 0; margin: 0;
@ -11,33 +12,41 @@ body {
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
} }
label { label {
font-weight: 700; font-weight: 700;
} }
html { html {
height: 100%; height: 100%;
margin: 0; margin: 0;
box-sizing: border-box; box-sizing: border-box;
} }
#app { #app {
margin: 0; margin: 0;
height: 100%; height: 100%;
} }
*, *,
*::before, *::before,
*::after { *::after {
box-sizing: inherit; box-sizing: inherit;
} }
.no-padding { .no-padding {
padding: 0 !important; padding: 0 !important;
} }
.padding-content { .padding-content {
padding: 4px 0; padding: 4px 0;
} }
a:focus, a:focus,
a:active { a:active {
outline: none; outline: none;
} }
a, a,
a:focus, a:focus,
a:hover { a:hover {
@ -45,33 +54,49 @@ a:hover {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
div:focus { div:focus {
outline: none; outline: none;
} }
.fr { .fr {
float: right; float: right;
} }
.fl { .fl {
float: left; float: left;
} }
.pr-5 { .pr-5 {
padding-right: 5px; padding-right: 5px;
} }
.pl-5 { .pl-5 {
padding-left: 5px; padding-left: 5px;
} }
.pl-10 { .pl-10 {
padding-left: 10px; padding-left: 10px;
} }
.mt-5 {
margin-top: 5px;
}
.mr-10 {
margin-right: 10px;
}
.block { .block {
display: block; display: block;
} }
.pointer { .pointer {
cursor: pointer; cursor: pointer;
} }
.inlineBlock { .inlineBlock {
display: block; display: block;
} }
.clearfix { .clearfix {
&::after { &::after {
visibility: hidden; visibility: hidden;
@ -82,6 +107,7 @@ div:focus {
height: 0; height: 0;
} }
} }
aside { aside {
background: #eef1f6; background: #eef1f6;
padding: 8px 24px; padding: 8px 24px;
@ -94,9 +120,11 @@ aside {
color: #2c3e50; color: #2c3e50;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
a { a {
color: #337ab7; color: #337ab7;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
color: rgb(32, 160, 255); color: rgb(32, 160, 255);
} }
@ -107,16 +135,20 @@ aside {
.app-container { .app-container {
padding: 20px; padding: 20px;
} }
.components-container { .components-container {
margin: 30px 50px; margin: 30px 50px;
position: relative; position: relative;
} }
.pagination-container { .pagination-container {
margin-top: 30px; margin-top: 30px;
} }
.text-center { .text-center {
text-align: center; text-align: center;
} }
.sub-navbar { .sub-navbar {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
@ -126,27 +158,34 @@ aside {
padding-right: 20px; padding-right: 20px;
transition: 600ms ease position; transition: 600ms ease position;
background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
.subtitle { .subtitle {
font-size: 20px; font-size: 20px;
color: #fff; color: #fff;
} }
&.draft { &.draft {
background: #d0d0d0; background: #d0d0d0;
} }
&.deleted { &.deleted {
background: #d0d0d0; background: #d0d0d0;
} }
} }
.link-type, .link-type,
.link-type:focus { .link-type:focus {
color: #337ab7; color: #337ab7;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
color: rgb(32, 160, 255); color: rgb(32, 160, 255);
} }
} }
.filter-container { .filter-container {
padding-bottom: 10px; padding-bottom: 10px;
.filter-item { .filter-item {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
@ -158,6 +197,7 @@ aside {
.multiselect { .multiselect {
line-height: 16px; line-height: 16px;
} }
.multiselect--active { .multiselect--active {
z-index: 1000 !important; z-index: 1000 !important;
} }

30
src/components/parser/Parser.vue

@ -1,5 +1,6 @@
<script> <script>
import {deepClone, jsonClone} from '@/utils/index' import {deepClone, jsonClone} from '@/utils/index'
import {evalExpression} from '@/utils/expression'
import render from '@/components/render/render.js' import render from '@/components/render/render.js'
import _ from 'lodash' import _ from 'lodash'
@ -33,8 +34,11 @@ const layouts = {
if (formConfCopy.showNumber) { if (formConfCopy.showNumber) {
label = scheme.serialNumber + ': ' + label label = scheme.serialNumber + ': ' + label
} }
this.$set(this[this.formConf.formModel], scheme.__vModel__, [])
let colStyle = scheme.logicShow ? '' : 'display:none'
return ( return (
<el-col span={config.span}> <el-col span={config.span} style={colStyle}>
<el-form-item label-width={labelWidth} prop={scheme.__vModel__} <el-form-item label-width={labelWidth} prop={scheme.__vModel__}
label={config.showLabel ? label : ''}> label={config.showLabel ? label : ''}>
<render conf={scheme} {...{on: listeners}} /> <render conf={scheme} {...{on: listeners}} />
@ -155,9 +159,15 @@ function deleteUpload(config, scheme, file, fileList) {
} }
function setValue(event, config, scheme) { function setValue(event, config, scheme) {
console.log(event)
console.log(config)
console.log(scheme)
console.log(this[this.formConf.formModel])
this.$set(config, 'defaultValue', event) this.$set(config, 'defaultValue', event)
this.$set(this[this.formConf.formModel], scheme.__vModel__, event) this.$set(this[this.formConf.formModel], scheme.__vModel__, event)
setValueLabel.call(this, event, config, scheme) setValueLabel.call(this, event, config, scheme)
const {formConfCopy} = this
} }
/** /**
@ -184,7 +194,7 @@ function setValueLabel(event, config, scheme) {
// //
if (item === 0) { if (item === 0) {
labelArr.push(this[this.formConf.labelFormModel][`${scheme.__vModel__}other`]) labelArr.push(this[this.formConf.labelFormModel][`${scheme.__vModel__}other`])
}else if(item){ } else if (item) {
let {label} = getObject(_.get(scheme, tagOptionKey), 'value', item) let {label} = getObject(_.get(scheme, tagOptionKey), 'value', item)
labelArr.push(label) labelArr.push(label)
} }
@ -280,7 +290,7 @@ export default {
if (tagOptionKey && defaultValue) { if (tagOptionKey && defaultValue) {
if (defaultValue instanceof Array) { if (defaultValue instanceof Array) {
defaultValue.forEach(item => { defaultValue.forEach(item => {
if(item){ if (item) {
let {label} = getObject(_.get(cur, tagOptionKey), 'value', item) let {label} = getObject(_.get(cur, tagOptionKey), 'value', item)
labelStr += label + ',' labelStr += label + ','
} }
@ -340,16 +350,16 @@ export default {
}, },
submitForm() { submitForm() {
this.$refs[this.formConf.formRef].validate(valid => { this.$refs[this.formConf.formRef].validate(valid => {
if (!valid){ if (!valid) {
// //
if(document.getElementsByClassName('el-form-item__error').length>0){ if (document.getElementsByClassName('el-form-item__error').length > 0) {
} }
setTimeout(()=>{ setTimeout(() => {
let isError= document.getElementsByClassName("is-error"); let isError = document.getElementsByClassName('is-error')
isError[0].querySelector('input').focus(); isError[0].querySelector('input').focus()
},100); }, 100)
return false; return false
} }
// sumit // sumit
this.$emit('submit', { this.$emit('submit', {

43
src/layout/example.vue

@ -1,43 +0,0 @@
<template>
<div>
<div id="nav">
<RouterLink to="/example/sprite">sprite精灵图</RouterLink>
<RouterLink to="/example/svgicon">svg icon</RouterLink>
<RouterLink to="/example/globalComponent">全局组件</RouterLink>
<RouterLink to="/example/axios">axios</RouterLink>
<RouterLink to="/example/cookie">cookie</RouterLink>
<RouterLink to="/example/meta">meta</RouterLink>
<RouterLink to="/example/vuex">vuex</RouterLink>
<RouterLink to="/example/component">组件</RouterLink>
<RouterLink :to="{name:'exampleParams',params:{test:'123'}}">路由params</RouterLink>
<RouterLink :to="{path:'/example/query',query:{test:'123'}}">路由query</RouterLink>
<RouterLink to="/example/reload">刷新当前页面</RouterLink>
<RouterLink to="/example/permission/router">router鉴权</RouterLink>
<RouterLink to="/example/permission/js">js鉴权</RouterLink>
</div>
<RouterView />
</div>
</template>
<style lang="scss" scoped>
#nav {
margin-bottom: 10px;
a {
text-decoration: none;
font-size: 14px;
&::after {
content: '|';
margin: 0 10px;
font-weight: normal;
font-size: 14px;
}
&:last-child::after {
content: none;
}
&.router-link-active {
font-weight: bold;
font-size: 18px;
}
}
}
</style>

23
src/utils/convert.js

@ -1,6 +1,9 @@
/**
* 处理项目数据
*
*/
import _ from 'lodash' import _ from 'lodash'
import {imageComponents, inputComponents, selectComponents} from '@/components/generator/config' import {imageComponents, inputComponents, selectComponents} from '@/components/generator/config'
import {jsonClone} from '@/utils/index'
/** /**
* 表单json转换为后台需要的对象 * 表单json转换为后台需要的对象
@ -39,13 +42,13 @@ let typeMap = new Map()
* @param data * @param data
*/ */
export function dbDataConvertForItemJson(data) { export function dbDataConvertForItemJson(data) {
let {required,placeholder}=data let {required, placeholder} = data
if (required&&!placeholder) {//必填项目验证未填默认提示语 if (required && !placeholder) {//必填项目验证未填默认提示语
data.placeholder="此题为必填项目" data.placeholder = '此题为必填项目'
} }
if (!typeMap.size > 0) { if (!typeMap.size > 0) {
//根据类型获取默认数据 //根据类型获取默认数据
_.concat(inputComponents, selectComponents,imageComponents).forEach(item => { _.concat(inputComponents, selectComponents, imageComponents).forEach(item => {
typeMap.set(item.typeId, item) typeMap.set(item.typeId, item)
}) })
} }
@ -58,9 +61,10 @@ export function dbDataConvertForItemJson(data) {
_.set(jsonItem, param[key], value) _.set(jsonItem, param[key], value)
}) })
} }
jsonItem.dId = data.id
jsonItem.sort = data.sort jsonItem.sort = data.sort
jsonItem.typeId = data.type jsonItem.typeId = data.type
jsonItem.__config__.span = data.span jsonItem.__config__.span = data.span
jsonItem.__config__.formId = data.formItemId jsonItem.__config__.formId = data.formItemId
jsonItem.__config__.label = data.label jsonItem.__config__.label = data.label
jsonItem.__config__.required = data.required jsonItem.__config__.required = data.required
@ -79,16 +83,17 @@ export function dbDataConvertForItemJson(data) {
} }
jsonItem.regList = data.regList jsonItem.regList = data.regList
jsonItem.placeholder = data.placeholder jsonItem.placeholder = data.placeholder
jsonItem.formItemId = data.formItemId
jsonItem.__vModel__ = 'field' + data.formItemId jsonItem.__vModel__ = 'field' + data.formItemId
return jsonItem return jsonItem
} }
/** /**
* 不同属性的存在json的位置不用 使用变量记录key 通过lodash表达式获取 1 2 3 4 为typeId *
* @type {{'1': {maxlength: string, prepend: string, append: string}}} * @type {{'1': {maxlength: string, prepend: string, append: string}}}
*
*/ */
const dataParams = {
let dataParams = {
//单行文本 //单行文本
'INPUT': { 'INPUT': {
'prepend': '__slot__.prepend', 'prepend': '__slot__.prepend',

50
src/utils/expression.js

@ -0,0 +1,50 @@
import _ from 'lodash'
/**
* 自定义表达式
*/
const expressionOperator = {
'eq': function(v1, v2) {
return _.isEqual(v1, v2)
},
'ne': function(v1, v2) {
return !_.isEqual(v1, v2)
}
}
/**
* 逻辑连接符
* @type {{'1': string, '2': string}}
*/
const LogicConnector = {
1: '||',
2: '&&'
}
/**
* 获取表达式
* @conditionList 条件列表
* @connector 连接符 ||或者 &&
*/
export function getExpression(conditionList, connector) {
let exList = conditionList.map(item => {
return `#id${item.formItemId} ${item.expression} ${item.optionValue}`
})
return _.join(exList, LogicConnector[connector])
}
/**
* 执行表达式是否成立
*/
export function evalExpression(context, expression) {
let exArray = expression.split(/[|][&]/)
exArray.forEach(item => {
let itemExpArr = item.split(' ')
let varName = itemExpArr[0].replace('#id')
let sp = itemExpArr[1]
let value = itemExpArr[2]
let flag = expressionOperator[sp](context[varName], value)
})
return flag
}

63
src/views/form/ProjectForm.vue

@ -29,6 +29,7 @@
<script> <script>
import Parser from '@/components/parser/Parser' import Parser from '@/components/parser/Parser'
import {dbDataConvertForItemJson} from '@/utils/convert' import {dbDataConvertForItemJson} from '@/utils/convert'
import {getExpression} from '@/utils/expression'
window.onload = function() { window.onload = function() {
document.addEventListener('touchstart', function(event) { document.addEventListener('touchstart', function(event) {
@ -54,6 +55,7 @@ export default {
}, },
data() { data() {
return { return {
logicShowTriggerRule: {},
startParser: false, startParser: false,
projectTheme: { projectTheme: {
headImgUrl: '', headImgUrl: '',
@ -63,6 +65,7 @@ export default {
}, },
formConf: { formConf: {
fields: [], fields: [],
logicShowRule: {},
projectKey: '', projectKey: '',
projectKind: 1, projectKind: 1,
__methods__: {}, __methods__: {},
@ -106,17 +109,29 @@ export default {
} }
this.formConf.size = window.innerWidth < 480 ? 'medium' : 'small' this.formConf.size = window.innerWidth < 480 ? 'medium' : 'small'
}, },
mounted() { async mounted() {
let url = `/user/project/details/${this.formConf.projectKey}` let url = `/user/project/details/${this.formConf.projectKey}`
if (this.formConf.projectKind == 2) { if (this.formConf.projectKind == 2) {
url = `/project/template/details/${this.formConf.projectKey}` url = `/project/template/details/${this.formConf.projectKey}`
} }
let logicItemList = []
//
if (this.formConf.projectKind == 1) {
let res = await this.queryLogicItemList()
logicItemList = res.data
}
let logicItemMap = new Map()
logicItemList.forEach(item => {
logicItemMap.set(item.formItemId, item)
this.logicShowTriggerHandle(item)
})
this.$api.get(url).then(res => { this.$api.get(url).then(res => {
if (res.data) { if (res.data) {
let serialNumber = 1 let serialNumber = 1
let fields = res.data.projectItems.map(item => { let fields = res.data.projectItems.map(item => {
let projectItem = dbDataConvertForItemJson(item) let projectItem = dbDataConvertForItemJson(item)
projectItem.serialNumber = serialNumber projectItem.serialNumber = serialNumber
projectItem.logicShow = logicItemMap.get(projectItem.formItemId) ? false : true
serialNumber++ serialNumber++
return projectItem return projectItem
}) })
@ -125,18 +140,14 @@ export default {
this.formConf.title = res.data.project.name this.formConf.title = res.data.project.name
this.formConf.description = res.data.project.describe this.formConf.description = res.data.project.describe
} }
this.formConf.logicShowRule = this.logicShowTriggerRule
//
if (res.data.userProjectTheme) { if (res.data.userProjectTheme) {
this.projectTheme = res.data.userProjectTheme this.projectTheme = res.data.userProjectTheme
let {submitBtnText, showNumber, btnsColor} = res.data.userProjectTheme let {submitBtnText, showNumber, btnsColor} = res.data.userProjectTheme
if (submitBtnText) { if (submitBtnText) this.formConf.submitBtnText = submitBtnText
this.formConf.submitBtnText = submitBtnText if (showNumber) this.formConf.showNumber = showNumber
} if (btnsColor) this.formConf.submitBtnColor = btnsColor
if (showNumber) {
this.formConf.showNumber = showNumber
}
if (btnsColor) {
this.formConf.submitBtnColor = btnsColor
}
} }
this.startParser = true this.startParser = true
@ -144,6 +155,38 @@ export default {
}) })
}, },
methods: { methods: {
/**
* 处理逻辑显示数据
*/
logicShowTriggerHandle(logicItem) {
if (!logicItem) {
return
}
//
logicItem.conditionList.forEach(item => {
let rules = this.logicShowTriggerRule[item.formItemId]
if (!rules) {
rules = new Set()
}
rules.add({
//
triggerFormItemId: logicItem.formItemId,
logicExpression: getExpression(logicItem.conditionList, logicItem.expression)
})
this.logicShowTriggerRule[item.formItemId] = rules
})
},
// axios
queryLogicItemList() {
return new Promise((resolve, reject) => {
this.$api.get('/user/project/logic/list', {params: {projectKey: this.formConf.projectKey}})
.then((res) => {
resolve(res)
}).catch((err) => {
reject(err)
})
})
},
submitForm(data) { submitForm(data) {
this.$emit('submit', data) this.$emit('submit', data)
} }

6
src/views/form/editor.vue

@ -15,14 +15,12 @@
:clone="cloneComponent" :clone="cloneComponent"
draggable=".components-item" draggable=".components-item"
:sort="false" :sort="false"
@end="onEnd" @end="onEnd">
>
<div <div
v-for="(element, index) in item.list" v-for="(element, index) in item.list"
:key="index" :key="index"
class="components-item" class="components-item"
@click="addComponent(element)" @click="addComponent(element)">
>
<div class="components-body"> <div class="components-body">
<svg-icon :name="element.__config__.tagIcon"/> <svg-icon :name="element.__config__.tagIcon"/>
{{ element.__config__.label }} {{ element.__config__.label }}

175
src/views/form/logic.vue

@ -1,7 +1,7 @@
<template> <template>
<div class="project-logic-container"> <div class="project-logic-container">
<el-scrollbar style="height: 90vh;"> <el-scrollbar class="scrollbar-container">
<el-row type="flex" style="width: 230px" justify="center" align="middle"> <el-row type="flex" class="header-row" justify="center" align="middle">
<el-col :span="12"> <el-col :span="12">
<p class="logic_title">显示逻辑</p> <p class="logic_title">显示逻辑</p>
</el-col> </el-col>
@ -13,25 +13,25 @@
</el-col> </el-col>
</el-row> </el-row>
<div class="show-logic-container"> <div class="show-logic-container">
<div v-if="!logicList.length"> <div v-if="!logicList.length" class="not-logic-container">
<el-row> <el-row>
<el-col :offset="10"> <el-col :offset="10">
<el-button type="text" @click="addLogicHandle"> <el-button type="text" @click="addLogicHandle">
<i class="el-icon-circle-plus-outline" style="font-size: 20px"></i> <i class="el-icon-circle-plus-outline"></i>
<span style="font-size: 18px">添加逻辑</span> <span class="label">添加逻辑</span>
</el-button> </el-button>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
<div v-else> <div v-else class="logic-item-container">
<el-row type="flex" align="middle" justify="center"> <el-row type="flex" align="middle" justify="center">
<el-col :span="11" :offset="1"> <el-col :span="11" :offset="1">
<p style="font-size: 14px;color: #aaa"> {{ logicList.length + 1 }}. 条显示逻辑</p> <p> {{ logicList.length }}. 条显示逻辑</p>
</el-col> </el-col>
<el-col :span="6" :offset="6"> <el-col :span="6" :offset="6">
<el-button type="primary" size="mini" @click="addLogicHandle"> <el-button type="primary" size="mini" @click="addLogicHandle">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<span style="font-size: 15px">添加逻辑</span> <span class="label">添加逻辑</span>
</el-button> </el-button>
</el-col> </el-col>
</el-row> </el-row>
@ -40,15 +40,15 @@
:key="index"> :key="index">
<el-row type="flex" align="middle" justify="center"> <el-row type="flex" align="middle" justify="center">
<el-col :offset="1" :span="6"> <el-col :offset="1" :span="6">
<span style="margin-right: 8px">{{ index + 1 }}.</span> <span class="mr-10">{{ index + 1 }}.</span>
<el-select <el-select
:disabled="!!logicItem.showFormItemId" :disabled="!!logicItem.formItemId"
v-model="logicItem.showFormItemId" placeholder="请选择问题"> v-model="logicItem.formItemId" placeholder="请选择问题">
<el-option <el-option
v-for="item in getProjectItemList() " v-for="item in getProjectItemList(logicItem.formItemId) "
:key="item.id" :key="item.id"
:label="item.label" :label="item.label"
:value="item.id"> :value="item.formItemId">
</el-option> </el-option>
</el-select> </el-select>
</el-col> </el-col>
@ -56,7 +56,7 @@
<span>符合以下</span> <span>符合以下</span>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-select v-model="logicItem.showExpression" placeholder="请选择"> <el-select v-model="logicItem.expression" placeholder="请选择">
<el-option <el-option
v-for="item in questionOptions" v-for="item in questionOptions"
:key="item.value" :key="item.value"
@ -73,14 +73,14 @@
v-for="(cItem,cIndex) in logicItem.conditionList" v-for="(cItem,cIndex) in logicItem.conditionList"
:key="cIndex" :key="cIndex"
:gutter="20" :gutter="20"
style="margin-top: 5px" type="flex" align="middle" justify="center"> class="mt-5" type="flex" align="middle" justify="center">
<el-col :offset="1" :span="6"> <el-col :offset="1" :span="6">
<el-select v-model="cItem.formItemId" placeholder="请选择题目"> <el-select v-model="cItem.formItemId" placeholder="请选择题目">
<el-option <el-option
v-for="item in getConditionProjectItemList(logicItem)" v-for="item in getConditionProjectItemList(logicItem)"
:key="item.id" :key="item.id"
:label="item.label" :label="item.label"
:value="item.id"> :value="item.formItemId">
</el-option> </el-option>
</el-select> </el-select>
</el-col> </el-col>
@ -106,14 +106,12 @@
</el-col> </el-col>
<el-col :span="9"> <el-col :span="9">
<el-button type="text" @click="addConditionHandle(logicItem)"> <el-button type="text" @click="addConditionHandle(logicItem)">
<i class="el-icon-circle-plus-outline" <i class="el-icon-circle-plus-outline"/>
style="font-size: 24px"/>
</el-button> </el-button>
<el-button type="text" <el-button type="text"
style="color: #ff4949" class="remove"
@click="removeConditionHandle(logicItem,index,cIndex)"> @click="removeConditionHandle(logicItem,index,cIndex)">
<i class="el-icon-remove-outline" <i class="el-icon-remove-outline"/>
style="font-size: 24px"/>
</el-button> </el-button>
</el-col> </el-col>
@ -138,13 +136,14 @@ export default {
}, },
mounted() { mounted() {
this.queryProjectItems() this.queryProjectItems()
this.queryProjectLogics()
}, },
data() { data() {
return { return {
// //
defaultLogicItem: { defaultLogicItem: {
showFormItemId: null, formItemId: null,
showExpression: 'all', expression: 1,
conditionList: [ conditionList: [
{ {
formItemId: null, formItemId: null,
@ -154,72 +153,113 @@ export default {
] ]
}, },
conditionOptions: [{ conditionOptions: [{
value: 'checked', value: 'eq',
label: '选中' label: '选中'
}, { }, {
value: 'unchecked', value: 'ne',
label: '未选中' label: '未选中'
}], }],
questionOptions: [{ questionOptions: [{
value: 'all', value: 1,
label: '全部' label: '全部'
}, { }, {
value: 'any', value: 2,
label: '任意' label: '任意'
}], }],
allProjectItemList: [], allProjectItemList: [],
logicList: [] logicList: []
} }
}, methods: { },
watch: {
getLogicList: {
handler(val, oldVal) {
//
let updateVal = _.differenceWith(val, oldVal, (arrVal, othVal) => {
if (JSON.stringify(arrVal) == JSON.stringify(othVal)) {
return true
}
return false
})
console.log(updateVal)
if (updateVal && updateVal[0] && updateVal[0].conditionList.length) {
let updateData = updateVal[0]
updateData.projectKey = this.projectKey
if (updateData.formItemId) {
this.saveProjectLogic(updateData)
}
}
},
deep: true
}
},
computed: {
// vue watch
getLogicList() {
return JSON.parse(JSON.stringify(this.logicList))
}
},
methods: {
addConditionHandle(logicItem) { addConditionHandle(logicItem) {
logicItem.conditionList.push({}) logicItem.conditionList.push({})
}, },
removeConditionHandle(logicItem, logicIndex, index) { removeConditionHandle(logicItem, logicIndex, index) {
logicItem.conditionList.splice(index, 1) logicItem.conditionList.splice(index, 1)
if (logicItem.conditionList.length == 0) { if (logicItem.conditionList.length == 0) {
this.logicList.splice(logicIndex, 1) this.$api.post(`/user/project/logic/delete`, logicItem).then(res => {
this.logicList.splice(logicIndex, 1)
})
} }
}, },
addLogicHandle() { addLogicHandle() {
this.logicList.push(jsonSimpleClone(this.defaultLogicItem)) this.logicList.push(jsonSimpleClone(this.defaultLogicItem))
}, },
getConditionProjectItemList(logicItem) { getConditionProjectItemList(logicItem) {
let showFormItemId = logicItem.showFormItemId let showFormItemId = logicItem.formItemId
if (!showFormItemId) { if (!showFormItemId) {
return return
} }
//使 //使
let conditionProjectItemList = jsonSimpleClone(this.allProjectItemList) let conditionProjectItemList = jsonSimpleClone(this.allProjectItemList)
let index = conditionProjectItemList.findIndex(item => item.id == showFormItemId) let index = conditionProjectItemList.findIndex(item => item.formItemId == showFormItemId)
conditionProjectItemList = _.slice(conditionProjectItemList, 0, index) conditionProjectItemList = _.slice(conditionProjectItemList, 0, index)
conditionProjectItemList = conditionProjectItemList.filter((item) => { conditionProjectItemList = conditionProjectItemList.filter((item) => {
return ['RADIO','CHECKBOX','SELECT'].includes(item.type) return ['RADIO', 'CHECKBOX', 'SELECT'].includes(item.type)
}) })
return conditionProjectItemList return conditionProjectItemList
}, },
getProjectItemList() { getProjectItemList(formItemId) {
// //
let selectedFormItemList = this.logicList.map(item => item.showFormItemId) let selectedFormItemList = this.logicList.map(item => item.formItemId)
let projectItemList = jsonSimpleClone(this.allProjectItemList) let projectItemList = jsonSimpleClone(this.allProjectItemList)
//
projectItemList.shift() projectItemList.shift()
return projectItemList.filter((item) => { return projectItemList.filter((item) => {
return !selectedFormItemList.includes(item.id) return !selectedFormItemList.includes(item.id) || item.formItemId == formItemId
}) })
}, },
getFormItemOptions(formItemId) { getFormItemOptions(formItemId) {
let formItem = this.allProjectItemList.find(item => item.id == formItemId) let formItem = this.allProjectItemList.find(item => item.formItemId == formItemId)
if (formItem) { if (formItem) {
return formItem.expand.options return formItem.expand.options
} }
return [] return []
}, },
queryProjectLogics() {
this.$api.get(`/user/project/logic/list`, {params: {projectKey: this.projectKey}}).then(res => {
this.logicList = res.data
})
},
queryProjectItems() { queryProjectItems() {
this.$api.get(`/user/project/item/list`, {params: {key: this.projectKey}}).then(res => { this.$api.get(`/user/project/item/list`, {params: {key: this.projectKey}}).then(res => {
this.allProjectItemList = res.data this.allProjectItemList = res.data
// // })
// let projectItemList = res.data },
// projectItemList.shift() saveProjectLogic(data) {
// this.projectItemList = projectItemList this.$api.post(`/user/project/logic/save`, data).then(res => {
if (!data.id) {
let index = _.findIndex(this.logicList, {formItemId: data.formItemId})
this.logicList[index].id = res.data.id
}
}) })
} }
} }
@ -227,25 +267,56 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
.project-logic-container { .project-logic-container {
width: 100%; width: 100%;
padding: 0px;
margin: 0;
background-color: #F7F7F7; background-color: #F7F7F7;
min-height: 84vh; min-height: 84vh;
min-width: 80vw; min-width: 80vw;
display: flex; display: flex;
justify-content: center; justify-content: center;
.scrollbar-container {
height: 90vh;
}
.header-row {
width: 230px;
}
.logic_title {
font-size: 18px;
height: 45px;
line-height: 45px;
color: #484848;
text-indent: 20px;
padding-top: 20px;
}
} }
.project-logic-container .logic_title { .not-logic-container {
font-size: 18px; .el-icon-circle-plus-outline {
height: 45px; font-size: 20px;
line-height: 45px; }
color: #484848;
text-indent: 20px; .label {
padding-top: 20px; font-size: 18px
}
}
.logic-item-container {
.tips {
font-size: 14px;
color: #aaa
}
.label {
font-size: 15px
}
.remove {
color: #ff4949
}
} }
.el-icon-question { .el-icon-question {
@ -264,6 +335,10 @@ export default {
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)
} }
.el-icon-circle-plus-outline, .el-icon-remove-outline {
font-size: 24px
}
</style> </style>
<style> <style>
.question-popper.el-tooltip__popper[x-placement^="top"] .popper__arrow { .question-popper.el-tooltip__popper[x-placement^="top"] .popper__arrow {

Loading…
Cancel
Save