Commit 0510a583 by 高源

优化table

parent a0b8da4d
......@@ -17,7 +17,8 @@
</div>
<div style="width: 40%;display: flex; flex-direction: row;justify-content: flex-end;">
<el-button size="mini" style="width: 50px;height: 20px;margin-right: 5px;">导入任务</el-button>
<el-button size="mini" style="width: 50px;height: 20px;margin-right: 5px;" @click="exportJson">导出任务</el-button>
<el-button size="mini" style="width: 50px;height: 20px;margin-right: 5px;"
@click="exportJson">导出任务</el-button>
<el-button size="mini" style="width: 50px;height: 20px;margin-right: 15px;">保存任务</el-button>
</div>
</div>
......@@ -28,30 +29,40 @@
<span style="width: 63px;padding-left: 15px;font-size: 13px;">动作集合: </span>
<div class="scroll-container" @wheel="handleScroll" style="width: 325px;padding-left: 5px;">
<div class="scroll-content">
<span id="Breadcrumb" @click="onBreadcrumb(item)" v-for="item in currentActionsParents" :key="item.tagId" :style="{ color: item == currentAction ? '#68C23A!important' : '#409EFF' }">{{
<span id="Breadcrumb" @click="onBreadcrumb(item)" v-for="item in currentActionsParents"
:key="item.tagId"
:style="{ color: item == currentAction ? '#68C23A!important' : '#409EFF' }">{{
item.Name
}}></span>
</div>
</div>
</div>
<div style="width: 10%;margin-right: 15px;display:flex;align-items: center;justify-content: flex-end;">
<el-button :disabled="state" type="primary" size="mini" style="width: 20px;height: 20px;" @click="newAction" id="addButton">
<el-button :disabled="state" type="primary" size="mini" style="width: 20px;height: 20px;"
@click="newAction" id="addButton">
<img style="width: 12px;height: 12px;" src="./assets/add.svg" id="addImg">
</el-button>
</div>
</div>
<div style="display: flex;align-items: flex-start;justify-content: space-between;width: 460px;min-height: 36px;">
<div
style="display: flex;align-items: flex-start;justify-content: space-between;width: 460px;min-height: 36px;">
<!-- 动作标签 -->
<div style="margin-bottom: 5px;margin-right: 15px;white-space: wrap;display: flex;width: 100%;">
<draggable v-model="currentAction.actions" chosenClass="chosen" forceFallback="true" group="people" animation="1000" @start="onStart" @end="onEnd">
<draggable v-model="currentAction.actions" chosenClass="chosen" forceFallback="true" group="people"
animation="1000" @start="onStart" @end="onEnd">
<transition-group>
<el-tag class="boxtags" v-for="(action, index) in currentAction.actions" @click="selectTag(action)" :style="{ backgroundColor: action == activedAction ? '#68C23A!important' : '#409EFF' }" :key="action.tagId">
<el-tag class="boxtags" v-for="(action, index) in currentAction.actions"
@click="selectTag(action)"
:style="{ backgroundColor: action == activedAction ? '#68C23A!important' : '#409EFF' }"
:key="action.tagId">
<div style="display: flex;align-items: center;height: 25px;position: relative;">
<span style="min-width: 40px;display: flex;align-items: center;">
<div class="circle">{{ index + 1 }}</div>
<span style="margin-left: 2px;">{{ action.Name }}</span>
</span>
<img id="closeimg" @click="handleClose(action)" style="width: 17px;position: absolute;top: -6px;right: -16px;" src="./assets/close.svg">
<img id="closeimg" @click="handleClose(action)"
style="width: 17px;position: absolute;top: -6px;right: -16px;"
src="./assets/close.svg">
</div>
</el-tag>
</transition-group>
......@@ -61,28 +72,36 @@
<el-divider></el-divider>
<!-- 容器配置 -->
<div v-if="isShowAction">
<div style="height: 35px;width: 100%;display: flex;justify-content: space-between;align-items: center;border-bottom: 1px solid rgb(165 165 165);">
<div style="width: 50%;height: 100%;display: flex;align-items: center;">
<span style="width: 59px;padding-left: 15px;">动作名称:</span>
<div>
<el-input class="input-new-tag dongzuo" v-model="activedAction.Name" size="small" placeholder="请输入动作名称">
</el-input>
</div>
</div>
<div style="width: 50%;height: 100%;padding-left: 10px;display: flex;align-items: center;justify-content: flex-start;">
<div
style="height: 35px;width: 100%;display: flex;justify-content: space-between;align-items: center;border-bottom: 1px solid rgb(165 165 165);">
<div
style="width: 50%;height: 100%;padding-left: 15px;display: flex;align-items: center;justify-content: flex-start;">
<span style="width: 65px;">动作类型:</span>
<div>
<el-select id="eventType" name="eventType" v-model="activedAction.Alias" placeholder="请选择类型" @change="handleChange" @visible-change="handleVisibleChange" ref="mySelect" filterable remote>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
<el-select id="eventType" name="eventType" v-model="activedAction.Alias" placeholder="请选择类型"
@change="handleChange" @visible-change="handleVisibleChange" ref="mySelect" filterable
remote>
<el-option v-for="item in options" :key="item.value" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</div>
<div style="width: 50%;height: 100%;display: flex;align-items: center;">
<span style="width: 59px;">动作名称:</span>
<div>
<el-input class="input-new-tag dongzuo" v-model="activedAction.Name" size="small"
placeholder="请输入动作名称">
</el-input>
</div>
</div>
</div>
<div style="margin-left: 15px;margin-top: 10px;" v-if="activedAction.Alias == 'actions'">
<el-button style="width: 60px !important;height: 20px !important;" @click="toActions">进入容器</el-button>
</div>
<component :is="dynamicComponent" @dataChanged="handleDataChange" :activedAction="activedAction" :widthResize="widthResize" v-if="activedAction.Alias !== ''">
<component :is="dynamicComponent" @dataChanged="handleDataChange" :activedAction="activedAction"
:widthResize="widthResize" v-if="activedAction.Alias !== ''">
</component>
</div>
</div>
......@@ -580,7 +599,7 @@ export default {
}
.el-select .el-input__inner {
width: 145px !important;
width: 120px !important;
}
......@@ -679,5 +698,4 @@ export default {
/*选中样式*/
.chosen {
border: solid 2px #3089dc !important;
}
</style>
}</style>
......@@ -26,10 +26,10 @@
</div>
<!-- 全部表格信息 -->
<div style="overflow: auto;height: 230px;" :style="{ width: widthResize + 'px' }">
<vxe-table :data="SelectTableData" ref="xTableColumn" border class="mytable-scrollbar" height="220"
<vxe-table :data="selectTableData" ref="xTableColumn" border class="mytable-scrollbar" height="220"
v-if="isSelectTable" auto-resize style="margin-bottom: 5px;" @current-change="currentChangeEvent"
highlight-hover-row highlight-current-row>
<vxe-column field="" min-width="170">
<vxe-column field="" min-width="130">
<template #header>
<span style="font-size: 13px;">列名</span>
</template>
......@@ -39,7 +39,7 @@
</div>
</template>
</vxe-column>
<vxe-column field="" min-width="170">
<vxe-column field="" min-width="130">
<template #header>
<span style="font-size: 13px;">属性名</span>
</template>
......@@ -49,7 +49,7 @@
</div>
</template>
</vxe-column>
<vxe-column field="" min-width="170">
<vxe-column field="" min-width="130">
<template #header>
<span style="font-size: 13px;">值类型</span>
</template>
......@@ -70,7 +70,6 @@
<span style="font-size: 13px;">操作</span>
</template>
<template #default="{ row }">
<img style="width: 38px;height: 28px;vertical-align: bottom;cursor: pointer;"
src="../assets/close.svg" @click.stop="columnDelete(row)" v-if="row.xpath !== ''">
<template v-else>
......@@ -79,8 +78,6 @@
src="../assets/addTable.svg" @click.stop="selectElement">
</el-tooltip>
</template>
</template>
</vxe-column>
</vxe-table>
......@@ -105,7 +102,7 @@ export default {
selectTable: false,
tableColumn: [],
tableData: [],
SelectTableData: [],
selectTableData: [],
isSelectTable: true,
table: null,
contextMenuListenerAdded: false,
......@@ -115,40 +112,26 @@ export default {
}
},
created () {
const createEmptyCell = () => ({
name: '',
type: '',
typeOptions: [{ value: 'text', label: '文本' }],
xpath: ''
});
if (this.activedAction.table !== undefined) {
for (let i = 0; i < this.activedAction.table.cells.length; i++) {
let info = {};
info.type = this.activedAction.table.cells[i].type;
info.name = this.activedAction.table.cells[i].name;
info.title = this.activedAction.table.cells[i].title;
info.typeOptions = this.activedAction.table.cells[i].types;
info.xpath = this.activedAction.table.cells[i].xpath;
this.SelectTableData.push(info)
}
this.activedAction.table.cells.forEach(cell => {
const { type, name, title, types: typeOptions, xpath } = cell;
this.selectTableData.push({ type, name, title, typeOptions, xpath });
});
this.tableName = this.activedAction.table.name;
let obj = {}
obj.name = ''
obj.type = ''
obj.typeOptions = [
{ value: 'text', label: '文本' },
]
obj.xpath = ''
this.SelectTableData.push(obj)
this.selectTableData.push(createEmptyCell());
}
if (this.SelectTableData.length == 0) {
let obj = {}
obj.name = ''
obj.type = ''
obj.typeOptions = [
{ value: 'text', label: '文本' },
]
obj.xpath = ''
this.SelectTableData.push(obj)
if (this.selectTableData.length === 0) {
this.selectTableData.push(createEmptyCell());
}
},
mounted () {
let _this = this
document.addEventListener('click', function handleClick (event) {
const handleClick = (event) => {
// 如果点击的不是当前高亮的元素,移除高亮
if (event.target !== window.currentlyHighlighted) {
if (window.currentlyHighlighted) {
......@@ -156,80 +139,73 @@ export default {
}
window.currentlyHighlighted = null;
}
if (_this.selectedRow == null) return
if (event.target.id == 'addImg' || event.target.id == 'addButton') {
_this.setElementBackgroundColor(_this.selectedRow.xpath, '');
_this.selectedRow = null;
//点击添加动作,将当前选中的元素背景清空
if (this.selectedRow && (event.target.id === 'addImg' || event.target.id === 'addButton')) {
this.setElementBackgroundColor(this.selectedRow.xpath, '');
this.columnBack()
this.selectedRow = null;
document.removeEventListener('click', handleClick);
return;
// 移除监听器的代码已经移动到函数开头
}
});
};
document.addEventListener('click', handleClick);
},
watch: {},
computed: {},
methods: {
getTable () {
let _this = this
_this.table = new table()
// 验证name属性是否唯一
let data = [...this.SelectTableData]
data = data.filter(item => item.xpath);
// console.log(data)
_this.validateNames(data)
this.table = new table();
const data = this.selectTableData.filter(item => item.xpath);
if (data.length == 0) return
// 提交验证
this.validateNames(data);
},
// 删除行
columnDelete (row) {
let _this = this
_this.SelectTableData = this.SelectTableData.filter(item => item._X_ROW_KEY
!== row._X_ROW_KEY
)
_this.setElementBackgroundColor(_this.$refs.xTableColumn.getCurrentRecord().xpath, '')
// 先将删除的元素清空,并且将背景色还原
_this.SelectTableData = _this.SelectTableData.filter(xpath => xpath.xpath !== row.xpath);
_this.setElementBackgroundColor(row.xpath, '')
// 将表格最后一个选中,添加背景色
if (_this.SelectTableData.length > 0) {
console.log(_this.SelectTableData)
if (_this.SelectTableData.length == 1) return
_this.$refs.xTableColumn.setCurrentRow(_this.SelectTableData[_this.SelectTableData.length - 2])
_this.setElementBackgroundColor(_this.SelectTableData[_this.SelectTableData.length - 2].xpath, '#68C23A')
// 更新selectTableData,移除指定行
this.selectTableData = this.selectTableData.filter(item => item._X_ROW_KEY !== row._X_ROW_KEY && item.xpath !== row.xpath);
// 清空背景色
if (this.$refs.xTableColumn.getCurrentRecord()) {
this.setElementBackgroundColor(this.$refs.xTableColumn.getCurrentRecord().xpath, '');
}
this.setElementBackgroundColor(row.xpath, '');
// 如果仍有数据,更新选中行和背景色
const dataLength = this.selectTableData.length;
if (dataLength > 1) {
const lastItem = this.selectTableData[dataLength - 2];
this.$refs.xTableColumn.setCurrentRow(lastItem);
this.setElementBackgroundColor(lastItem.xpath, '#68C23A');
}
// 更新table中的cells
if (this.table) {
this.table.cells = this.table.cells.filter(xpath => xpath !== row.xpath);
}
if (_this.table == null) return
_this.table.cells = _this.table.cells.filter(xpath => xpath !== row.xpath);
},
columnBack () {
let _this = this
_this.isSelectTable = true
let tablePath = _this.table.xpath.split('/');
tablePath.pop()
tablePath = tablePath.join("/")
_this.setElementBackgroundColor(tablePath, '')
for (let i = 0; i < _this.table.cells.length; i++) {
for (let k = 1; k <= _this.tableData.length; k++) {
let path = _this.table.cells[i].tableXpath + '[' + k + ']/' + _this.table.cells[i].relativeXpath
_this.setElementBackgroundColor(path, '')
this.isSelectTable = true;
// 更新tablePath的背景色
let tablePath = this.table.xpath.split('/');
tablePath.pop();
this.setElementBackgroundColor(tablePath.join("/"), '');
// 清除所有cell的背景色
this.table.cells.forEach(cell => {
for (let k = 1; k <= this.tableData.length; k++) {
let path = `${cell.tableXpath}[${k}]/${cell.relativeXpath}`;
this.setElementBackgroundColor(path, '');
}
}
_this.tableData = []
});
// 清空tableData
this.tableData = [];
},
// 行选中事件
currentChangeEvent ({ row }) {
if (this.selectedRow == null) {
this.selectedRow = row
}
if (this.selectedRow.xpath !== row.xpath) {
this.setElementBackgroundColor(this.selectedRow.xpath, '')
this.selectedRow = row
this.setElementBackgroundColor(row.xpath, '#68C23A')
} else {
this.setElementBackgroundColor(row.xpath, '#68C23A')
}
if (row.xpath === '') return;
// 如果之前已选中其他行,清除其背景色
if (this.selectedRow && this.selectedRow.xpath !== row.xpath) {
this.setElementBackgroundColor(this.selectedRow.xpath, '');
}
// 设置当前行为选中行,并更新背景色
this.selectedRow = row;
this.setElementBackgroundColor(row.xpath, '#68C23A');
},
// 定义事件处理函数
......@@ -258,9 +234,9 @@ export default {
});
info.typeOptions = []
info.typeOptions = typeOptions
info.xpath = _this.getElementXPath(targetElement)
info.contentText = targetElement.textContent
info.title = 'columnName'
// info.xpath = _this.getElementXPath(targetElement)
// info.contentText = targetElement.textContent
// info.title = 'columnName'
} else if (targetElement.tagName === 'IMG') {
// 图片
info = {
......@@ -273,9 +249,9 @@ export default {
});
info.typeOptions = []
info.typeOptions = typeOptions
info.xpath = _this.getElementXPath(targetElement)
info.contentText = targetElement.textContent
info.title = 'columnName'
// info.xpath = _this.getElementXPath(targetElement)
// info.contentText = targetElement.textContent
// info.title = 'columnName'
} else {
// 其他标签
info = {
......@@ -286,22 +262,22 @@ export default {
});
info.typeOptions = []
info.typeOptions = typeOptions
info.xpath = _this.getElementXPath(targetElement)
info.contentText = targetElement.textContent
info.title = 'columnName'
// info.xpath = _this.getElementXPath(targetElement)
// info.contentText = targetElement.textContent
// info.title = 'columnName'
}
info.name = 'ID' + _this.index++
info.type = ''
_this.SelectTableData.unshift(info)
// 将新加入的tableData添加高亮
// console.log(this.$refs.xTableColumn)
info.xpath = _this.getElementXPath(targetElement)
info.contentText = targetElement.textContent
info.title = 'columnName'
_this.selectTableData.unshift(info)
if (this.$refs.xTableColumn !== undefined) {
// if (this.SelectTableData.length > 1) {
this.$refs.xTableColumn.setCurrentRow(_this.SelectTableData[0])
// }
this.$refs.xTableColumn.setCurrentRow(_this.selectTableData[0])
}
if (this.selectedRow !== null) {
this.setElementBackgroundColor(this.selectedRow.xpath, '');
}
// 移除先前元素的背景色(如果有)
if (window.currentlyHighlighted) {
window.currentlyHighlighted.style.backgroundColor = '';
......@@ -321,13 +297,6 @@ export default {
document.addEventListener('contextmenu', this.contextMenuHandler, false);
this.contextMenuListenerAdded = true;
},
// 取消按钮调用
cancelSelect () {
this.selectTable = false;
// 在取消按钮点击时移除事件监听器
document.removeEventListener('contextmenu', this.contextMenuHandler);
this.contextMenuListenerAdded = false;
},
// 获取xpath
getElementXPath (element) {
let _this = this
......@@ -353,82 +322,80 @@ export default {
}
},
validateNames (arr) {
let _this = this;
let names = new Set();
// 检查表名是否为空
if (_this.tableName == '') {
if (this.tableName === '') {
this.$message.error("请填写表名");
return; // 找到重复后退出函数
return;
}
// 检查元素是否为空
if (_this.SelectTableData.length == 0) {
if (this.selectTableData.length === 0) {
this.$message.error("还未选择元素");
return
return;
}
// 遍历 arr
for (const item of arr) {
// 检查 name 是否为空
if (!item.name) {
this.$message.error("属性名不能为空");
return; // 如果 name 为空,则退出函数
return;
}
// 检查 name 是否重复
if (names.has(item.name)) {
this.$message.error("属性名不能一样: " + item.name);
return; // 找到重复后退出函数
}
// 检查类型是否为空
if (item.typeOptions.length == 1) {
item.type = item.typeOptions[0].value
} else if (item.typeOptions.length > 1) {
if (item.type == '') {
this.$message.error("类型值不能为空");
return;
}
if (item.typeOptions.length === 1) {
item.type = item.typeOptions[0].value;
} else if (item.typeOptions.length > 1 && item.type === '') {
this.$message.error("类型值不能为空");
return
}
names.add(item.name);
}
// 遍历 SelectTableData
for (let i = 0; i < _this.SelectTableData.length - 1; i++) {
// _this.SelectTableData[i].name = 'ID' + i
_this.table.newCell(_this.SelectTableData[i].xpath, _this.SelectTableData[i].name, _this.SelectTableData[i].type, _this.SelectTableData[i].typeOptions, _this.SelectTableData[i].title)
}
_this.table.verify()
_this.table.name = _this.tableName
_this.tableColumn = []
_this.tableData = []
_this.tableData = _this.table.getData()
// 检查数据是否为空
if (_this.tableData.length == 0) return
// 遍历 SelectTableData
for (let i = 0; i < _this.SelectTableData.length - 1; i++) {
let objs = {}
objs.field = _this.SelectTableData[i].name
objs.title = _this.SelectTableData[i].title
// objs.width = 150
_this.tableColumn.push(objs)
}
_this.isSelectTable = false
_this.table.Name = _this.activedAction.Name
_this.table.Alias = _this.activedAction.Alias
_this.$emit('dataChanged', _this.table);
// 防止父级改变,子级未改变重新赋值
_this.activedAction.table = _this.table;
_this.$emit('dataChanged', _this.activedAction);
// 选中表格区域
let tablePath = _this.table.xpath.split('/');
tablePath.pop()
tablePath = tablePath.join("/")
_this.setElementBackgroundColor(tablePath, '#AED7E5')
for (let i = 0; i < _this.table.cells.length; i++) {
for (let k = 1; k <= _this.tableData.length; k++) {
let path = _this.table.cells[i].tableXpath + '[' + k + ']/' + _this.table.cells[i].relativeXpath
_this.setElementBackgroundColor(path, '#68C23A')
this.updateSelectTableData();
// this.setTableProperties();
// this.highlightTableAndCells();
},
// 更新tableData
updateSelectTableData () {
this.selectTableData.forEach((item, index) => {
if (item.xpath == '') return
this.table.newCell(item.xpath, item.name, item.type, item.typeOptions, item.title);
});
this.table.verify();
this.tableData = this.table.getData();
console.log(this.tableData)
console.log(this.table)
},
// 动态建立tablecolumn
setTableProperties () {
if (this.tableData == null) return
this.table.name = this.tableName;
this.tableColumn = this.selectTableData.map(item => ({ field: item.name, title: item.title }));
this.isSelectTable = false;
this.table.Name = this.activedAction.Name;
this.table.Alias = this.activedAction.Alias;
this.$emit('dataChanged', this.table);
this.activedAction.table = this.table;
this.$emit('dataChanged', this.activedAction);
},
// 高亮选中
highlightTableAndCells () {
if (this.tableData == null) {
return this.$message.error("请选择同一行数据");
}
// if (this.$refs.xTableColumn.getCurrentRecord()) {
// this.setElementBackgroundColor(this.$refs.xTableColumn.getCurrentRecord().xpath, '');
// }
let tablePath = this.table.xpath.split('/');
tablePath.pop();
this.setElementBackgroundColor(tablePath.join('/'), '#AED7E5');
this.table.cells.forEach(cell => {
for (let k = 1; k <= this.tableData.length; k++) {
let path = `${cell.tableXpath}[${k}]/${cell.relativeXpath}`;
this.setElementBackgroundColor(path, '#68C23A');
}
});
}
},
}
</script>
......@@ -449,6 +416,6 @@ export default {
.vxe-cell .vxe-textarea>.vxe-textarea--inner,
.vxe-table--filter-wrapper .vxe-input>.vxe-input--inner,
.vxe-table--filter-wrapper .vxe-textarea>.vxe-textarea--inner {
width: 145px !important;
width: 100px !important;
}
</style>
\ No newline at end of file
......@@ -50,6 +50,7 @@ function table () {
while (tableXpathArray.length > 0) {
this.cells.forEach(cell => cell.updateRelativePath(tableXpathArray));//先对所有的Cell更新下相对路径
if (this.cells.every(cell => cell.isExist())) break;//如果每个cell都存在,成功
if(tableXpathArray[tableXpathArray.length - 1]=='HTML') return
tableXpathArray.pop();//向上一级找
}
if (tableXpathArray.length < 1) return _isVerified;//如果没有共同父节点,返回false
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment