Merge pull request #13369 from dataease/pr@dev-v2@feat_export_api_permission

feat(X-Pack): 导出API权限独立控制 #12840
This commit is contained in:
fit2cloud-chenyw 2024-11-17 14:24:06 +08:00 committed by GitHub
commit 1050351d9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 61 additions and 21 deletions

View File

@ -55,7 +55,7 @@ import java.util.stream.Collectors;
* @Author Junjun
*/
@RestController
@RequestMapping("chartData")
@RequestMapping("/chartData")
public class ChartDataServer implements ChartDataApi {
@Resource
private ChartDataManage chartDataManage;
@ -230,6 +230,7 @@ public class ChartDataServer implements ChartDataApi {
}
@DeLinkPermit("#p0.dvId")
@Override
public void innerExportDetails(ChartExcelRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
@ -299,6 +300,7 @@ public class ChartDataServer implements ChartDataApi {
}
}
@DeLinkPermit("#p0.dvId")
@Override
public void innerExportDataSetDetails(ChartExcelRequest request, HttpServletResponse response) throws Exception {
this.innerExportDetails(request, response);

View File

@ -19,7 +19,7 @@ import java.util.List;
@Component
public class LinkInterceptor implements HandlerInterceptor {
private final static String whiteListText = "/user/ipInfo, /apisix/check, /datasetData/enumValue, /datasetData/enumValueObj, /datasetData/getFieldTree, /dekey, /symmetricKey, /share/validate, /sysParameter/queryOnlineMap, /chartData/innerExportDetails";
private final static String whiteListText = "/user/ipInfo, /apisix/check, /datasetData/enumValue, /datasetData/enumValueObj, /datasetData/getFieldTree, /dekey, /symmetricKey, /share/validate, /sysParameter/queryOnlineMap";
@Override

View File

@ -135,7 +135,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
@Override
public DataVisualizationVO findCopyResource(Long dvId, String busiFlag) {
DataVisualizationVO result = findById(new DataVisualizationBaseRequest(dvId, busiFlag));
DataVisualizationVO result = Objects.requireNonNull(CommonBeanFactory.proxy(this.getClass())).findById(new DataVisualizationBaseRequest(dvId, busiFlag));
if (result != null && result.getPid() == -1) {
return result;
} else {

View File

@ -173,7 +173,6 @@
v-if="
!['picture-group', 'rich-text'].includes(element.innerType) &&
barShowCheck('previewDownload') &&
authShow &&
showDownload &&
(exportPermissions[0] || exportPermissions[1])
"
@ -242,7 +241,6 @@ const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const copyStore = copyStoreWithOut()
const customTabsSortRef = ref(null)
const authShow = computed(() => !dvInfo.value.weight || dvInfo.value.weight > 3)
const exportPermissions = computed(() =>
exportPermission(dvInfo.value['weight'], dvInfo.value['ext'])
)

View File

@ -73,7 +73,11 @@
>
<span>导出Excel(带格式)</span>
</el-button>
<el-divider class="close-divider" direction="vertical" v-if="authShow" />
<el-divider
class="close-divider"
direction="vertical"
v-if="exportPermissions[0] || exportPermissions[1] || exportPermissions[2]"
/>
</div>
<div
v-loading="downLoading"
@ -212,8 +216,6 @@ const DETAIL_TABLE_ATTR: DeepPartial<ChartObj> = {
showPosition: 'dialog'
}
const authShow = computed(() => editMode.value === 'edit' || dvInfo.value.weight > 3)
const exportPermissions = computed(() =>
exportPermission(dvInfo.value['weight'], dvInfo.value['ext'])
)
@ -337,7 +339,8 @@ const downloadViewDetails = (downloadType = 'view') => {
chartExtRequest,
data: viewDataInfo,
type: sourceViewType.value,
downloadType: downloadType
downloadType: downloadType,
busiFlag: dvInfo.value.type
}
exportLoading.value = true
exportExcelDownload(chart, () => {

View File

@ -331,6 +331,7 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
updateTime: canvasInfo.updateTime,
watermarkInfo: watermarkInfo,
weight: canvasInfo.weight,
ext: canvasInfo.ext,
mobileLayout: canvasInfo.mobileLayout || false
}
const canvasVersion = canvasInfo.version

View File

@ -502,6 +502,7 @@ export const exportExcelDownload = (chart, callBack?) => {
viewId: chart.id,
viewInfo: chart,
viewName: excelName,
busiFlag: chart.busiFlag,
downloadType: chart.downloadType
}
if (chart.type.includes('chart-mix')) {

View File

@ -180,7 +180,7 @@ const initOpenHandler = newWindow => {
style="width: 100%; overflow: hidden"
trigger="hover"
placement="left-start"
v-if="dvInfo.weight > 3"
v-if="exportPermissions[0]"
>
<div class="ed-dropdown-menu__item flex-align-center icon">
<el-icon><Download /></el-icon>
@ -200,7 +200,7 @@ const initOpenHandler = newWindow => {
<el-dropdown-item style="width: 118px" @click="downloadAsAppTemplate('app')">{{
t('visualization.apply_template')
}}</el-dropdown-item>
<el-dropdown-item v-if="exportPermissions[0]" @click="download('img')">{{
<el-dropdown-item @click="download('img')">{{
t('chart.image')
}}</el-dropdown-item>
</el-dropdown-menu>

View File

@ -81,6 +81,7 @@ import { XpackComponent } from '@/components/plugin'
import { useCache } from '@/hooks/web/useCache'
import { RefreshLeft } from '@element-plus/icons-vue'
import { iconFieldMap } from '@/components/icon-group/field-list'
import { exportPermission } from '@/utils/utils'
const { t } = useI18n()
const interactiveStore = interactiveStoreWithOut()
const { wsCache } = useCache()
@ -100,6 +101,7 @@ interface Node {
nodeType: string
createTime: number
weight: number
ext?: number
}
const appStore = useAppStoreWithOut()
const rootManage = ref(false)
@ -141,6 +143,7 @@ const mounted = ref(false)
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
const isIframe = computed(() => appStore.getIsIframe)
const exportPermissions = computed(() => exportPermission(nodeInfo.weight, nodeInfo.ext))
const createPanel = path => {
const baseUrl = `#/${path}?opt=create&id=${nodeInfo.id}`
window.open(baseUrl, '_blank')
@ -356,6 +359,7 @@ const handleNodeClick = (data: BusiTreeNode) => {
const nodeData = res as unknown as Node[]
Object.assign(nodeInfo, nodeData)
nodeInfo.weight = data.weight
nodeInfo.ext = data.ext || 0
columnsPreview = []
dataPreview = []
activeName.value = 'dataPreview'
@ -968,7 +972,7 @@ const getMenuList = (val: boolean) => {
/></Icon> </template
>{{ t('data_set.new_data_screen') }}
</el-button>
<el-button secondary @click="exportDataset">
<el-button v-if="exportPermissions[0]" secondary @click="exportDataset">
<template #icon>
<Icon name="icon_download_outlined"
><icon_download_outlined class="svg-icon"

@ -1 +1 @@
Subproject commit bba26306bc91332d6c62e0638a28ed4bc653c13c
Subproject commit 7dc82ac0883ef2463995f5c82fa800379fefbea4

View File

@ -2,6 +2,8 @@ package io.dataease.api.chart;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.api.chart.request.ChartExcelRequest;
import io.dataease.auth.DeApiPath;
import io.dataease.auth.DePermit;
import io.dataease.extensions.view.dto.ChartViewDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -12,29 +14,34 @@ import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
import static io.dataease.constant.AuthResourceEnum.PANEL;
/**
* @Author Junjun
*/
@Tag(name = "图表管理:数据")
@ApiSupport(order = 989)
@DeApiPath(value = "/chartData", rt = PANEL)
public interface ChartDataApi {
@Operation(summary = "获取图表数据")
@PostMapping("getData")
ChartViewDTO getData(@RequestBody ChartViewDTO chartViewDTO) throws Exception;
@Operation(summary = "导出数据")
@PostMapping("innerExportDetails")
@PostMapping("/innerExportDetails")
@DePermit(value = {"#p0.dvId+':export_view'"}, busiFlag = "#p0.busiFlag")
void innerExportDetails(@RequestBody ChartExcelRequest request, HttpServletResponse response) throws Exception;
@Operation(summary = "导出明细数据")
@PostMapping("innerExportDataSetDetails")
@PostMapping("/innerExportDataSetDetails")
@DePermit(value = {"#p0.dvId+':export_detail'"}, busiFlag = "#p0.busiFlag")
void innerExportDataSetDetails(@RequestBody ChartExcelRequest request, HttpServletResponse response) throws Exception;
@Operation(summary = "获取字段值")
@PostMapping("getFieldData/{fieldId}/{fieldType}")
@PostMapping("/getFieldData/{fieldId}/{fieldType}")
List<String> getFieldData(@RequestBody ChartViewDTO view, @PathVariable Long fieldId, @PathVariable String fieldType) throws Exception;
@Operation(summary = "获取下钻字段值")
@PostMapping("getDrillFieldData/{fieldId}")
@PostMapping("/getDrillFieldData/{fieldId}")
List<String> getDrillFieldData(@RequestBody ChartViewDTO view, @PathVariable Long fieldId) throws Exception;
}

View File

@ -17,6 +17,8 @@ public class ChartExcelRequest extends ChartExcelRequestInner {
private String dvId;
private String busiFlag;
private String viewId;
private String viewName;

View File

@ -1,6 +1,7 @@
package io.dataease.api.dataset;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.api.dataset.dto.DataSetExportRequest;
import io.dataease.api.dataset.dto.DatasetNodeDTO;
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
import io.dataease.api.dataset.vo.DataSetBarVO;
@ -10,7 +11,6 @@ import io.dataease.extensions.datasource.dto.DatasetTableDTO;
import io.dataease.extensions.view.dto.SqlVariableDetails;
import io.dataease.model.BusiNodeRequest;
import io.dataease.model.BusiNodeVO;
import io.dataease.api.dataset.dto.DataSetExportRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
@ -98,7 +98,8 @@ public interface DatasetTreeApi {
@PostMapping("detailWithPerm")
List<DatasetTableDTO> detailWithPerm(@RequestBody List<Long> ids) throws Exception;
@DePermit(value = {"#p0.id+':export'"})
@Operation(summary = "数据集导出")
@PostMapping("/exportDataset")
public void exportDataset(@RequestBody DataSetExportRequest request) throws Exception;
void exportDataset(@RequestBody DataSetExportRequest request) throws Exception;
}

View File

@ -7,6 +7,7 @@ import io.dataease.api.permissions.auth.dto.BusiPerCheckDTO;
import io.dataease.api.permissions.auth.dto.BusiResourceCreator;
import io.dataease.api.permissions.auth.dto.BusiResourceEditor;
import io.dataease.api.permissions.auth.dto.BusiResourceMover;
import io.dataease.api.permissions.auth.vo.PermissionValVO;
import io.dataease.api.permissions.auth.vo.ResourceNodeVO;
import io.dataease.model.BusiNodeRequest;
import io.dataease.model.BusiNodeVO;
@ -75,8 +76,8 @@ public interface InteractiveAuthApi {
@Operation(summary = "权限查询")
@ApiOperationSupport(order = 9)
@PostMapping("/queryAuth")
Integer queryAuth(@RequestBody BusiPerCheckDTO checkDTO);
@PostMapping("/queryAuth/{id}")
PermissionValVO queryAuth(@PathVariable("id") Long id);
@GetMapping("/query2Root/{id}/{flag}")
List<ResourceNodeVO> query2Root(@PathVariable("id") Long id, @PathVariable("flag") Integer flag);

View File

@ -0,0 +1,20 @@
package io.dataease.api.permissions.auth.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class PermissionValVO implements Serializable {
@Serial
private static final long serialVersionUID = -6677497144947905694L;
private int weight;
private int ext;
}