|
@@ -6,7 +6,8 @@
|
|
|
<div class="nav-title">报表模版设计</div>
|
|
|
</div>
|
|
|
<div>
|
|
|
- hhhh
|
|
|
+ <el-tree node-key="id"
|
|
|
+ class="filter-tree group-tree"></el-tree>
|
|
|
</div>
|
|
|
</el-tab-pane>
|
|
|
<el-tab-pane>
|
|
@@ -22,6 +23,7 @@
|
|
|
@node-contextmenu="rightNodeEvent"
|
|
|
@node-click="handleNodeClick"
|
|
|
:highlight-current="false"
|
|
|
+ :expand-on-click-node="false"
|
|
|
:default-expand-all="true"></el-tree>
|
|
|
</div>
|
|
|
</el-tab-pane>
|
|
@@ -76,6 +78,7 @@
|
|
|
</el-select>
|
|
|
<el-button size="mini" @click="addDataItem" style="float: right;width: 100px;margin-top: 4px;">添加数据项</el-button>
|
|
|
</el-form-item>
|
|
|
+ <el-tag size="mini" v-if="chooseItemDataView" class="cy-item-tag">已选择({{ chooseItemDataList.length }})项</el-tag>
|
|
|
</div>
|
|
|
<!-- <el-button size="mini" style="float: right;margin-top: 15px;margin-right: 14px;">添加数据项</el-button>-->
|
|
|
</el-form>
|
|
@@ -140,40 +143,59 @@
|
|
|
<el-input placeholder="请输入关键字进行过滤" v-model="filterItemData"></el-input>
|
|
|
<el-tree class="cy-item-tree"
|
|
|
ref="itemTree"
|
|
|
- :data="itemDataList"
|
|
|
- :indent="0"
|
|
|
+ :data="itemDataListByTree"
|
|
|
+ :indent="10"
|
|
|
node-key="id"
|
|
|
+ show-checkbox
|
|
|
+ :check-on-click-node="true"
|
|
|
:filter-node-method="filterItemDataNode"
|
|
|
:highlight-current="true"
|
|
|
- :default-expand-all="true"></el-tree>
|
|
|
+ :default-expand-all="true">
|
|
|
+ <span class="custom-tree-node" slot-scope="{ node, data }">
|
|
|
+ <svg-icon v-if="!data.children" icon-class="file"/>
|
|
|
+ <svg-icon v-else-if="node.expanded" icon-class="folder-open"/>
|
|
|
+ <svg-icon v-else icon-class="folder"/>
|
|
|
+ <span :title='node.label || "-"' style="margin-left: 2px;">{{node.label}}</span>
|
|
|
+ </span>
|
|
|
+ </el-tree>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- 操作按钮 -->
|
|
|
<div class="cy-transform-btn">
|
|
|
<el-row>
|
|
|
- <el-button size="mini">添加 >></el-button>
|
|
|
+ <el-button size="mini" @click="addCheckNodesBtnEvent">添加 >></el-button>
|
|
|
</el-row>
|
|
|
<el-row>
|
|
|
- <el-button size="mini"><< 移除</el-button>
|
|
|
+ <el-button size="mini" @click="removeCheckNodesBtnEvent"><< 移除</el-button>
|
|
|
</el-row>
|
|
|
<el-row>
|
|
|
- <el-button size="mini">全部移除</el-button>
|
|
|
+ <el-button size="mini" @click="removeAllCheckNodesBtnEvent">全部移除</el-button>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
<!-- 已选择数据项 -->
|
|
|
<div class="cy-transform-data">
|
|
|
<el-divider content-position="left">已选择数据项</el-divider>
|
|
|
<div class="cy-line">
|
|
|
- <el-tree :data="chooseItemDataList"
|
|
|
+ <el-tree :data="chooseItemDataListByTree"
|
|
|
+ ref="chooseItemTree"
|
|
|
:indent="0"
|
|
|
node-key="id"
|
|
|
+ show-checkbox
|
|
|
+ :check-on-click-node="true"
|
|
|
:highlight-current="true"
|
|
|
- :default-expand-all="true"></el-tree>
|
|
|
+ :default-expand-all="true">
|
|
|
+ <span class="custom-tree-node" slot-scope="{ node, data }">
|
|
|
+ <svg-icon v-if="!data.children" icon-class="file"/>
|
|
|
+ <svg-icon v-else-if="node.expanded" icon-class="folder-open"/>
|
|
|
+ <svg-icon v-else icon-class="folder"/>
|
|
|
+ <span :title='node.label || "-"' style="margin-left: 2px;">{{node.label}}</span>
|
|
|
+ </span>
|
|
|
+ </el-tree>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<span slot='footer'>
|
|
|
- <el-button type="primary">确定</el-button>
|
|
|
+ <el-button type="primary" @click="itemDialogSave">确定</el-button>
|
|
|
<el-button @click="itemDialogClose">取消</el-button>
|
|
|
</span>
|
|
|
</el-dialog>
|
|
@@ -181,7 +203,13 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import {getAllDataSource, getAllItemGroup, getDataSourceItemTree} from "@/api/datasource";
|
|
|
+import {
|
|
|
+ getAllDataSource,
|
|
|
+ getAllItemGroup,
|
|
|
+ getDataSourceItemTree,
|
|
|
+ saveOrUpdateDataSource,
|
|
|
+ saveOrUpdateItemGroup
|
|
|
+} from "@/api/datasource";
|
|
|
import {getDictByKey} from "@/api/basic";
|
|
|
import {showLoading} from "@/utils/cqcy";
|
|
|
|
|
@@ -211,9 +239,12 @@ export default {
|
|
|
dataSourceList: [],
|
|
|
// 数据项
|
|
|
itemDataList: [],
|
|
|
+ itemDataListByTree: [],
|
|
|
filterItemData: '',
|
|
|
// 已选择的数据项
|
|
|
chooseItemDataList: [],
|
|
|
+ chooseItemDataListByTree: [],
|
|
|
+ chooseItemDataView: false,
|
|
|
groupBasicForm: {
|
|
|
groupName: '',
|
|
|
groupDescribe: '',
|
|
@@ -235,7 +266,15 @@ export default {
|
|
|
watch: {
|
|
|
filterItemData(val) {
|
|
|
this.$refs.itemTree.filter(val)
|
|
|
- }
|
|
|
+ },
|
|
|
+ /** 组添加右键值监听 */
|
|
|
+ visibleGroupMenu(value) {
|
|
|
+ if (value) {
|
|
|
+ document.body.addEventListener('click', this.closeMenu)
|
|
|
+ } else {
|
|
|
+ document.body.removeEventListener('click', this.closeMenu)
|
|
|
+ }
|
|
|
+ },
|
|
|
},
|
|
|
computed: {
|
|
|
},
|
|
@@ -274,9 +313,41 @@ export default {
|
|
|
handleSave() {
|
|
|
this.$refs['groupBasicForm'].validate(valid => {
|
|
|
if (valid && this.checkParams()) {
|
|
|
+ // 参数封装
|
|
|
+ let params = JSON.parse(JSON.stringify(this.groupBasicForm))
|
|
|
+ params.readMode = this.groupRateForm.readMode
|
|
|
+ params.modeValue = this.groupRateForm.modeValue
|
|
|
+ this.addGroupItem(params)
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
+ /** 保存组配置 */
|
|
|
+ addGroupItem(params) {
|
|
|
+ const loading = showLoading(this, '保存中,请稍候···')
|
|
|
+ saveOrUpdateItemGroup(params).then(res => {
|
|
|
+ loading.close()
|
|
|
+ if (res.data) {
|
|
|
+ this.$alert('保存成功!', '温馨提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ callback: action => {
|
|
|
+ this.handleCancel()
|
|
|
+ // 刷新组列表
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$message({
|
|
|
+ message: '保存失败!',
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ }).catch((e) => {
|
|
|
+ loading.close()
|
|
|
+ this.$message({
|
|
|
+ message: '保存失败!',
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
/** 选择数据源值改变事件 */
|
|
|
dataSourceChange(val) {
|
|
|
this.groupBasicForm.dataSourceId = val
|
|
@@ -322,15 +393,65 @@ export default {
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
- const loading = showLoading(this, '加载中,请稍候···')
|
|
|
- getDataSourceItemTree(id).then(res => {
|
|
|
- loading.close()
|
|
|
- this.itemDataList = res.data
|
|
|
- this.dataItemDialogVisible = true
|
|
|
- }).catch((e) => {
|
|
|
- loading.close()
|
|
|
- console.error(e)
|
|
|
- })
|
|
|
+ // const loading = showLoading(this, '加载中,请稍候···')
|
|
|
+ // getDataSourceItemTree(id).then(res => {
|
|
|
+ // loading.close()
|
|
|
+ // this.itemDataList = res.data
|
|
|
+ // this.itemDataListByTree = res.data
|
|
|
+ // this.dataItemDialogVisible = true
|
|
|
+ // }).catch((e) => {
|
|
|
+ // loading.close()
|
|
|
+ // console.error(e)
|
|
|
+ // })
|
|
|
+ let ada = [{
|
|
|
+ id: 1,
|
|
|
+ label: '一级 1',
|
|
|
+ children: [{
|
|
|
+ id: 4,
|
|
|
+ label: '二级 1-1',
|
|
|
+ children: [{
|
|
|
+ id: 9,
|
|
|
+ label: '三级 1-1-1',
|
|
|
+ children: [{
|
|
|
+ id: 41,
|
|
|
+ label: '四级 1-1-1-1',
|
|
|
+ children: [{
|
|
|
+ id: 51,
|
|
|
+ label: '五级 1-1-1-1-1'
|
|
|
+ }, {
|
|
|
+ id: 52,
|
|
|
+ label: '五级 1-1-1-1-2'
|
|
|
+ }]
|
|
|
+ }]
|
|
|
+ }, {
|
|
|
+ id: 10,
|
|
|
+ label: '三级 1-1-2'
|
|
|
+ }]
|
|
|
+ }]
|
|
|
+ }, {
|
|
|
+ id: 2,
|
|
|
+ label: '一级 2',
|
|
|
+ children: [{
|
|
|
+ id: 5,
|
|
|
+ label: '二级 2-1'
|
|
|
+ }, {
|
|
|
+ id: 6,
|
|
|
+ label: '二级 2-2'
|
|
|
+ }]
|
|
|
+ }, {
|
|
|
+ id: 3,
|
|
|
+ label: '一级 3',
|
|
|
+ children: [{
|
|
|
+ id: 7,
|
|
|
+ label: '二级 3-1'
|
|
|
+ }, {
|
|
|
+ id: 8,
|
|
|
+ label: '二级 3-2'
|
|
|
+ }]
|
|
|
+ }]
|
|
|
+ this.itemDataList = JSON.parse(JSON.stringify(ada))
|
|
|
+ this.itemDataListByTree = ada
|
|
|
+ this.dataItemDialogVisible = true
|
|
|
},
|
|
|
/** 参数检查 */
|
|
|
checkParams() {
|
|
@@ -364,6 +485,122 @@ export default {
|
|
|
}
|
|
|
return true
|
|
|
},
|
|
|
+ /**
|
|
|
+ * 显示层级数据
|
|
|
+ * @param tree {Array} 树数据
|
|
|
+ * @param func {Function} 回调函数
|
|
|
+ * @param field {String} 字段名称
|
|
|
+ * @param path {Array} 路径数据
|
|
|
+ * @returns {*[]|[]|*}
|
|
|
+ */
|
|
|
+ treeFindPath(tree, func, field = "", path = []) {
|
|
|
+ if (!tree) return []
|
|
|
+ for (const data of tree) {
|
|
|
+ field === "" ? path.push(data) : path.push(data[field]);
|
|
|
+ if (func(data)) return path
|
|
|
+ if (data.children) {
|
|
|
+ const findChildren = this.treeFindPath(data.children, func, field, path)
|
|
|
+ if (findChildren.length) return findChildren
|
|
|
+ }
|
|
|
+ path.pop()
|
|
|
+ }
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ /** 添加数据项 */
|
|
|
+ addCheckNodesBtnEvent() {
|
|
|
+ let checkedNodes = this.$refs.itemTree.getCheckedNodes(false, true)
|
|
|
+ if (checkedNodes.length == 0) {
|
|
|
+ this.$message({
|
|
|
+ message: '请选择数据项!',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 根据当前选择节点拼接为:XXXX.XXXX.XXX
|
|
|
+ let chooseChannelNameList = []
|
|
|
+ for (let i in checkedNodes) {
|
|
|
+ let checkedNode = checkedNodes[i]
|
|
|
+ if (checkedNode.children && checkedNode.children.length > 0) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ const nodeId = checkedNode.$treeNodeId;
|
|
|
+ let channelName = this.treeFindPath(this.itemDataListByTree, data => data.$treeNodeId === nodeId, "label")
|
|
|
+ let temp = {
|
|
|
+ 'label': channelName.join('.')
|
|
|
+ }
|
|
|
+ chooseChannelNameList.push(temp)
|
|
|
+ }
|
|
|
+ // 去重
|
|
|
+ let arr = JSON.parse(JSON.stringify(this.chooseItemDataListByTree))
|
|
|
+ if (arr.length == 0) {
|
|
|
+ arr = chooseChannelNameList
|
|
|
+ } else {
|
|
|
+ for (let i in chooseChannelNameList) {
|
|
|
+ let flag = false
|
|
|
+ for (let j in arr) {
|
|
|
+ if (chooseChannelNameList[i].label == arr[j].label) {
|
|
|
+ flag = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!flag) {
|
|
|
+ arr.push(chooseChannelNameList[i])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.chooseItemDataListByTree = arr
|
|
|
+ this.$refs.itemTree.setCheckedKeys([])
|
|
|
+ },
|
|
|
+ /** 移除全部数据项 */
|
|
|
+ removeAllCheckNodesBtnEvent() {
|
|
|
+ if (this.chooseItemDataListByTree.length == 0) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.chooseItemDataListByTree = []
|
|
|
+ this.$refs.itemTree.setCheckedKeys([])
|
|
|
+ },
|
|
|
+ /** 移除数据项 */
|
|
|
+ removeCheckNodesBtnEvent() {
|
|
|
+ let checkedNodes = this.$refs.chooseItemTree.getCheckedNodes(false, true)
|
|
|
+ if (checkedNodes.length == 0) {
|
|
|
+ this.$message({
|
|
|
+ message: '请选择数据项!',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 移除当前选择项
|
|
|
+ for (let i in checkedNodes) {
|
|
|
+ let index = this.chooseItemDataListByTree.indexOf(checkedNodes[i])
|
|
|
+ if (index >= 0) {
|
|
|
+ this.chooseItemDataListByTree.splice(index, 1)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 重置选择
|
|
|
+ this.$refs.itemTree.setCheckedKeys([])
|
|
|
+ this.$refs.chooseItemTree.setCheckedKeys([])
|
|
|
+ },
|
|
|
+ /** 选择数据项弹出层保存事件 */
|
|
|
+ itemDialogSave() {
|
|
|
+ if (this.chooseItemDataListByTree.length == 0) {
|
|
|
+ this.$message({
|
|
|
+ message: '请选择数据项!',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let itemList = []
|
|
|
+ let itemNameList = this.chooseItemDataListByTree.map(map => { return map.label })
|
|
|
+ for (let i in itemNameList) {
|
|
|
+ itemList.push({
|
|
|
+ 'itemName': itemNameList[i]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.groupBasicForm.itemList = itemList
|
|
|
+ this.chooseItemDataList = this.chooseItemDataListByTree
|
|
|
+ this.dataItemDialogVisible = false
|
|
|
+ this.chooseItemDataView = true
|
|
|
+ },
|
|
|
/** 关闭右键弹出层 */
|
|
|
closeMenu() {
|
|
|
this.visibleGroupMenu = false
|
|
@@ -382,8 +619,8 @@ export default {
|
|
|
},
|
|
|
/** 选择数据项弹出层关闭事件 */
|
|
|
itemDialogClose(done) {
|
|
|
- this.itemDataList = []
|
|
|
- this.chooseItemDataList = []
|
|
|
+ this.itemDataListByTree = []
|
|
|
+ this.chooseItemDataListByTree = []
|
|
|
if (typeof(done) === 'function') {
|
|
|
done()
|
|
|
} else {
|
|
@@ -522,6 +759,18 @@ export default {
|
|
|
}
|
|
|
|
|
|
.cy-transform-data {
|
|
|
- width: calc(100% - 60px);
|
|
|
+ width: calc(50% - 60px);
|
|
|
+}
|
|
|
+
|
|
|
+.custom-tree-node {
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.cy-item-tag {
|
|
|
+ float: right;
|
|
|
+ margin-top: -7px;
|
|
|
+ margin-right: 10px;
|
|
|
}
|
|
|
</style>
|