forked from github/dataease
Merge pull request #9000 from dataease/pr@dev-v2@feat_share_uuid_custom
feat: 公共链接后缀可自定义close #8195
This commit is contained in:
commit
4066c3bcee
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackShareProxyRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackSharePwdValidator;
|
||||
import io.dataease.api.xpack.share.request.XpackShareUuidEditor;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareGridVO;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareProxyVO;
|
||||
import io.dataease.auth.bo.TokenUserBO;
|
||||
@ -31,6 +32,8 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component("xpackShareManage")
|
||||
@ -70,6 +73,35 @@ public class XpackShareManage {
|
||||
xpackShareMapper.insert(xpackShare);
|
||||
}
|
||||
|
||||
public String editUuid(XpackShareUuidEditor editor) {
|
||||
Long resourceId = editor.getResourceId();
|
||||
String uuid = editor.getUuid();
|
||||
XpackShare originData = queryByResource(resourceId);
|
||||
if (ObjectUtils.isEmpty(originData)) {
|
||||
return "公共链接不存在,请先创建!";
|
||||
}
|
||||
if (StringUtils.isBlank(uuid)) {
|
||||
return "不能为空!";
|
||||
}
|
||||
if (StringUtils.equals(uuid, originData.getUuid())) {
|
||||
return "";
|
||||
}
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("uuid", uuid);
|
||||
if (xpackShareMapper.selectCount(queryWrapper) > 0) {
|
||||
return "已存在相同的链接,请重新输入!";
|
||||
}
|
||||
String regex = "^[a-zA-Z0-9]{8,16}$";
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(uuid);
|
||||
if (!matcher.matches()) {
|
||||
return "仅支持8-16位(字母数字),请重新输入!";
|
||||
}
|
||||
originData.setUuid(uuid);
|
||||
xpackShareMapper.updateById(originData);
|
||||
return "";
|
||||
}
|
||||
|
||||
public void editExp(Long resourceId, Long exp) {
|
||||
XpackShare originData = queryByResource(resourceId);
|
||||
if (ObjectUtils.isEmpty(originData)) {
|
||||
@ -92,6 +124,8 @@ public class XpackShareManage {
|
||||
xpackShareMapper.updateById(originData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public IPage<XpackSharePO> querySharePage(int goPage, int pageSize, VisualizationWorkbranchQueryRequest request) {
|
||||
Long uid = AuthUtils.getUser().getUserId();
|
||||
QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
|
||||
@ -170,16 +204,16 @@ public class XpackShareManage {
|
||||
if (StringUtils.isBlank(xpackShare.getPwd())) return true;
|
||||
if (StringUtils.isBlank(ciphertext)) return false;
|
||||
String text = RsaUtils.decryptStr(ciphertext);
|
||||
int splitIndex = 8;
|
||||
String pwd = text.substring(splitIndex);
|
||||
int splitIndex = text.indexOf(",");
|
||||
String pwd = text.substring(splitIndex + 1);
|
||||
String uuid = text.substring(0, splitIndex);
|
||||
return StringUtils.equals(xpackShare.getUuid(), uuid) && StringUtils.equals(xpackShare.getPwd(), pwd);
|
||||
}
|
||||
|
||||
public boolean validatePwd(XpackSharePwdValidator validator) {
|
||||
String ciphertext = RsaUtils.decryptStr(validator.getCiphertext());
|
||||
int splitIndex = 8;
|
||||
String pwd = ciphertext.substring(splitIndex);
|
||||
int splitIndex = ciphertext.indexOf(",");
|
||||
String pwd = ciphertext.substring(splitIndex + 1);
|
||||
String uuid = ciphertext.substring(0, splitIndex);
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("uuid", uuid);
|
||||
|
@ -2,10 +2,7 @@ package io.dataease.share.server;
|
||||
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.xpack.share.XpackShareApi;
|
||||
import io.dataease.api.xpack.share.request.XpackShareExpRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackShareProxyRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackSharePwdRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackSharePwdValidator;
|
||||
import io.dataease.api.xpack.share.request.*;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareGridVO;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareProxyVO;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareVO;
|
||||
@ -70,7 +67,12 @@ public class XpackShareServer implements XpackShareApi {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> queryRelationByUserId(@PathVariable("uid") Long uid) {
|
||||
public Map<String, String> queryRelationByUserId(Long uid) {
|
||||
return xpackShareManage.queryRelationByUserId(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String editUuid(XpackShareUuidEditor editor) {
|
||||
return xpackShareManage.editUuid(editor);
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ import { rsaEncryp } from '@/utils/encryption'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { queryDekey } from '@/api/login'
|
||||
import { CustomPassword } from '@/components/custom-password'
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
const { wsCache } = useCache()
|
||||
const appStore = useAppStoreWithOut()
|
||||
|
||||
@ -76,15 +78,9 @@ const refresh = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
const curLocation = window.location.href
|
||||
const paramIndex = curLocation.indexOf('?')
|
||||
const uuidIndex = curLocation.indexOf('de-link/') + 8
|
||||
const uuid = curLocation.substring(
|
||||
uuidIndex,
|
||||
paramIndex !== -1 ? paramIndex : curLocation.length
|
||||
)
|
||||
const uuid = route.params.uuid
|
||||
const pwd = form.value.password
|
||||
const text = uuid + pwd
|
||||
const text = `${uuid},${pwd}`
|
||||
const ciphertext = rsaEncryp(text)
|
||||
request.post({ url: '/share/validate', data: { ciphertext } }).then(res => {
|
||||
if (res.data) {
|
||||
@ -100,6 +96,7 @@ const refresh = async (formEl: FormInstance | undefined) => {
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
debugger
|
||||
if (!wsCache.get(appStore.getDekey)) {
|
||||
queryDekey()
|
||||
.then(res => {
|
||||
|
@ -31,7 +31,26 @@
|
||||
<el-switch size="small" v-model="shareEnable" @change="enableSwitcher" />
|
||||
{{ shareTips }}
|
||||
</div>
|
||||
<div v-if="shareEnable" class="text">{{ linkAddr }}</div>
|
||||
<div v-if="shareEnable" class="custom-link-line">
|
||||
<el-input
|
||||
ref="linkUuidRef"
|
||||
placeholder=""
|
||||
v-model="state.detailInfo.uuid"
|
||||
:disabled="!linkCustom"
|
||||
@blur="finishEditUuid"
|
||||
>
|
||||
<template #prefix>
|
||||
{{ formatLinkBase() }}
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button v-if="linkCustom" text @click="finishEditUuid">完成</el-button>
|
||||
<el-button v-else @click="editUuid" size="default" plain>
|
||||
<template #icon>
|
||||
<icon name="icon_admin_outlined"></icon>
|
||||
</template>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div v-if="shareEnable" class="exp-container">
|
||||
<el-checkbox
|
||||
:disabled="!shareEnable"
|
||||
@ -133,6 +152,8 @@ const passwdEnable = ref(false)
|
||||
const shareEnable = ref(false)
|
||||
const linkAddr = ref('')
|
||||
const expError = ref(false)
|
||||
const linkCustom = ref(false)
|
||||
const linkUuidRef = ref(null)
|
||||
const state = reactive({
|
||||
detailInfo: {
|
||||
id: '',
|
||||
@ -147,9 +168,46 @@ const shareTips = computed(
|
||||
() =>
|
||||
`开启后,用户可以通过该链接访问${props.resourceType === 'dashboard' ? '仪表板' : '数据大屏'}`
|
||||
)
|
||||
const editUuid = () => {
|
||||
linkCustom.value = true
|
||||
nextTick(() => {
|
||||
if (linkUuidRef?.value) {
|
||||
linkUuidRef.value.input.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
const validateUuid = async () => {
|
||||
const val = state.detailInfo.uuid
|
||||
const className = 'link-uuid-error-msg'
|
||||
if (!val) {
|
||||
showPageError('不能为空!', linkUuidRef, className)
|
||||
return false
|
||||
}
|
||||
const regex = /^[a-zA-Z0-9]{8,16}$/
|
||||
const result = regex.test(val)
|
||||
if (!result) {
|
||||
showPageError('仅支持8-16位(字母数字),请重新输入!', linkUuidRef, className)
|
||||
} else {
|
||||
const msg = await uuidValidateApi(val)
|
||||
showPageError(msg, linkUuidRef, className)
|
||||
return !msg
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const uuidValidateApi = async val => {
|
||||
const url = '/share/editUuid'
|
||||
const data = { resourceId: props.resourceId, uuid: val }
|
||||
const res = await request.post({ url, data })
|
||||
return res.data
|
||||
}
|
||||
const finishEditUuid = async () => {
|
||||
const uuidValid = await validateUuid()
|
||||
linkCustom.value = !uuidValid
|
||||
}
|
||||
const copyPwd = async () => {
|
||||
if (shareEnable.value && passwdEnable.value) {
|
||||
if (!state.detailInfo.autoPwd && existErrorMsg()) {
|
||||
if (!state.detailInfo.autoPwd && existErrorMsg('link-pwd-error-msg')) {
|
||||
ElMessage.warning('密码格式错误,请重新填写!')
|
||||
return
|
||||
}
|
||||
@ -166,6 +224,10 @@ const copyPwd = async () => {
|
||||
const copyInfo = async () => {
|
||||
if (shareEnable.value) {
|
||||
try {
|
||||
if (existErrorMsg('link-uuid-error-msg')) {
|
||||
ElMessage.warning('链接格式错误,请重新填写!')
|
||||
return
|
||||
}
|
||||
await toClipboard(linkAddr.value)
|
||||
ElMessage.success(t('common.copy_success'))
|
||||
} catch (e) {
|
||||
@ -226,6 +288,9 @@ const enableSwitcher = () => {
|
||||
}
|
||||
|
||||
const formatLinkAddr = () => {
|
||||
linkAddr.value = formatLinkBase() + state.detailInfo.uuid
|
||||
}
|
||||
const formatLinkBase = () => {
|
||||
let prefix = '/'
|
||||
if (window.DataEaseBi?.baseUrl) {
|
||||
prefix = window.DataEaseBi.baseUrl + '#'
|
||||
@ -233,7 +298,7 @@ const formatLinkAddr = () => {
|
||||
const href = window.location.href
|
||||
prefix = href.substring(0, href.indexOf('#') + 1)
|
||||
}
|
||||
linkAddr.value = prefix + SHARE_BASE + state.detailInfo.uuid
|
||||
return prefix + SHARE_BASE
|
||||
}
|
||||
|
||||
const expEnableSwitcher = val => {
|
||||
@ -260,32 +325,36 @@ const expChangeHandler = exp => {
|
||||
loadShareInfo()
|
||||
})
|
||||
}
|
||||
const beforeClose = done => {
|
||||
if (validatePwdFormat()) {
|
||||
const beforeClose = async done => {
|
||||
const pwdValid = validatePwdFormat()
|
||||
const uuidValid = await validateUuid()
|
||||
if (pwdValid && uuidValid) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
const validatePwdFormat = () => {
|
||||
if (!shareEnable.value || state.detailInfo.autoPwd) {
|
||||
showPageError(null)
|
||||
showPageError(null, pwdRef)
|
||||
return true
|
||||
}
|
||||
const val = state.detailInfo.pwd
|
||||
if (!val) {
|
||||
showPageError('密码不能为空,请重新输入!')
|
||||
showPageError('密码不能为空,请重新输入!', pwdRef)
|
||||
return false
|
||||
}
|
||||
const regex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{4,10}$/
|
||||
if (!regex.test(val)) {
|
||||
showPageError('密码必须是包含数字、字母、特殊字符[!@#$%^&*()_+]的4-10位字符串')
|
||||
showPageError('密码必须是包含数字、字母、特殊字符[!@#$%^&*()_+]的4-10位字符串', pwdRef)
|
||||
return false
|
||||
}
|
||||
showPageError(null)
|
||||
showPageError(null, pwdRef)
|
||||
resetPwdHandler(val, false)
|
||||
return true
|
||||
}
|
||||
const showPageError = msg => {
|
||||
const domRef = pwdRef
|
||||
const showPageError = (msg, target, className?: string) => {
|
||||
className = className || 'link-pwd-error-msg'
|
||||
const fullClassName = `.${className}`
|
||||
const domRef = target || pwdRef
|
||||
if (!domRef.value) {
|
||||
return
|
||||
}
|
||||
@ -293,7 +362,7 @@ const showPageError = msg => {
|
||||
if (!msg) {
|
||||
e.style = null
|
||||
e.style.borderColor = null
|
||||
const child = e.parentElement.querySelector('.link-pwd-error-msg')
|
||||
const child = e.parentElement.querySelector(fullClassName)
|
||||
if (child) {
|
||||
e.parentElement['style'] = null
|
||||
e.parentElement.removeChild(child)
|
||||
@ -302,10 +371,10 @@ const showPageError = msg => {
|
||||
e.style.color = 'red'
|
||||
e.style.borderColor = 'red'
|
||||
e.parentElement['style']['box-shadow'] = '0 0 0 1px red inset'
|
||||
const child = e.parentElement.querySelector('.link-pwd-error-msg')
|
||||
const child = e.parentElement.querySelector(fullClassName)
|
||||
if (!child) {
|
||||
const errorDom = document.createElement('div')
|
||||
errorDom.className = 'link-pwd-error-msg'
|
||||
errorDom.className = className
|
||||
errorDom.innerText = msg
|
||||
e.parentElement.appendChild(errorDom)
|
||||
} else {
|
||||
@ -313,12 +382,12 @@ const showPageError = msg => {
|
||||
}
|
||||
}
|
||||
}
|
||||
const existErrorMsg = () => {
|
||||
return document.getElementsByClassName('link-pwd-error-msg')?.length
|
||||
const existErrorMsg = (className: string) => {
|
||||
return document.getElementsByClassName(className)?.length
|
||||
}
|
||||
const autoEnableSwitcher = val => {
|
||||
if (val) {
|
||||
showPageError(null)
|
||||
showPageError(null, pwdRef)
|
||||
resetPwd()
|
||||
} else {
|
||||
state.detailInfo.pwd = ''
|
||||
@ -348,11 +417,29 @@ const resetPwdHandler = (pwd?: string, autoPwd?: boolean) => {
|
||||
}
|
||||
|
||||
const getUuid = () => {
|
||||
return 'xyxy'.replace(/[xy]/g, function (c) {
|
||||
var r = (Math.random() * 16) | 0,
|
||||
v = c == 'x' ? r : (r & 0x3) | 0x8
|
||||
return v.toString(16)
|
||||
})
|
||||
const length = 10
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+'
|
||||
let result = ''
|
||||
const specialChars = '!@#$%^&*()_+'
|
||||
let hasSpecialChar = false
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (i === 0) {
|
||||
result += characters.charAt(Math.floor(Math.random() * characters.length))
|
||||
} else {
|
||||
if (!hasSpecialChar && i < length - 2) {
|
||||
result += specialChars.charAt(Math.floor(Math.random() * specialChars.length))
|
||||
hasSpecialChar = true
|
||||
} else {
|
||||
result += characters.charAt(Math.floor(Math.random() * characters.length))
|
||||
}
|
||||
}
|
||||
}
|
||||
result = result
|
||||
.split('')
|
||||
.sort(() => 0.5 - Math.random())
|
||||
.join('')
|
||||
return result
|
||||
}
|
||||
|
||||
const execute = () => {
|
||||
@ -483,18 +570,26 @@ onMounted(() => {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #bbbfc4;
|
||||
background: #eff0f1;
|
||||
.custom-link-line {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
height: 32px;
|
||||
padding: 5px 12px;
|
||||
color: #8f959e;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
line-height: 22px;
|
||||
align-items: center;
|
||||
button {
|
||||
width: 40px;
|
||||
min-width: 40px;
|
||||
margin-left: 8px;
|
||||
height: 100%;
|
||||
}
|
||||
:deep(.link-uuid-error-msg) {
|
||||
color: red;
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
font-size: 10px;
|
||||
height: 10px;
|
||||
top: 25px;
|
||||
width: 350px;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,27 @@
|
||||
<el-switch size="small" v-model="shareEnable" @change="enableSwitcher" />
|
||||
{{ shareTips }}
|
||||
</div>
|
||||
<div v-if="shareEnable" class="text share-padding">
|
||||
<!-- <div v-if="shareEnable" class="text share-padding">
|
||||
<el-input v-model="linkAddr" disabled />
|
||||
</div> -->
|
||||
<div v-if="shareEnable" class="custom-link-line share-padding">
|
||||
<el-input
|
||||
ref="linkUuidRef"
|
||||
placeholder=""
|
||||
v-model="state.detailInfo.uuid"
|
||||
:disabled="!linkCustom"
|
||||
@blur="finishEditUuid"
|
||||
>
|
||||
<template #prefix>
|
||||
{{ formatLinkBase() }}
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button v-if="linkCustom" text @click.stop="finishEditUuid">完成</el-button>
|
||||
<el-button v-else @click.stop="editUuid" size="default" plain>
|
||||
<template #icon>
|
||||
<icon name="icon_admin_outlined"></icon>
|
||||
</template>
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="shareEnable" class="exp-container share-padding">
|
||||
<el-checkbox
|
||||
@ -129,6 +148,8 @@ const passwdEnable = ref(false)
|
||||
const shareEnable = ref(false)
|
||||
const linkAddr = ref('')
|
||||
const expError = ref(false)
|
||||
const linkCustom = ref(false)
|
||||
const linkUuidRef = ref(null)
|
||||
const state = reactive({
|
||||
detailInfo: {
|
||||
id: '',
|
||||
@ -145,8 +166,10 @@ watch(
|
||||
popoverVisible.value = false
|
||||
}
|
||||
)
|
||||
const hideShare = () => {
|
||||
if (validatePwdFormat()) {
|
||||
const hideShare = async () => {
|
||||
const pwdValid = validatePwdFormat()
|
||||
const uuidValid = await validateUuid()
|
||||
if (pwdValid && uuidValid) {
|
||||
popoverVisible.value = false
|
||||
return
|
||||
}
|
||||
@ -170,6 +193,10 @@ const shareTips = computed(
|
||||
const copyInfo = async () => {
|
||||
if (shareEnable.value) {
|
||||
try {
|
||||
if (existErrorMsg('link-uuid-error-msg')) {
|
||||
ElMessage.warning('链接格式错误,请重新填写!')
|
||||
return
|
||||
}
|
||||
await toClipboard(linkAddr.value)
|
||||
ElMessage.success(t('common.copy_success'))
|
||||
} catch (e) {
|
||||
@ -233,6 +260,9 @@ const enableSwitcher = () => {
|
||||
}
|
||||
|
||||
const formatLinkAddr = () => {
|
||||
linkAddr.value = formatLinkBase() + state.detailInfo.uuid
|
||||
}
|
||||
const formatLinkBase = () => {
|
||||
let prefix = '/'
|
||||
if (window.DataEaseBi?.baseUrl) {
|
||||
prefix = window.DataEaseBi.baseUrl + '#'
|
||||
@ -240,7 +270,7 @@ const formatLinkAddr = () => {
|
||||
const href = window.location.href
|
||||
prefix = href.substring(0, href.indexOf('#') + 1)
|
||||
}
|
||||
linkAddr.value = prefix + SHARE_BASE + state.detailInfo.uuid
|
||||
return prefix + SHARE_BASE
|
||||
}
|
||||
|
||||
const expEnableSwitcher = val => {
|
||||
@ -316,25 +346,27 @@ const getUuid = () => {
|
||||
|
||||
const validatePwdFormat = () => {
|
||||
if (!shareEnable.value || !passwdEnable.value || state.detailInfo.autoPwd) {
|
||||
showPageError(null)
|
||||
showPageError(null, pwdRef)
|
||||
return true
|
||||
}
|
||||
const val = state.detailInfo.pwd
|
||||
if (!val) {
|
||||
showPageError('密码不能为空,请重新输入!')
|
||||
showPageError('密码不能为空,请重新输入!', pwdRef)
|
||||
return false
|
||||
}
|
||||
const regex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^&*()_+])[A-Za-z\d!@#$%^&*()_+]{4,10}$/
|
||||
if (!regex.test(val)) {
|
||||
showPageError('密码必须是包含数字、字母、特殊字符[!@#$%^&*()_+]的4-10位字符串')
|
||||
showPageError('密码必须是包含数字、字母、特殊字符[!@#$%^&*()_+]的4-10位字符串', pwdRef)
|
||||
return false
|
||||
}
|
||||
showPageError(null)
|
||||
showPageError(null, pwdRef)
|
||||
resetPwdHandler(val, false)
|
||||
return true
|
||||
}
|
||||
const showPageError = msg => {
|
||||
const domRef = pwdRef
|
||||
const showPageError = (msg, target, className?: string) => {
|
||||
className = className || 'link-pwd-error-msg'
|
||||
const fullClassName = `.${className}`
|
||||
const domRef = target || pwdRef
|
||||
if (!domRef.value) {
|
||||
return
|
||||
}
|
||||
@ -342,7 +374,7 @@ const showPageError = msg => {
|
||||
if (!msg) {
|
||||
e.style = null
|
||||
e.style.borderColor = null
|
||||
const child = e.parentElement.querySelector('.link-pwd-error-msg')
|
||||
const child = e.parentElement.querySelector(fullClassName)
|
||||
if (child) {
|
||||
e.parentElement['style'] = null
|
||||
e.parentElement.removeChild(child)
|
||||
@ -351,10 +383,10 @@ const showPageError = msg => {
|
||||
e.style.color = 'red'
|
||||
e.style.borderColor = 'red'
|
||||
e.parentElement['style']['box-shadow'] = '0 0 0 1px red inset'
|
||||
const child = e.parentElement.querySelector('.link-pwd-error-msg')
|
||||
const child = e.parentElement.querySelector(fullClassName)
|
||||
if (!child) {
|
||||
const errorDom = document.createElement('div')
|
||||
errorDom.className = 'link-pwd-error-msg'
|
||||
errorDom.className = className
|
||||
errorDom.innerText = msg
|
||||
e.parentElement.appendChild(errorDom)
|
||||
} else {
|
||||
@ -362,12 +394,12 @@ const showPageError = msg => {
|
||||
}
|
||||
}
|
||||
}
|
||||
const existErrorMsg = () => {
|
||||
return document.getElementsByClassName('link-pwd-error-msg')?.length
|
||||
const existErrorMsg = (className: string) => {
|
||||
return document.getElementsByClassName(className)?.length
|
||||
}
|
||||
const autoEnableSwitcher = val => {
|
||||
if (val) {
|
||||
showPageError(null)
|
||||
showPageError(null, pwdRef)
|
||||
resetPwd()
|
||||
} else {
|
||||
state.detailInfo.pwd = ''
|
||||
@ -379,7 +411,7 @@ const autoEnableSwitcher = val => {
|
||||
|
||||
const copyPwd = async () => {
|
||||
if (shareEnable.value && passwdEnable.value) {
|
||||
if (!state.detailInfo.autoPwd && existErrorMsg()) {
|
||||
if (!state.detailInfo.autoPwd && existErrorMsg('link-pwd-error-msg')) {
|
||||
ElMessage.warning('密码格式错误,请重新填写!')
|
||||
return
|
||||
}
|
||||
@ -393,6 +425,43 @@ const copyPwd = async () => {
|
||||
ElMessage.warning(t('common.copy_unsupported'))
|
||||
}
|
||||
}
|
||||
const editUuid = () => {
|
||||
linkCustom.value = true
|
||||
nextTick(() => {
|
||||
if (linkUuidRef?.value) {
|
||||
linkUuidRef.value.input.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
const validateUuid = async () => {
|
||||
const val = state.detailInfo.uuid
|
||||
const className = 'link-uuid-error-msg'
|
||||
if (!val) {
|
||||
showPageError('不能为空!', linkUuidRef, className)
|
||||
return false
|
||||
}
|
||||
const regex = /^[a-zA-Z0-9]{8,16}$/
|
||||
const result = regex.test(val)
|
||||
if (!result) {
|
||||
showPageError('仅支持8-16位(字母数字),请重新输入!', linkUuidRef, className)
|
||||
} else {
|
||||
const msg = await uuidValidateApi(val)
|
||||
showPageError(msg, linkUuidRef, className)
|
||||
return !msg
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const uuidValidateApi = async val => {
|
||||
const url = '/share/editUuid'
|
||||
const data = { resourceId: props.resourceId, uuid: val }
|
||||
const res = await request.post({ url, data })
|
||||
return res.data
|
||||
}
|
||||
const finishEditUuid = async () => {
|
||||
const uuidValid = await validateUuid()
|
||||
linkCustom.value = !uuidValid
|
||||
}
|
||||
|
||||
const execute = () => {
|
||||
share()
|
||||
@ -436,6 +505,27 @@ defineExpose({
|
||||
.text {
|
||||
padding-bottom: 5px !important;
|
||||
}
|
||||
.custom-link-line {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
align-items: center;
|
||||
button {
|
||||
width: 40px;
|
||||
min-width: 40px;
|
||||
margin-left: 8px;
|
||||
height: 100%;
|
||||
}
|
||||
:deep(.link-uuid-error-msg) {
|
||||
color: red;
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
font-size: 10px;
|
||||
height: 10px;
|
||||
top: 25px;
|
||||
width: 350px;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.inline-share-item-picker {
|
||||
display: flex;
|
||||
|
@ -1,10 +1,7 @@
|
||||
package io.dataease.api.xpack.share;
|
||||
|
||||
import io.dataease.api.xpack.share.request.XpackShareExpRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackShareProxyRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackSharePwdRequest;
|
||||
import io.dataease.api.xpack.share.request.*;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.xpack.share.request.XpackSharePwdValidator;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareGridVO;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareProxyVO;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareVO;
|
||||
@ -61,4 +58,8 @@ public interface XpackShareApi {
|
||||
@Operation(summary = "", hidden = true)
|
||||
@GetMapping("/queryRelationByUserId/{uid}")
|
||||
Map<String, String> queryRelationByUserId(@PathVariable("uid") Long uid);
|
||||
|
||||
@Operation(summary = "编辑分享uuid")
|
||||
@PostMapping("/editUuid")
|
||||
String editUuid(@RequestBody XpackShareUuidEditor editor);
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
package io.dataease.api.xpack.share.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Schema(description = "分享UUID编辑器")
|
||||
@Data
|
||||
public class XpackShareUuidEditor implements Serializable {
|
||||
|
||||
@Schema(description = "资源ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long resourceId;
|
||||
@Schema(description = "分享UUID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String uuid;
|
||||
}
|
Loading…
Reference in New Issue
Block a user