| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- <template>
- <el-container class="event-script-container">
- <el-aside width="300px" class="event-script-aside">
- <el-container>
- <el-header height="40px">
- <el-button type="text" size="small" icon="el-icon-plus" @click="handleAdd">{{$t('fm.eventscript.config.add')}}</el-button>
- </el-header>
- <el-main>
- <el-scrollbar style="height: 100%;">
- <el-menu class="event-script-aside-menu" :default-active="selectKey" @select="handleSelect">
- <el-menu-item :index="item.key" v-for="(item, index) in list" :key="item.key" :disabled="!saved || !isFormChange()" @click.native="handleSelect(item.key)">
- <div slot="title">
- <span class="event-script-menu-i" :class="{'is-vis': item.type == 'rule'}">{{item.type == 'rule' ? 'VIS' : 'JS'}}</span>
- <div class="event-script-menu-label">{{item.name}}</div>
- <div class="event-script-menu-action" >
- <i v-if="!readonlyFunctions.includes(item.name)" class="fm-iconfont icon-icon_clone" @click.stop="handleClone(index)" :title="$t('fm.tooltip.clone')"></i>
- <i v-if="!readonlyFunctions.includes(item.name)" class="fm-iconfont icon-trash" @click.stop="handleRemove(index)" :title="$t('fm.tooltip.trash')"></i>
- </div>
- </div>
- </el-menu-item>
- </el-menu>
- </el-scrollbar>
- </el-main>
- </el-container>
- </el-aside>
- <el-main class="event-script-main">
- <el-container v-if="selectIndex >= 0">
- <el-header height="40px">
- <div class="event-script-action">
- <el-button type="primary" size="mini" @click="handleSave(true)" v-if="this.eventType">{{$t('fm.eventscript.config.confirm')}}</el-button>
- <el-button type="primary" size="mini" @click="handleSave(false)">{{$t('fm.eventscript.config.save')}}</el-button>
- <el-button size="mini" @click="handleCancal">{{$t('fm.eventscript.config.cancel')}}</el-button>
- </div>
- </el-header>
- <el-main>
- <el-form ref="dataForm" :model="formData" :rules="formRules" :label-width="'120px'" size="small" label-position="left" :key="selectKey" @submit.native.prevent>
- <el-form-item :label="$t('fm.eventscript.config.name')" :label-width="$i18n.locale == 'zh-CN' ? '80px' : '125px'" prop="name">
- <el-input v-model="formData.name" :disabled="readonlyFunctions.includes(formData.name)"></el-input>
- </el-form-item>
- <el-form-item label-width="0" v-if="formData.type">
- <el-radio-group v-model="formData.type">
- <el-radio-button label="rule">{{$t('fm.eventscript.config.rules')}}</el-radio-button>
- <el-radio-button label="js">{{$t('fm.eventscript.config.js')}}</el-radio-button>
- </el-radio-group>
- </el-form-item>
- <el-form-item label-width="0" prop="func" style="margin-bottom: 0px;" v-if="!formData.type || formData.type == 'js'">
- <div class="code-line">Function () {</div>
-
- <code-editor v-model="formData.func" mode="javascript" :height="formData.type ? '350px' : '400px'"></code-editor>
- <div class="code-line">}</div>
- </el-form-item>
- <template v-if="formData.type == 'rule'">
- <event-rule v-model="formData.rules"></event-rule>
- </template>
- </el-form>
- </el-main>
- </el-container>
- </el-main>
- </el-container>
- </template>
- <script>
- import ArrayDynamic from '../DataSource/arrayDynamic'
- import CodeEditor from '../CodeEditor'
- import axios from 'axios'
- import request from '../../util/request'
- import { Message, MessageBox } from 'element-ui'
- import EventRule from './rule.vue'
- import _ from 'lodash'
- import { ruleToFunction } from '../../util/rule-funcs.js'
- export default {
- components: {
- ArrayDynamic,
- CodeEditor,
- EventRule
- },
- props: {
- value: {
- type: Array,
- default: () => []
- }
- },
- data () {
- return {
- formData: {
- key: '',
- name: '',
- func: '',
- type: 'rule'
- },
- tmpData: {},
- formRules: {
- name: [
- {required: true, message: ' '},
- { validator: (rule, value, callback) => {
- let currentItem = this.historyList.find(item => item.name ==value)
- if (currentItem && currentItem.key != this.selectKey) {
- callback(new Error(this.$t('fm.eventscript.message.repeat')))
- } else {
- callback()
- }
- }}
- ]
- },
- list: [...this.value],
- selectIndex: -1,
- selectKey: '',
- historyList: [...this.value],
- saved: true,
- eventType: '',
- readonlyFunctions: ['mounted', 'refresh', 'onFormChange']
- }
- },
- provide () {
- return {
- 'getEventsArray': this.getEventsArray
- }
- },
- methods: {
- handleSave (confirm) {
- this.$refs.dataForm.validate((valid) => {
- if (valid) {
- try {
- if (this.formData.type === 'rule') {
- new Function(`return (async () => {${ruleToFunction(this.formData.rules)}})()`)
- } else {
- new Function(this.formData.func)
- }
- this.$set(this.list, this.list.findIndex(item => item.key === this.selectKey), this.formData)
- this.historyList = [...this.list]
- this.saved = true
- this.tmpData = _.cloneDeep(this.formData)
- this.$emit('input', this.historyList)
- if (confirm) {
- this.$emit('on-confirm-event', {...this.formData, type: this.eventType})
- } else {
- Message.success(this.$t('fm.eventscript.message.saveSuccess'))
- }
- } catch (error) {
- Message.error(this.$t('fm.message.eventSaveError') + error.message)
- }
- }
- })
- },
- handleAdd () {
- if (!this.saved || !this.isFormChange()) {
- Message.warning(this.$t('fm.eventscript.message.saveError'))
- return;
- }
- let key = Math.random().toString(36).slice(-8)
- this.list.push({
- key: key,
- name: 'func_'+key,
- func: '',
- type: 'rule'
- })
- this.selectKey = key
- this.saved = false
- },
- loadNewFunction (name) {
- let key = Math.random().toString(36).slice(-8)
- this.list.push({
- key: key,
- name: name + '_' + key,
- func: '',
- type: 'rule'
- })
- this.selectKey = key
- this.saved = false
- this.eventType = name
- },
- loadForm () {
- let currentData = this.list[this.selectIndex]
- this.formData = {
- ...currentData,
- type: currentData.type || 'js'
- }
- this.tmpData = _.cloneDeep(this.formData)
- },
- handleSelect (key) {
- if (key === this.selectKey) {
- return
- }
- if (!this.saved || !this.isFormChange()) {
- Message.warning(this.$t('fm.eventscript.message.saveError'))
- return;
- }
- this.selectKey = key
- },
- isFormChange () {
- if (this.selectKey && Object.keys(this.tmpData).length) {
- return _.isEqual(this.formData, this.tmpData)
- } else {
- return true
- }
- },
- loadFunction (key, name) {
- this.selectKey = key
- if (name) {
- this.eventType = name
- }
- },
- handleCancal () {
- this.selectKey = ''
- this.list = [...this.historyList]
- this.saved = true
- },
- handleClone (index) {
- if (!this.saved || !this.isFormChange()) {
- Message.warning(this.$t('fm.eventscript.message.saveError'))
- return;
- }
- let currentData = this.list[index]
- let key = Math.random().toString(36).slice(-8)
- let cloneData = {
- ...currentData,
- key,
- name: currentData.name + '_copy'
- }
- this.list.push(cloneData)
- this.selectKey = key
- this.saved = false
- },
- handleRemove (index) {
- let currentData = this.list[index]
- MessageBox.confirm(`${this.$t('fm.eventscript.message.confirmRemove')} [${currentData.name}] ?`, '', {
- type: 'warning'
- }).then(() => {
- if (currentData.key === this.selectKey) {
- this.selectKey = ''
- this.saved = true
- }
- this.list.splice(index, 1)
- if (index < this.historyList.length) {
- this.historyList.splice(index, 1)
- }
- this.$emit('input', this.historyList)
- }).catch(() => {})
- },
- getEventsArray () {
- return this.list.map(item => ({key: item.key, name: item.name, type: item.type})).filter(item => item.key != 'mounted' && item.key != 'refresh' && item.key != this.selectKey)
- }
- },
- watch: {
- selectKey (val) {
- if (val) {
- this.selectIndex = this.list.findIndex(item => item.key === val)
- if (this.selectIndex >= 0) {
- this.loadForm()
- }
- } else {
- this.selectIndex = -1
- }
- }
- }
- }
- </script>
- <style lang="scss">
- .event-script-container{
- .event-script-main{
- padding: 0;
- >.el-container{
- display: flex;
- height: 100%;
- >.el-header{
- padding: 5px;
- border-bottom: 1px solid #eee;
- background: #F2F6FC;
- }
- }
-
- .event-script-action{
- text-align: right;
- }
- .code-line{
- font-size: 14px;
- color: blue;
- font-weight: 500;
- }
- .code-desc{
- margin-left: 2px;
- font-size: 12px;
- color: #999;
- }
- .el-collapse-item{
- border: 1px solid #EBEEF5;
- }
- .el-collapse-item__header{
- background: #EBEEF5;
- // border: 0;
- height: 36px;
- line-height: 36px;
- padding: 5px;
- }
- .el-collapse-item__wrap{
- border: 0;
- .el-collapse-item__content{
- padding: 5px;
- }
- }
- }
- .event-script-aside{
- border-right: 1px solid #eee;
- >.el-container{
- display: flex;
- height: 100%;
- >.el-main{
- margin: 0;
- padding: 0;
- }
- >.el-header{
- padding: 5px;
- border-bottom: 1px solid #eee;
- background: #F2F6FC;
- }
- }
- .event-script-aside-menu{
- margin: 10px;
- border-right: 0;
- .el-menu-item{
- border: 1px solid #DCDFE6;
- background: #fff;
- border-radius: 3px;
- padding: 10px !important;
- height: auto;
- line-height: 1;
- cursor: default;
- position: relative;
- &.is-disabled{
- opacity: 1;
- cursor: default;
- background: #fff;
- }
- &.is-active{
- background: #E4E7ED;
- color: #303133;
- }
- &.is-active.is-disabled{
- background: #E4E7ED !important;
- color: #303133;
- }
- +.el-menu-item{
- margin-top: 6px;
- }
- }
- .event-script-menu-label{
- overflow:hidden;
- text-overflow:ellipsis;
- white-space:nowrap;
- display: inline-block;
- width: 190px;
- margin-left: 30px;
- }
- .event-script-menu-i{
- position: absolute;
- font-size: 12px;
- left: 5px;
- top: 13px;
- width: 30px;
- text-align: left;
- padding-left: 5px;
- color: #67C23A;
- font-style: italic;
- &.is-vis{
- color: #e6a23c;
- }
- }
- .event-script-menu-action{
- display: inline-block;
- padding-right: 10px;
- color: #666;
- font-weight: 600;
- >i{
- cursor: pointer;
- margin-left: 5px;
- }
- }
- }
- }
- }
- </style>
|