Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ce2c3e5d2 | ||
|
|
f7910e986b | ||
|
|
20c088992e | ||
|
|
0f77ddc022 | ||
|
|
37a2e547d3 | ||
|
|
ebaa8425d6 |
@@ -4,6 +4,7 @@ import com.auth0.jwt.JWT;
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.license.utils.LicenseUtil;
|
||||
import io.dataease.share.dao.auto.entity.XpackShare;
|
||||
import io.dataease.share.dao.auto.mapper.XpackShareRepository;
|
||||
import io.dataease.utils.ServletUtils;
|
||||
@@ -25,8 +26,9 @@ public class ShareVisitorPermissionManage {
|
||||
}
|
||||
|
||||
public int creatorPermissions(Long resourceId) {
|
||||
if (!LicenseUtil.licenseValid()) return 7;
|
||||
var auth = io.dataease.utils.CommonBeanFactory.getBean(io.dataease.api.permissions.auth.api.InteractiveAuthApi.class);
|
||||
if (auth == null) return 7;
|
||||
if (auth == null) return 0;
|
||||
var permission = auth.queryAuth(resourceId);
|
||||
if (permission == null || permission.getWeight() <= 1) return 0;
|
||||
if (permission.getWeight() == 9) return 7;
|
||||
@@ -48,6 +50,8 @@ public class ShareVisitorPermissionManage {
|
||||
var shares = repository.findAll((root, query, cb) -> cb.and(
|
||||
cb.equal(root.get("creator"), uid), cb.equal(root.get("resourceId"), resourceId)));
|
||||
if (shares.isEmpty()) DEException.throwException(Translator.get("i18n_share_operation_denied"));
|
||||
// Community sharing retains its original operations, but still requires an existing link.
|
||||
if (!LicenseUtil.licenseValid()) return 7;
|
||||
// Be conservative if legacy duplicate shares exist.
|
||||
return shares.stream().mapToInt(ShareVisitorPermissionManage::permissions).reduce(7, (a, b) -> a & b)
|
||||
& creatorPermissions(resourceId);
|
||||
|
||||
@@ -42,6 +42,9 @@ public class XpackShareServer implements XpackShareApi {
|
||||
|
||||
@PostMapping("/visitorPermissions")
|
||||
public void saveVisitorPermissions(@RequestBody VisitorPermissionsRequest request) {
|
||||
if (!io.dataease.license.utils.LicenseUtil.licenseValid()) {
|
||||
DEException.throwException(io.dataease.i18n.Translator.get("i18n_share_operation_denied"));
|
||||
}
|
||||
if (request.resourceId() == null || request.visitorPermissions() == null
|
||||
|| request.visitorPermissions() < 0 || request.visitorPermissions() > 7) {
|
||||
DEException.throwException(io.dataease.i18n.Translator.get("i18n_share_operation_denied"));
|
||||
|
||||
@@ -31,7 +31,12 @@
|
||||
<div ref="shareDialogRef" class="share-dialog-container">
|
||||
<div class="copy-link">
|
||||
<div class="open-share flex-align-center">
|
||||
<el-switch size="small" v-model="shareEnable" @change="enableSwitcher" />
|
||||
<el-switch
|
||||
size="small"
|
||||
v-model="shareEnable"
|
||||
:disabled="!shareInfoReady"
|
||||
@change="enableSwitcher"
|
||||
/>
|
||||
{{ shareTips }}
|
||||
</div>
|
||||
<div v-if="shareEnable" class="custom-link-line">
|
||||
@@ -189,7 +194,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<ShareVisitorPermissions
|
||||
v-if="shareEnable"
|
||||
v-if="shareEnable && !appearanceStore.getCommunity"
|
||||
v-model="visitorChoices"
|
||||
:allowed="state.detailInfo.allowedVisitorPermissions ?? 7"
|
||||
/>
|
||||
@@ -228,6 +233,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ShareVisitorPermissions from './ShareVisitorPermissions.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import dvShare from '@/assets/svg/dv-share.svg'
|
||||
import icon_shareLabel_outlined from '@/assets/svg/icon_share-label_outlined.svg'
|
||||
import deCopy from '@/assets/svg/de-copy.svg'
|
||||
@@ -260,6 +266,8 @@ const props = defineProps({
|
||||
weight: propTypes.number.def(0),
|
||||
isButton: propTypes.bool.def(false)
|
||||
})
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const shareInfoReady = ref(false)
|
||||
const visitorChoices = ref<number[]>([])
|
||||
const originUuid = ref('')
|
||||
const customPwdRef = ref()
|
||||
@@ -376,13 +384,15 @@ const copyInfo = async () => {
|
||||
}
|
||||
}
|
||||
savingPermissions.value = true
|
||||
await request.post({
|
||||
url: '/share/visitorPermissions',
|
||||
data: {
|
||||
resourceId: props.resourceId,
|
||||
visitorPermissions: visitorChoices.value.reduce((a, b) => a | b, 0)
|
||||
}
|
||||
})
|
||||
if (!appearanceStore.getCommunity) {
|
||||
await request.post({
|
||||
url: '/share/visitorPermissions',
|
||||
data: {
|
||||
resourceId: props.resourceId,
|
||||
visitorPermissions: visitorChoices.value.reduce((a, b) => a | b, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
formatLinkAddr()
|
||||
let info = linkAddr.value
|
||||
if (passwdEnable.value) {
|
||||
@@ -429,6 +439,7 @@ const share = () => {
|
||||
}
|
||||
|
||||
const loadShareInfo = (cb, resetPermissions = false) => {
|
||||
shareInfoReady.value = false
|
||||
showLoading()
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/detail/${resourceId}`
|
||||
@@ -452,6 +463,10 @@ const loadShareInfo = (cb, resetPermissions = false) => {
|
||||
originUuid.value = res.data.uuid
|
||||
}
|
||||
setPageInfo()
|
||||
shareInfoReady.value = true
|
||||
})
|
||||
.catch(() => {
|
||||
// The request interceptor reports the error; do not allow toggling an unknown state.
|
||||
})
|
||||
.finally(() => {
|
||||
closeLoading()
|
||||
@@ -460,8 +475,8 @@ const loadShareInfo = (cb, resetPermissions = false) => {
|
||||
}
|
||||
|
||||
const setPageInfo = () => {
|
||||
if (state.detailInfo.id && state.detailInfo.uuid) {
|
||||
shareEnable.value = true
|
||||
shareEnable.value = !!(state.detailInfo.id && state.detailInfo.uuid)
|
||||
if (shareEnable.value) {
|
||||
formatLinkAddr()
|
||||
}
|
||||
passwdEnable.value = !!state.detailInfo.pwd
|
||||
@@ -469,6 +484,8 @@ const setPageInfo = () => {
|
||||
}
|
||||
|
||||
const enableSwitcher = () => {
|
||||
if (!shareInfoReady.value) return
|
||||
shareInfoReady.value = false
|
||||
showLoading()
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/switcher/${resourceId}`
|
||||
@@ -477,6 +494,9 @@ const enableSwitcher = () => {
|
||||
.then(() => {
|
||||
loadShareInfo(null)
|
||||
})
|
||||
.catch(() => {
|
||||
loadShareInfo(null)
|
||||
})
|
||||
.finally(() => {
|
||||
closeLoading()
|
||||
})
|
||||
|
||||
@@ -27,7 +27,12 @@
|
||||
<div v-if="!shareDisable" ref="shareContainerRef" class="share-container">
|
||||
<div class="share-title share-padding">{{ t('work_branch.public_link_share') }}</div>
|
||||
<div class="open-share flex-align-center share-padding">
|
||||
<el-switch size="small" v-model="shareEnable" @change="enableSwitcher" />
|
||||
<el-switch
|
||||
size="small"
|
||||
v-model="shareEnable"
|
||||
:disabled="!shareInfoReady"
|
||||
@change="enableSwitcher"
|
||||
/>
|
||||
{{ shareTips }}
|
||||
</div>
|
||||
<div v-if="shareEnable" class="custom-link-line share-padding">
|
||||
@@ -189,7 +194,7 @@
|
||||
</div>
|
||||
|
||||
<ShareVisitorPermissions
|
||||
v-if="shareEnable"
|
||||
v-if="shareEnable && !appearanceStore.getCommunity"
|
||||
v-model="visitorChoices"
|
||||
:allowed="state.detailInfo.allowedVisitorPermissions ?? 7"
|
||||
/>
|
||||
@@ -229,6 +234,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ShareVisitorPermissions from './ShareVisitorPermissions.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import icon_shareLabel_outlined from '@/assets/svg/icon_share-label_outlined.svg'
|
||||
import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
|
||||
import icon_close_outlined from '@/assets/svg/icon_close_outlined.svg'
|
||||
@@ -345,6 +351,8 @@ const shareTips = computed(
|
||||
const shareDisable = computed(() => shareStore.getShareDisable)
|
||||
const sharePeRequire = computed(() => shareStore.getSharePeRequire)
|
||||
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const shareInfoReady = ref(false)
|
||||
const visitorChoices = ref<number[]>([])
|
||||
const savingPermissions = ref(false)
|
||||
const copyInfo = async () => {
|
||||
@@ -366,13 +374,15 @@ const copyInfo = async () => {
|
||||
}
|
||||
}
|
||||
savingPermissions.value = true
|
||||
await request.post({
|
||||
url: '/share/visitorPermissions',
|
||||
data: {
|
||||
resourceId: props.resourceId,
|
||||
visitorPermissions: visitorChoices.value.reduce((a, b) => a | b, 0)
|
||||
}
|
||||
})
|
||||
if (!appearanceStore.getCommunity) {
|
||||
await request.post({
|
||||
url: '/share/visitorPermissions',
|
||||
data: {
|
||||
resourceId: props.resourceId,
|
||||
visitorPermissions: visitorChoices.value.reduce((a, b) => a | b, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
formatLinkAddr()
|
||||
let info = linkAddr.value
|
||||
if (passwdEnable.value) {
|
||||
@@ -416,6 +426,7 @@ const share = () => {
|
||||
}
|
||||
|
||||
const loadShareInfo = (cb, resetPermissions = false) => {
|
||||
shareInfoReady.value = false
|
||||
showLoading()
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/detail/${resourceId}`
|
||||
@@ -439,6 +450,10 @@ const loadShareInfo = (cb, resetPermissions = false) => {
|
||||
originUuid.value = res.data.uuid
|
||||
}
|
||||
setPageInfo()
|
||||
shareInfoReady.value = true
|
||||
})
|
||||
.catch(() => {
|
||||
// The request interceptor reports the error; do not allow toggling an unknown state.
|
||||
})
|
||||
.finally(() => {
|
||||
closeLoading()
|
||||
@@ -460,6 +475,8 @@ const setPageInfo = () => {
|
||||
}
|
||||
|
||||
const enableSwitcher = () => {
|
||||
if (!shareInfoReady.value) return
|
||||
shareInfoReady.value = false
|
||||
showLoading()
|
||||
const resourceId = props.resourceId
|
||||
const url = `/share/switcher/${resourceId}`
|
||||
@@ -468,6 +485,9 @@ const enableSwitcher = () => {
|
||||
.then(() => {
|
||||
loadShareInfo(null)
|
||||
})
|
||||
.catch(() => {
|
||||
loadShareInfo(null)
|
||||
})
|
||||
.finally(() => {
|
||||
closeLoading()
|
||||
})
|
||||
|
||||
2
de-xpack
2
de-xpack
Submodule de-xpack updated: 70cb52b788...68bb20dc94
@@ -32,42 +32,42 @@ function db_defaults() {
|
||||
mysql)
|
||||
DB_DEFAULT_PORT=3306
|
||||
DB_DEFAULT_PARAMS="autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true"
|
||||
DB_DRIVER_JAR="mariadb-java-client-3.3.6.jar"
|
||||
DB_DRIVER_PATTERN="mariadb-java-client-*.jar"
|
||||
;;
|
||||
pg)
|
||||
DB_DEFAULT_PORT=5432
|
||||
DB_DEFAULT_PARAMS="connectTimeout=10"
|
||||
DB_DRIVER_JAR="postgresql-42.7.11.jar"
|
||||
DB_DRIVER_PATTERN="postgresql-*.jar"
|
||||
;;
|
||||
oracle)
|
||||
DB_DEFAULT_PORT=1521
|
||||
DB_DEFAULT_PARAMS="useUnicode=true&characterEncoding=UTF-8"
|
||||
DB_DRIVER_JAR="ojdbc10-19.19.0.0.jar"
|
||||
DB_DRIVER_PATTERN="ojdbc[0-9]*.jar"
|
||||
;;
|
||||
dm)
|
||||
DB_DEFAULT_PORT=5236
|
||||
DB_DEFAULT_PARAMS="charset=UTF-8&loginTimeout=10&connectTimeout=10000"
|
||||
DB_DRIVER_JAR="DmJdbcDriver18.jar"
|
||||
DB_DRIVER_PATTERN="DmJdbcDriver*.jar"
|
||||
;;
|
||||
kingbase)
|
||||
DB_DEFAULT_PORT=54321
|
||||
DB_DEFAULT_PARAMS="connectTimeout=10"
|
||||
DB_DRIVER_JAR="kingbase8-9.0.1.jar"
|
||||
DB_DRIVER_PATTERN="kingbase[0-9]*.jar"
|
||||
;;
|
||||
sqlserver)
|
||||
DB_DEFAULT_PORT=1433
|
||||
DB_DEFAULT_PARAMS="encrypt=false"
|
||||
DB_DRIVER_JAR="mssql-jdbc-13.4.0.jre11.jar"
|
||||
DB_DRIVER_PATTERN="mssql-jdbc-*.jar"
|
||||
;;
|
||||
greatsql)
|
||||
DB_DEFAULT_PORT=3306
|
||||
DB_DEFAULT_PARAMS="autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true"
|
||||
DB_DRIVER_JAR="mariadb-java-client-3.3.6.jar"
|
||||
DB_DRIVER_PATTERN="mariadb-java-client-*.jar"
|
||||
;;
|
||||
*)
|
||||
DB_DEFAULT_PORT=3306
|
||||
DB_DEFAULT_PARAMS=""
|
||||
DB_DRIVER_JAR=""
|
||||
DB_DRIVER_PATTERN=""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -138,23 +138,47 @@ function prompt_database_config() {
|
||||
log_content "数据库类型: ${DE_DB_TYPE}, 使用外置数据库: ${DE_EXTERNAL_DB}"
|
||||
}
|
||||
|
||||
# 复制数据库驱动到 data/driver
|
||||
# 同类 JPA 驱动只保留安装包版本,避免新旧 jar 同时被加载。
|
||||
function copy_db_driver() {
|
||||
db_defaults "$DE_DB_TYPE"
|
||||
if [[ -z "$DB_DRIVER_JAR" ]]; then
|
||||
log_content "[警告] ${DE_DB_TYPE} 未配置驱动 jar,请确认 drivers 目录包含对应驱动"
|
||||
return
|
||||
if [[ -z "$DB_DRIVER_PATTERN" ]]; then
|
||||
log_content "[错误] ${DE_DB_TYPE} 未配置驱动类型"
|
||||
return 1
|
||||
fi
|
||||
local drivers_folder="${CURRENT_DIR}/drivers"
|
||||
[[ -d "$drivers_folder" ]] || drivers_folder="${CURRENT_DIR}/../drivers"
|
||||
local driver_source="${drivers_folder}/${DB_DRIVER_JAR}"
|
||||
if [[ -f "$driver_source" ]]; then
|
||||
mkdir -p ${DE_RUN_BASE}/data/driver
|
||||
cp "$driver_source" ${DE_RUN_BASE}/data/driver/
|
||||
log_content "已复制数据库驱动: ${DB_DRIVER_JAR}"
|
||||
else
|
||||
log_content "[警告] 未找到驱动 ${driver_source},请检查安装包是否包含该驱动"
|
||||
local driver_source driver_file
|
||||
local driver_sources=()
|
||||
# 模式刻意不加引号,以匹配版本变化;目录仍保留引号以支持空格。
|
||||
for driver_file in "$drivers_folder"/$DB_DRIVER_PATTERN; do
|
||||
[[ -f "$driver_file" ]] && driver_sources+=("$driver_file")
|
||||
done
|
||||
if [[ ${#driver_sources[@]} -ne 1 ]]; then
|
||||
log_content "[错误] 安装包必须包含唯一的 ${DE_DB_TYPE} 驱动(${DB_DRIVER_PATTERN}),实际找到 ${#driver_sources[@]} 个"
|
||||
return 1
|
||||
fi
|
||||
driver_source="${driver_sources[0]}"
|
||||
local driver_name="${driver_source##*/}"
|
||||
local driver_target="${DE_RUN_BASE}/data/driver"
|
||||
local staged_driver
|
||||
mkdir -p "$driver_target" || return 1
|
||||
staged_driver=$(mktemp "$driver_target/.jpa-driver.XXXXXX") || return 1
|
||||
# 完整复制后再替换,复制失败时保留原有驱动。
|
||||
if ! cp "$driver_source" "$staged_driver" || ! chmod 644 "$staged_driver" ||
|
||||
! mv -f "$staged_driver" "$driver_target/$driver_name"; then
|
||||
rm -f "$staged_driver"
|
||||
log_content "[错误] 复制数据库驱动失败: ${driver_name}"
|
||||
return 1
|
||||
fi
|
||||
for driver_file in "$driver_target"/$DB_DRIVER_PATTERN; do
|
||||
[[ -e "$driver_file" || -L "$driver_file" ]] || continue
|
||||
[[ "$driver_file" == "$driver_target/$driver_name" ]] && continue
|
||||
if ! rm -f "$driver_file"; then
|
||||
log_content "[错误] 清理旧数据库驱动失败: ${driver_file}"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
log_content "已更新数据库驱动: ${driver_name}"
|
||||
}
|
||||
|
||||
function check_and_prepare_env_params() {
|
||||
@@ -277,7 +301,7 @@ function prepare_de_run_base() {
|
||||
fi
|
||||
|
||||
# 复制数据库驱动到 data/driver
|
||||
copy_db_driver
|
||||
copy_db_driver || exit 1
|
||||
|
||||
# 内置地图由镜像 map-origin 提供,持久化 map 仅保存用户覆盖文件
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user