新建组件configFormulaSalary
<template>
<div>
<el-dialog title="公式配置"
:visible="isConfigFormula" top="15vh"
width="1200px" custom-class="config-dialog"
:before-close="onClose"
append-to-body
:close-on-click-modal="false"
@mousedown.native="handleDialogMousedown($event)"
@mouseup.native="handleDialogMouseup($event)"
>
<div class="form-main">
<div class="left-cont">
<div class="left-title">{{info? info.name : ''}}=</div>
<div class="input-box">
<el-input type="textarea" v-model="formulaValue"
autofocus="autofocus" @keyup.enter.native="searchHandle"
ref="configInput" id="configInput"
placeholder="请输入计算公式或选择函数" @focus="getCursor"></el-input>
</div>
<div class="formula-btn">
<div class="formula-left">
<el-button class="btn-experience" @click="onCheckItemFormula">公式校验</el-button>
<span class="margin-l-20 tips-box" v-if="msgSuccessTips">
<i class="el-icon-circle-check"></i>
{{msgSuccessTips}}
</span>
<span class="margin-l-20 tips-box err" v-if="msgErrorTips">
<i class="el-icon-circle-close"></i>
{{msgErrorTips}}
</span>
</div>
<div class="right-form-btn">
<el-select v-model="formulaRule" placeholder="请选择" class="config-select-btn">
<el-option
v-for="item in formulaRuleList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<span class="label-text">保留</span>
<el-select v-model="decimalPoint" placeholder="请选择" class="select-right">
<el-option
v-for="item in decimalPointList"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<span class="label-text">位小数</span>
</div>
</div>
<div class="formula-item">
<span class="item-title">快捷运算符</span>
<span class="formula-label" v-for="(unit,indexU) in formulaTypeList"
:key="indexU" @click="onSelectOperator(unit.value)">{{unit.label}}</span>
</div>
<div class="bottom-drap">
<div class="drap-title">点击选择薪资字段</div>
<div class="drap-list">
<!-- <el-checkbox-group v-model="drapSelectList" @change="onSelect">
<el-checkbox-button v-for="(drap,indexD) in drapList"
:label="'#'+drap+'#'" :key="indexD">{{drap}}</el-checkbox-button>
</el-checkbox-group> -->
<div class="list" v-for="(drap,indexD) in drapList" :key="indexD">
<div class="item" @click="onSelect(drap,'#')" v-if="info.name !==drap">{{drap}}</div>
</div>
</div>
</div>
</div>
<div class="right-cont" @mouseleave="onLeave">
<div class="title-bar">插入函数</div>
<div class="right-box">
<div class="box-title-bar">常用函数</div>
<ul class="box-item-list" >
<li class="item-cont" v-for="(formula,indexV) in formulaData.common"
:key="indexV" @mouseenter="onEnterFormulaData(indexV,formula,1)"
:class="isSelectIndex1 == indexV?'is-active':''"
@click="onSelect(formula.grammar)">
<span>{{formula.title}}</span>
<el-button type="text">插入</el-button>
</li>
</ul>
<div class="box-title-bar">系统函数</div>
<ul class="box-item-list">
<li class="item-cont" v-for="(formula,indexV) in formulaData.system"
:key="indexV" @mouseenter="onEnterFormulaData(indexV,formula,2)"
:class="isSelectIndex2 == indexV?'is-active':''"
@click="onSelect(formula.grammar)">
<span>{{formula.title}}</span>
<el-button type="text">插入</el-button>
</li>
</ul>
</div>
<div class="right-item-por" v-show="selectClass">
<div class="title">{{selectFunObj.title}}</div>
<p v-html="selectFunObj.describe"></p>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="onClose">取 消</el-button>
<el-button type="primary" @click="onSubmit('ruleForm')">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
// import {getCommonAndSystemFunctions,checkItemFormula} from "@/api/salary"
export default {
props: {
isConfigFormula: Boolean,
info: Object,
drapList: Array,
fieldGroupList: Array
},
data () {
return {
formulaValue: '',
formulaRule: 'round',
formulaRuleList: [
{ value: 'round', label:'四舍五入' },
{ value: 'floor', label:'向下取整' },
{ value: 'ceil', label:'向上取整' },
],
blurIndex: null,//输入框光标位置
msgSuccessTips: '',
msgErrorTips: '',
decimalPoint: 2,
decimalPointList: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
formulaTypeList: [
{value: '+', label: '+'},
{value: '-', label: '-'},
{value: '*', label: '*'},
{value: '/', label: '/'},
{value: '()', label: '()'},
{value: '>', label: '>'},
{value: '<', label: '<'},
{value: '=', label: '='},
{value: '>=', label: '≥'},
{value: '<=', label: '≤'},
{value: '!=', label: '≠'},
{value: "''", label: "''"},
],
drapSelectList: [],
selectFunObj: {},
selectClass: false,
isSelectIndex1: null,
isSelectIndex2: null,
formulaData:{
system: [],
common: [],
},
classDialogmodel: false,
}
},
created(){
if (this.info) {
this.formulaValue = this.info.text
this.formulaRule = this.info.mode || 'round'
this.decimalPoint = this.info.count !==null && this.info.count !== undefined ? this.info.count : 2
this.getList()
}
},
methods: {
// 选择薪资项
onSelect(e,value){
let index=this.blurIndex
let str=this.formulaValue
if(value) {
// this.formulaValue = this.formulaValue + ' #'+e+'#'
let formulaValue ='#'+e+'#'
this.insertAtCursor(formulaValue)
} else {
// this.formulaValue = this.formulaValue +e
// this.formulaValue=str.slice(0, index) + e + str.slice(index);
this.insertAtCursor(e)
}
},
onSelectOperator(e){
// this.formulaValue = this.formulaValue +e
this.insertAtCursor(e)
},
// 获取光标位置
async insertAtCursor(myValue) {
const myField = document.querySelector('#configInput');
// const myField = this.$refs.configInput;
if (myField.selectionStart || myField.selectionStart === 0) {
var startPos = myField.selectionStart
var endPos = myField.selectionEnd
this.formulaValue = myField.value.substring(0, startPos) + myValue
+ myField.value.substring(endPos, myField.value.length)
await this.$nextTick() // 这句是重点, 圈起来
myField.focus()
// 检测函数是否下一次插入点位置 设置光标位置
if(myValue.indexOf('(') !== -1) {
let arr = myValue.split('')
let index = arr.findIndex(o=>{return o=='('})
// myField.setSelectionRange(endPos + myValue.length, endPos + myValue.length)
myField.setSelectionRange(endPos + index+1, endPos + index+1)
} else {
myField.setSelectionRange(endPos + myValue.length, endPos + myValue.length)
}
} else {
this.formulaValue += myValue
}
},
onCheckItemFormula() {
let arr = this.fieldGroupList.reduce((last,next)=>{
return last.concat(...next.fieldList)
},[])
let parmetn = {
checkItemName: this.info.name,
formulaText: this.formulaValue,
salaryItemGroupList: Array.from(new Set(arr)),
}
this.msgSuccessTips = ''
this.msgErrorTips = ''
// checkItemFormula(parmetn).then(res=> {
// if(res.code='SUCCESS') {
// this.msgSuccessTips = res.message
// }
// }).catch(err=> {
// this.$message.error({
// message: err.message
// })
// this.msgErrorTips = err.message
// })
},
getCursor(e){
this.blurIndex = e.srcElement.selectionStart
},
searchHandle(event) {
event.preventDefault();
},
onLeave(vule){
this.selectClass = false;
this.isSelectIndex1 = null
this.isSelectIndex2 = null
},
onEnterFormulaData(index,row,type) {
this.selectClass = true
this.selectFunObj = row
if(type==1) {
this.isSelectIndex1 = index
this.isSelectIndex2 = null
} else {
this.isSelectIndex1 = null
this.isSelectIndex2 = index
}
},
onClose () {
this.$emit('onClose')
},
onSubmit () {
let data = {
formulaValue: this.formulaValue,
mode: this.formulaRule,
count: this.decimalPoint,
}
this.$emit('onSubmitEdit',data)
},
onRuleChange(event) {
this.ruleForm.ruleId = event
},
getList () {
// getCommonAndSystemFunctions().then(res=> {
// if(res.code=="SUCCESS") {
// this.formulaData.common = res.common
// this.formulaData.system = res.system
// }
// }).catch(err=> {
// this.$message.error({
// message: err.message
// })
// })
},
// 监测弹框鼠标事件
handleDialogMousedown(e) {
// 如果为true,则表示点击发生在遮罩层
this.classDialogmodel= !!e.target.classList.contains('el-dialog__wrapper')
},
handleDialogMouseup(e) {
if((!!e.target.classList.contains('el-dialog__wrapper')) && this.classDialogmodel){
this.onClose()
}
this.classDialogmodel=false
},
},
watch: {
isConfigFormula() {
if(this.isConfigFormula) {
this.getList()
}
}
}
}
</script>
<style lang="less" scoped>
@deep: ~'>>>';
// 删除薪资组
@{deep}.config-dialog {
.el-dialog__header {
padding: 20px 24px 14px;
font-size: 18px;
line-height: 18px;
font-family: PingFang SC;
font-weight: 400;
color: #333;
border-bottom: 1px solid #E9E9E9;
}
.form-main {
display: flex;
justify-content: flex-start;
}
.el-dialog__body {
padding: 0 !important;
}
.el-dialog__footer {
text-align: right;
padding-top: 10px;
padding-bottom: 14px;
border-top: 1px solid #E9E9E9;
.el-button {
padding: 0;
width: 80px;
height: 32px;
text-align: center;
line-height: 32px;
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
}
.close-but {
border: 1px solid #D9D9D9;
border-radius: 4px;
color: #666666;
&:hover {
background: transparent;
}
}
.primary-btn {
color: #FFFFFF;
background: #3277FF;
border-radius: 4px;
}
}
.left-cont {
width: 850px;
padding: 0 24px;
border-right: 1px solid #E8E8E8;
.left-title {
font-size: 14px;
font-family: 'PingFang-SC-Bold';
font-weight: bold;
color: #333;
padding: 14px 0;
}
.input-box {
padding-bottom: 10px;
.el-textarea__inner {
width: 100%;
height: 124px;
line-height: 26px;
border: 1px solid #D5D5D5;
border-radius: 4px;
font-size: 14px;
color: #333;
padding: 0 10px;
&::placeholder {
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
// color: #CCCCCC;
}
}
}
.formula-btn {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 24px;
.btn-experience {
width: 86px;
height: 32px;
padding: 0;
text-align: center;
line-height: 32px;
background: #3277FF;
border-radius: 4px;
border-color: #3277FF;
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
color: #FFFFFF;
}
.right-form-btn {
}
.config-select-btn {
.el-input__inner {
width: 102px;
height: 32px;
line-height: 32px;
background: #FFFFFF;
border: 1px solid #D5D5D5;
border-radius: 4px;
// color: #333;
&::placeholder {
// color: #666;
}
}
.el-input__icon {
line-height: 32px;
}
}
.select-right {
margin-left: 10px;
.el-input__inner {
width: 56px;
height: 32px;
line-height: 32px;
background: #FFFFFF;
border: 1px solid #D5D5D5;
border-radius: 4px;
// color: #333;
&::placeholder {
// color: #666;
}
}
.el-input__icon {
line-height: 32px;
}
}
.label-text {
display: inline-block;
font-size: 14px;
font-family: PingFang SC;
padding-left: 10px;
font-weight: 400;
color: #666666;
}
}
.formula-item {
display: flex;
justify-content: flex-start;
align-items: center;
padding-bottom: 14px;
.item-title {
display: inline-block;
font-size: 14px;
font-family: 'PingFang-SC-Bold';
font-weight: bold;
color: #333;
margin-right: 12px;
}
.formula-label {
display: inline-block;
width: 44px;
height: 32px;
text-align: center;
line-height: 30px;
font-size: 20px;
font-family: 'PingFang-SC-Medium';
font-weight: 500;
color: #666666;
border: 1px solid #D5D5D5;
border-radius: 4px;
margin-right: 14px;
cursor: pointer;
&:hover,&.is-active {
border-color: #3277FF;
color: #3277FF;
}
}
}
.bottom-drap {
padding-bottom: 25px;
.drap-title {
font-size: 14px;
line-height: 14px;
padding-bottom: 15px;
font-family: 'PingFang-SC-Bold';
font-weight: bold;
color: #333;
}
.drap-list {
width: 801px;
height: 200px;
background: #FAFAFA;
overflow: hidden;
overflow-y: scroll;
padding: 15px 10px;
display: flex;
// align-items: center;
flex-wrap: wrap;
.item{
width: 118px;
padding: 0 10px;
height: 32px;
line-height: 30px;
text-align: center;
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
color: #333;
background: #FFFFFF;
border: 1px solid #D9D9D9;
border-radius: 4px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
margin-right: 14px;
margin-bottom: 14px;
cursor: pointer;
}
&::-webkit-scrollbar { /*滚动条整体样式*/
display: none;
}
}
.el-checkbox-button {
.el-checkbox-button__inner {
width: 118px;
padding: 0 10px;
height: 32px;
line-height: 30px;
text-align: center;
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
color: #333;
background: #FFFFFF;
border: 1px solid #D9D9D9;
border-radius: 4px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
margin-right: 14px;
margin-bottom: 14px;
}
&:nth-child(6n){
.el-checkbox-button__inner {
margin-right: 0;
}
}
&.is-checked,&:hover {
.el-checkbox-button__inner {
border-color: #3277FF;
color: #3277FF;
}
}
}
}
}
.formula-left {
display: flex;
justify-content: flex-start;
align-items: center;
.tips-box {
display: inline-block;
font-size: 14px;
max-width: 350px;
line-height: 16px;
color: #15bc83;
&.err {
color: #ff4141;
}
}
}
.right-cont {
padding: 0 24px;
position: relative;
.title-bar {
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
color: #333;
line-height: 42px;
}
.right-box {
width: 301px;
height: 480px;
border: 1px solid #DCDCDC;
border-radius: 4px;
overflow: hidden;
overflow-y: scroll;
padding: 12px 0px;
&::-webkit-scrollbar { /*滚动条整体样式*/
width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
background-color: transparent;
}
&::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
border-radius: 2px;
border: 5px solid #A9AAB1;
box-shadow: 5px 0 0 #A9AAB1 inset;
}
&::-webkit-scrollbar-thumb:hover {
box-shadow: 5px 0 0 #A9AAB1 inset;
}
.box-title-bar {
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
color: #AEAEAE;
line-height: 14px;
padding:0 5px,
}
.box-item-list {
padding: 8px 0;
}
.item-cont {
font-size: 14px;
font-family: PingFang SC;
font-weight: 400;
color: #333;
line-height: 14px;
padding: 10px 12px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
&:hover, &.is-active {
background: #3277FF;
color: #fff;
}
.el-button {
padding: 0;
color: #fff;
}
}
}
.right-item-por {
position: absolute;
left: -280px;
height: 480px;
width: 300px;
overflow: hidden;
overflow-y: scroll;
padding: 10px 20px;
background: #fff;
border: 1px solid #DCDCDC;
top: 41px;
border-radius: 4px;
font-size: 12px;
color: #333;
line-height: 30px;
&::-webkit-scrollbar { /*滚动条整体样式*/
width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
background-color: transparent;
}
&::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
border-radius: 2px;
border: 5px solid #A9AAB1;
box-shadow: 5px 0 0 #A9AAB1 inset;
}
&::-webkit-scrollbar-thumb:hover {
box-shadow: 5px 0 0 #A9AAB1 inset;
}
.title {
font-size: 16px;
color: #333;
line-height: 30px;
}
}
}
}
</style>
在父组件中引入configFormulaSalary
<!-- 配置 -->
<configFormulaSalary :isConfigFormula="isConfigFormula" :drapList="drapList" :info="formulaSalaryInfo"
@onClose="onConfigFormulaClose" @onSubmitEdit="onConfigFormulaGroup" v-if="isConfigFormula"
:fieldGroupList="fieldGroupList"></configFormulaSalary>
<script>
import configFormulaSalary from './components/configFormulaSalary.vue'
export default {
name: 'App',
components: {
HelloWorld,
configFormulaSalary
},
data () {
return {
isConfigFormula:false,
classmodel: false,
drapList:[],
formulaSalaryInfo:{},
fieldGroupList: []
}
},
methods: {
// 关闭配置弹框
onConfigFormulaClose(){
this.isConfigFormula = false
},
// 打开配置弹框
onConfigFormulaGroup(e){
this.isConfigFormula = true
},
}
}
</script>