<template>
<div class="main-drag">
<div v-if="stencil === '0'" class="mapped-fields">
<el-form ref="mapped" :model="mapped" class="demo-fieldsForm">
<el-form-item label="切换数据集" prop="dataset" class="demo-fieldsForm">
<el-select v-model="mapped.dataset" placeholder="请选择数据集" @change="changeDataset">
<el-option v-for="(item) in mappedFieldsList" :key="item.fieldId" :label="item.fieldName"
:value="item.fieldId" />
</el-select>
</el-form-item>
</el-form>
</div>
<!--使用draggable组件-->
<div class="itxst">
<div class="drag-drop">
<div class="drag-drop-col calculators">
<p class="font-weight">拖拽字段到计算区域</p>
<transition>
<draggable v-model="calculators" v-bind="{ group: { name: 'itxst', pull: 'clone', put: false }, sort: false }"
animation="300" :move="onMove" @end="endCalculators">
<transition-group>
<div v-for="(item, index) in calculators" :key="index + 'number'"
:class="item.type === 'Number' ? 'calculators-item' : 'calculators-item-blue'">{{ item.name }}</div>
</transition-group>
</draggable>
</transition>
</div>
<!-- 数据集模块 -->
<div class="drag-drop-col">
<p class="font-weight">
{{ stencil === "0" ? '数据集的模板字段' : '数据源字段' }}
</p>
<draggable v-model="fields" v-bind="{ group: { name: 'itxst', pull: 'clone', put: false }, sort: false }"
animation="300" :move="onMove" @end="endFields">
<transition-group class="transition-groups">
<div v-for="(item, index) in fields" :key="index + 'fieldName'" class="field-item">
<Vptip :content="item.fieldName" :width="'100%'" style="max-width: 500px;" class="item">
{{ `${item.fieldName}` }}
</Vptip>
<!-- <el-tooltip class="item" effect="dark" :content="item.fieldName" placement="top"
style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">
<div>{{ item.fieldName }}</div>
</el-tooltip> -->
</div>
</transition-group>
</draggable>
</div>
<!-- 指标拖拽模块 -->
<div class="drag-drop-col">
<p class="font-weight">当前模板的指标字段</p>
<draggable v-model="indicators" v-bind="{ group: { name: 'itxst', pull: 'clone', put: false }, sort: false }"
animation="300" :move="onMove" @end="endFields">
<transition-group class="transition-groups">
<div v-for="(item, index) in indicators" :key="index + 'templateFieldName'" class="field-item"
style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">
<Vptip :content="item.templateFieldName" :width="'100%'" style="max-width: 500px;" class="item">
{{ `${item.templateFieldName}` }}
</Vptip>
<!-- <el-tooltip class="item" effect="dark" :content="item.templateFieldName"
style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;" placement="top">
<div>{{ item.templateFieldName }}</div>
</el-tooltip> -->
</div>
</transition-group>
</draggable>
</div>
</div>
<!-- 公式模块 -->
<div class="col-operations">
<div class="operations-left">
<p class="font-weight">计算区域</p>
<transition>
<draggable v-model="operations" group="itxst" animation="300" :move="onMove" @end="endOperationsOne">
<transition-group class="group-over">
<!-- 此处只能是index,因为存在上面两个列表拉下来两个的情况会产生相同的id -->
<div v-for="(item, index) in operations" :key="index" :class="decideSstyle(item.type, item.name)">
<div class="contains-item-name" v-if="item.name">
{{ item.name }}
</div>
<el-tooltip class="contains-item-names" effect="dark" placement="top" :open-delay="400"
v-if="item.templateFieldName">
<div slot="content">
<span>类型:指标字段</span><br />
<span>名称:{{ item.templateFieldName }}</span>
</div>
<div class="contains-item-name" v-if="item.templateFieldName">
{{ item.templateFieldName }}
</div>
</el-tooltip>
<el-tooltip class="contains-item-names" effect="dark" placement="top" :open-delay="400"
v-if="item.fieldName">
<div slot="content">
<span>{{ stencil === "0" ? '数据集名称' : '数据源名称' }}:{{ item.fieldBelongName }} </span><br />
<span>类型:{{ stencil === "0" ? '模板字段' : '数据源字段' }}</span><br />
<span>名称:{{ item.fieldName }} </span>
</div>
<div class="contains-item-name" v-if="item.fieldName">
{{ item.fieldName }}
</div>
</el-tooltip>
<div v-if="(item.name === 'SUM' || item.name === 'AVG') && item.open === false" class="margin-auto"
@click="item.open = true"><i class="el-icon-d-arrow-right"></i></div>
<div v-if="item.name === 'SUM' && item.open === true" class="sum-class">
<draggable :key="item.sumId + 'sum'" v-model="sumList[getSumIndex(item.sumId)].list" group="itxst"
animation="300" :move="onMove" @end="endOperationsTwo">
<transition-group class="trans-group">
<!-- 此处只能是index,因为存在上面两个列表拉下来两个的情况会产生相同的id -->
<div v-for="(itm, idx) in sumList[getSumIndex(item.sumId)].list" :key="idx + 'sum'"
class="field-item-father">
<div class="field-item" v-if="itm.name">
{{ itm.name }}
</div>
<el-tooltip class="tooltip-div" effect="dark" placement="top" :open-delay="200"
v-if="itm.templateFieldName">
<div slot="content">
<span>类型: 指标字段</span><br />
<span>名称:{{ itm.templateFieldName }}</span>
</div>
<div class="field-item" v-if="itm.templateFieldName">
{{ itm.templateFieldName }}
</div>
</el-tooltip>
<el-tooltip class="tooltip-div" effect="dark" placement="top" :open-delay="200"
v-if="itm.fieldName">
<div slot="content">
<span>{{ stencil === "0" ? '数据集名称' : '数据源名称' }}:{{ itm.fieldBelongName }}</span><br />
<span>类型: {{ stencil === "0" ? '模板字段' : '数据源字段' }}</span><br />
<span>名称:{{ itm.fieldName }}</span>
</div>
<div class="field-item" v-if="itm.fieldName">
{{ itm.fieldName }}
</div>
</el-tooltip>
</div>
</transition-group>
</draggable>
</div>
<div v-if="item.name === 'AVG' && item.open === true" class="sum-class">
<draggable :key="item.averageId + 'avg'" v-model="averageList[getAverageIndex(item.averageId)].list"
group="itxst" animation="300" :move="onMove" @end="endOperationsThree">
<transition-group class="trans-group">
<!-- 此处只能是index,因为存在上面两个列表拉下来两个的情况会产生相同的id -->
<div v-for="(itm, idx) in averageList[getAverageIndex(item.averageId)].list" :key="idx + 'avg'"
class="field-item-father">
<div class="field-item" v-if="itm.name">
{{ itm.name }}
</div>
<el-tooltip class="tooltip-div" effect="dark" placement="top" :open-delay="200"
v-if="itm.templateFieldName">
<div slot="content">
<span>类型: 指标字段</span><br />
<span>名称:{{ itm.templateFieldName }}</span>
</div>
<div class="field-item" v-if="itm.templateFieldName">
{{ itm.templateFieldName }}
</div>
</el-tooltip>
<el-tooltip class="tooltip-div" effect="dark" placement="top" :open-delay="200"
v-if="itm.fieldName">
<div slot="content">
<span>{{ stencil === "0" ? '数据集名称' : '数据源名称' }}:{{ itm.fieldBelongName }}</span><br />
<span>类型:{{ stencil === "0" ? '模板字段' : '数据源字段' }}</span><br />
<span>名称:{{ itm.fieldName }}</span>
</div>
<div class="field-item" v-if="itm.fieldName">
{{ itm.fieldName }}
</div>
</el-tooltip>
</div>
</transition-group>
</draggable>
</div>
<div v-if="(item.name === 'SUM' || item.name === 'AVG') && item.open === true" class="margin-auto"
@click="item.open = false"><i class="el-icon-d-arrow-left"></i></div>
</div>
</transition-group>
</draggable>
</transition>
<el-button class="button-calculation" size="mini" type="primary" @click="calculation()">生成计算</el-button>
</div>
<!-- 垃圾回收站 -->
<div class="operations-right" style="position: relative;">
<i class="el-icon-delete" style="position: absolute;top: 150px;left: 43%; "></i>
<draggable v-model="recycleBin" group="itxst" animation="300" :move="onMove" @end="endOperations">
<transition-group class="recycle recycle-group">
<!-- 此处只能是index,因为存在上面两个列表拉下来两个的情况会产生相同的id -->
<div v-for="(item, index) in recycleBin" :key="index" class="calculators-item">{{ item.name }}</div>
</transition-group>
</draggable>
</div>
</div>
</div>
</div>
</template>
<script>
// 拖拽组件
import Vptip from "@/components/vptip" // 自定义Tooltip 文字提示
import draggable from 'vuedraggable'
export default {
name: 'customField',
components: {
draggable,
Vptip
},
props: {
// 数据源字段
mappedFieldsList: {
type: Array,
default: () => []
},
// 区分模板还是评价 1:模板 0:评价
stencil: {
type: String,
default: ''
},
// 数据条件范围
rangeFieldList: {
type: Array,
default: () => []
},
// 页面初始渲染数据
formFieldsOne: {
type: Array,
default: () => []
}
},
data() {
return {
// 数据集
mapped: {
dataset: ''
},
// 计算器元素数组
calculators: [
{ id: 1, name: '1', type: 'Number' },
{ id: 2, name: '2', type: 'Number' },
{ id: 3, name: '3', type: 'Number' },
{ id: 4, name: '(', type: 'BracketsLeft' },
{ id: 5, name: '4', type: 'Number' },
{ id: 6, name: '5', type: 'Number' },
{ id: 7, name: '6', type: 'Number' },
{ id: 8, name: ')', type: 'BracketsRight' },
{ id: 9, name: '7', type: 'Number' },
{ id: 10, name: '8', type: 'Number' },
{ id: 11, name: '9', type: 'Number' },
{ id: 12, name: 'SUM', sumId: 1, open: true },
{ id: 13, name: '0', type: 'Number' },
{ id: 14, name: '.', type: 'DecimalPoint' },
{ id: 15, name: '/', type: 'Symbols' },
{ id: 16, name: 'AVG', averageId: 1, open: true },
{ id: 17, name: '+', type: 'Symbols' },
{ id: 18, name: '-', type: 'Symbols' },
{ id: 19, name: '*', type: 'Symbols' }
],
// 可拖拽的计算字段
fields: [],
// 可拖拽的指标字段
indicators: [],
// 计算生成的算式
operations: [],
// 进行回收的字段
recycleBin: [],
// 拖拽的是什么
moveId: '',
// 空数组之在的样式,设置了这个样式才能拖入
style: 'min-height:200px;display: block;',
// 是否通过校验
passingCalibration: true,
// SUM之中的字段
sumList: [],
// AVG之中的字段
averageList: [],
// 计算num数组从第几个开始算起
listSumId: 1,
// 计算AVG数组从第几个开始算起
listAverageId: 1,
// numId:进行新添加的id的时候从第几个开始加
numId: 20
}
},
computed: {
getSumIndex() {
return this.findSumIndex
},
getAverageIndex() {
return this.findAverageIndex
}
},
watch: {
formFieldsOne: {
handler(item1, item2) {
this.rest(this.formFieldsOne)
},
immediate: true
}
},
mounted() {
// 放入对应的数据源字段
if (this.stencil === '0') {
this.fields = []
} else {
this.fields = this.mappedFieldsList
}
// 对应指标字段
this.indicators = this.rangeFieldList
},
methods: {
// 重置操作
rest(ruleForm) {
// 数据集
this.mapped.dataset = ''
if (this.stencil === '0') {
// 可拖拽的计算字段
this.fields = []
}
// 计算生成的算式
this.operations = ruleForm[0] !== undefined ? ruleForm[0] : []
// AVG之中的字段
this.averageList = ruleForm[1] !== undefined ? ruleForm[1] : []
// SUM之中的字段
this.sumList = ruleForm[2] !== undefined ? ruleForm[2] : []
// 计算num数组从第几个开始算起
let numSum = 0
for (let i = 0; i < this.sumList.length; i++) {
if (numSum < this.sumList[i].sumId) {
numSum = this.sumList[i].sumId
}
}
this.calculators.splice(11, 1, { id: 12, name: 'SUM', sumId: numSum + 1, open: true })
this.listSumId = numSum + 1
// 计算AVG数组从第几个开始算起
let numAvg = 0
for (let i = 0; i < this.averageList.length; i++) {
if (numAvg < this.averageList[i].averageId) {
numAvg = this.averageList[i].averageId
}
}
this.calculators.splice(15, 1, { id: 16, name: 'AVG', averageId: numAvg + 1, open: true })
this.listAverageId = numAvg + 1
// numId:进行新添加的id的时候从第几个开始加
this.numId = 20
},
// 更改选项对父组件进行传值
changeDataset() {
for (let i = 0; i < this.mappedFieldsList.length; i++) {
if (this.mapped.dataset === this.mappedFieldsList[i].fieldId) {
this.fields = this.mappedFieldsList[i].fieldList
}
}
},
// 进行渲染的计算属性计算
findSumIndex(sumId) {
return this.sumList.findIndex(item => item.sumId === sumId)
},
findAverageIndex(averageId) {
return this.averageList.findIndex(item => item.averageId === averageId)
},
// 进行计算器拖拽
endCalculators(e) {
// 阻止拖拽事件
if (e.relatedContext && e.relatedContext.element instanceof HTMLElement &&
e.draggedContext.element.type === 'Symbols' &&
e.relatedContext.element.classList.contains('sum-class')) {
e.cancel()
}
// 如果拖拽的是SUM
if (this.moveId === 'SUM') {
this.calculators.splice(11, 1, { id: this.numId, name: 'SUM', sumId: this.listSumId + 1, open: true })
this.listSumId++
this.numId++
}
// 如果拖拽的是AVG
if (this.moveId === 'AVG') {
this.calculators.splice(15, 1, { id: this.numId, name: 'AVG', averageId: this.listAverageId + 1, open: true })
this.listAverageId++
this.numId++
}
const that = this
that.recycleBin = []
},
// 进行元素字段拖拽
endFields(e) {
const that = this
that.recycleBin = []
},
// 进行删除拖动
endOperations(e) {
this.recycleBin = []
},
// 进行删除拖动
endOperationsOne(e) {
this.recycleBin = []
},
// 进行删除拖动
endOperationsTwo(e) {
this.recycleBin = []
},
// 进行删除拖动
endOperationsThree(e) {
this.recycleBin = []
},
// move回调方法
onMove(e, originalEvent) {
if (this.sumList.length === 0) this.sumList = []
if (this.averageList.length === 0) this.averageList = []
this.moveId = e.draggedContext.element.name
let index = -1
for (let i = 0; i < this.sumList.length; i++) {
if (this.sumList[i].sumId === this.listSumId) {
index = i
}
}
// 如果是在进行sum拖拽添加空数组
if (e.draggedContext.element.name === 'SUM') {
if (index !== -1) {
this.sumList.splice(index, 1, { sumId: this.listSumId, list: [] })
} else {
this.sumList.push({ sumId: this.listSumId, list: [] })
}
}
// 如果是在进行AVERAGE拖拽添加空数组
let indexAvg = -1
for (let i = 0; i < this.averageList.length; i++) {
if (this.averageList[i].averageId === this.listAverageId) {
indexAvg = i
}
}
if (e.draggedContext.element.name === 'AVG') {
if (indexAvg !== -1) {
this.averageList.splice(indexAvg, 1, { averageId: this.listAverageId, list: [] })
} else {
this.averageList.push({ averageId: this.listAverageId, list: [] })
}
}
/**
* 禁止往SUM中拖拽计算器内容
* if(拖拽位置停靠在SUM内||停靠位置为第一个数据且外围有数据)
* &&不是向回收站拖拽
* &&(类型不是undefined名称&&不是SUM){不允许拖拽}
*/
if ((e.related.className === 'field-item-father' ||
(this.operations.length !== 0 && e.relatedContext.list.length === 0)) &&
e.related.className !== 'recycle recycle-group' &&
(e.draggedContext.element.type !== undefined || e.draggedContext.element.name === 'SUM' || e.draggedContext.element.name === 'AVG')
) {
return false
}
return true
},
// 操控计算区域样式
decideSstyle(type, name) {
// 如果是字段或者求和求差
if (type === undefined) {
if (name === 'AVG' || name === 'SUM') {
return 'contains-item'
}
return 'field-item-down'
// 如果是数字
} else if (type === 'Number') {
return 'calculators-item-down'
// 如果是运算符
} else {
return 'calculators-item-blue-down'
}
},
sureFieldOne() {
this.calculation()
if (this.passingCalibration === true) {
return true
} else {
return false
}
},
// 生成计算
calculation() {
this.passingCalibration = true
// 如果计算区域为空
if (this.operations.length === 0) {
// Msg0052:运算表达式不符合规则
this.$message.error(this.$manages.Msg0052)
return
}
// 括号栈
const stack = []
for (let i = 0; i < this.operations.length; i++) {
// 进行括号堆栈的判断
// 存在左括号就将左括号存进去
if (this.operations[i].type === 'BracketsLeft') {
stack.push('(')
}
// 存在右括号
if (this.operations[i].type === 'BracketsRight') {
// 如果在没有左括号的前提下存在了右括号为不合理
if (stack.length === 0) {
this.passingCalibration = false
}
// 正常情况下存在了右括号将堆栈删掉一个
stack.pop()
}
// 只看前一个和后一个的情况下
if (i > 0 && i < this.operations.length - 1) {
// 当当前为字段时
if (this.operations[i].type === undefined) {
// 上一个不能为字段
// 上一个不能为数字
// 上一个不能为小数点
// 下一个不能为字段
// 下一个不能为数字
// 下一个不能为小数点
if (this.operations[i - 1].type === undefined ||
this.operations[i - 1].type === 'Number' ||
this.operations[i - 1].type === 'DecimalPoint' ||
this.operations[i + 1].type === undefined ||
this.operations[i + 1].type === 'Number' ||
this.operations[i + 1].type === 'DecimalPoint'
) {
this.passingCalibration = false
}
// 当当前为数字时
} else if (this.operations[i].type === 'Number') {
// 上一个不能为字段
// 下一个不能为字段
if (this.operations[i - 1].type === undefined ||
this.operations[i + 1].type === undefined
) {
this.passingCalibration = false
}
// 当当前为运算符的时候
} else if (this.operations[i].type === 'Symbols') {
// 上一个不能为运算符
// 上一个不能为小数点
// 上一个不能为左括号
// 下一个不能为运算符
// 下一个不能为小数点
// 下一个不能为右括号
if (this.operations[i - 1].type === 'Symbols' ||
this.operations[i - 1].type === 'DecimalPoint' ||
this.operations[i - 1].type === 'BracketsLeft' ||
this.operations[i + 1].type === 'Symbols' ||
this.operations[i + 1].type === 'DecimalPoint' ||
this.operations[i + 1].type === 'BracketsRight'
) {
this.passingCalibration = false
}
// 当当前为左括号的时候
} else if (this.operations[i].type === 'BracketsLeft') {
// 上一个不能为小数点
// 下一个不能为小数点
if (this.operations[i - 1].type === 'DecimalPoint' ||
this.operations[i + 1].type === 'DecimalPoint' ||
this.operations[i - 1].type === 'Number' ||
this.operations[i - 1].type === undefined
) {
this.passingCalibration = false
}
// 当当前为右括号的时候
} else if (this.operations[i].type === 'BracketsRight') {
// 上一个不能为小数点
// 下一个不能为小数点
if (this.operations[i - 1].type === 'DecimalPoint' ||
this.operations[i + 1].type === 'DecimalPoint' ||
this.operations[i + 1].type === 'Number' ||
this.operations[i + 1].type === undefined
) {
this.passingCalibration = false
}
// 当为小数点时
} else if (this.operations[i].type === 'DecimalPoint') {
// 下一个只能为数字
// 上一个只能为数字
if (this.operations[i - 1].type !== 'Number' ||
this.operations[i + 1].type !== 'Number'
) {
this.passingCalibration = false
}
let j = i
j++
// 对小数点后面的数字进行判断
while (j < this.operations.length - 1) {
j++
const type = this.operations[j].type
// 如果进入到了运算符,括号证明此数字结束可以进行跳出
if (type === 'Symbols' ||
type === 'BracketsLeft' ||
type === 'BracketsRight') {
j = this.operations.length
// 如果在跳出前再次遇见小数点则证明不合理
} else if (type === 'DecimalPoint') {
this.passingCalibration = false
j = this.operations.length
}
}
}
}
}
// 如果最后括号数没归零则等式不合理
if (stack.length !== 0) {
this.passingCalibration = false
}
// 开头如果不是数字字段百分号左括号就不符合
if (this.operations[0].type !== 'Number' &&
this.operations[0].type !== undefined &&
this.operations[0].type !== 'BracketsLeft') {
this.passingCalibration = false
}
// 结尾如果不是数字字段右括号就不符合
if (this.operations[this.operations.length - 1].type !== 'Number' &&
this.operations[this.operations.length - 1].type !== undefined &&
this.operations[this.operations.length - 1].type !== 'BracketsRight') {
this.passingCalibration = false
}
// 排除掉仅有两位且还不同字段的情况,
// 排除掉两个都为后端字段的情况
if (this.operations.length === 2 && (
this.operations[0].type === undefined ||
this.operations[1].type === undefined)) {
this.passingCalibration = false
}
// 如果仅为一位的时候
if (this.operations.length === 1) {
if (this.operations[0].type === 'Number' || this.operations[0].type === undefined) {
this.passingCalibration = true
}
}
// 进行SUM和AVG是否有值的判断
for (let i = 0; i < this.operations.length; i++) {
if (this.operations[i].name === 'SUM') {
const presence = this.sumList.findIndex(item => item.sumId === this.operations[i].sumId)
// 如果SUM内容为空
if (this.sumList[presence].list.length === 0) {
this.passingCalibration = false
}
} else if (this.operations[i].name === 'AVG') {
const presence = this.averageList.findIndex(item => item.averageId === this.operations[i].averageId)
// 如果AVG内容为空
if (this.averageList[presence].list.length === 0) {
this.passingCalibration = false
}
}
}
// 如果计算列式不合理
if (this.passingCalibration === false) {
// Msg0052:运算表达式不符合规则
this.$message.error(this.$manages.Msg0052)
// 如果计算列式合理
} else {
this.$emit('get-custom-calculation', this.operations, this.averageList, this.sumList)
}
}
}
}
// 原生拖拽自带逻辑
// eslint-disable-next-line no-extend-native
Array.prototype.filter = Array.prototype.filter || function (func) {
var arr = this
var r = []
for (var i = 0; i < arr.length; i++) {
if (func(arr[i], i, arr)) {
r.push(arr[i])
}
}
return r
}
</script>
<style lang="scss" scoped>
.main-drag {
width: 60vw;
height: auto;
overflow: hidden;
}
.mapped-fields {
height: 10vh;
width: calc(60vw - 2px);
min-height: 60px;
min-width: 530px;
border: solid 1px #DCDFE6;
border-radius: 3px;
display: flex;
flex-direction: column;
justify-content: center;
margin-bottom: 20px;
.demo-fieldsForm {
margin-left: 20px;
::v-deep .el-form-item {
margin-bottom: 0;
}
}
}
.itxst {
width: 60vw;
height: auto;
overflow: hidden;
text-align: left;
}
.drag-drop {
display: flex;
border: solid 1px #DCDFE6;
border-radius: 5px;
margin-bottom: 20px;
padding: 10px 10px;
.calculators {
width: 200px;
}
}
.col-operations {
height: auto;
display: flex;
margin-top: 10px;
overflow: hidden;
.operations-left {
height: auto;
min-height: 200px;
width: 88%;
border: solid 1px #DCDFE6;
border-radius: 5px;
margin-right: 2%;
padding: 1%;
.button-calculation {
float: right;
}
}
.operations-right {
height: auto;
min-height: 200px;
width: 10%;
border: dashed 1px #DCDFE6;
border-radius: 5px;
background: #dfdfdf;
}
}
.drag-drop-col {
height: 250px;
padding: 10px;
float: left;
overflow: auto;
width: calc(29vw - 100px);
}
.drag-drop-col+.drag-drop-col {
border-left: 1px dashed #DCDFE6;
}
.col {
width: 100%;
height: 200px;
flex: 1;
padding: 10px;
border: solid 1px #DCDFE6;
border-radius: 5px;
float: left;
}
.calculators-item {
height: 22px;
line-height: 20px;
width: auto;
min-width: 32px;
float: left;
border: 1px solid #b3d8ff;
color: #409eff;
background: #ecf5ff;
font-size: 14px;
text-align: center;
border-radius: 3px;
margin: 4px;
}
.calculators-item:hover {
cursor: move;
}
.calculators-item-down {
height: 30px;
line-height: 30px;
width: auto;
min-width: 32px;
float: left;
border: 1px solid #b3d8ff;
color: #409eff;
background: #ecf5ff;
font-size: 14px;
text-align: center;
border-radius: 3px;
margin: 5px;
}
.calculators-item-down:hover {
cursor: move;
}
.calculators-item-blue {
height: 22px;
line-height: 20px;
width: auto;
min-width: 32px;
float: left;
border: 1px solid #409eff;
color: #fff;
background: #409eff;
font-size: 12px;
text-align: center;
border-radius: 3px;
margin: 4px;
}
.calculators-item-blue:hover {
cursor: move;
}
.calculators-item-blue-down {
height: 30px;
line-height: 30px;
width: auto;
min-width: 32px;
float: left;
border: 1px solid #409eff;
color: #fff;
background: #409eff;
font-size: 12px;
text-align: center;
border-radius: 3px;
margin: 5px;
}
.calculators-item-blue-down:hover {
cursor: move;
}
.field-item {
color: #e6a23c;
text-align: center;
width: 93px;
height: 24px;
line-height: 24px;
border-radius: 4px;
border: 1px solid #e6a23c;
background-color: #fdf6ec;
float: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin: 2px;
font-size: 12px;
}
.field-item-father {
float: left;
}
.field-item:hover {
cursor: move;
}
.field-item-down {
color: #e6a23c;
text-align: center;
width: 93px;
height: 30px;
line-height: 30px;
border-radius: 4px;
border: 1px solid #e6a23c;
background-color: #fdf6ec;
float: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin: 5px;
}
.field-item-down:hover {
cursor: move;
}
.contains-item {
min-height: 28px;
line-height: 28px;
width: auto;
min-width: 25px;
float: left;
margin: 5px;
color: #fff;
background: #409eff;
text-align: center;
display: flex;
border: 1px solid #409eff;
border-radius: 3px;
// height: 30px;
}
.contains-item:hover {
cursor: move;
}
.contains-item-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 35px;
margin: auto;
}
.contains-item-names {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 35px;
margin: auto;
}
.sum-class {
min-height: 26px;
min-width: 100px;
height: auto;
border-left: 1px solid #c0c0c0;
border-radius: 3px;
float: left;
background-color: #fff;
}
.group-over {
overflow: auto;
max-height: 250px;
height: auto;
min-height: 200px;
display: block;
}
.font-weight {
font-weight: 700;
}
::v-deep .transition-groups {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.margin-auto {
margin: auto;
}
.trans-group {
height: auto;
min-height: 28px;
display: block;
}
.recycle-group {
height: 200px;
display: block;
}
::v-deep .tooltip-div {
width: 93px !important;
height: 24px !important;
}
</style>