feat(仪表板、数据大屏): 仪表板和数据大屏从编辑到保存期间若被其他人保存了,则给出提示,支持覆盖和取消
This commit is contained in:
parent
facf7a1477
commit
643eb9b0bb
@ -128,6 +128,16 @@ public class DataVisualizationInfo implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Integer version;
|
private Integer version;
|
||||||
|
|
||||||
|
private String contentId;
|
||||||
|
|
||||||
|
public String getContentId() {
|
||||||
|
return contentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentId(String contentId) {
|
||||||
|
this.contentId = contentId;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,11 @@ import org.apache.ibatis.annotations.Mapper;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Mapper 接口
|
* 可视化大屏信息表 Mapper 接口
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author fit2cloud
|
* @author fit2cloud
|
||||||
* @since 2024-04-11
|
* @since 2024-11-18
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface DataVisualizationInfoMapper extends BaseMapper<DataVisualizationInfo> {
|
public interface DataVisualizationInfoMapper extends BaseMapper<DataVisualizationInfo> {
|
||||||
|
|||||||
@ -429,6 +429,25 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String checkCanvasChange(DataVisualizationBaseRequest request) {
|
||||||
|
Long dvId = request.getId();
|
||||||
|
Boolean checkHistory = request.getCheckHistory();
|
||||||
|
if (dvId == null) {
|
||||||
|
DEException.throwException("ID can not be null");
|
||||||
|
}
|
||||||
|
// 内容ID校验
|
||||||
|
if(checkHistory !=null && checkHistory){
|
||||||
|
QueryWrapper<DataVisualizationInfo> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("content_id", request.getContentId());
|
||||||
|
queryWrapper.eq("id", dvId);
|
||||||
|
if (visualizationInfoMapper.exists(queryWrapper)) {
|
||||||
|
return "Repeat";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, stExp = "#p0.type")
|
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, stExp = "#p0.type")
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|||||||
@ -1,2 +1,6 @@
|
|||||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||||
VALUES (1048232869488627719, 'basic.defaultSort', '1', 'text', 13);
|
VALUES (1048232869488627719, 'basic.defaultSort', '1', 'text', 13);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE `data_visualization_info`
|
||||||
|
ADD COLUMN `content_id` varchar(50) NULL DEFAULT '0' COMMENT '内容标识';
|
||||||
|
|||||||
@ -3,4 +3,7 @@ VALUES (1048232869488627719, 'basic.defaultSort', '1', 'text', 13);
|
|||||||
|
|
||||||
INSERT INTO `core_menu` VALUES (70, 0, 1, 'msg', NULL, 200, NULL, '/msg', 1, 1, 0);
|
INSERT INTO `core_menu` VALUES (70, 0, 1, 'msg', NULL, 200, NULL, '/msg', 1, 1, 0);
|
||||||
|
|
||||||
UPDATE `xpack_setting_authentication` set `synced` = 0 where `name` = 'oidc' or name = 'cas';
|
UPDATE `xpack_setting_authentication` set `synced` = 0 where `name` = 'oidc' or name = 'cas';
|
||||||
|
|
||||||
|
ALTER TABLE `data_visualization_info`
|
||||||
|
ADD COLUMN `content_id` varchar(50) NULL DEFAULT '0' COMMENT '内容标识';
|
||||||
|
|||||||
@ -166,7 +166,8 @@
|
|||||||
`delete_flag`,
|
`delete_flag`,
|
||||||
`delete_time`,
|
`delete_time`,
|
||||||
`delete_by`,
|
`delete_by`,
|
||||||
`version`
|
`version`,
|
||||||
|
`content_id`
|
||||||
FROM data_visualization_info
|
FROM data_visualization_info
|
||||||
where data_visualization_info.delete_flag = 0
|
where data_visualization_info.delete_flag = 0
|
||||||
and data_visualization_info.id = #{dvId}
|
and data_visualization_info.id = #{dvId}
|
||||||
|
|||||||
@ -52,6 +52,9 @@ export const findDvType = async dvId =>
|
|||||||
|
|
||||||
export const save = data => request.post({ url: '/dataVisualization/save', data })
|
export const save = data => request.post({ url: '/dataVisualization/save', data })
|
||||||
|
|
||||||
|
export const checkCanvasChange = data =>
|
||||||
|
request.post({ url: '/dataVisualization/checkCanvasChange', data, loading: true })
|
||||||
|
|
||||||
export const saveCanvas = data =>
|
export const saveCanvas = data =>
|
||||||
request.post({ url: '/dataVisualization/saveCanvas', data, loading: true })
|
request.post({ url: '/dataVisualization/saveCanvas', data, loading: true })
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,13 @@ import MediaGroup from '@/custom-component/component-group/MediaGroup.vue'
|
|||||||
import TextGroup from '@/custom-component/component-group/TextGroup.vue'
|
import TextGroup from '@/custom-component/component-group/TextGroup.vue'
|
||||||
import CommonGroup from '@/custom-component/component-group/CommonGroup.vue'
|
import CommonGroup from '@/custom-component/component-group/CommonGroup.vue'
|
||||||
import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue'
|
import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue'
|
||||||
import { canvasSave, initCanvasData } from '@/utils/canvasUtils'
|
import {
|
||||||
|
canvasSave,
|
||||||
|
checkCanvasChangePre,
|
||||||
|
checkCanvasHistory,
|
||||||
|
confirmUpdateCanvas,
|
||||||
|
initCanvasData
|
||||||
|
} from '@/utils/canvasUtils'
|
||||||
import { changeSizeWithScale } from '@/utils/changeComponentsSizeWithScale'
|
import { changeSizeWithScale } from '@/utils/changeComponentsSizeWithScale'
|
||||||
import MoreComGroup from '@/custom-component/component-group/MoreComGroup.vue'
|
import MoreComGroup from '@/custom-component/component-group/MoreComGroup.vue'
|
||||||
import { XpackComponent } from '@/components/plugin'
|
import { XpackComponent } from '@/components/plugin'
|
||||||
@ -41,6 +47,7 @@ import DeAppApply from '@/views/common/DeAppApply.vue'
|
|||||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
import { useUserStoreWithOut } from '@/store/modules/user'
|
import { useUserStoreWithOut } from '@/store/modules/user'
|
||||||
import TabsGroup from '@/custom-component/component-group/TabsGroup.vue'
|
import TabsGroup from '@/custom-component/component-group/TabsGroup.vue'
|
||||||
|
import { checkCanvasChange } from '@/api/visualization/dataVisualization'
|
||||||
let nameEdit = ref(false)
|
let nameEdit = ref(false)
|
||||||
let inputName = ref('')
|
let inputName = ref('')
|
||||||
let nameInput = ref(null)
|
let nameInput = ref(null)
|
||||||
@ -150,7 +157,9 @@ const saveCanvasWithCheck = () => {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
saveResource()
|
checkCanvasChangePre(() => {
|
||||||
|
saveResource()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveResource = () => {
|
const saveResource = () => {
|
||||||
|
|||||||
@ -1348,7 +1348,8 @@ export const dvMainStore = defineStore('dataVisualization', {
|
|||||||
selfWatermarkStatus: null,
|
selfWatermarkStatus: null,
|
||||||
watermarkInfo: {},
|
watermarkInfo: {},
|
||||||
type: null,
|
type: null,
|
||||||
mobileLayout: false
|
mobileLayout: false,
|
||||||
|
contentId: 0
|
||||||
}
|
}
|
||||||
this.mainScrollTop = 0
|
this.mainScrollTop = 0
|
||||||
},
|
},
|
||||||
@ -1396,13 +1397,16 @@ export const dvMainStore = defineStore('dataVisualization', {
|
|||||||
getViewDetails(viewId) {
|
getViewDetails(viewId) {
|
||||||
return this.canvasViewInfo[viewId]
|
return this.canvasViewInfo[viewId]
|
||||||
},
|
},
|
||||||
updateDvInfoId(newId) {
|
updateDvInfoId(newId, contentId?) {
|
||||||
if (this.dvInfo) {
|
if (this.dvInfo) {
|
||||||
this.dvInfo.dataState = 'ready'
|
this.dvInfo.dataState = 'ready'
|
||||||
this.dvInfo.optType = null
|
this.dvInfo.optType = null
|
||||||
if (newId) {
|
if (newId) {
|
||||||
this.dvInfo.id = newId
|
this.dvInfo.id = newId
|
||||||
}
|
}
|
||||||
|
if (contentId) {
|
||||||
|
this.dvInfo.contentId = contentId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
popAreaActiveSwitch() {
|
popAreaActiveSwitch() {
|
||||||
@ -1430,7 +1434,8 @@ export const dvMainStore = defineStore('dataVisualization', {
|
|||||||
status: 1,
|
status: 1,
|
||||||
selfWatermarkStatus: true,
|
selfWatermarkStatus: true,
|
||||||
watermarkInfo: watermarkInfo,
|
watermarkInfo: watermarkInfo,
|
||||||
mobileLayout: false
|
mobileLayout: false,
|
||||||
|
contentId: '0'
|
||||||
}
|
}
|
||||||
const canvasStyleDataNew =
|
const canvasStyleDataNew =
|
||||||
dvType === 'dashboard'
|
dvType === 'dashboard'
|
||||||
@ -1472,7 +1477,8 @@ export const dvMainStore = defineStore('dataVisualization', {
|
|||||||
selfWatermarkStatus: null,
|
selfWatermarkStatus: null,
|
||||||
watermarkInfo: {},
|
watermarkInfo: {},
|
||||||
type: null,
|
type: null,
|
||||||
mobileLayout: false
|
mobileLayout: false,
|
||||||
|
contentId: '0'
|
||||||
}
|
}
|
||||||
this.canvasStyleData = { ...deepCopy(DEFAULT_CANVAS_STYLE_DATA_DARK), backgroundColor: null }
|
this.canvasStyleData = { ...deepCopy(DEFAULT_CANVAS_STYLE_DATA_DARK), backgroundColor: null }
|
||||||
},
|
},
|
||||||
|
|||||||
@ -11,7 +11,9 @@ import eventBus from '@/utils/eventBus'
|
|||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import {
|
import {
|
||||||
appCanvasNameCheck,
|
appCanvasNameCheck,
|
||||||
|
checkCanvasChange,
|
||||||
decompression,
|
decompression,
|
||||||
|
deleteLogic,
|
||||||
dvNameCheck,
|
dvNameCheck,
|
||||||
findById,
|
findById,
|
||||||
findCopyResource,
|
findCopyResource,
|
||||||
@ -27,7 +29,8 @@ import {
|
|||||||
} from '@/views/chart/components/editor/util/chart'
|
} from '@/views/chart/components/editor/util/chart'
|
||||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||||
import { deepCopy } from '@/utils/utils'
|
import { deepCopy } from '@/utils/utils'
|
||||||
import { ElMessage } from 'element-plus-secondary'
|
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
|
||||||
|
import { guid } from '@/views/visualized/data/dataset/form/util'
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const {
|
const {
|
||||||
inMobile,
|
inMobile,
|
||||||
@ -332,6 +335,7 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
|
|||||||
watermarkInfo: watermarkInfo,
|
watermarkInfo: watermarkInfo,
|
||||||
weight: canvasInfo.weight,
|
weight: canvasInfo.weight,
|
||||||
ext: canvasInfo.ext,
|
ext: canvasInfo.ext,
|
||||||
|
contentId: canvasInfo.contentId,
|
||||||
mobileLayout: canvasInfo.mobileLayout || false
|
mobileLayout: canvasInfo.mobileLayout || false
|
||||||
}
|
}
|
||||||
const canvasVersion = canvasInfo.version
|
const canvasVersion = canvasInfo.version
|
||||||
@ -517,6 +521,34 @@ export function checkIsBatchOptView(viewId) {
|
|||||||
return curBatchOptComponents.value.includes(viewId)
|
return curBatchOptComponents.value.includes(viewId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function checkCanvasHistory(callBack) {
|
||||||
|
ElMessageBox.confirm('当前存在变更是否覆盖', {
|
||||||
|
confirmButtonType: 'danger',
|
||||||
|
type: 'warning',
|
||||||
|
tip: '确认覆盖',
|
||||||
|
autofocus: false,
|
||||||
|
showClose: false
|
||||||
|
}).then(() => {
|
||||||
|
callBack()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkCanvasChangePre(callBack) {
|
||||||
|
// do pre
|
||||||
|
const isUpdate = dvInfo.value.id && dvInfo.value.optType !== 'copy'
|
||||||
|
if (isUpdate) {
|
||||||
|
checkCanvasChange(dvInfo.value).then(rsp => {
|
||||||
|
if (rsp.data === 'Repeat') {
|
||||||
|
checkCanvasHistory(() => {
|
||||||
|
callBack()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
callBack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function canvasSave(callBack) {
|
export async function canvasSave(callBack) {
|
||||||
dvMainStore.removeGroupArea()
|
dvMainStore.removeGroupArea()
|
||||||
const componentDataToSave = cloneDeep(componentData.value)
|
const componentDataToSave = cloneDeep(componentData.value)
|
||||||
@ -535,12 +567,14 @@ export async function canvasSave(callBack) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const newContentId = guid()
|
||||||
const canvasInfo = {
|
const canvasInfo = {
|
||||||
canvasStyleData: JSON.stringify(canvasStyleData.value),
|
canvasStyleData: JSON.stringify(canvasStyleData.value),
|
||||||
componentData: JSON.stringify(componentDataToSave),
|
componentData: JSON.stringify(componentDataToSave),
|
||||||
canvasViewInfo: canvasViewInfo.value,
|
canvasViewInfo: canvasViewInfo.value,
|
||||||
appData: appData.value,
|
appData: appData.value,
|
||||||
...dvInfo.value,
|
...dvInfo.value,
|
||||||
|
contentId: newContentId,
|
||||||
watermarkInfo: null
|
watermarkInfo: null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,7 +591,6 @@ export async function canvasSave(callBack) {
|
|||||||
ElMessage.error('数据集分组名称已存在')
|
ElMessage.error('数据集分组名称已存在')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const method = dvInfo.value.id && dvInfo.value.optType !== 'copy' ? updateCanvas : saveCanvas
|
const method = dvInfo.value.id && dvInfo.value.optType !== 'copy' ? updateCanvas : saveCanvas
|
||||||
if (method === updateCanvas) {
|
if (method === updateCanvas) {
|
||||||
await dvNameCheck({
|
await dvNameCheck({
|
||||||
|
|||||||
@ -53,6 +53,11 @@ public interface DataVisualizationApi {
|
|||||||
@Operation(summary = "应用名称检查")
|
@Operation(summary = "应用名称检查")
|
||||||
String appCanvasNameCheck(@RequestBody DataVisualizationBaseRequest request) throws Exception;
|
String appCanvasNameCheck(@RequestBody DataVisualizationBaseRequest request) throws Exception;
|
||||||
|
|
||||||
|
@PostMapping("/checkCanvasChange")
|
||||||
|
@DePermit(value = {"#p0.id + ':manage'"}, busiFlag = "#p0.type")
|
||||||
|
@Operation(summary = "画布变动校验")
|
||||||
|
String checkCanvasChange(@RequestBody DataVisualizationBaseRequest request);
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/updateCanvas")
|
@PostMapping("/updateCanvas")
|
||||||
@DePermit(value = {"#p0.id + ':manage'"}, busiFlag = "#p0.type")
|
@DePermit(value = {"#p0.id + ':manage'"}, busiFlag = "#p0.type")
|
||||||
|
|||||||
@ -51,6 +51,12 @@ public class DataVisualizationBaseRequest extends DataVisualizationVO {
|
|||||||
// 数据集分组名称
|
// 数据集分组名称
|
||||||
private String datasetFolderName;
|
private String datasetFolderName;
|
||||||
|
|
||||||
|
//新赋值的content_id
|
||||||
|
private String newContentId;
|
||||||
|
|
||||||
|
// 是否强制校验新旧contentId
|
||||||
|
private Boolean checkHistory = false;
|
||||||
|
|
||||||
|
|
||||||
public DataVisualizationBaseRequest(Long id,String busiFlag) {
|
public DataVisualizationBaseRequest(Long id,String busiFlag) {
|
||||||
this.busiFlag = busiFlag;
|
this.busiFlag = busiFlag;
|
||||||
|
|||||||
@ -145,6 +145,11 @@ public class DataVisualizationVO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Integer version;
|
private Integer version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容标识
|
||||||
|
*/
|
||||||
|
private String contentId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图表基本信息
|
* 图表基本信息
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user