mirror of
https://github.com/dataease/dataease.git
synced 2025-02-24 11:32:57 +08:00
parent
ad75afa456
commit
e7d2cc82b9
@ -3,6 +3,7 @@ package io.dataease.share.manage;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.dataease.api.system.vo.ShareBaseVO;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackShareProxyRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackSharePwdValidator;
|
||||
@ -21,6 +22,7 @@ import io.dataease.share.dao.auto.mapper.XpackShareMapper;
|
||||
import io.dataease.share.dao.ext.mapper.XpackShareExtMapper;
|
||||
import io.dataease.share.dao.ext.po.XpackSharePO;
|
||||
import io.dataease.share.util.LinkTokenUtil;
|
||||
import io.dataease.system.manage.SysParameterManage;
|
||||
import io.dataease.utils.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@ -51,6 +53,9 @@ public class XpackShareManage {
|
||||
@Resource
|
||||
private ShareTicketManage shareTicketManage;
|
||||
|
||||
@Resource
|
||||
private SysParameterManage sysParameterManage;
|
||||
|
||||
public XpackShare queryByResource(Long resourceId) {
|
||||
Long userId = AuthUtils.getUser().getUserId();
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
@ -190,7 +195,20 @@ public class XpackShareManage {
|
||||
return CommonBeanFactory.getBean(this.getClass());
|
||||
}
|
||||
|
||||
private boolean peRequireValid(ShareBaseVO sharedBase, XpackShare share) {
|
||||
if (ObjectUtils.isEmpty(sharedBase) || !sharedBase.isPeRequire()) return true;
|
||||
Long exp = share.getExp();
|
||||
String pwd = share.getPwd();
|
||||
return StringUtils.isNotBlank(pwd) && ObjectUtils.isNotEmpty(exp);
|
||||
}
|
||||
|
||||
public XpackShareProxyVO proxyInfo(XpackShareProxyRequest request) {
|
||||
ShareBaseVO sharedBase = sysParameterManage.shareBase();
|
||||
if (ObjectUtils.isNotEmpty(sharedBase) && sharedBase.isDisable()) {
|
||||
XpackShareProxyVO vo = new XpackShareProxyVO();
|
||||
vo.setShareDisable(true);
|
||||
return vo;
|
||||
}
|
||||
boolean inIframeError = request.isInIframe() && !LicenseUtil.licenseValid();
|
||||
if (inIframeError) {
|
||||
return new XpackShareProxyVO();
|
||||
@ -200,13 +218,18 @@ public class XpackShareManage {
|
||||
XpackShare xpackShare = xpackShareMapper.selectOne(queryWrapper);
|
||||
if (ObjectUtils.isEmpty(xpackShare))
|
||||
return null;
|
||||
if (!peRequireValid(sharedBase, xpackShare)) {
|
||||
XpackShareProxyVO vo = new XpackShareProxyVO();
|
||||
vo.setPeRequireValid(false);
|
||||
return vo;
|
||||
}
|
||||
String linkToken = LinkTokenUtil.generate(xpackShare.getCreator(), xpackShare.getResourceId(), xpackShare.getExp(), xpackShare.getPwd(), xpackShare.getOid());
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
response.addHeader(AuthConstant.LINK_TOKEN_KEY, linkToken);
|
||||
Integer type = xpackShare.getType();
|
||||
String typeText = (ObjectUtils.isNotEmpty(type) && type == 1) ? "dashboard" : "dataV";
|
||||
TicketValidVO validVO = shareTicketManage.validateTicket(request.getTicket(), xpackShare);
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError, validVO);
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError, false, true, validVO);
|
||||
}
|
||||
|
||||
private boolean linkExp(XpackShare xpackShare) {
|
||||
|
@ -3,6 +3,7 @@ package io.dataease.system.manage;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.dataease.api.system.request.OnlineMapEditor;
|
||||
import io.dataease.api.system.vo.SettingItemVO;
|
||||
import io.dataease.api.system.vo.ShareBaseVO;
|
||||
import io.dataease.datasource.server.DatasourceServer;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.system.dao.auto.entity.CoreSysSetting;
|
||||
@ -20,7 +21,6 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -159,4 +159,17 @@ public class SysParameterManage {
|
||||
private SysParameterManage proxy() {
|
||||
return CommonBeanFactory.getBean(SysParameterManage.class);
|
||||
}
|
||||
|
||||
public ShareBaseVO shareBase() {
|
||||
String disableText = singleVal("basic.shareDisable");
|
||||
String requireText = singleVal("basic.sharePeRequire");
|
||||
ShareBaseVO vo = new ShareBaseVO();
|
||||
if (StringUtils.isNotBlank(disableText) && StringUtils.equals("true", disableText)) {
|
||||
vo.setDisable(true);
|
||||
}
|
||||
if (StringUtils.isNotBlank(requireText) && StringUtils.equals("true", requireText)) {
|
||||
vo.setPeRequire(true);
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package io.dataease.system.server;
|
||||
import io.dataease.api.system.SysParameterApi;
|
||||
import io.dataease.api.system.request.OnlineMapEditor;
|
||||
import io.dataease.api.system.vo.SettingItemVO;
|
||||
import io.dataease.api.system.vo.ShareBaseVO;
|
||||
import io.dataease.constant.XpackSettingConstants;
|
||||
import io.dataease.system.dao.auto.entity.CoreSysSetting;
|
||||
import io.dataease.system.manage.SysParameterManage;
|
||||
@ -69,4 +70,9 @@ public class SysParameterServer implements SysParameterApi {
|
||||
public Integer defaultLogin() {
|
||||
return sysParameterManage.defaultLogin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShareBaseVO shareBase() {
|
||||
return sysParameterManage.shareBase();
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,24 @@
|
||||
INSERT INTO area (id, level, name, pid) VALUES ('156440315', 'district', '大鹏新区', '156440300');
|
||||
INSERT INTO area (id, level, name, pid)
|
||||
VALUES ('156440315', 'district', '大鹏新区', '156440300');
|
||||
|
||||
DELETE ccv
|
||||
FROM
|
||||
core_chart_view ccv
|
||||
INNER JOIN data_visualization_info dvi ON ccv.scene_id = dvi.id
|
||||
WHERE
|
||||
dvi.delete_flag =1;
|
||||
delete from data_visualization_info dvi where dvi.delete_flag =1;
|
||||
DELETE FROM area where pid = '156710100' OR id = '156710100';
|
||||
FROM core_chart_view ccv
|
||||
INNER JOIN data_visualization_info dvi ON ccv.scene_id = dvi.id
|
||||
WHERE dvi.delete_flag = 1;
|
||||
delete
|
||||
from data_visualization_info dvi
|
||||
where dvi.delete_flag = 1;
|
||||
DELETE
|
||||
FROM area
|
||||
where pid = '156710100'
|
||||
OR id = '156710100';
|
||||
|
||||
ALTER TABLE `core_chart_view`
|
||||
ADD COLUMN `custom_attr_mobile` longtext NULL COMMENT '图形属性_移动端' AFTER `custom_attr`,
|
||||
ADD COLUMN `custom_style_mobile` longtext NULL COMMENT '组件样式_移动端' AFTER `custom_style`;
|
||||
ADD COLUMN `custom_attr_mobile` longtext NULL COMMENT '图形属性_移动端' AFTER `custom_attr`,
|
||||
ADD COLUMN `custom_style_mobile` longtext NULL COMMENT '组件样式_移动端' AFTER `custom_style`;
|
||||
|
||||
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627717, 'basic.shareDisable', 'false', 'text', 11);
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627718, 'basic.sharePeRequire', 'false', 'text', 12);
|
@ -121,3 +121,10 @@ export const queryOuterParamsDsInfo = async dvId => {
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
||||
export const queryShareBaseApi = () => {
|
||||
return request.get({
|
||||
url: '/sysParameter/shareBase',
|
||||
loading: false
|
||||
})
|
||||
}
|
||||
|
@ -3,8 +3,11 @@ import { Icon } from '@/components/icon-custom'
|
||||
import icon_more_outlined from '@/assets/svg/icon_more_outlined.svg'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import type { Placement } from 'element-plus-secondary'
|
||||
import { ref, PropType } from 'vue'
|
||||
import { ref, PropType, computed } from 'vue'
|
||||
import ShareHandler from '@/views/share/share/ShareHandler.vue'
|
||||
import { useShareStoreWithOut } from '@/store/modules/share'
|
||||
const shareStore = useShareStoreWithOut()
|
||||
|
||||
export interface Menu {
|
||||
svgName?: string
|
||||
label?: string
|
||||
@ -34,6 +37,10 @@ const props = defineProps({
|
||||
anyManage: propTypes.bool.def(false)
|
||||
})
|
||||
|
||||
const shareDisable = computed(() => {
|
||||
return shareStore.getShareDisable
|
||||
})
|
||||
|
||||
const shareComponent = ref(null)
|
||||
const menus = ref([
|
||||
...props.menuList.map(item => {
|
||||
@ -52,6 +59,9 @@ const handleCommand = (command: string | number | object) => {
|
||||
emit('handleCommand', command)
|
||||
}
|
||||
const callBack = param => {
|
||||
if (shareDisable.value) {
|
||||
return
|
||||
}
|
||||
if (props.node.leaf && props.node?.weight >= 7) {
|
||||
menus.value[0]['divided'] = true
|
||||
menus.value.splice(0, 0, param)
|
||||
@ -89,6 +99,7 @@ const emit = defineEmits(['handleCommand'])
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<ShareHandler
|
||||
v-if="!shareDisable"
|
||||
ref="shareComponent"
|
||||
:resource-id="props.node.id"
|
||||
:resource-type="props.resourceType"
|
||||
|
@ -2617,7 +2617,9 @@ export default {
|
||||
pwdStrategy: '开启密码策略',
|
||||
dip: '禁用初始密码',
|
||||
pvp: '密码有效期',
|
||||
defaultLogin: '默认登录方式'
|
||||
defaultLogin: '默认登录方式',
|
||||
shareDisable: '禁用分享',
|
||||
sharePeRequire: '分享有效期密码必填'
|
||||
},
|
||||
setting_email: {
|
||||
title: '邮件设置',
|
||||
|
34
core/core-frontend/src/store/modules/share.ts
Normal file
34
core/core-frontend/src/store/modules/share.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { store } from '@/store/index'
|
||||
|
||||
interface ShareState {
|
||||
shareDisable: boolean
|
||||
sharePeRequire: boolean
|
||||
}
|
||||
|
||||
export const useShareStore = defineStore('shareStore', {
|
||||
state: (): ShareState => {
|
||||
return {
|
||||
shareDisable: false,
|
||||
sharePeRequire: false
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getShareDisable(): boolean {
|
||||
return this.shareDisable
|
||||
},
|
||||
getSharePeRequire(): boolean {
|
||||
return this.sharePeRequire
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setData(data: ShareState) {
|
||||
this.shareDisable = data.shareDisable
|
||||
this.sharePeRequire = data.sharePeRequire
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const useShareStoreWithOut = () => {
|
||||
return useShareStore(store)
|
||||
}
|
@ -17,7 +17,12 @@ import dvFolder from '@/assets/svg/dv-folder.svg'
|
||||
import icon_operationAnalysis_outlined from '@/assets/svg/icon_operation-analysis_outlined.svg'
|
||||
import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
|
||||
import { onMounted, reactive, ref, toRefs, watch, nextTick, computed } from 'vue'
|
||||
import { copyResource, deleteLogic, ResourceOrFolder } from '@/api/visualization/dataVisualization'
|
||||
import {
|
||||
copyResource,
|
||||
deleteLogic,
|
||||
ResourceOrFolder,
|
||||
queryShareBaseApi
|
||||
} from '@/api/visualization/dataVisualization'
|
||||
import { ElIcon, ElMessage, ElMessageBox, ElScrollbar } from 'element-plus-secondary'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
@ -30,6 +35,8 @@ import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import DvHandleMore from '@/components/handle-more/src/DvHandleMore.vue'
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import { useShareStoreWithOut } from '@/store/modules/share'
|
||||
const shareStore = useShareStoreWithOut()
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
import router from '@/router'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
@ -503,9 +510,20 @@ const loadInit = () => {
|
||||
state.curSortType = historyTreeSort
|
||||
}
|
||||
}
|
||||
|
||||
const loadShareBase = () => {
|
||||
queryShareBaseApi().then(res => {
|
||||
const param = {
|
||||
shareDisable: res.data?.disable,
|
||||
sharePeRequire: res.data?.peRequire
|
||||
}
|
||||
shareStore.setData(param)
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
loadInit()
|
||||
getTree()
|
||||
loadShareBase()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
|
@ -17,6 +17,9 @@ import { ref, watch, computed } from 'vue'
|
||||
import ShareVisualHead from '@/views/share/share/ShareVisualHead.vue'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { useShareStoreWithOut } from '@/store/modules/share'
|
||||
const shareStore = useShareStoreWithOut()
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const appStore = useAppStoreWithOut()
|
||||
const { dvInfo } = storeToRefs(dvMainStore)
|
||||
@ -38,6 +41,7 @@ const preview = () => {
|
||||
}
|
||||
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
||||
const isIframe = computed(() => appStore.getIsIframe)
|
||||
const shareDisable = computed(() => shareStore.getShareDisable)
|
||||
|
||||
const reload = () => {
|
||||
emit('reload', dvInfo.value.id)
|
||||
@ -156,6 +160,7 @@ const initOpenHandler = newWindow => {
|
||||
预览</el-button
|
||||
>
|
||||
<ShareVisualHead
|
||||
v-if="!shareDisable"
|
||||
:resource-id="dvInfo.id"
|
||||
:weight="dvInfo.weight"
|
||||
:resource-type="dvInfo.type"
|
||||
|
10
core/core-frontend/src/views/share/link/ErrorTemplate.vue
Normal file
10
core/core-frontend/src/views/share/link/ErrorTemplate.vue
Normal file
@ -0,0 +1,10 @@
|
||||
<script lang="ts" setup>
|
||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
const props = defineProps({
|
||||
msg: propTypes.string.def('')
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<EmptyBackground img-type="noneWhite" :description="props.msg" />
|
||||
</template>
|
@ -15,6 +15,8 @@ export interface ProxyInfo {
|
||||
pwdValid?: boolean
|
||||
type: string
|
||||
inIframeError: boolean
|
||||
shareDisable: boolean
|
||||
peRequireValid: boolean
|
||||
ticketValidVO: TicketValidVO
|
||||
}
|
||||
class ShareProxy {
|
||||
|
@ -3,7 +3,13 @@
|
||||
class="link-container"
|
||||
v-loading="loading || requestStore.loadingMap[permissionStore.currentPath]"
|
||||
>
|
||||
<IframeError v-if="!loading && iframeError" />
|
||||
<ErrorTemplate
|
||||
v-if="!loading && (disableError || peRequireError)"
|
||||
:msg="
|
||||
disableError ? '已禁用分享功能,请联系管理员!' : '已设置有效期密码必填,当前链接无效!'
|
||||
"
|
||||
/>
|
||||
<IframeError v-else-if="!loading && iframeError" />
|
||||
<LinkError v-else-if="!loading && !linkExist" />
|
||||
<Exp v-else-if="!loading && linkExp" />
|
||||
<PwdTips v-else-if="!loading && !pwdValid" />
|
||||
@ -30,10 +36,13 @@ import LinkError from './error.vue'
|
||||
import PwdTips from './pwd.vue'
|
||||
import IframeError from './IframeError.vue'
|
||||
import TicketError from './TicketError.vue'
|
||||
import ErrorTemplate from './ErrorTemplate.vue'
|
||||
const requestStore = useRequestStoreWithOut()
|
||||
const permissionStore = usePermissionStoreWithOut()
|
||||
const pcanvas = ref(null)
|
||||
const iframeError = ref(true)
|
||||
const disableError = ref(true)
|
||||
const peRequireError = ref(true)
|
||||
const linkExist = ref(false)
|
||||
const loading = ref(true)
|
||||
const linkExp = ref(false)
|
||||
@ -47,12 +56,24 @@ const state = reactive({
|
||||
})
|
||||
onMounted(async () => {
|
||||
const proxyInfo = (await shareProxy.loadProxy()) as ProxyInfo
|
||||
if (proxyInfo?.shareDisable) {
|
||||
loading.value = false
|
||||
disableError.value = true
|
||||
return
|
||||
}
|
||||
disableError.value = false
|
||||
if (proxyInfo?.inIframeError) {
|
||||
loading.value = false
|
||||
iframeError.value = true
|
||||
return
|
||||
}
|
||||
iframeError.value = false
|
||||
if (proxyInfo && !proxyInfo.peRequireValid) {
|
||||
loading.value = false
|
||||
peRequireError.value = true
|
||||
return
|
||||
}
|
||||
peRequireError.value = false
|
||||
if (!proxyInfo?.resourceId) {
|
||||
loading.value = false
|
||||
return
|
||||
|
@ -56,11 +56,18 @@
|
||||
|
||||
<div v-if="shareEnable" class="exp-container">
|
||||
<el-checkbox
|
||||
ref="expCheckbox"
|
||||
:disabled="!shareEnable"
|
||||
v-model="overTimeEnable"
|
||||
@change="expEnableSwitcher"
|
||||
:label="t('visualization.over_time')"
|
||||
/>
|
||||
>
|
||||
<div class="checkbox-span">
|
||||
<span>{{ t('visualization.over_time') }}</span>
|
||||
<span class="pe-require" :class="{ 'pe-tips-hidden': !sharePeRequire }">
|
||||
<span>*</span>
|
||||
</span>
|
||||
</div>
|
||||
</el-checkbox>
|
||||
<div class="inline-share-item-picker">
|
||||
<el-date-picker
|
||||
:clearable="false"
|
||||
@ -80,11 +87,18 @@
|
||||
</div>
|
||||
<div v-if="shareEnable" class="pwd-container">
|
||||
<el-checkbox
|
||||
ref="pwdCheckbox"
|
||||
:disabled="!shareEnable"
|
||||
v-model="passwdEnable"
|
||||
@change="pwdEnableSwitcher"
|
||||
:label="t('visualization.passwd_protect')"
|
||||
/>
|
||||
>
|
||||
<div class="checkbox-span">
|
||||
<span>{{ t('visualization.passwd_protect') }}</span>
|
||||
<span class="pe-require" :class="{ 'pe-tips-hidden': !sharePeRequire }">
|
||||
<span>*</span>
|
||||
</span>
|
||||
</div>
|
||||
</el-checkbox>
|
||||
<div class="auto-pwd-container" v-if="passwdEnable">
|
||||
<el-checkbox
|
||||
:disabled="!shareEnable"
|
||||
@ -153,6 +167,8 @@ import { ElMessage, ElLoading } from 'element-plus-secondary'
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
import ShareTicket from './ShareTicket.vue'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { useShareStoreWithOut } from '@/store/modules/share'
|
||||
const shareStore = useShareStoreWithOut()
|
||||
const embeddedStore = useEmbedded()
|
||||
const { toClipboard } = useClipboard()
|
||||
const { t } = useI18n()
|
||||
@ -164,6 +180,8 @@ const props = defineProps({
|
||||
isButton: propTypes.bool.def(false)
|
||||
})
|
||||
const pwdRef = ref(null)
|
||||
const expCheckbox = ref()
|
||||
const pwdCheckbox = ref()
|
||||
const loadingInstance = ref<any>(null)
|
||||
const dialogVisible = ref(false)
|
||||
const overTimeEnable = ref(false)
|
||||
@ -189,6 +207,8 @@ const shareTips = computed(
|
||||
() =>
|
||||
`开启后,用户可以通过该链接访问${props.resourceType === 'dashboard' ? '仪表板' : '数据大屏'}`
|
||||
)
|
||||
const shareDisable = computed(() => shareStore.getShareDisable)
|
||||
const sharePeRequire = computed(() => shareStore.getSharePeRequire)
|
||||
const editUuid = () => {
|
||||
linkCustom.value = true
|
||||
nextTick(() => {
|
||||
@ -274,10 +294,10 @@ const closeLoading = () => {
|
||||
|
||||
const share = () => {
|
||||
dialogVisible.value = true
|
||||
loadShareInfo()
|
||||
loadShareInfo(validatePeRequire)
|
||||
}
|
||||
|
||||
const loadShareInfo = () => {
|
||||
const loadShareInfo = cb => {
|
||||
showLoading()
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/detail/${resourceId}`
|
||||
@ -289,6 +309,7 @@ const loadShareInfo = () => {
|
||||
})
|
||||
.finally(() => {
|
||||
closeLoading()
|
||||
cb && cb()
|
||||
})
|
||||
}
|
||||
|
||||
@ -305,7 +326,7 @@ const enableSwitcher = () => {
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/switcher/${resourceId}`
|
||||
request.post({ url }).then(() => {
|
||||
loadShareInfo()
|
||||
loadShareInfo(null)
|
||||
})
|
||||
}
|
||||
|
||||
@ -335,6 +356,7 @@ const expEnableSwitcher = val => {
|
||||
exp = now.getTime()
|
||||
state.detailInfo.exp = exp
|
||||
}
|
||||
validateExpRequire()
|
||||
expChangeHandler(exp)
|
||||
}
|
||||
|
||||
@ -348,7 +370,7 @@ const expChangeHandler = exp => {
|
||||
const url = '/share/editExp'
|
||||
const data = { resourceId, exp }
|
||||
request.post({ url, data }).then(() => {
|
||||
loadShareInfo()
|
||||
loadShareInfo(null)
|
||||
})
|
||||
}
|
||||
const beforeClose = async done => {
|
||||
@ -357,6 +379,12 @@ const beforeClose = async done => {
|
||||
done()
|
||||
return
|
||||
}
|
||||
if (sharePeRequire.value) {
|
||||
const peRequireValid = validatePeRequire()
|
||||
if (!peRequireValid) {
|
||||
return
|
||||
}
|
||||
}
|
||||
const pwdValid = validatePwdFormat()
|
||||
const uuidValid = await validateUuid()
|
||||
if (pwdValid && uuidValid) {
|
||||
@ -364,6 +392,32 @@ const beforeClose = async done => {
|
||||
done()
|
||||
}
|
||||
}
|
||||
const validatePeRequire = () => {
|
||||
if (shareEnable.value && sharePeRequire.value) {
|
||||
const expRequireValid = validateExpRequire()
|
||||
const pwdRequireValid = validatePwdRequire()
|
||||
return expRequireValid && pwdRequireValid
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const validateExpRequire = () => {
|
||||
if (!sharePeRequire.value || overTimeEnable.value) {
|
||||
showCheckboxError(null, expCheckbox)
|
||||
return true
|
||||
}
|
||||
showCheckboxError('必填', expCheckbox)
|
||||
return false
|
||||
}
|
||||
|
||||
const validatePwdRequire = () => {
|
||||
if (!sharePeRequire.value || passwdEnable.value) {
|
||||
showCheckboxError(null, pwdCheckbox)
|
||||
return true
|
||||
}
|
||||
showCheckboxError('必填', pwdCheckbox)
|
||||
return false
|
||||
}
|
||||
const validatePwdFormat = () => {
|
||||
if (!shareEnable.value || state.detailInfo.autoPwd) {
|
||||
showPageError(null, pwdRef)
|
||||
@ -383,6 +437,34 @@ const validatePwdFormat = () => {
|
||||
resetPwdHandler(val, false)
|
||||
return true
|
||||
}
|
||||
const showCheckboxError = (msg, target, className?: string) => {
|
||||
if (!target.value) {
|
||||
return
|
||||
}
|
||||
className = className || 'checkbox-span-require'
|
||||
const fullClassName = `.${className}`
|
||||
const e = target.value.$el
|
||||
if (!msg) {
|
||||
e.style = null
|
||||
e.children[0].children[1].style.borderColor = null
|
||||
const child = e.children[1].children[0].querySelector(fullClassName)
|
||||
if (child) {
|
||||
e.children[1].children[0].removeChild(child)
|
||||
}
|
||||
} else {
|
||||
e.style.color = 'red'
|
||||
e.children[0].children[1].style.borderColor = 'red'
|
||||
const child = e.children[1].children[0].querySelector(fullClassName)
|
||||
if (!child) {
|
||||
const errorDom = document.createElement('span')
|
||||
errorDom.className = className
|
||||
errorDom.innerText = msg
|
||||
e.children[1].children[0].appendChild(errorDom)
|
||||
} else {
|
||||
child.innerText = msg
|
||||
}
|
||||
}
|
||||
}
|
||||
const showPageError = (msg, target, className?: string) => {
|
||||
className = className || 'link-pwd-error-msg'
|
||||
const fullClassName = `.${className}`
|
||||
@ -433,6 +515,7 @@ const pwdEnableSwitcher = val => {
|
||||
if (val) {
|
||||
pwd = getUuid()
|
||||
}
|
||||
validatePwdRequire()
|
||||
resetPwdHandler(pwd, true)
|
||||
}
|
||||
const resetPwd = () => {
|
||||
@ -444,7 +527,7 @@ const resetPwdHandler = (pwd?: string, autoPwd?: boolean) => {
|
||||
const url = '/share/editPwd'
|
||||
const data = { resourceId, pwd, autoPwd }
|
||||
request.post({ url, data }).then(() => {
|
||||
loadShareInfo()
|
||||
loadShareInfo(null)
|
||||
})
|
||||
}
|
||||
|
||||
@ -642,4 +725,20 @@ onMounted(() => {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
:deep(.checkbox-span) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.pe-require {
|
||||
color: red;
|
||||
font-size: 10px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
}
|
||||
.checkbox-span-require {
|
||||
font-size: 10px;
|
||||
}
|
||||
.pe-tips-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -23,7 +23,11 @@
|
||||
{{ t('visualization.share') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<div class="share-container" :class="{ 'hidden-link-container': showTicket }">
|
||||
<div
|
||||
v-if="!shareDisable"
|
||||
class="share-container"
|
||||
:class="{ 'hidden-link-container': showTicket }"
|
||||
>
|
||||
<div class="share-title share-padding">公共链接分享</div>
|
||||
<div class="open-share flex-align-center share-padding">
|
||||
<el-switch size="small" v-model="shareEnable" @change="enableSwitcher" />
|
||||
@ -51,11 +55,18 @@
|
||||
</div>
|
||||
<div v-if="shareEnable" class="exp-container share-padding">
|
||||
<el-checkbox
|
||||
ref="expCheckbox"
|
||||
:disabled="!shareEnable"
|
||||
v-model="overTimeEnable"
|
||||
@change="expEnableSwitcher"
|
||||
:label="t('visualization.over_time')"
|
||||
/>
|
||||
>
|
||||
<div class="checkbox-span">
|
||||
<span>{{ t('visualization.over_time') }}</span>
|
||||
<span class="pe-require" :class="{ 'pe-tips-hidden': !sharePeRequire }">
|
||||
<span>*</span>
|
||||
</span>
|
||||
</div>
|
||||
</el-checkbox>
|
||||
<div class="inline-share-item-picker">
|
||||
<el-date-picker
|
||||
:clearable="false"
|
||||
@ -76,11 +87,18 @@
|
||||
</div>
|
||||
<div v-if="shareEnable" class="pwd-container share-padding">
|
||||
<el-checkbox
|
||||
ref="pwdCheckbox"
|
||||
:disabled="!shareEnable"
|
||||
v-model="passwdEnable"
|
||||
@change="pwdEnableSwitcher"
|
||||
:label="t('visualization.passwd_protect')"
|
||||
/>
|
||||
>
|
||||
<div class="checkbox-span">
|
||||
<span>{{ t('visualization.passwd_protect') }}</span>
|
||||
<span class="pe-require" :class="{ 'pe-tips-hidden': !sharePeRequire }">
|
||||
<span>*</span>
|
||||
</span>
|
||||
</div>
|
||||
</el-checkbox>
|
||||
<div class="auto-pwd-container" v-if="passwdEnable">
|
||||
<el-checkbox
|
||||
:disabled="!shareEnable"
|
||||
@ -123,7 +141,13 @@
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="shareEnable && showTicket" class="share-ticket-container">
|
||||
<div v-else class="share-container">
|
||||
<div class="share-title share-padding">公共链接分享</div>
|
||||
<div class="open-share flex-align-center share-padding">
|
||||
<span>已经开启全局禁用分享,分享功能暂不可用,请联系管理员!</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!shareDisable && shareEnable && showTicket" class="share-ticket-container">
|
||||
<share-ticket
|
||||
:uuid="state.detailInfo.uuid"
|
||||
:resource-id="props.resourceId"
|
||||
@ -147,6 +171,8 @@ import { ElMessage, ElLoading } from 'element-plus-secondary'
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
import ShareTicket from './ShareTicket.vue'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { useShareStoreWithOut } from '@/store/modules/share'
|
||||
const shareStore = useShareStoreWithOut()
|
||||
const embeddedStore = useEmbedded()
|
||||
const { toClipboard } = useClipboard()
|
||||
const { t } = useI18n()
|
||||
@ -157,6 +183,8 @@ const props = defineProps({
|
||||
})
|
||||
const popoverVisible = ref(false)
|
||||
const pwdRef = ref(null)
|
||||
const expCheckbox = ref()
|
||||
const pwdCheckbox = ref()
|
||||
const loadingInstance = ref<any>(null)
|
||||
const overTimeEnable = ref(false)
|
||||
const passwdEnable = ref(false)
|
||||
@ -187,6 +215,12 @@ const hideShare = async () => {
|
||||
popoverVisible.value = false
|
||||
return
|
||||
}
|
||||
if (sharePeRequire.value) {
|
||||
const peRequireValid = validatePeRequire()
|
||||
if (!peRequireValid) {
|
||||
return
|
||||
}
|
||||
}
|
||||
const pwdValid = validatePwdFormat()
|
||||
const uuidValid = await validateUuid()
|
||||
if (pwdValid && uuidValid) {
|
||||
@ -210,6 +244,8 @@ const shareTips = computed(
|
||||
() =>
|
||||
`开启后,用户可以通过该链接访问${props.resourceType === 'dashboard' ? '仪表板' : '数据大屏'}`
|
||||
)
|
||||
const shareDisable = computed(() => shareStore.getShareDisable)
|
||||
const sharePeRequire = computed(() => shareStore.getSharePeRequire)
|
||||
|
||||
const copyInfo = async () => {
|
||||
if (shareEnable.value) {
|
||||
@ -242,10 +278,10 @@ const closeLoading = () => {
|
||||
}
|
||||
|
||||
const share = () => {
|
||||
loadShareInfo()
|
||||
loadShareInfo(validatePeRequire)
|
||||
}
|
||||
|
||||
const loadShareInfo = () => {
|
||||
const loadShareInfo = cb => {
|
||||
showLoading()
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/detail/${resourceId}`
|
||||
@ -257,6 +293,7 @@ const loadShareInfo = () => {
|
||||
})
|
||||
.finally(() => {
|
||||
closeLoading()
|
||||
cb && cb()
|
||||
})
|
||||
}
|
||||
|
||||
@ -277,7 +314,7 @@ const enableSwitcher = () => {
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/switcher/${resourceId}`
|
||||
request.post({ url }).then(() => {
|
||||
loadShareInfo()
|
||||
loadShareInfo(null)
|
||||
})
|
||||
}
|
||||
|
||||
@ -307,6 +344,7 @@ const expEnableSwitcher = val => {
|
||||
exp = now.getTime()
|
||||
state.detailInfo.exp = exp
|
||||
}
|
||||
validateExpRequire()
|
||||
expChangeHandler(exp)
|
||||
}
|
||||
|
||||
@ -320,7 +358,7 @@ const expChangeHandler = exp => {
|
||||
const url = '/share/editExp'
|
||||
const data = { resourceId, exp }
|
||||
request.post({ url, data }).then(() => {
|
||||
loadShareInfo()
|
||||
loadShareInfo(null)
|
||||
})
|
||||
}
|
||||
|
||||
@ -329,6 +367,7 @@ const pwdEnableSwitcher = val => {
|
||||
if (val) {
|
||||
pwd = getUuid()
|
||||
}
|
||||
validatePwdRequire()
|
||||
resetPwdHandler(pwd, true)
|
||||
}
|
||||
const resetPwd = () => {
|
||||
@ -340,7 +379,7 @@ const resetPwdHandler = (pwd?: string, autoPwd?: boolean) => {
|
||||
const url = '/share/editPwd'
|
||||
const data = { resourceId, pwd, autoPwd }
|
||||
request.post({ url, data }).then(() => {
|
||||
loadShareInfo()
|
||||
loadShareInfo(null)
|
||||
})
|
||||
}
|
||||
|
||||
@ -369,7 +408,32 @@ const getUuid = () => {
|
||||
.join('')
|
||||
return result
|
||||
}
|
||||
const validatePeRequire = () => {
|
||||
if (shareEnable.value && sharePeRequire.value) {
|
||||
const expRequireValid = validateExpRequire()
|
||||
const pwdRequireValid = validatePwdRequire()
|
||||
return expRequireValid && pwdRequireValid
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const validateExpRequire = () => {
|
||||
if (!sharePeRequire.value || overTimeEnable.value) {
|
||||
showCheckboxError(null, expCheckbox)
|
||||
return true
|
||||
}
|
||||
showCheckboxError('必填', expCheckbox)
|
||||
return false
|
||||
}
|
||||
|
||||
const validatePwdRequire = () => {
|
||||
if (!sharePeRequire.value || passwdEnable.value) {
|
||||
showCheckboxError(null, pwdCheckbox)
|
||||
return true
|
||||
}
|
||||
showCheckboxError('必填', pwdCheckbox)
|
||||
return false
|
||||
}
|
||||
const validatePwdFormat = () => {
|
||||
if (!shareEnable.value || !passwdEnable.value || state.detailInfo.autoPwd) {
|
||||
showPageError(null, pwdRef)
|
||||
@ -389,6 +453,34 @@ const validatePwdFormat = () => {
|
||||
resetPwdHandler(val, false)
|
||||
return true
|
||||
}
|
||||
const showCheckboxError = (msg, target, className?: string) => {
|
||||
if (!target.value) {
|
||||
return
|
||||
}
|
||||
className = className || 'checkbox-span-require'
|
||||
const fullClassName = `.${className}`
|
||||
const e = target.value.$el
|
||||
if (!msg) {
|
||||
e.style = null
|
||||
e.children[0].children[1].style.borderColor = null
|
||||
const child = e.children[1].children[0].querySelector(fullClassName)
|
||||
if (child) {
|
||||
e.children[1].children[0].removeChild(child)
|
||||
}
|
||||
} else {
|
||||
e.style.color = 'red'
|
||||
e.children[0].children[1].style.borderColor = 'red'
|
||||
const child = e.children[1].children[0].querySelector(fullClassName)
|
||||
if (!child) {
|
||||
const errorDom = document.createElement('span')
|
||||
errorDom.className = className
|
||||
errorDom.innerText = msg
|
||||
e.children[1].children[0].appendChild(errorDom)
|
||||
} else {
|
||||
child.innerText = msg
|
||||
}
|
||||
}
|
||||
}
|
||||
const showPageError = (msg, target, className?: string) => {
|
||||
className = className || 'link-pwd-error-msg'
|
||||
const fullClassName = `.${className}`
|
||||
@ -578,6 +670,23 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.checkbox-span) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.pe-require {
|
||||
color: red;
|
||||
font-size: 10px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
}
|
||||
.checkbox-span-require {
|
||||
font-size: 10px;
|
||||
}
|
||||
.pe-tips-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.inline-share-item-picker {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -234,7 +234,11 @@ defineExpose({
|
||||
<el-switch
|
||||
class="de-basic-switch"
|
||||
v-if="
|
||||
item.pkey === 'autoCreateUser' || item.pkey === 'pwdStrategy' || item.pkey === 'dip'
|
||||
item.pkey === 'autoCreateUser' ||
|
||||
item.pkey === 'pwdStrategy' ||
|
||||
item.pkey === 'dip' ||
|
||||
item.pkey === 'shareDisable' ||
|
||||
item.pkey === 'sharePeRequire'
|
||||
"
|
||||
active-value="true"
|
||||
inactive-value="false"
|
||||
|
@ -42,6 +42,10 @@ const tooltips = [
|
||||
{
|
||||
key: 'setting_basic.platformRid',
|
||||
val: '作用域包括认证设置和平台对接'
|
||||
},
|
||||
{
|
||||
key: 'setting_basic.shareDisable',
|
||||
val: '开启后仪表板以及大屏分享无效'
|
||||
}
|
||||
]
|
||||
const state = reactive({
|
||||
@ -87,7 +91,9 @@ const search = cb => {
|
||||
if (
|
||||
item.pkey === 'basic.autoCreateUser' ||
|
||||
item.pkey === 'basic.dip' ||
|
||||
item.pkey === 'basic.pwdStrategy'
|
||||
item.pkey === 'basic.pwdStrategy' ||
|
||||
item.pkey === 'basic.shareDisable' ||
|
||||
item.pkey === 'basic.sharePeRequire'
|
||||
) {
|
||||
item.pval = item.pval === 'true' ? '开启' : '未开启'
|
||||
} else if (item.pkey === 'basic.platformOid') {
|
||||
|
@ -16,7 +16,6 @@ import GridTable from '@/components/grid-table/src/GridTable.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import dayjs from 'dayjs'
|
||||
import { shortcutOption } from './ShortcutOption'
|
||||
/* import { XpackComponent } from '@/components/plugin' */
|
||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import { storeApi } from '@/api/visualization/dataVisualization'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
@ -33,6 +32,9 @@ const interactiveStore = interactiveStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
const appStore = useAppStoreWithOut()
|
||||
const embeddedStore = useEmbedded()
|
||||
|
||||
import { useShareStoreWithOut } from '@/store/modules/share'
|
||||
const shareStore = useShareStoreWithOut()
|
||||
const { push } = useRouter()
|
||||
defineProps({
|
||||
expand: {
|
||||
@ -50,6 +52,9 @@ const state = reactive({
|
||||
tableColumn: []
|
||||
})
|
||||
const busiDataMap = computed(() => interactiveStore.getData)
|
||||
const shareDisable = computed(() => {
|
||||
return shareStore.getShareDisable
|
||||
})
|
||||
const iconMap = {
|
||||
panel: icon_dashboard_outlined,
|
||||
panelMobile: dvDashboardSpineMobile,
|
||||
@ -135,14 +140,6 @@ const loadTableData = () => {
|
||||
})
|
||||
}
|
||||
|
||||
/* const panelLoad = paneInfo => {
|
||||
tablePaneList.value.push({
|
||||
title: paneInfo.title,
|
||||
name: paneInfo.name,
|
||||
disabled: tablePaneList.value[1].disabled
|
||||
})
|
||||
} */
|
||||
|
||||
const tablePaneList = ref([
|
||||
{ title: t('work_branch.recently_used'), name: 'recent', disabled: false },
|
||||
{ title: t('work_branch.my_collection'), name: 'store', disabled: false },
|
||||
@ -258,7 +255,7 @@ const getEmptyDesc = (): string => {
|
||||
>
|
||||
<el-tabs v-model="activeName" class="dashboard-type-tabs" @tab-click="handleClick">
|
||||
<el-tab-pane
|
||||
v-for="item in tablePaneList"
|
||||
v-for="item in tablePaneList.filter(pannel => !shareDisable || pannel.name !== 'share')"
|
||||
:key="item.name"
|
||||
:disabled="item.disabled"
|
||||
:label="item.title"
|
||||
@ -278,9 +275,7 @@ const getEmptyDesc = (): string => {
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<!-- <XpackComponent jsname="c2hhcmUtcGFuZWw=" @loaded="panelLoad" /> -->
|
||||
<!-- <XpackComponent :active-name="activeName" jsname="c2hhcmU=" @set-loading="setLoading" /> -->
|
||||
<share-grid :active-name="activeName" @set-loading="setLoading" />
|
||||
<share-grid v-if="!shareDisable" :active-name="activeName" @set-loading="setLoading" />
|
||||
<el-row v-if="activeName === 'recent' || activeName === 'store'">
|
||||
<el-col :span="12">
|
||||
<el-select
|
||||
@ -396,18 +391,12 @@ const getEmptyDesc = (): string => {
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<ShareHandler
|
||||
v-if="!shareDisable"
|
||||
:in-grid="true"
|
||||
:weight="scope.row.weight"
|
||||
:resource-id="activeName === 'recent' ? scope.row.id : scope.row.resourceId"
|
||||
:resource-type="scope.row.type"
|
||||
/>
|
||||
<!-- <XpackComponent
|
||||
:in-grid="true"
|
||||
jsname="c2hhcmUtaGFuZGxlcg=="
|
||||
:weight="scope.row.weight"
|
||||
:resource-id="activeName === 'recent' ? scope.row.id : scope.row.resourceId"
|
||||
:resource-type="scope.row.type"
|
||||
/> -->
|
||||
<el-tooltip
|
||||
v-if="activeName === 'store'"
|
||||
effect="dark"
|
||||
|
@ -22,6 +22,11 @@ import DeResourceCreateOptV2 from '@/views/common/DeResourceCreateOptV2.vue'
|
||||
import { Base64 } from 'js-base64'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import { useShareStoreWithOut } from '@/store/modules/share'
|
||||
import { queryShareBaseApi } from '@/api/visualization/dataVisualization'
|
||||
|
||||
const shareStore = useShareStoreWithOut()
|
||||
|
||||
const userStore = useUserStoreWithOut()
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
const permissionStore = usePermissionStoreWithOut()
|
||||
@ -281,8 +286,19 @@ const toTemplateMarketAdd = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const loadShareBase = () => {
|
||||
queryShareBaseApi().then(res => {
|
||||
const param = {
|
||||
shareDisable: res.data?.disable,
|
||||
sharePeRequire: res.data?.peRequire
|
||||
}
|
||||
shareStore.setData(param)
|
||||
})
|
||||
}
|
||||
|
||||
fillCardInfo()
|
||||
initMarketTemplate()
|
||||
loadShareBase()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -3,6 +3,7 @@ package io.dataease.api.system;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.system.request.OnlineMapEditor;
|
||||
import io.dataease.api.system.vo.SettingItemVO;
|
||||
import io.dataease.api.system.vo.ShareBaseVO;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -52,4 +53,8 @@ public interface SysParameterApi {
|
||||
@GetMapping("/defaultLogin")
|
||||
Integer defaultLogin();
|
||||
|
||||
@GetMapping("/shareBase")
|
||||
@Operation(summary = "查询分享设置")
|
||||
ShareBaseVO shareBase();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package io.dataease.api.system.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Schema(description = "分享设置参数项")
|
||||
@Data
|
||||
public class ShareBaseVO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -8418758128428770485L;
|
||||
@Schema(description = "禁用分享")
|
||||
private boolean disable;
|
||||
|
||||
@Schema(description = "有效期密码必填")
|
||||
private boolean peRequire;
|
||||
}
|
@ -33,5 +33,9 @@ public class XpackShareProxyVO implements Serializable {
|
||||
private String type;
|
||||
private boolean inIframeError = true;
|
||||
|
||||
private boolean shareDisable = false;
|
||||
|
||||
private boolean peRequireValid = true;
|
||||
|
||||
private TicketValidVO ticketValidVO;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user