vue elementUI Plus实现拖拽流程图,不引入插件,纯手写实现。
1.设计思路:
左侧button列表是要拖拽的组件。中间是拖拽后的流程图。右侧是拖拽后的数据列表。
我们拖动左侧组件放入中间的流程图中,并把button携带的数据信息带过来。
2.设计细节
左侧button组件列表可拖动并携带信息,当拖动到中间流程图上方时,流程图网格变色。当鼠标释放后,数据传递,流程图变化。
拖拽事件流程和参数
dragstart:当元素开始被拖拽时触发。
drag:元素正在被拖拽时持续触发(某些浏览器支持)。
dragend:当拖拽结束时触发。
dragenter:当拖拽的元素进入目标元素时触发。
dragover:当拖拽的元素在目标元素上移动时持续触发。
dragleave:当拖拽的元素离开目标元素时触发。
drop:当拖拽的元素在目标元素上释放时触发。
3.详细代码实现
html
<template>
<div class="scriptDraweAdd">
<drawer-Box
:drawerVisible="drawer.visible"
:drawerFooter="drawer.drawerFooter"
:direction="drawer.direction"
:drawerSize="drawer.drawerSize"
:drawerTitle="drawer.drawerTitle"
@handleDrawerOpened="handleDrawerOpened"
@handleDrawerClose="handleDrawerClose"
@handleDrawerSubmit="handleDrawerSubmit"
>
<div class="main h100">
<el-form ref="addFormRef" :model="editFrom" size="small" status-icon class="h100" label-width="auto">
<el-row :gutter="0">
<el-col>
<el-row :gutter="10">
<el-col :span="4" class="mb20 setting-title"><span>General settings</span></el-col>
<el-col :span="10" class="mb20">
<el-form-item prop="projectName" :rules="rules.projectName">
<template v-slot:label
><span>Project Name </span>
<el-tooltip effect="dark" content="Project Name" placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-input v-model="editFrom.projectName" placeholder="Project Name" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="10" class="mb20">
<el-form-item prop="version" :rules="rules.version">
<template v-slot:label
><span>Version </span>
<el-tooltip effect="dark" content="Software Version" placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-input v-model="editFrom.version" placeholder="Software Version" clearable></el-input>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col>
<el-row :gutter="10">
<el-col :span="4" class="mb20"><span></span></el-col>
<!-- <el-col :span="10" class="mb20">
<el-form-item prop="softwareName" :rules="rules.softwareName">
<template v-slot:label
><span>Software Name </span>
<el-tooltip effect="dark" content="Software Name" placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-input v-model="editFrom.softwareName" placeholder="Software Name" clearable></el-input>
</el-form-item>
</el-col> -->
<el-col :span="10" class="mb20">
<el-form-item prop="function" :rules="rules.function">
<template v-slot:label
><span>Function </span>
<el-tooltip effect="dark" content="Function of the script" placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-select v-model="editFrom.function" placeholder="Function">
<el-option v-for="item in functionOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col>
<el-row :gutter="10">
<el-col :span="4" class="mb20 setting-title"><span>Advanced settings</span></el-col>
<el-col :span="10" class="mb20">
<el-form-item label="" prop="maxRunTime" :rules="rules.maxRunTime">
<template v-slot:label
><span>Max Run Time </span>
<el-tooltip effect="dark" content="The max run time of the script" placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-input-number type="number" v-model="editFrom.maxRunTime" :min="0" :max="1000" placeholder="Max Run Time" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="10" class="mb20">
<el-form-item prop="startStopService" :rules="rules.startStopService">
<template v-slot:label
><span>Start Stop Service </span>
<el-tooltip effect="dark" content="Service(s) needed to be pause during software installation, separate with commas." placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-input v-model="editFrom.startStopService" placeholder="Start Stop Service" clearable></el-input>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col>
<el-row :gutter="10">
<el-col :span="4" class="mb20"><span></span></el-col>
<el-col :span="10" class="mb20">
<el-form-item prop="debugEnable" :rules="rules.debugEnable">
<template v-slot:label
><span>Debug Enable </span>
<el-tooltip effect="dark" content="Used to enable logging." placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-switch v-model="editFrom.debugEnable" :active-value="true" :inactive-value="false" />
</el-form-item>
</el-col>
<el-col :span="10" class="mb20">
<el-form-item prop="defaultMsicLine" :rules="rules.defaultMsicLine">
<template v-slot:label
><span>Default MSIC Line </span>
<el-tooltip effect="dark" content="Default MSI commands, used for each MSI installer." placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-input v-model="editFrom.defaultMsicLine" placeholder="Default MSIC Line" clearable></el-input>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col>
<el-row :gutter="10">
<el-col :span="4" class="mb20"><span></span></el-col>
<el-col :span="10" class="mb20">
<el-form-item prop="uDriveMap" :rules="rules.uDriveMap">
<template v-slot:label
><span>U-Drive Map </span>
<el-tooltip effect="dark" content="If the software stored on U-Drive." placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-switch v-model="editFrom.uDriveMap" :active-value="true" :inactive-value="false" />
</el-form-item>
</el-col>
<el-col :span="10" class="mb20">
<el-form-item label="IFS Script" prop="ifsScript" :rules="rules.ifsScript">
<template v-slot:label
><span>IFS Script </span>
<el-tooltip effect="dark" content="If you need to run the script on your local computer." placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-switch v-model="editFrom.ifsScript" :active-value="true" :inactive-value="false" />
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col>
<el-row :gutter="10">
<el-col :span="4" class="mb20"><span></span></el-col>
<!-- <el-col :span="10" class="mb20">
<el-form-item prop="patchCommands">
<template v-slot:label
><span>Patch Commands </span>
<el-tooltip effect="dark" content="Used if need to install software to alternate folder." placement="top">
<i>
<svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" />
</i>
</el-tooltip>
</template>
<el-input v-model="editFrom.patchCommands" placeholder="Patch Commands" disabled></el-input>
</el-form-item>
</el-col> -->
<el-col :span="10" class="mb20">
<el-form-item label="Remarks" prop="remarks" :rules="rules.remarks">
<el-input v-model="editFrom.remarks" clearable placeholder="Remarks" :rows="2" type="textarea" />
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col>
<el-row :gutter="10" class="custom-row-height">
<el-col :span="8" class="mb20">
<div class="searchdiv">
<div style="display: flex">
<el-input style="margin-right: 10px" v-model="searchScriptName" placeholder="Script Name" @keyup.enter="getScriptList()" clearable></el-input>
<el-button @click="getScriptList()" type="primary">
<i> <svg-icon icon-class="icon_screen" class-name="iconfont font14" /> </i
></el-button>
</div>
<div class="paramslabel">
<el-tooltip v-for="(item, index) in scriptList" :key="index" placement="top" raw-content :content="remarkHTML(item.remarks)">
<el-button draggable="true" @dragstart="dragstart($event, item)" @dragend="dragend($event, item)" class="buttondiv" :title="item.scriptName" type="primary">{{
item.scriptName
}}</el-button>
</el-tooltip>
</div>
</div>
</el-col>
<el-col :span="9" class="mb20">
<div class="flowdiv">
<div class="flowlabel">
<div>
<el-button class="buttondiv" type="primary">Start</el-button>
<div :class="['add-contain-div', overFlag.over0 ? 'add-contain-div-active' : '']" @dragover="dragOver($event, 'over0')" @drop="drop($event, 0)">
<svg-icon icon-class="downward_vertical_line" class="addline" />
<svg-icon icon-class="icon_add" class="addicon" />
</div>
</div>
<div v-for="(item, index) in editFrom.scriptList" :key="index" style="padding-left: 60px">
<!-- <el-button v-show="true" class="buttondiv2" type="primary">{{ item.gClientScriptId }}</el-button> -->
<el-input style="width: 180px" v-show="false" v-model="item.gClientScriptId" placeholder="gClientScriptId" readonly></el-input>
<el-tooltip placement="top" raw-content :content="remarkHTML(item.remarks)">
<el-button class="buttondiv" type="primary">{{ item.scriptName }}</el-button>
</el-tooltip>
<el-button type="text" @click="deleteMethod(index)" class="deletebutton">
<svg-icon icon-class="icon_delete2" class="deleteline" />
</el-button>
<div style="padding-right: 60px" @dragover="dragOver($event, 'over' + (index + 1))" @drop="drop($event, index + 1)">
<div :class="['add-contain-div', overFlag['over' + (index + 1)] ? 'add-contain-div-active' : '']">
<svg-icon icon-class="downward_vertical_line" class="addline" />
<svg-icon icon-class="icon_add" class="addicon" />
</div>
</div>
</div>
<el-button class="buttondiv" type="primary">End</el-button>
</div>
</div>
</el-col>
<el-col :span="7" class="mb20" style="min-width:350px">
<div v-for="(item2, index2) in editFrom.scriptList" :key="index2 + 'params'">
<div class="paramsdiv">
<div class="params-title-parent">
<el-form-item
><span style="margin-left: 10px; font-weight: bold">{{ item2.scriptName }}</span></el-form-item
>
</div>
<div class="paramsdiv-content">
<el-form-item label-width="auto" label="Order No."> <el-input style="width: 100%" v-model="item2.orderNum" placeholder="Order No." readonly></el-input></el-form-item>
<el-form-item label="CmdRCOpt" label-width="auto" :prop="`scriptList[${index2}].cmdRcopt`" :rules="[{ required: true, message: `Please input CmdRCOpt`, trigger: 'change' }]">
<el-select v-model="item2.cmdRcopt" placeholder="CmdRCOpt" disabled style="width: 100%">
<el-option v-for="item3 in cmdRCOptOptions" :key="item3.value" :label="item3.label" :value="item3.value" />
</el-select>
</el-form-item>
<div v-for="(item, index) in item2.paramslist" :key="index2 + '_' + index">
<el-form-item v-show="false" label="Order No." label-width="140px">
<el-input style="width: 100%" v-model="item.index" placeholder="Order No." readonly></el-input>
</el-form-item>
<div v-if="item.dataType === 'String'" class="paramsdiv-params">
<el-form-item
:prop="`scriptList[${index2}].paramslist[${index}].value`"
:rules="[{ required: true, message: `Please input ${item.name}`, trigger: 'blur' }]"
label-width="auto"
>
<template v-slot:label
><span>{{ item.name }}</span>
<el-tooltip effect="dark" :content="item.remarks" placement="top">
<i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i>
</el-tooltip>
<el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag>
</template>
<el-input style="width: 100%" v-model="item.value" :placeholder="item.name"></el-input>
</el-form-item>
</div>
<div v-if="item.dataType === 'Int'" class="paramsdiv-params">
<el-form-item
:prop="`scriptList[${index2}].paramslist[${index}].value`"
:rules="[{ required: true, message: `Please input ${item.name}`, trigger: 'change' }]"
label-width="auto"
>
<template v-slot:label
><span>{{ item.name }}</span>
<el-tooltip effect="dark" :content="item.remarks" placement="top">
<i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i>
</el-tooltip>
<el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag>
</template>
<!-- <el-input style="width: 100%" v-model="item.value" :placeholder="item.name"></el-input> -->
<el-input-number type="number" v-model="item.value" :placeholder="item.name" style="width: 100%" />
</el-form-item>
</div>
<div v-if="item.dataType === 'Boolean'" class="paramsdiv-params">
<el-form-item
:prop="`scriptList[${index2}].paramslist[${index}].value`"
:rules="[{ required: true, message: `Please input ${item.name}`, trigger: 'change' }]"
label-width="auto"
>
<template v-slot:label
><span>{{ item.name }}</span>
<el-tooltip effect="dark" :content="item.remarks" placement="top">
<i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i>
</el-tooltip>
<el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag>
</template>
<el-switch v-model="item.value" :active-value="true" :inactive-value="false" :value="false" :disabled="index === 0" />
</el-form-item>
</div>
<div v-if="item.dataType === 'File'" class="paramsdiv-params">
<el-form-item
:label="item.name"
:placeholder="item.name"
:prop="`scriptList[${index2}].paramslist[${index}].fileList`"
:rules="[{ required: true, message: `Please upload file`, validator: validator, trigger: 'change' }]"
label-width="auto"
>
<template v-slot:label
><span>{{ item.name }}</span>
<el-tooltip effect="dark" :content="item.remarks" placement="top">
<i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i>
</el-tooltip>
<el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag>
</template>
<el-upload
:disabled="item.isOriginalFile === 1"
:action="upload.action"
:headers="upload.headers"
:limit="upload.limit"
multiple
v-model:file-list="item.fileList"
:on-success="(res) => handleUploadSuccess(res, item, index)"
:on-remove="(uploadFile, uploadFiles) => handleRemove(uploadFile, uploadFiles, item, index)"
:before-upload="(file) => beforeAvatarUpload(file, item, index)"
:on-exceed="(uploadFile, uploadFiles) => handleExceed(uploadFile, uploadFiles, item, index)"
:on-preview="(uploadFile) => handlePreview(uploadFile, item, index)"
>
<el-button :disabled="item.fileList && item.fileList.length > 0" type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">.ps1, .txt files with a size less than 2M</div>
</template>
</el-upload>
</el-form-item>
<el-form-item v-show="false" label="File Name" label-width="140px">
<el-input style="width: 80%" v-model="item.fileName" placeholder="File Name" readonly></el-input>
</el-form-item>
<el-form-item :prop="`scriptList[${index2}].paramslist[${index}].fileContent`" label-width="140px" style="margin-top: -20px">
<el-input
v-show="false"
type="textarea"
readonly
style="width: 100%"
v-model="item.fileContent"
placeholder="File Content"
:autosize="{ minRows: 3, maxRows: 10000 }"
></el-input>
</el-form-item>
</div>
</div>
</div>
</div>
</div>
</el-col>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</drawer-Box>
</div>
</template>
<script>
import { toRefs, reactive, onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import DrawerBox from '../drawer/index'
import gClientApi from '@/api/gClientApi'
import gClientManagementApi from '@/api/gClientManagementApi'
import { removeProperty } from '@/utils/validate'
import { Session } from '@/utils/storage'
export default {
name: 'GclientScriptMenagement',
emits: ['handleSearch', 'handleClose', 'downScriptFile'],
components: {
DrawerBox
// vxeTable
},
props: {
drawer: {
type: Object,
default: () => {
return {}
}
},
GclientScriptMenagement: {
type: Object,
default: () => {
return {}
}
}
},
setup(props, ctx) {
// 列表数组 接口返回的数据
const vxeData = reactive({
tableList: []
})
const addFormRef = ref(null)
// 复选框数组
const vxeList = reactive({
checkList: []
})
const useTableHeader = reactive({})
const state = reactive({
upload: {
action: process.env.VUE_APP_API_URL + '/portal/v1/GClientScript/scriptUpload',
headers: {
Authorization: Session.get('token')
},
accept: '.ps1, .txt',
fileSize: 2,
limit: 1
},
functionOptions: [
{ lable: 'Install', value: 'Install' },
{ lable: 'Uninstall', value: 'Uninstall' }
],
typeOptions: [
{ label: 'String', value: 'String' },
{ label: 'Int', value: 'Int' },
{ label: 'Boolean', value: 'Boolean' },
{ label: 'File', value: 'File' }
],
cmdRCOptOptions: [
{ label: 'Continue running', value: 0 },
{ label: 'Command failed,stop running', value: 1 },
{ label: 'Command failed,continue running', value: 2 }
],
editFrom: {
softwareName: '',
version: '',
projectName: '',
// applicationName: '',
patchCommands: '',
maxRunTime: 90,
startStopService: '',
debugEnable: true,
defaultMsicLine: '',
uDriveMap: false,
function: 'Install',
ifsScript: false,
remarks: '',
scriptList: []
},
editFrom2: {
softwareName: '',
version: '',
projectName: '',
// applicationName: '',
patchCommands: '',
maxRunTime: 90,
startStopService: '',
debugEnable: true,
defaultMsicLine: '',
uDriveMap: false,
function: 'Install',
ifsScript: false,
remarks: '',
scriptList: []
},
scriptList: [],
rules: {
softwareName: [{ required: true, message: 'Please input Software Name', trigger: 'blur' }],
version: [{ required: true, message: 'Please input Version', trigger: 'blur' }],
projectName: [{ required: true, message: 'Please input Project Name', trigger: 'blur' }],
// applicationName: [{ required: true, message: 'Please input Application Name', trigger: 'blur' }],
patchCommands: [{ required: true, message: 'Please input Patch Commands', trigger: 'blur' }],
maxRunTime: [{ required: true, message: 'Please input Max Run Time', trigger: 'blur' }],
startStopService: [{ required: true, message: 'Please input Start Stop Service', trigger: 'blur' }],
debugEnable: [{ required: true, message: 'Please input Debug Enable', trigger: 'blur' }],
defaultMsicLine: [{ required: true, message: 'Please input Default MSIC Line', trigger: 'blur' }],
uDriveMap: [{ required: true, message: 'Please input U-Drive Map', trigger: 'blur' }],
function: [{ required: true, message: 'Please input Function', trigger: 'blur' }],
ifsScript: [{ required: true, message: 'Please input IFS Script', trigger: 'blur' }]
},
paramsIndex: 1,
searchScriptName: '',
overFlag: {}
})
const getParamsName = (index) => {
return `Param Name ${index + 1}`
}
const getParamsRules = (name) => {
let msg = `Please input ${name}`
let tips = [{ required: true, message: msg, trigger: 'blur' }]
return tips
}
const validator = (rule, value, callback) => {
if (value && value.length > 0) {
callback() // 表示验证通过
} else {
callback(new Error('length>0'))
}
}
const deleteMethod = (index) => {
const newArray = state.editFrom.scriptList.filter((element, index2) => index2 !== index)
state.editFrom.scriptList = newArray
state.editFrom.scriptList.forEach((val, index) => {
val.orderNum = index + 1
})
}
const SubmitList = (checkData) => {
vxeList.checkList = checkData
}
// 数据提交
const handleDrawerSubmit = async () => {
addFormRef.value.validate(async (valid) => {
if (valid) {
const data = { ...state.editFrom }
console.log(data)
const res = await gClientManagementApi.add(data)
if (res.code === 200) {
resetForm(addFormRef.value)
handleDrawerClose()
ctx.emit('handleSearch')
ElMessage({
showClose: true,
message: res.message,
type: 'success'
})
} else {
ElMessage({
showClose: true,
message: res.message,
type: 'error'
})
}
} else {
console.log('error submit!')
return false
}
})
}
// Drawer 打开时触发
const handleDrawerOpened = () => {
getScriptList()
}
// Drawer 关闭
const handleDrawerClose = () => {
state.editFrom = JSON.parse(JSON.stringify(state.editFrom2))
ctx.emit('handleClose', 'Add')
}
const dragstart = (event, item) => {
// console.log(event, item)
// 使用 dataTransfer 对象传递JSON数据作为文本
event.dataTransfer.setData('text/plain', JSON.stringify(item))
}
const dragend = (event, item) => {
state.overFlag = {}
}
const dragOver = (event, name) => {
// 阻止浏览器默认操作,允许drop事件发生
event.preventDefault()
state.overFlag = {}
state.overFlag[name] = true
// console.log(state.overFlag)
}
const drop = (event, index) => {
// 阻止浏览器默认操作
event.preventDefault()
// 获取传递的JSON数据
const jsonData = event.dataTransfer.getData('text/plain')
// 解析JSON数据
const data = JSON.parse(jsonData)
state.overFlag = {}
state.editFrom.scriptList.splice(index, 0, data)
state.editFrom.scriptList = JSON.parse(JSON.stringify(state.editFrom.scriptList))
state.editFrom.scriptList.forEach((val, index) => {
val.orderNum = index + 1
})
console.log('get', state.editFrom.scriptList)
}
// 表单 Reset
const resetForm = (formEl) => {
if (!formEl) return
formEl.resetFields()
state.editFrom = JSON.parse(JSON.stringify(state.editFrom2))
}
const handleBlur = () => {
// console.log('1111', state.editFrom.scriptList)
}
const getScriptList = async () => {
// console.log(columns.value)
// console.log(exportColumns.value)
// 条件检索
const query = removeProperty(JSON.parse(JSON.stringify({ scriptName: state.searchScriptName })))
console.log(query)
const res = await gClientApi.getDownLoadData({ ...query })
if (res.code === 200) {
const _arr = res.data.map((item) => {
let paramslist = []
if (item.paramsNameList && item.paramsNameList.length > 0) {
item.paramsNameList.map((element) => {
if (null !== element.value && undefined !== element.value && '' !== element.value) {
paramslist.push({ ...element })
} else {
paramslist.push({ ...element, value: '', fileList: [], fileName: '', fileContent: '' })
}
})
}
item.paramslist = paramslist
item.gClientScriptId = item.id
let _item = { ...item }
return _item
})
state.scriptList = JSON.parse(JSON.stringify(_arr))
// ElMessage({
// message: res.message,
// type: 'success'
// })
} else {
ElMessage({
message: res.message,
type: 'error'
})
}
}
// 上传图片验证
const beforeAvatarUpload = (file, item, index) => {
// 校检文件类型
if (state.upload.accept) {
// 文件后缀名
let fileExtension = ''
if (file.name.lastIndexOf('.') > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
}
const isTypeOk = state.upload.accept.indexOf(fileExtension) > -1
if (!isTypeOk) {
ElMessage({
showClose: true,
message: `The file format is incorrect. Please upload the file in ${state.upload.accept} format!`,
type: 'error'
})
return false
}
}
// 校检文件大小
if (state.upload.fileSize) {
const isLt = file.size / 1024 / 1024 < state.upload.fileSize
if (!isLt) {
ElMessage({
showClose: true,
message: `The uploaded file size cannot exceed ${state.upload.fileSize} MB!`,
type: 'error'
})
return false
}
}
return true
}
// 文件个数超出
const handleExceed = (files, uploadFiles, item, index) => {
ElMessage({
showClose: true,
message: `The number of uploaded files cannot exceed ${state.upload.limit} !`,
type: 'error'
})
}
// 文件上传成功时的钩子
const handleUploadSuccess = (res, item, index) => {
switch (res.code) {
case 200:
item.fileContent = res.data.fileContent
item.fileName = res.data.fileName
item.value = res.data.fileName
// ruleForm.systemScreenshot = res.data.filePath
ElMessage({
showClose: true,
message: res.message,
type: 'success'
})
break
case 401:
Session.clear()
window.location.reload()
break
case 403:
Session.clear()
window.location.reload()
break
default:
ElMessage({
showClose: true,
message: res.message,
type: 'error'
})
}
}
// 文件列表移除文件时的钩子
const handleRemove = (uploadFile, uploadFiles, item, index) => {
item.fileList = []
item.fileContent = ''
item.fileName = ''
item.value = ''
}
// 点击文件列表中已上传的文件时的钩子
const handlePreview = (uploadFile, item, index) => {
// ctx.emit('downScriptFile', item)
}
const handleChange = (value, item) => {
console.log(value, item)
}
const fileChange = (name, item) => {
addFormRef.value.validateField(name, (val) => {
if (!val) {
return true
} else {
return false
}
})
}
const remarkHTML = (remark) => {
// return remark.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
if (remark) {
return remark.replace(/\n|\r\n/g, '<br/>').replace(/ /g, ' ')
}
return ''
}
onMounted(() => {})
return {
...toRefs(state),
...toRefs(vxeData),
...toRefs(vxeList),
...toRefs(useTableHeader),
addFormRef,
handleDrawerOpened,
handleDrawerClose,
handleDrawerSubmit,
SubmitList,
getParamsName,
getParamsRules,
deleteMethod,
resetForm,
getScriptList,
dragstart,
dragOver,
drop,
dragend,
handleBlur,
validator,
beforeAvatarUpload,
handleExceed,
handleUploadSuccess,
handleRemove,
handleChange,
handlePreview,
fileChange,
remarkHTML
}
}
}
</script>
<style lang="scss">
.scriptDraweAdd {
// .setting-title {
// font-size: var(--el-form-label-font-size);
// color: var(--el-text-color-regular);
// height: 32px;
// line-height: 32px;
// padding: 0 12px 0 0;
// box-sizing: border-box;
// font-weight: bold;
// }
.drawer_title {
font-weight: bold;
margin-bottom: 16px;
}
.name-parent {
display: flex;
.title {
font-weight: bold;
width: 5px;
height: 30px;
margin-right: 5px;
background-color: var(--color-primary) !important;
}
.blank {
font-weight: bold;
width: 5px;
height: 30px;
margin-right: 5px;
}
.label {
flex: 1;
}
}
.title {
font-weight: bold;
width: 5px;
height: 30px;
margin-right: 5px;
background-color: var(--color-primary) !important;
}
.no-label .el-form-item__label {
display: none;
}
.custom-row-height {
/* 使用calc()函数从100vh中减去100px */
// height: calc(100vh - 600px);
min-height: 400px;
.searchdiv {
flex: 1;
height: 100%;
padding: 5px;
border-radius: 4px;
border: 1px solid #cccccc;
box-sizing: border-box;
.paramslabel {
margin-top: 10px;
display: flex; /* 启用Flexbox布局 */
flex-direction: column; /* 子元素纵向排列 */
justify-content: center; /* 子元素在父容器内水平居中(纵向上的居中) */
align-items: center; /* 子元素在父容器内水平居中(横向上的居中) */
.buttondiv {
width: 60%;
// min-width: 290px;
max-width: 300px;
height: 30px;
margin: 7px;
color: var(--color-primary) !important;
background-color: #fff;
border: 2px solid var(--color-primary);
}
}
}
.flowdiv {
min-width: 500px;
flex: 1;
height: 100%;
padding: 5px;
border-radius: 4px;
border: 1px solid #cccccc;
box-sizing: border-box;
.deletebutton {
width: 48px;
height: 32px;
color: #606266 !important;
.deleteline {
width: 40px;
height: 32px;
color: #606266 !important;
}
}
.flowlabel {
margin-top: 10px;
display: flex; /* 启用Flexbox布局 */
flex-direction: column; /* 子元素纵向排列 */
justify-content: center; /* 子元素在父容器内水平居中(纵向上的居中) */
align-items: center; /* 子元素在父容器内水平居中(横向上的居中) */
.add-contain-div {
margin: -5px 5px -5px 5px;
height: 60px;
// background-color: var(--color-primary) !important;
position: relative;
.addline {
position: absolute;
width: 100%;
height: 100%;
color: #606266;
}
.addicon {
position: absolute;
width: 40%;
height: 40%;
color: #606266;
margin-left: 130px;
margin-top: 17px;
}
}
.add-contain-div-active {
border: 1px dashed var(--color-primary);
}
.buttondiv {
width: 300px;
height: 30px;
margin: 5px;
color: var(--color-primary) !important;
background-color: #fff;
border: 2px solid var(--color-primary);
}
.buttondiv2 {
width: 250px;
height: 30px;
margin: 5px;
color: var(--color-primary) !important;
background-color: #fff;
border: 2px solid var(--color-primary);
&:hover {
border: 2px solid var(--el-color-primary);
background-color: var(--el-color-primary) !important;
color: #fff !important;
}
&:active,
&:focus {
background-color: var(--color-primary) !important;
color: #fff !important;
}
}
// .deletediv{
// float:right;
// right:0px;
// width:auto;
// }
}
}
}
.paramsdiv {
min-width: 500px;
flex: 1 1 0%;
height: 100%;
border-radius: 2px;
border: 1px solid #cccccc;
box-sizing: border-box;
margin-left: 0px;
padding-bottom: 25px;
margin-bottom: 20px;
margin-right: 0px;
.paramsdiv-content {
padding: 5px;
.paramsdiv-params {
margin-bottom: 30px;
}
}
.params-title-parent {
padding: 5px 5px 5px 5px;
display: flex;
justify-content: space-between;
/* 如果需要,可以添加以下样式以确保父 div 占据整个宽度 */
width: 100%;
border-bottom: 1px solid rgb(230, 230, 230);
background-color: #fbfbfb;
margin-bottom: 20px;
.child {
/* 你可以根据需要添加子 div 的样式 */
}
.left {
/* 你可以在这里添加左边子 div 的特定样式 */
}
.right {
/* 你可以在这里添加右边子 div 的特定样式 */
}
}
}
}
</style>