提交 b4a09f37 authored 作者: taojinlong's avatar taojinlong

Merge branch 'dev' of github.com:dataease/dataease into dev

......@@ -51,6 +51,7 @@ public class ShiroConfig {
filterMap.put("jwt", new JWTFilter());
filterMap.put("logout", new F2CLogoutFilter());
filterMap.put("link", new F2CLinkFilter());
filterMap.put("doc", new F2CDocFilter());
factoryBean.setSecurityManager(securityManager);
factoryBean.setLoginUrl("/login");
factoryBean.setUnauthorizedUrl("/login");
......
package io.dataease.auth.filter;
import org.apache.shiro.web.filter.authc.AnonymousFilter;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class F2CDocFilter extends AnonymousFilter {
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
HttpServletRequest req = (HttpServletRequest) request;
String path = "/deApi";
try {
req.getRequestDispatcher(path).forward(req, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
......@@ -43,9 +43,11 @@ public class ExtAuthServiceImpl implements ExtAuthService {
@Override
public AuthURD resourceTarget(String resourceId) {
AuthURD authURD = new AuthURD();
SysAuthExample example = new SysAuthExample();
/*SysAuthExample example = new SysAuthExample();
example.createCriteria().andAuthSourceEqualTo(resourceId);
List<SysAuth> sysAuths = sysAuthMapper.selectByExample(example);
List<SysAuth> sysAuths = sysAuthMapper.selectByExample(example);*/
List<SysAuth> sysAuths = extAuthMapper.queryByResource(resourceId);
Map<String, List<SysAuth>> authMap = sysAuths.stream().collect(Collectors.groupingBy(SysAuth::getAuthTargetType));
if (!CollectionUtils.isEmpty(authMap.get("user"))) {
authURD.setUserIds(authMap.get("user").stream().map(item -> Long.parseLong(item.getAuthTarget())).collect(Collectors.toList()));
......
......@@ -20,7 +20,8 @@ public class ShiroServiceImpl implements ShiroService {
// 配置过滤:不会被拦截的链接 -> 放行 start ----------------------------------------------------------
// 放行Swagger2页面,需要放行这些
filterChainDefinitionMap.put("/doc.html",ANON);
filterChainDefinitionMap.put("/doc.html**","doc");
filterChainDefinitionMap.put("/deApi**",ANON);
filterChainDefinitionMap.put("/swagger-ui.html",ANON);
filterChainDefinitionMap.put("/swagger-ui/**",ANON);
filterChainDefinitionMap.put("/swagger/**",ANON);
......
package io.dataease.base.mapper.ext;
import io.dataease.base.domain.SysAuth;
import org.apache.ibatis.annotations.Param;
import java.util.List;
......@@ -12,6 +13,6 @@ public interface ExtAuthMapper {
List<Long> queryUserIdWithDeptIds(@Param("deptIds") List<Long> deptIds);
List<SysAuth> queryByResource(@Param("resourceId") String resourceId);
// Set<Long> queryUserIdWithRD(@Param("roleIds") List<Long> roleIds, @Param("deptIds") List<Long> deptIds);
}
......@@ -23,5 +23,12 @@
</select>
<select id="queryByResource" resultMap="io.dataease.base.mapper.SysAuthMapper.BaseResultMap" >
select a.*
from sys_auth a left join sys_auth_detail b on a.id = b.auth_id
where a.auth_source = #{resourceId} and b.privilege_value = 1
</select>
</mapper>
......@@ -34,9 +34,16 @@
<select id="query" parameterType="io.dataease.base.mapper.ext.query.GridExample" resultMap="BaseResultMap">
select u.*,u.user_id as id, d.pid, d.name as dept_name
from sys_user u
left join sys_dept d on d.dept_id = u.dept_id
SELECT DISTINCT
u.*,
u.user_id AS id,
d.pid,
d.NAME AS dept_name
FROM
sys_user u
LEFT JOIN sys_dept d ON d.dept_id = u.dept_id
LEFT JOIN sys_users_roles sur ON sur.user_id = u.user_id
LEFT JOIN sys_role r ON r.role_id = sur.role_id
<if test="_parameter != null">
<include refid="io.dataease.base.mapper.ext.query.GridSql.gridCondition" />
......
......@@ -64,12 +64,11 @@ public class Knife4jConfiguration {
return defaultApi("系统管理", "io.dataease.controller.sys");
}
@Bean(value = "pluginsApi")
/*@DependsOn(value = "licStatusCondition")*/
/*@Bean(value = "pluginsApi")
@Conditional(LicStatusCondition.class)
public Docket pluginsApi() {
return defaultApi("插件管理", "io.dataease.plugins.server");
}
}*/
private ApiInfo apiInfo(){
......
package io.dataease.controller;
import io.dataease.commons.license.DefaultLicenseService;
import io.dataease.commons.license.F2CLicenseResponse;
import io.dataease.exception.DataEaseException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
@Controller
@RequestMapping
public class IndexController {
@Resource
private DefaultLicenseService defaultLicenseService;
@GetMapping(value = "/")
public String index() {
return "index.html";
......@@ -28,5 +36,18 @@ public class IndexController {
return "test.html";
}
@GetMapping("/deApi")
public String deApi() {
F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense();
switch (f2CLicenseResponse.getStatus()) {
case valid:
return "doc.html";
default:
// DataEaseException.throwException("Invalid License.");
return "nolic.html";
}
// return "index.html";
}
}
package io.dataease.dto.chart;
import io.dataease.base.domain.ChartViewWithBLOBs;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
/**
......@@ -22,4 +24,6 @@ public class ChartViewDTO extends ChartViewWithBLOBs {
private String sql;
private boolean drill;
private List<ChartExtFilterRequest> drillFilters;
}
DROP VIEW
IF
EXISTS `v_auth_model`;
CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `v_auth_model` AS SELECT
`sys_user`.`user_id` AS `id`,
`sys_user`.`username` AS `name`,
`sys_user`.`username` AS `label`,
'0' AS `pid`,
'leaf' AS `node_type`,
'user' AS `model_type`,
'user' AS `model_inner_type`,
'target' AS `auth_type`,
`sys_user`.`create_by` AS `create_by`
FROM
`sys_user`
WHERE
( `sys_user`.`is_admin` <> 1 )
UNION ALL
SELECT
`sys_role`.`role_id` AS `id`,
`sys_role`.`name` AS `name`,
`sys_role`.`name` AS `label`,
'0' AS `pid`,
'leaf' AS `node_type`,
'role' AS `model_type`,
'role' AS `model_inner_type`,
'target' AS `auth_type`,
`sys_role`.`create_by` AS `create_by`
FROM
`sys_role` UNION ALL
SELECT
`sys_dept`.`dept_id` AS `id`,
`sys_dept`.`name` AS `name`,
`sys_dept`.`name` AS `lable`,
cast( `sys_dept`.`pid` AS CHAR charset utf8mb4 ) AS `pid`,
IF
(( `sys_dept`.`sub_count` = 0 ), 'leaf', 'spine' ) AS `node_type`,
'dept' AS `model_type`,
'dept' AS `model_inner_type`,
'target' AS `auth_type`,
`sys_dept`.`create_by` AS `create_by`
FROM
`sys_dept` UNION ALL
SELECT
`datasource`.`id` AS `id`,
`datasource`.`name` AS `NAME`,
`datasource`.`name` AS `label`,
'0' AS `pid`,
'leaf' AS `node_type`,
'link' AS `model_type`,
`datasource`.`type` AS `model_inner_type`,
'source' AS `auth_type`,
`datasource`.`create_by` AS `create_by`
FROM
`datasource` UNION ALL
SELECT
`dataset_group`.`id` AS `id`,
`dataset_group`.`name` AS `NAME`,
`dataset_group`.`name` AS `lable`,
IF
( isnull( `dataset_group`.`pid` ), '0', `dataset_group`.`pid` ) AS `pid`,
'spine' AS `node_type`,
'dataset' AS `model_type`,
`dataset_group`.`type` AS `model_inner_type`,
'source' AS `auth_type`,
`dataset_group`.`create_by` AS `create_by`
FROM
`dataset_group` UNION ALL
SELECT
`dataset_table`.`id` AS `id`,
`dataset_table`.`name` AS `NAME`,
`dataset_table`.`name` AS `lable`,
`dataset_table`.`scene_id` AS `pid`,
'leaf' AS `node_type`,
'dataset' AS `model_type`,
`dataset_table`.`type` AS `model_inner_type`,
'source' AS `auth_type`,
`dataset_table`.`create_by` AS `create_by`
FROM
`dataset_table` UNION ALL
SELECT
`chart_group`.`id` AS `id`,
`chart_group`.`name` AS `name`,
`chart_group`.`name` AS `label`,
IF
( isnull( `chart_group`.`pid` ), '0', `chart_group`.`pid` ) AS `pid`,
'spine' AS `node_type`,
'chart' AS `model_type`,
`chart_group`.`type` AS `model_inner_type`,
'source' AS `auth_type`,
`chart_group`.`create_by` AS `create_by`
FROM
`chart_group` UNION ALL
SELECT
`chart_view`.`id` AS `id`,
`chart_view`.`name` AS `name`,
`chart_view`.`name` AS `label`,
`chart_view`.`scene_id` AS `pid`,
'leaf' AS `node_type`,
'chart' AS `model_type`,
`chart_view`.`type` AS `model_inner_type`,
'source' AS `auth_type`,
`chart_view`.`create_by` AS `create_by`
FROM
`chart_view` UNION ALL
SELECT
`panel_group`.`id` AS `id`,
`panel_group`.`name` AS `NAME`,
`panel_group`.`name` AS `label`,(
CASE
`panel_group`.`id`
WHEN 'panel_list' THEN
'0'
WHEN 'default_panel' THEN
'0' ELSE `panel_group`.`pid`
END
) AS `pid`,
IF
(( `panel_group`.`node_type` = 'folder' ), 'spine', 'leaf' ) AS `node_type`,
'panel' AS `model_type`,
`panel_group`.`panel_type` AS `model_inner_type`,
'source' AS `auth_type`,
`panel_group`.`create_by` AS `create_by`
FROM
`panel_group` UNION ALL
SELECT
`sys_menu`.`menu_id` AS `menu_id`,
`sys_menu`.`title` AS `name`,
`sys_menu`.`title` AS `label`,
`sys_menu`.`pid` AS `pid`,
IF
(( `sys_menu`.`sub_count` > 0 ), 'spine', 'leaf' ) AS `node_type`,
'menu' AS `model_type`,(
CASE
`sys_menu`.`type`
WHEN 0 THEN
'folder'
WHEN 1 THEN
'menu'
WHEN 2 THEN
'button'
END
) AS `model_inner_type`,
'source' AS `auth_type`,
`sys_menu`.`create_by` AS `create_by`
FROM
`sys_menu`
WHERE
(sys_menu.i_frame !=1 or sys_menu.i_frame is null) UNION ALL
SELECT
`plugin_sys_menu`.`menu_id` AS `menu_id`,
`plugin_sys_menu`.`title` AS `name`,
`plugin_sys_menu`.`title` AS `label`,
`plugin_sys_menu`.`pid` AS `pid`,
IF
(( `plugin_sys_menu`.`sub_count` > 0 ), 'spine', 'leaf' ) AS `node_type`,
'menu' AS `model_type`,(
CASE
`plugin_sys_menu`.`type`
WHEN 0 THEN
'folder'
WHEN 1 THEN
'menu'
WHEN 2 THEN
'button'
END
) AS `model_inner_type`,
'source' AS `auth_type`,
`plugin_sys_menu`.`create_by` AS `create_by`
FROM
`plugin_sys_menu`
WHERE
(plugin_sys_menu.i_frame !=1 or plugin_sys_menu.i_frame is null);
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
<title>DataEase</title>
</head>
<body style="height: 100%;">
<div id="nolic"></div>
</body>
</html>
<template>
<div>
<div style="width: 100%;">
<el-dropdown trigger="click" @mouseup="handleMouseUp">
<el-button ref="trackButton" class="icon iconfont icon-shezhi">TEST</el-button>
<el-dropdown-menu>
<el-dropdown-item icon="el-icon-document-copy" @click.native="copy">{{ $t('panel.copy') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" @click.native="deleteComponent">{{ $t('panel.delete') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-upload2" @click.native="topComponent">{{ $t('panel.topComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-download" @click.native="bottomComponent">{{ $t('panel.bottomComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-arrow-up" @click.native="upComponent">{{ $t('panel.upComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-arrow-down" @click.native="downComponent">{{ $t('panel.downComponent') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-link" @click.native="linkageSetting">联动设置</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import bus from '@/utils/bus'
import { getViewLinkageGather } from '@/api/panel/linkage'
export default {
data() {
return {
copyData: null,
editFilter: [
'view',
'custom'
]
}
},
computed: mapState([
'menuTop',
'menuLeft',
'menuShow',
'curComponent',
'componentData',
'canvasStyleData'
]),
methods: {
trackButtonClick() {
this.$refs.trackButton.click()
this.$refs.trackButton.$el.click()
},
edit() {
// 编辑时临时保存 当前修改的画布
this.$store.dispatch('panel/setComponentDataTemp', JSON.stringify(this.componentData))
this.$store.dispatch('panel/setCanvasStyleDataTemp', JSON.stringify(this.canvasStyleData))
if (this.curComponent.type === 'view') {
this.$store.dispatch('chart/setViewId', null)
this.$store.dispatch('chart/setViewId', this.curComponent.propValue.viewId)
bus.$emit('PanelSwitchComponent', { name: 'ChartEdit', param: { 'id': this.curComponent.propValue.viewId, 'optType': 'edit' }})
}
if (this.curComponent.type === 'custom') {
bus.$emit('component-dialog-edit')
}
// 编辑样式组件
if (this.curComponent.type === 'v-text' || this.curComponent.type === 'rect-shape') {
bus.$emit('component-dialog-style')
}
},
lock() {
this.$store.commit('lock')
},
unlock() {
this.$store.commit('unlock')
},
// 点击菜单时不取消当前组件的选中状态
handleMouseUp() {
this.$store.commit('setClickComponentStatus', true)
},
cut() {
this.deleteCurCondition()
this.$store.commit('cut')
},
copy() {
this.$store.commit('copy')
this.paste()
},
paste() {
this.$store.commit('paste', true)
this.$store.commit('recordSnapshot')
},
deleteComponent() {
this.deleteCurCondition()
this.$store.commit('deleteComponent')
this.$store.commit('recordSnapshot')
this.$store.commit('setCurComponent', { component: null, index: null })
},
deleteCurCondition() {
if (this.curComponent.type === 'custom') {
this.$store.commit('removeViewFilter', this.curComponent.id)
bus.$emit('delete-condition', { componentId: this.curComponent.id })
}
},
upComponent() {
this.$store.commit('upComponent')
this.$store.commit('recordSnapshot')
},
downComponent() {
this.$store.commit('downComponent')
this.$store.commit('recordSnapshot')
},
topComponent() {
this.$store.commit('topComponent')
this.$store.commit('recordSnapshot')
},
bottomComponent() {
this.$store.commit('bottomComponent')
this.$store.commit('recordSnapshot')
},
linkageSetting() {
debugger
// sourceViewId 也加入查询
const targetViewIds = this.componentData.filter(item => item.type === 'view' && item.propValue && item.propValue.viewId)
.map(item => item.propValue.viewId)
// 获取当前仪表板当前视图联动信息
const requestInfo = {
'panelId': this.$store.state.panel.panelInfo.id,
'sourceViewId': this.curComponent.propValue.viewId,
'targetViewIds': targetViewIds
}
getViewLinkageGather(requestInfo).then(rsp => {
this.$store.commit('setLinkageInfo', rsp.data)
})
}
}
}
</script>
<style lang="scss" scoped>
.contextmenu {
position: absolute;
z-index: 1000;
ul {
border: 1px solid #e4e7ed;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
box-sizing: border-box;
margin: 5px 0;
padding: 6px 0;
li {
font-size: 14px;
padding: 0 20px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #606266;
height: 34px;
line-height: 34px;
box-sizing: border-box;
cursor: pointer;
&:hover {
background-color: #f5f7fa;
}
}
}
}
</style>
<template>
<div>
<el-dropdown trigger="click">
<input id="input" ref="trackButton" type="button" hidden>
<el-dropdown-menu class="track-menu" :append-to-body="false">
<el-dropdown-item v-for="(item, key) in trackMenu" :key="key" @click.native="trackMenuClick(item)"><span class="menu-item">{{ i18n_map[item] }}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
export default {
props: {
trackMenu: {
type: Array,
required: true
}
},
data() {
return {
i18n_map: {
drill: this.$t('panel.drill'),
linkage: this.$t('panel.linkage')
}
}
},
computed: {
},
methods: {
trackButtonClick() {
this.$refs.trackButton.click()
},
trackMenuClick(menu) {
this.$emit('trackClick', menu)
}
}
}
</script>
<style lang="scss" scoped>
.menu-item {
font-size: 12px;
}
::v-deep ul {
width: 80px;
}
.track-menu {
border: #3a8ee6 1px solid;
}
</style>
......@@ -16,9 +16,13 @@
{{ $t('chart.chart_error_tips') }}
</div>
</div>
<chart-component v-if="requestStatus==='success'&&chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :ref="element.propValue.id" class="chart-class" :chart="chart" />
<table-normal v-if="requestStatus==='success'&&chart.type && chart.type.includes('table')" :ref="element.propValue.id" :chart="chart" class="table-class" />
<label-normal v-if="requestStatus==='success'&&chart.type && chart.type.includes('text')" :ref="element.propValue.id" :chart="chart" class="table-class" />
<chart-component v-if="httpRequest.status &&chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :ref="element.propValue.id" class="chart-class" :chart="chart" :track-menu="trackMenu" @onChartClick="chartClick" />
<!-- <chart-component :ref="element.propValue.id" class="chart-class" :chart="chart" :track-menu="trackMenu" @onChartClick="chartClick" />-->
<table-normal v-if="httpRequest.status &&chart.type && chart.type.includes('table')" :ref="element.propValue.id" :chart="chart" class="table-class" />
<label-normal v-if="httpRequest.status && chart.type && chart.type.includes('text')" :ref="element.propValue.id" :chart="chart" class="table-class" />
<div style="position: absolute;left: 20px;bottom:14px;">
<drill-path :drill-filters="drillFilters" @onDrillJump="drillJump" />
</div>
</div>
</template>
......@@ -37,9 +41,11 @@ import { BASE_CHART_STRING } from '@/views/chart/chart/chart'
import eventBus from '@/components/canvas/utils/eventBus'
import { deepCopy } from '@/components/canvas/utils/utils'
import { getToken, getLinkToken } from '@/utils/auth'
import DrillPath from '@/views/chart/view/DrillPath'
import { areaMapping } from '@/api/map/map'
export default {
name: 'UserView',
components: { ChartComponent, TableNormal, LabelNormal },
components: { ChartComponent, TableNormal, LabelNormal, DrillPath },
props: {
element: {
type: Object,
......@@ -77,7 +83,15 @@ export default {
refId: null,
chart: BASE_CHART_STRING,
requestStatus: 'waiting',
message: null
message: null,
drillClickDimensionList: [],
drillFilters: [],
drillFields: [],
places: [],
httpRequest: {
status: true,
msg: ''
}
}
},
computed: {
......@@ -85,6 +99,7 @@ export default {
const filter = {}
filter.filter = this.element.filters
filter.linkageFilters = this.element.linkageFilters
filter.drill = this.drillClickDimensionList
return filter
},
filters() {
......@@ -99,8 +114,23 @@ export default {
console.log('linkageFilters:' + JSON.stringify(this.element.linkageFilters))
return JSON.parse(JSON.stringify(this.element.linkageFilters))
},
trackMenu() {
const trackMenuInfo = []
let linkageCount = 0
this.chart.data && this.chart.data.fields && this.chart.data.fields.forEach(item => {
const sourceInfo = this.chart.id + '#' + item.id
if (this.nowPanelTrackInfo[sourceInfo]) {
linkageCount++
}
})
linkageCount && trackMenuInfo.push('linkage')
this.drillFields.length && trackMenuInfo.push('drill')
console.log('trackMenuInfo' + JSON.stringify(trackMenuInfo))
return trackMenuInfo
},
...mapState([
'canvasStyleData'
'canvasStyleData',
'nowPanelTrackInfo'
])
},
......@@ -111,8 +141,13 @@ export default {
},
linkageFilters: {
handler(newVal, oldVal) {
debugger
isChange(newVal, oldVal) && this.getData(this.element.propValue.viewId)
// isChange(newVal, oldVal) && this.getData(this.element.propValue.viewId)
if (isChange(newVal, oldVal)) {
// if (this.chart.type === 'map') {
// this.doMapLink(newVal)
// }
this.getData(this.element.propValue.viewId)
}
},
deep: true
},
......@@ -145,6 +180,7 @@ export default {
this.refId = uuid.v1
// this.filter.filter = this.$store.getters.conditions
this.getData(this.element.propValue.viewId)
this.initAreas()
},
mounted() {
},
......@@ -191,15 +227,24 @@ export default {
// 将视图传入echart组件
if (response.success) {
this.chart = response.data
this.chart.drillFields = this.chart.drillFields ? JSON.parse(this.chart.drillFields) : []
if (!response.data.drill) {
this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1)
}
this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters))
this.drillFields = JSON.parse(JSON.stringify(response.data.drillFields))
this.requestStatus = 'merging'
this.mergeStyle()
this.requestStatus = 'success'
this.httpRequest.status = true
} else {
this.requestStatus = 'error'
this.message = response.message
}
return true
}).catch(err => {
this.httpRequest.status = err.response.data.success
this.httpRequest.msg = err.response.data.message
this.requestStatus = 'error'
if (err && err.response && err.response.data) {
this.message = err.response.data.message
......@@ -225,6 +270,114 @@ export default {
tableChart.customAttr = JSON.stringify(tableChart.customAttr)
tableChart.customStyle = JSON.stringify(tableChart.customStyle)
eventBus.$emit('openChartDetailsDialog', { chart: this.chart, tableChart: tableChart })
},
chartClick(param) {
if (this.drillClickDimensionList.length < this.chart.drillFields.length - 1) {
this.chart.type === 'map' && this.sendToChildren(param)
this.drillClickDimensionList.push({ dimensionList: param.data.dimensionList })
this.getData(this.element.propValue.viewId)
}
},
resetDrill() {
const length = this.drillClickDimensionList.length
this.drillClickDimensionList = []
if (this.chart.type === 'map') {
this.backToParent(0, length)
}
},
drillJump(index) {
const length = this.drillClickDimensionList.length
this.drillClickDimensionList = this.drillClickDimensionList.slice(0, index)
if (this.chart.type === 'map') {
this.backToParent(index, length)
}
this.getData(this.element.propValue.viewId)
},
// 回到父级地图
backToParent(index, length) {
if (length <= 0) return
const times = length - 1 - index
let temp = times
let tempNode = this.currentAcreaNode
while (temp >= 0) {
tempNode = this.findEntityByCode(tempNode.pcode, this.places)
temp--
}
this.currentAcreaNode = tempNode
const current = this.$refs[this.element.propValue.id]
current && current.registerDynamicMap && current.registerDynamicMap(this.currentAcreaNode.code)
// this.$refs.dynamicChart && this.$refs.dynamicChart.registerDynamicMap && this.$refs.dynamicChart.registerDynamicMap(this.currentAcreaNode.code)
},
// 切换下一级地图
sendToChildren(param) {
const length = param.data.dimensionList.length
const name = param.data.dimensionList[length - 1].value
let aCode = null
if (this.currentAcreaNode) {
aCode = this.currentAcreaNode.code
}
// const aCode = this.currentAcreaNode ? this.currentAcreaNode.code : null
const customAttr = JSON.parse(this.chart.customAttr)
const currentNode = this.findEntityByCode(aCode || customAttr.areaCode, this.places)
if (currentNode && currentNode.children && currentNode.children.length > 0) {
const nextNode = currentNode.children.find(item => item.name === name)
// this.view.customAttr.areaCode = nextNode.code
this.currentAcreaNode = nextNode
const current = this.$refs[this.element.propValue.id]
current && current.registerDynamicMap && current.registerDynamicMap(nextNode.code)
}
},
findEntityByCode(code, array) {
if (array === null || array.length === 0) array = this.places
for (let index = 0; index < array.length; index++) {
const node = array[index]
if (node.code === code) return node
if (node.children && node.children.length > 0) {
const temp = this.findEntityByCode(code, node.children)
if (temp) return temp
}
}
},
initAreas() {
let mapping
if ((mapping = localStorage.getItem('areaMapping')) !== null) {
this.places = JSON.parse(mapping)
return
}
Object.keys(this.places).length === 0 && areaMapping().then(res => {
this.places = res.data
localStorage.setItem('areaMapping', JSON.stringify(res.data))
})
},
doMapLink(linkFilters) {
if (!linkFilters && linkFilters.length === 0) return
const value = linkFilters[0].value
if (!value && value.length === 0) return
const name = value[0]
if (!name) return
const areaNode = this.findEntityByname(name, [])
if (!areaNode) return
const current = this.$refs[this.element.propValue.id]
current && current.registerDynamicMap && current.registerDynamicMap(areaNode.code)
},
// 根据地名获取areaCode
findEntityByname(name, array) {
if (array === null || array.length === 0) array = this.places
for (let index = 0; index < array.length; index++) {
const node = array[index]
if (node.name === name) return node
if (node.children && node.children.length > 0) {
const temp = this.findEntityByname(name, node.children)
if (temp) return temp
}
}
}
}
}
......
......@@ -1180,7 +1180,9 @@ export default {
panel_save_tips: 'Do you want to save the changes you made to.',
panel_save_warn_tips: "Your changes will be lost if you don't save them!",
do_not_save: "Don't Save",
save_and_close: 'Save'
save_and_close: 'Save',
drill: 'drill',
linkage: 'linkage'
},
plugin: {
local_install: 'Local installation',
......
......@@ -1180,7 +1180,9 @@ export default {
panel_save_tips: '仪表板已变动,是否保存?',
panel_save_warn_tips: '如果未保存,你对仪表板做的变更将会丢失!',
do_not_save: '不保存',
save: '保存'
save: '保存',
drill: '下钻',
linkage: '联动'
},
plugin: {
local_install: '本地安裝',
......
......@@ -1182,7 +1182,9 @@ export default {
panel_save_tips: '仪表板已变动,是否保存?',
panel_save_warn_tips: '如果未保存,你对仪表板做的变更将会丢失!',
do_not_save: '不保存',
save: '保存'
save: '保存',
drill: '下钻',
linkage: '联动'
},
plugin: {
local_install: '本地安装',
......
<template>
<div id="nolic" style="height:100%;">
<router-view />
</div>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style scoped>
</style>
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/nolic/index.vue'),
meta: {
title: '首页'
}
}
]
})
import Vue from 'vue'
import Nolic from './Nolic.vue'
import router from './nolic-router'
import store from '../store'
import '@/styles/index.scss' // global css
import i18n from '../lang' // internationalization
import ElementUI from 'element-ui'
import '@/components/canvas/custom-component' // 注册自定义组件
import widgets from '@/components/widget'
import * as echarts from 'echarts'
import UmyUi from 'umy-ui'
Vue.use(UmyUi)
Vue.prototype.$echarts = echarts
Vue.config.productionTip = false
Vue.use(widgets)
Vue.use(ElementUI, {
i18n: (key, value) => i18n.t(key, value)
})
new Vue({
router,
store,
i18n,
render: h => h(Nolic)
}).$mount('#nolic')
......@@ -161,7 +161,6 @@ const data = {
// 添加联动 下钻 等过滤组件
addViewTrackFilter(state, data) {
debugger
const viewId = data.viewId
const trackInfo = state.nowPanelTrackInfo
for (let index = 0; index < state.componentData.length; index++) {
......
......@@ -215,35 +215,35 @@
margin: 1em 0;
}
.markdown > p,
.markdown > blockquote,
.markdown > .highlight,
.markdown > ol,
.markdown > ul {
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul > li {
.markdown ul>li {
list-style: circle;
}
.markdown > ul li,
.markdown blockquote ul > li {
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown > ul li p,
.markdown > ol li p {
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol > li {
.markdown ol>li {
list-style: decimal;
}
.markdown > ol li,
.markdown blockquote ol > li {
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
......@@ -260,7 +260,7 @@
font-weight: 600;
}
.markdown > table {
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
......@@ -269,20 +269,20 @@
margin-bottom: 24px;
}
.markdown > table th {
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown > table th,
.markdown > table td {
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown > table th {
.markdown>table th {
background: #F7F7F7;
}
......@@ -318,8 +318,8 @@
display: inline-block;
}
.markdown > br,
.markdown > p > br {
.markdown>br,
.markdown>p>br {
clear: both;
}
......@@ -453,13 +453,13 @@ pre[class*="language-"] {
overflow: auto;
}
:not(pre) > code[class*="language-"],
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
......
......@@ -54,6 +54,48 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe973;</span>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">&amp;#xe973;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6ed;</span>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">&amp;#xe6ed;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6f7;</span>
<div class="name">联动</div>
<div class="code-name">&amp;#xe6f7;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe613;</span>
<div class="name">下钻</div>
<div class="code-name">&amp;#xe613;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe61f;</span>
<div class="name">上钻</div>
<div class="code-name">&amp;#xe61f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe637;</span>
<div class="name">取消联动</div>
<div class="code-name">&amp;#xe637;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe604;</span>
<div class="name">edit-2</div>
<div class="code-name">&amp;#xe604;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe612;</span>
<div class="name">edit-2</div>
......@@ -318,9 +360,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1627282547459') format('woff2'),
url('iconfont.woff?t=1627282547459') format('woff'),
url('iconfont.ttf?t=1627282547459') format('truetype');
src: url('iconfont.woff2?t=1628652979833') format('woff2'),
url('iconfont.woff?t=1628652979833') format('woff'),
url('iconfont.ttf?t=1628652979833') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
......@@ -346,6 +388,69 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-quxiaoshangzuan"></span>
<div class="name">
线性图标-取消下钻
</div>
<div class="code-name">.icon-quxiaoshangzuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-quxiaoxiazuan"></span>
<div class="name">
线性图标-取消下钻
</div>
<div class="code-name">.icon-quxiaoxiazuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-linkage"></span>
<div class="name">
联动
</div>
<div class="code-name">.icon-linkage
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiazuan"></span>
<div class="name">
下钻
</div>
<div class="code-name">.icon-xiazuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shangzuan"></span>
<div class="name">
上钻
</div>
<div class="code-name">.icon-shangzuan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-quxiaoliandong"></span>
<div class="name">
取消联动
</div>
<div class="code-name">.icon-quxiaoliandong
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-edit-outline"></span>
<div class="name">
edit-2
</div>
<div class="code-name">.icon-edit-outline
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-edit"></span>
<div class="name">
......@@ -742,6 +847,62 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaoshangzuan"></use>
</svg>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">#icon-quxiaoshangzuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaoxiazuan"></use>
</svg>
<div class="name">线性图标-取消下钻</div>
<div class="code-name">#icon-quxiaoxiazuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-linkage"></use>
</svg>
<div class="name">联动</div>
<div class="code-name">#icon-linkage</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiazuan"></use>
</svg>
<div class="name">下钻</div>
<div class="code-name">#icon-xiazuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shangzuan"></use>
</svg>
<div class="name">上钻</div>
<div class="code-name">#icon-shangzuan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-quxiaoliandong"></use>
</svg>
<div class="name">取消联动</div>
<div class="code-name">#icon-quxiaoliandong</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-edit-outline"></use>
</svg>
<div class="name">edit-2</div>
<div class="code-name">#icon-edit-outline</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-edit"></use>
......
@font-face {
font-family: "iconfont"; /* Project id 2459092 */
src: url('iconfont.woff2?t=1627282547459') format('woff2'),
url('iconfont.woff?t=1627282547459') format('woff'),
url('iconfont.ttf?t=1627282547459') format('truetype');
src: url('iconfont.woff2?t=1628652979833') format('woff2'),
url('iconfont.woff?t=1628652979833') format('woff'),
url('iconfont.ttf?t=1628652979833') format('truetype');
}
.iconfont {
......@@ -13,6 +13,34 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-quxiaoshangzuan:before {
content: "\e973";
}
.icon-quxiaoxiazuan:before {
content: "\e6ed";
}
.icon-linkage:before {
content: "\e6f7";
}
.icon-xiazuan:before {
content: "\e613";
}
.icon-shangzuan:before {
content: "\e61f";
}
.icon-quxiaoliandong:before {
content: "\e637";
}
.icon-edit-outline:before {
content: "\e604";
}
.icon-edit:before {
content: "\e612";
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -5,6 +5,55 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "23496077",
"name": "线性图标-取消下钻",
"font_class": "quxiaoshangzuan",
"unicode": "e973",
"unicode_decimal": 59763
},
{
"icon_id": "23005499",
"name": "线性图标-取消下钻",
"font_class": "quxiaoxiazuan",
"unicode": "e6ed",
"unicode_decimal": 59117
},
{
"icon_id": "8657066",
"name": "联动",
"font_class": "linkage",
"unicode": "e6f7",
"unicode_decimal": 59127
},
{
"icon_id": "12725578",
"name": "下钻",
"font_class": "xiazuan",
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "13006352",
"name": "上钻",
"font_class": "shangzuan",
"unicode": "e61f",
"unicode_decimal": 58911
},
{
"icon_id": "22983243",
"name": "取消联动",
"font_class": "quxiaoliandong",
"unicode": "e637",
"unicode_decimal": 58935
},
{
"icon_id": "5384479",
"name": "edit-2",
"font_class": "edit-outline",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "3684252",
"name": "edit-2",
......
......@@ -618,7 +618,8 @@ export const BASE_MAP = {
calculable: true,
inRange: {
color: ['lightskyblue', 'yellow', 'orangered']
}
},
right: 0
},
// legend: {},
series: [
......
<template>
<div style="display: flex;">
<view-track-bar ref="viewTrack" :track-menu="trackMenu" class="track-bar" :style="trackBarStyleTime" @trackClick="trackClick" />
<div :id="chartId" style="width: 100%;height: 100%;" />
</div>
</template>
......@@ -18,9 +19,11 @@ import { baseTreemapOption } from '../chart/treemap/treemap'
// import eventBus from '@/components/canvas/utils/eventBus'
import { uuid } from 'vue-uuid'
import { geoJson } from '@/api/map/map'
import ViewTrackBar from '@/components/canvas/components/Editor/ViewTrackBar'
export default {
name: 'ChartComponent',
components: { ViewTrackBar },
props: {
chart: {
type: Object,
......@@ -32,13 +35,35 @@ export default {
default: function() {
return {}
}
},
trackMenu: {
type: Array,
required: false,
default: function() {
return ['drill']
}
}
},
data() {
return {
myChart: {},
chartId: uuid.v1(),
currentGeoJson: null
currentGeoJson: null,
showTrackBar: true,
trackBarStyle: {
position: 'absolute',
left: '0px',
top: '0px'
},
pointParam: null,
downOrUp: false
}
},
computed: {
trackBarStyleTime() {
return this.trackBarStyle
}
},
watch: {
......@@ -60,8 +85,6 @@ export default {
},
methods: {
preDraw() {
const viewId = this.chart.id
const _store = this.$store
// 基于准备好的dom,初始化echarts实例
// 渲染echart等待dom加载完毕,渲染之前先尝试销毁具有相同id的echart 放置多次切换仪表板有重复id情况
const that = this
......@@ -75,15 +98,14 @@ export default {
this.myChart.off('click')
this.myChart.on('click', function(param) {
console.log(JSON.stringify(param.data))
const trackFilter = {
viewId: viewId,
dimensionList: param.data.dimensionList,
quotaList: param.data.quotaList
that.pointParam = param
if (that.trackMenu.length < 2) { // 只有一个事件直接调用
that.trackClick(that.trackMenu[0])
} else { // 视图关联多个事件
that.trackBarStyle.left = param.event.offsetX + 'px'
that.trackBarStyle.top = (param.event.offsetY - 15) + 'px'
that.$refs.viewTrack.trackButtonClick()
}
_store.commit('addViewTrackFilter', trackFilter)
that.$emit('onChartClick', param)
})
})
},
......@@ -123,19 +145,13 @@ export default {
const customAttr = JSON.parse(chart.customAttr)
if (!customAttr.areaCode) return
if (this.currentGeoJson) {
this.initMapChart(this.currentGeoJson, chart)
return
}
if (this.$store.getters.geoMap[customAttr.areaCode]) {
this.currentGeoJson = this.$store.getters.geoMap[customAttr.areaCode]
this.initMapChart(this.currentGeoJson, chart)
const json = this.$store.getters.geoMap[customAttr.areaCode]
this.initMapChart(json, chart)
return
}
geoJson(customAttr.areaCode).then(res => {
// this.initMapChart(res.data, chart)
this.initMapChart(res, chart)
this.$store.dispatch('map/setGeo', {
......@@ -143,16 +159,34 @@ export default {
value: res
// value: res.data
})
// this.currentGeoJson = res.data
this.currentGeoJson = res
})
return
}
this.myEcharts(chart_option)
},
registerDynamicMap(areaCode) {
if (this.$store.getters.geoMap[areaCode]) {
this.downOrUp = true
const json = this.$store.getters.geoMap[areaCode]
this.$echarts.registerMap('MAP', json)
return
}
geoJson(areaCode).then(res => {
this.downOrUp = true
this.$echarts.registerMap('MAP', res)
this.$store.dispatch('map/setGeo', {
key: areaCode,
value: res
})
})
},
initMapChart(geoJson, chart) {
// this.$echarts.registerMap('HK', geoJson)
this.$echarts.getMap('MAP') || this.$echarts.registerMap('MAP', geoJson)
if (!this.$echarts.getMap('MAP') || !this.downOrUp) {
this.$echarts.registerMap('MAP', geoJson)
}
// this.$echarts.getMap('MAP') || this.$echarts.registerMap('MAP', geoJson)
const base_json = JSON.parse(JSON.stringify(BASE_MAP))
const chart_option = baseMapOption(base_json, chart)
this.myEcharts(chart_option)
......@@ -169,6 +203,23 @@ export default {
// 指定图表的配置项和数据
const chart = this.myChart
chart.resize()
},
trackClick(trackAction) {
const linkageParam = {
viewId: this.chart.id,
dimensionList: this.pointParam.data.dimensionList,
quotaList: this.pointParam.data.quotaList
}
switch (trackAction) {
case 'drill':
this.$emit('onChartClick', this.pointParam)
break
case 'linkage':
this.$store.commit('addViewTrackFilter', linkageParam)
break
default:
break
}
}
}
}
......
......@@ -483,7 +483,7 @@
<el-col style="height: 100%;min-width: 500px;border-top: 1px solid #E6E6E6;">
<el-row style="width: 100%;height: 100%;" class="padding-lr">
<div ref="imageWrapper" style="height: 100%">
<chart-component v-if="httpRequest.status && chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :chart-id="chart.id" :chart="chart" class="chart-class" @onChartClick="chartClick" />
<chart-component v-if="httpRequest.status && chart.type && !chart.type.includes('table') && !chart.type.includes('text')" ref="dynamicChart" :chart-id="chart.id" :chart="chart" class="chart-class" @onChartClick="chartClick" />
<table-normal v-if="httpRequest.status && chart.type && chart.type.includes('table')" :chart="chart" class="table-class" />
<label-normal v-if="httpRequest.status && chart.type && chart.type.includes('text')" :chart="chart" class="table-class" />
<div v-if="!httpRequest.status" class="chart-error-class">
......@@ -494,6 +494,9 @@
</div>
</div>
</div>
<div style="position: absolute;left: 20px;bottom:14px;">
<drill-path :drill-filters="drillFilters" @onDrillJump="drillJump" />
</div>
</el-row>
</el-col>
</el-row>
......@@ -603,6 +606,7 @@ import ChartDragItem from '../components/drag-item/ChartDragItem'
import DrillItem from '../components/drag-item/DrillItem'
import ResultFilterEditor from '../components/filter/ResultFilterEditor'
import ChartComponent from '../components/ChartComponent'
import DrillPath from '@/views/chart/view/DrillPath'
import bus from '@/utils/bus'
import DatasetChartDetail from '../../dataset/common/DatasetChartDetail'
// shape attr,component style
......@@ -663,7 +667,8 @@ export default {
DimensionItem,
draggable,
ChartDragItem,
DrillItem
DrillItem,
DrillPath
},
props: {
param: {
......@@ -739,7 +744,8 @@ export default {
places: [],
attrActiveNames: [],
styleActiveNames: [],
drillClickDimensionList: []
drillClickDimensionList: [],
drillFilters: []
}
},
computed: {
......@@ -751,10 +757,10 @@ export default {
},
watch: {
'param': function() {
this.resetDrill()
if (this.param.optType === 'new') {
//
} else {
this.resetDrill()
this.getData(this.param.id)
}
},
......@@ -903,8 +909,8 @@ export default {
// this.get(response.data.id);
// this.getData(response.data.id)
this.resetDrill()
if (getData) {
this.resetDrill()
this.getData(response.data.id)
} else {
this.getChart(response.data.id)
......@@ -1017,6 +1023,7 @@ export default {
if (!response.data.drill) {
this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1)
}
this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters))
}).catch(err => {
this.resetView()
this.resetDrill()
......@@ -1505,13 +1512,87 @@ export default {
},
chartClick(param) {
if (this.drillClickDimensionList.length < this.view.drillFields.length - 1) {
this.chart.type === 'map' && this.sendToChildren(param)
this.drillClickDimensionList.push({ dimensionList: param.data.dimensionList })
this.getData(this.param.id)
}
},
resetDrill() {
const length = this.drillClickDimensionList.length
this.drillClickDimensionList = []
if (this.chart.type === 'map') {
this.backToParent(0, length)
this.currentAcreaNode = null
}
},
drillJump(index) {
const length = this.drillClickDimensionList.length
this.drillClickDimensionList = this.drillClickDimensionList.slice(0, index)
if (this.chart.type === 'map') {
this.backToParent(index, length)
}
this.getData(this.param.id)
},
// 回到父级地图
backToParent(index, length) {
if (length <= 0) return
const times = length - 1 - index
let temp = times
let tempNode = this.currentAcreaNode
while (temp >= 0) {
tempNode = this.findEntityByCode(tempNode.pcode, this.places)
temp--
}
this.currentAcreaNode = tempNode
this.$refs.dynamicChart && this.$refs.dynamicChart.registerDynamicMap && this.$refs.dynamicChart.registerDynamicMap(this.currentAcreaNode.code)
},
// 切换下一级地图
sendToChildren(param) {
const length = param.data.dimensionList.length
const name = param.data.dimensionList[length - 1].value
let aCode = null
if (this.currentAcreaNode) {
aCode = this.currentAcreaNode.code
}
// const aCode = this.currentAcreaNode ? this.currentAcreaNode.code : null
const currentNode = this.findEntityByCode(aCode || this.view.customAttr.areaCode, this.places)
if (currentNode && currentNode.children && currentNode.children.length > 0) {
const nextNode = currentNode.children.find(item => item.name === name)
// this.view.customAttr.areaCode = nextNode.code
this.currentAcreaNode = nextNode
this.$refs.dynamicChart && this.$refs.dynamicChart.registerDynamicMap && this.$refs.dynamicChart.registerDynamicMap(nextNode.code)
}
},
// 根据地名获取areaCode
// findEntityByname(name, array) {
// if (array === null || array.length === 0) array = this.places
// for (let index = 0; index < array.length; index++) {
// const node = array[index]
// if (node.name === name) return node
// if (node.children && node.children.length > 0) {
// const temp = this.findEntityByname(name, node.children)
// if (temp) return temp
// }
// }
// }
findEntityByCode(code, array) {
if (array === null || array.length === 0) array = this.places
for (let index = 0; index < array.length; index++) {
const node = array[index]
if (node.code === code) return node
if (node.children && node.children.length > 0) {
const temp = this.findEntityByCode(code, node.children)
if (temp) return temp
}
}
}
}
}
</script>
......
<template>
<div v-if="drillFilters && drillFilters.length > 0">
<el-breadcrumb separator-class="el-icon-arrow-right" class="drill-style">
<el-breadcrumb-item class="drill-item" @click.native="drillJump(0)">{{ $t('commons.all') }}</el-breadcrumb-item>
<el-breadcrumb-item v-for="(filter,index) in drillFilters" :key="index" class="drill-item" @click.native="drillJump(index + 1)">{{ filter.value[0] }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default {
name: 'DrillPath',
props: {
drillFilters: {
type: Array,
required: true
}
},
data() {
return {
}
},
watch: {
},
mounted() {
},
methods: {
drillJump(index) {
if (index < this.drillFilters.length) {
this.$emit('onDrillJump', index)
}
}
}
}
</script>
<style scoped>
.drill-style {
font-size: 12px;
}
.drill-style >>> .el-breadcrumb__separator{
margin: 0!important;
}
.drill-item{
cursor: pointer;
}
</style>
<template>
<div>缺少许可</div>
</template>
<script>
export default {
}
</script>
......@@ -208,8 +208,9 @@ export default {
{ label: this.$t('commons.disable'), value: '0' }
],
multiple: false
}
// { field: 'deptId', label: '组织', component: conditionTable }
},
{ field: 'd.name', label: this.$t('commons.organization'), component: 'DeComplexInput' },
{ field: 'r.name', label: this.$t('commons.role'), component: 'DeComplexInput' }
]
},
paginationConfig: {
......
......@@ -40,6 +40,11 @@ module.exports = {
entry: 'src/link/link.js',
template: 'public/link.html',
filename: 'link.html'
},
nolic: {
entry: 'src/nolic/nolic.js',
template: 'public/nolic.html',
filename: 'nolic.html'
}
},
configureWebpack: {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论