forked from github/dataease
Merge pull request #10438 from dataease/pr@dev-v2@feat_share_ticket
Pr@dev v2@feat share ticket
This commit is contained in:
commit
92917afb7a
@ -14,18 +14,18 @@ public class MybatisPlusGenerator {
|
||||
* 第一 我嫌麻烦
|
||||
* 第二 后面配置会放到nacos读起来更麻烦了
|
||||
*/
|
||||
private static final String url = "jdbc:mysql://localhost:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false";
|
||||
private static final String url = "jdbc:mysql://localhost:3306/de_standalone?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false";
|
||||
private static final String username = "root";
|
||||
private static final String password = "123456";
|
||||
private static final String password = "Password123@mysql";
|
||||
|
||||
/**
|
||||
* 业务模块例如datasource,dataset,panel等
|
||||
*/
|
||||
private static final String busi = "visualization";
|
||||
private static final String busi = "share";
|
||||
/**
|
||||
* 这是要生成代码的表名称
|
||||
*/
|
||||
private static final String TABLE_NAME = "data_visualization_info";
|
||||
private static final String TABLE_NAME = "xpack_share";
|
||||
|
||||
/**
|
||||
* 下面两个配置基本上不用动
|
||||
|
@ -9,7 +9,7 @@ import java.io.Serializable;
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2024-04-07
|
||||
* @since 2024-06-21
|
||||
*/
|
||||
@TableName("xpack_share")
|
||||
public class XpackShare implements Serializable {
|
||||
@ -66,6 +66,11 @@ public class XpackShare implements Serializable {
|
||||
*/
|
||||
private Boolean autoPwd;
|
||||
|
||||
/**
|
||||
* ticket必须
|
||||
*/
|
||||
private Boolean ticketRequire;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@ -146,6 +151,14 @@ public class XpackShare implements Serializable {
|
||||
this.autoPwd = autoPwd;
|
||||
}
|
||||
|
||||
public Boolean getTicketRequire() {
|
||||
return ticketRequire;
|
||||
}
|
||||
|
||||
public void setTicketRequire(Boolean ticketRequire) {
|
||||
this.ticketRequire = ticketRequire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "XpackShare{" +
|
||||
@ -159,6 +172,7 @@ public class XpackShare implements Serializable {
|
||||
", oid = " + oid +
|
||||
", type = " + type +
|
||||
", autoPwd = " + autoPwd +
|
||||
", ticketRequire = " + ticketRequire +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2024-04-07
|
||||
* @since 2024-06-21
|
||||
*/
|
||||
@Mapper
|
||||
public interface XpackShareMapper extends BaseMapper<XpackShare> {
|
||||
|
@ -6,6 +6,7 @@ import io.dataease.share.dao.ext.po.XpackSharePO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
@Mapper
|
||||
public interface XpackShareExtMapper {
|
||||
@ -28,4 +29,7 @@ public interface XpackShareExtMapper {
|
||||
|
||||
@Select("select type from data_visualization_info where id = #{id}")
|
||||
String visualizationType(@Param("id") Long id);
|
||||
|
||||
@Update("update core_share_ticket set uuid = #{ticketUuid} where uuid = #{originUuid}")
|
||||
void updateTicketUuid(@Param("originUuid") String originUuid, @Param("ticketUuid") String ticketUuid);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ 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.TicketValidVO;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareGridVO;
|
||||
import io.dataease.api.xpack.share.vo.XpackShareProxyVO;
|
||||
import io.dataease.auth.bo.TokenUserBO;
|
||||
@ -28,6 +29,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -46,6 +48,9 @@ public class XpackShareManage {
|
||||
@Resource(name = "xpackShareExtMapper")
|
||||
private XpackShareExtMapper xpackShareExtMapper;
|
||||
|
||||
@Resource
|
||||
private ShareTicketManage shareTicketManage;
|
||||
|
||||
public XpackShare queryByResource(Long resourceId) {
|
||||
Long userId = AuthUtils.getUser().getUserId();
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
@ -54,10 +59,12 @@ public class XpackShareManage {
|
||||
return xpackShareMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void switcher(Long resourceId) {
|
||||
XpackShare originData = queryByResource(resourceId);
|
||||
if (ObjectUtils.isNotEmpty(originData)) {
|
||||
xpackShareMapper.deleteById(originData.getId());
|
||||
shareTicketManage.deleteByShare(originData.getUuid());
|
||||
return;
|
||||
}
|
||||
TokenUserBO user = AuthUtils.getUser();
|
||||
@ -74,6 +81,7 @@ public class XpackShareManage {
|
||||
xpackShareMapper.insert(xpackShare);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public String editUuid(XpackShareUuidEditor editor) {
|
||||
Long resourceId = editor.getResourceId();
|
||||
String uuid = editor.getUuid();
|
||||
@ -98,6 +106,7 @@ public class XpackShareManage {
|
||||
if (!matcher.matches()) {
|
||||
return "仅支持8-16位(字母数字),请重新输入!";
|
||||
}
|
||||
shareTicketManage.updateByUuidChange(originData.getUuid(), uuid);
|
||||
originData.setUuid(uuid);
|
||||
xpackShareMapper.updateById(originData);
|
||||
return "";
|
||||
@ -196,7 +205,8 @@ public class XpackShareManage {
|
||||
response.addHeader(AuthConstant.LINK_TOKEN_KEY, linkToken);
|
||||
Integer type = xpackShare.getType();
|
||||
String typeText = (ObjectUtils.isNotEmpty(type) && type == 1) ? "dashboard" : "dataV";
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError);
|
||||
TicketValidVO validVO = shareTicketManage.validateTicket(request.getTicket(), xpackShare);
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError, validVO);
|
||||
}
|
||||
|
||||
private boolean linkExp(XpackShare xpackShare) {
|
||||
|
@ -17,4 +17,20 @@ CREATE TABLE `xpack_plugin`
|
||||
`module_name` varchar(255) NOT NULL COMMENT '模块名称',
|
||||
`jar_name` varchar(255) NOT NULL COMMENT 'Jar包名称',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT ='插件表';
|
||||
) COMMENT ='插件表';
|
||||
|
||||
ALTER TABLE `xpack_share`
|
||||
ADD COLUMN `ticket_require` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'ticket必须' AFTER `auto_pwd`;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `core_share_ticket`;
|
||||
CREATE TABLE `core_share_ticket`
|
||||
(
|
||||
`id` bigint NOT NULL COMMENT 'ID',
|
||||
`uuid` varchar(255) NOT NULL COMMENT '分享uuid',
|
||||
`ticket` varchar(255) NOT NULL COMMENT 'ticket',
|
||||
`exp` bigint DEFAULT NULL COMMENT 'ticket有效期',
|
||||
`args` longtext COMMENT 'ticket参数',
|
||||
`access_time` bigint DEFAULT NULL COMMENT '首次访问时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT ='分享Ticket表';
|
3
core/core-frontend/src/assets/svg/edit-done.svg
Normal file
3
core/core-frontend/src/assets/svg/edit-done.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12C23 18.0751 18.0751 23 12 23ZM10.84 14.2799L16.1433 8.97665C16.3386 8.78138 16.6551 8.78138 16.8504 8.97665L17.5575 9.68375C17.7528 9.87901 17.7528 10.1956 17.5575 10.3909L11.1936 16.7548C10.9983 16.9501 10.6817 16.9501 10.4864 16.7548L6.82603 13.0944C6.63077 12.8991 6.63077 12.5826 6.82603 12.3873L7.53314 11.6802C7.7284 11.4849 8.04498 11.4849 8.24024 11.6802L10.84 14.2799Z" fill=""/>
|
||||
</svg>
|
After Width: | Height: | Size: 694 B |
@ -16,7 +16,10 @@
|
||||
<el-dialog
|
||||
v-if="dialogVisible && props.weight >= 7"
|
||||
class="copy-link_dialog"
|
||||
:class="{ 'hidden-footer': !shareEnable || showTicket }"
|
||||
:class="{
|
||||
'hidden-footer': !shareEnable || showTicket,
|
||||
'is-ticket-dialog': shareEnable && showTicket
|
||||
}"
|
||||
v-model="dialogVisible"
|
||||
:close-on-click-modal="true"
|
||||
:append-to-body="true"
|
||||
@ -118,11 +121,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="shareEnable && showTicket" class="share-ticket-container">
|
||||
<share-ticket :link-url="linkAddr" @close="closeTicket" />
|
||||
<share-ticket
|
||||
:link-url="linkAddr"
|
||||
:uuid="state.detailInfo.uuid"
|
||||
:resource-id="props.resourceId"
|
||||
:ticket-require="state.detailInfo.ticketRequire"
|
||||
@require-change="updateRequireTicket"
|
||||
@close="closeTicket"
|
||||
/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<!-- <el-button secondary @click="openTicket">Ticket 设置</el-button> -->
|
||||
<el-button secondary @click="openTicket">Ticket 设置</el-button>
|
||||
<el-button :disabled="!shareEnable || expError" type="primary" @click.stop="copyInfo">
|
||||
{{ t('visualization.copy_link') }}
|
||||
</el-button>
|
||||
@ -167,7 +177,8 @@ const state = reactive({
|
||||
uuid: '',
|
||||
pwd: '',
|
||||
exp: 0,
|
||||
autoPwd: true
|
||||
autoPwd: true,
|
||||
ticketRequire: false
|
||||
} as ShareInfo
|
||||
})
|
||||
const emits = defineEmits(['loaded'])
|
||||
@ -460,6 +471,9 @@ const openTicket = () => {
|
||||
const closeTicket = () => {
|
||||
showTicket.value = false
|
||||
}
|
||||
const updateRequireTicket = val => {
|
||||
state.detailInfo.ticketRequire = val
|
||||
}
|
||||
|
||||
const execute = () => {
|
||||
share()
|
||||
@ -480,6 +494,11 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.is-ticket-dialog {
|
||||
.ed-dialog__header {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.copy-link_dialog {
|
||||
.ed-dialog__header {
|
||||
padding: 16px 16px 10px !important;
|
||||
|
@ -12,31 +12,46 @@
|
||||
<span class="ticket-title">{{ 'Ticket ' + $t('commons.setting') }}</span>
|
||||
</div>
|
||||
<div class="ticket-model-end">
|
||||
<el-checkbox v-model="requireTicket" @change="requireTicketChange" />
|
||||
<span>{{ $t('link_ticket.require') }}</span>
|
||||
<el-checkbox
|
||||
v-model="ticketRequire"
|
||||
@change="requireTicketChange"
|
||||
:label="t('link_ticket.require')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ticket-add">
|
||||
<el-button @click="addRow" text>
|
||||
<template #icon>
|
||||
<icon name="icon_add_outlined"></icon>
|
||||
</template>
|
||||
{{ t('commons.create') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="ticket-table">
|
||||
<!-- <div class="text-add-ticket">
|
||||
<el-button class="de-text-btn mr2" type="text" icon="el-icon-plus" @click="addRow">{{
|
||||
$t('commons.create')
|
||||
}}</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="tableData" style="width: 100%" size="mini">
|
||||
<el-table-column prop="ticket" label="ticket" width="120">
|
||||
<el-table :data="state.tableData" style="width: 100%" size="small">
|
||||
<el-table-column prop="ticket" label="ticket" width="130">
|
||||
<template v-slot="scope">
|
||||
<div class="ticket-row">
|
||||
<span>{{ scope.row.ticket }}</span>
|
||||
<el-tooltip class="item" effect="dark" :content="$t('commons.copy')" placement="top">
|
||||
<span
|
||||
<el-button
|
||||
text
|
||||
v-clipboard:copy="`${props.linkUrl}?ticket=${scope.row.ticket}`"
|
||||
v-clipboard:success="onCopy"
|
||||
v-clipboard:error="onError"
|
||||
>
|
||||
<template #icon>
|
||||
<Icon name="de-copy"></Icon>
|
||||
</template>
|
||||
</el-button>
|
||||
<!-- <span
|
||||
v-clipboard:copy="`${props.linkUrl}?ticket=${scope.row.ticket}`"
|
||||
v-clipboard:success="onCopy"
|
||||
v-clipboard:error="onError"
|
||||
class="copy-i"
|
||||
>
|
||||
<svg-icon icon-class="de-icon-copy" />
|
||||
</span>
|
||||
<icon name="de-copy"></icon>
|
||||
</span> -->
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
@ -44,17 +59,22 @@
|
||||
:content="`${$t('link_ticket.refresh')} ticket`"
|
||||
placement="top"
|
||||
>
|
||||
<span class="refresh-i">
|
||||
<i class="el-icon-refresh-right" @click="refreshTicket(scope.row)" />
|
||||
</span>
|
||||
<el-button text @click="refreshTicket(scope.row)">
|
||||
<template #icon>
|
||||
<Icon name="icon_refresh_outlined"></Icon>
|
||||
</template>
|
||||
</el-button>
|
||||
<!-- <span class="refresh-i" @click="refreshTicket(scope.row)">
|
||||
<icon name="icon_refresh_outlined" />
|
||||
</span> -->
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="exp" :label="$t('panel.over_time')" width="100">
|
||||
<el-table-column prop="exp" :label="$t('visualization.over_time')" width="100">
|
||||
<template v-slot:header>
|
||||
<span>{{ $t('panel.over_time') }}</span>
|
||||
<span>{{ $t('visualization.over_time') }}</span>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
@ -62,13 +82,14 @@
|
||||
placement="top"
|
||||
>
|
||||
<span class="check-tips">
|
||||
<svg-icon icon-class="de-icon-info" @click="closeTicket" />
|
||||
<svg-icon icon-class="de-icon-info" />
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-slot="scope">
|
||||
<el-input
|
||||
v-if="scope.row.isEdit"
|
||||
:ref="el => setExpRef(el, scope.$index)"
|
||||
v-model="scope.row.exp"
|
||||
type="number"
|
||||
:placeholder="$t('commons.input_content')"
|
||||
@ -86,6 +107,7 @@
|
||||
<template v-slot="scope">
|
||||
<el-input
|
||||
v-if="scope.row.isEdit"
|
||||
:ref="el => setArgRef(el, scope.$index)"
|
||||
v-model="scope.row.args"
|
||||
type="text"
|
||||
:placeholder="$t('commons.input_content')"
|
||||
@ -100,16 +122,18 @@
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')" width="80">
|
||||
<template v-slot="scope">
|
||||
<div class="ticket-op">
|
||||
<div class="ticket-row">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('commons.delete')"
|
||||
placement="top"
|
||||
>
|
||||
<span>
|
||||
<i class="el-icon-delete" @click="deleteTicket(scope.row, scope.$idnex)" />
|
||||
</span>
|
||||
<el-button text @click="deleteTicket(scope.row, scope.$idnex)">
|
||||
<template #icon>
|
||||
<Icon name="icon_delete-trash_outlined"></Icon>
|
||||
</template>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
@ -117,82 +141,196 @@
|
||||
:content="scope.row.isEdit ? $t('commons.save') : $t('commons.edit')"
|
||||
placement="top"
|
||||
>
|
||||
<span>
|
||||
<i v-if="!scope.row.isEdit" class="el-icon-edit" @click="editRow(scope.row)" />
|
||||
<i
|
||||
v-else
|
||||
class="el-icon-circle-check"
|
||||
@click="saveRow(scope.row, scope.$index)"
|
||||
/>
|
||||
</span>
|
||||
<el-button v-if="!scope.row.isEdit" text @click="editRow(scope.row)">
|
||||
<template #icon>
|
||||
<Icon name="icon_edit_outlined"></Icon>
|
||||
</template>
|
||||
</el-button>
|
||||
<el-button v-else text @click="saveRow(scope.row, scope.$index)">
|
||||
<template #icon>
|
||||
<Icon name="edit-done"></Icon>
|
||||
</template>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table> -->
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="ticket-btn">
|
||||
<el-button type="primary" @click.stop="finish"> 完成 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ref, reactive, onMounted, toRefs } from 'vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import request from '@/config/axios'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
|
||||
const { t } = useI18n()
|
||||
const props = defineProps({
|
||||
linkUrl: propTypes.string.def(null)
|
||||
linkUrl: propTypes.string.def(null),
|
||||
uuid: propTypes.string.def(null),
|
||||
resourceId: propTypes.string.def(null),
|
||||
ticketRequire: propTypes.bool
|
||||
})
|
||||
|
||||
const requireTicket = ref(false)
|
||||
const tableData = reactive([])
|
||||
const emits = defineEmits(['close'])
|
||||
const { ticketRequire } = toRefs(props)
|
||||
const expRefs = ref({})
|
||||
const argRefs = ref({})
|
||||
|
||||
const state = reactive({
|
||||
tableData: []
|
||||
})
|
||||
const emits = defineEmits(['close', 'requireChange'])
|
||||
|
||||
const close = () => {
|
||||
emits('close')
|
||||
}
|
||||
|
||||
const setExpRef = (el, index) => {
|
||||
if (el) {
|
||||
expRefs.value[index] = el
|
||||
}
|
||||
}
|
||||
|
||||
const setArgRef = (el, index) => {
|
||||
if (el) {
|
||||
argRefs.value[index] = el
|
||||
}
|
||||
}
|
||||
|
||||
const requireTicketChange = val => {
|
||||
console.log(val)
|
||||
const url = '/ticket/enableTicket'
|
||||
const data = {
|
||||
resourceId: props.resourceId,
|
||||
require: val
|
||||
}
|
||||
request.post({ url, data }).then(() => {
|
||||
emits('requireChange', val)
|
||||
})
|
||||
}
|
||||
|
||||
const addRow = () => {
|
||||
console.log(11)
|
||||
const row = {
|
||||
ticket: '',
|
||||
exp: 30,
|
||||
args: '',
|
||||
uuid: props.uuid
|
||||
}
|
||||
const url = '/ticket/saveTicket'
|
||||
request.post({ url, data: row }).then(res => {
|
||||
row.ticket = res.data
|
||||
row['isEdit'] = false
|
||||
state.tableData.splice(0, 0, row)
|
||||
})
|
||||
}
|
||||
|
||||
const refreshTicket = row => {
|
||||
console.log(row)
|
||||
}
|
||||
const closeTicket = () => {
|
||||
console.log(11)
|
||||
const url = '/ticket/saveTicket'
|
||||
const param = JSON.parse(JSON.stringify(row))
|
||||
param['generateNew'] = true
|
||||
request.post({ url, data: param }).then(res => {
|
||||
row.ticket = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const validateExp = (val, index) => {
|
||||
console.log(val)
|
||||
console.log(index)
|
||||
const cref = expRefs.value[index]
|
||||
const e = cref.input
|
||||
if (val === null || val === '' || typeof val === 'undefined') {
|
||||
state.tableData[index]['exp'] = 0
|
||||
return true
|
||||
}
|
||||
if (val > 1440 || val < 0) {
|
||||
e.style.color = 'red'
|
||||
e.parentNode.setAttribute('style', 'box-shadow: 0 0 0 1px red inset;')
|
||||
return false
|
||||
} else {
|
||||
e.style.color = null
|
||||
e.parentNode.removeAttribute('style')
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const validateArgs = (val, index) => {
|
||||
console.log(val)
|
||||
console.log(index)
|
||||
const cref = argRefs.value[index]
|
||||
const e = cref.input
|
||||
if (val === null || val === '' || typeof val === 'undefined') {
|
||||
e.style.color = null
|
||||
e.parentNode.removeAttribute('style')
|
||||
const child = e.parentNode.querySelector('.error-msg')
|
||||
if (child) {
|
||||
e.parentNode.removeChild(child)
|
||||
}
|
||||
return true
|
||||
}
|
||||
try {
|
||||
JSON.parse(val)
|
||||
e.style.color = null
|
||||
e.parentNode.removeAttribute('style')
|
||||
const child = e.parentNode.querySelector('.error-msg')
|
||||
if (child) {
|
||||
e.parentNode.removeChild(child)
|
||||
}
|
||||
return true
|
||||
} catch (error) {
|
||||
e.style.color = 'red'
|
||||
e.parentNode.setAttribute('style', 'box-shadow: 0 0 0 1px red inset;')
|
||||
const child = e.parentNode.querySelector('.error-msg')
|
||||
if (!child) {
|
||||
const errorDom = document.createElement('div')
|
||||
errorDom.className = 'error-msg'
|
||||
errorDom.innerText = '格式错误'
|
||||
e.parentNode.appendChild(errorDom)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const deleteTicket = (val, index) => {
|
||||
console.log(val)
|
||||
console.log(index)
|
||||
const deleteTicket = (row, index) => {
|
||||
const param = { ticket: row.ticket }
|
||||
const url = '/ticket/delTicket'
|
||||
request.post({ url, data: param }).then(() => {
|
||||
state.tableData.splice(index, 1)
|
||||
})
|
||||
}
|
||||
|
||||
const saveRow = (val, index) => {
|
||||
console.log(val)
|
||||
console.log(index)
|
||||
const saveRow = (row, index) => {
|
||||
const url = '/ticket/saveTicket'
|
||||
validateExp(row.exp, index) &&
|
||||
validateArgs(row.args, index) &&
|
||||
request.post({ url, data: row }).then(() => {
|
||||
row.isEdit = false
|
||||
})
|
||||
}
|
||||
const editRow = row => {
|
||||
console.log(row)
|
||||
row.isEdit = true
|
||||
}
|
||||
const onCopy = e => {
|
||||
console.log(e)
|
||||
const onCopy = () => {
|
||||
ElMessage.success('复制成功')
|
||||
}
|
||||
const onError = e => {
|
||||
console.log(e)
|
||||
}
|
||||
const finish = () => {
|
||||
close()
|
||||
}
|
||||
|
||||
const loadTicketData = () => {
|
||||
const resourceId = props.resourceId
|
||||
const url = `/ticket/query/${resourceId}`
|
||||
request.get({ url }).then(res => {
|
||||
state.tableData = res.data
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
loadTicketData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@ -200,8 +338,9 @@ const onError = e => {
|
||||
height: 261px;
|
||||
.ticket-model {
|
||||
display: flex;
|
||||
height: 22px;
|
||||
justify-content: space-between;
|
||||
padding: 16px 0;
|
||||
padding: 0;
|
||||
.ticket-model-start {
|
||||
display: flex;
|
||||
color: #1f2329;
|
||||
@ -212,6 +351,11 @@ const onError = e => {
|
||||
font-size: 14px;
|
||||
}
|
||||
.back-tips {
|
||||
i {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
width: 22px;
|
||||
margin-right: 4px;
|
||||
display: flex;
|
||||
@ -224,32 +368,91 @@ const onError = e => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
margin-right: 8px;
|
||||
.ticket-model-end {
|
||||
display: flex;
|
||||
label {
|
||||
height: 22px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ticket-add {
|
||||
margin: 16px 0;
|
||||
height: 22px;
|
||||
button {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
.ticket-table {
|
||||
padding: 0 0;
|
||||
// height: 260px;
|
||||
height: 50px;
|
||||
overflow-y: overlay;
|
||||
position: relative;
|
||||
::v-deep .error-msg {
|
||||
height: calc(100% - 124px);
|
||||
:deep(.error-msg) {
|
||||
color: red;
|
||||
position: fixed;
|
||||
z-index: 9;
|
||||
font-size: 10px;
|
||||
height: 10px;
|
||||
margin-bottom: 12px;
|
||||
margin-right: -80px;
|
||||
}
|
||||
::v-deep .check-tips {
|
||||
:deep(.check-tips) {
|
||||
margin-left: 4px;
|
||||
}
|
||||
.text-add-ticket {
|
||||
width: 48px;
|
||||
:deep(.ticket-row) {
|
||||
span {
|
||||
margin-right: 8px;
|
||||
}
|
||||
button {
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
height: 22px;
|
||||
gap: 4px;
|
||||
.ed-button + .ed-button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ed-table__header) {
|
||||
background-color: #f5f6f7;
|
||||
thead {
|
||||
tr {
|
||||
th {
|
||||
background-color: #f5f6f7 !important;
|
||||
.cell {
|
||||
line-height: 22px;
|
||||
padding: 4px 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
height: 38px;
|
||||
}
|
||||
:deep(.ed-table__row) {
|
||||
height: 39px;
|
||||
td {
|
||||
.cell {
|
||||
line-height: 22px;
|
||||
height: 22px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.ed-input__inner) {
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
.ticket-btn {
|
||||
margin-top: 16px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -4,6 +4,7 @@ export interface ShareInfo {
|
||||
uuid: string
|
||||
pwd?: string
|
||||
autoPwd: boolean
|
||||
ticketRequire?: boolean
|
||||
}
|
||||
|
||||
export const SHARE_BASE = '/de-link/'
|
||||
|
@ -0,0 +1,29 @@
|
||||
package io.dataease.api.xpack.share;
|
||||
|
||||
import io.dataease.api.xpack.share.request.TicketCreator;
|
||||
import io.dataease.api.xpack.share.request.TicketDelRequest;
|
||||
import io.dataease.api.xpack.share.request.TicketSwitchRequest;
|
||||
import io.dataease.api.xpack.share.vo.TicketVO;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "分享:TICKET")
|
||||
public interface ShareTicketApi {
|
||||
|
||||
@PostMapping("/saveTicket")
|
||||
String saveTicket(@RequestBody TicketCreator creator);
|
||||
|
||||
@PostMapping("/delTicket")
|
||||
void deleteTicket(@RequestBody TicketDelRequest request);
|
||||
|
||||
@PostMapping("/enableTicket")
|
||||
void switchRequire(@RequestBody TicketSwitchRequest request);
|
||||
|
||||
@GetMapping("/query/{resourceId}")
|
||||
List<TicketVO> query(@PathVariable("resourceId") Long resourceId);
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package io.dataease.api.xpack.share.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class TicketCreator implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 8661378104009097296L;
|
||||
|
||||
private String ticket;
|
||||
|
||||
private Long exp;
|
||||
|
||||
private String args;
|
||||
|
||||
private String uuid;
|
||||
|
||||
private boolean generateNew;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package io.dataease.api.xpack.share.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class TicketDelRequest implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -3978489349675065507L;
|
||||
|
||||
private String ticket;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package io.dataease.api.xpack.share.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class TicketSwitchRequest implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 7670768142874123370L;
|
||||
|
||||
private String resourceId;
|
||||
|
||||
private Boolean require = false;
|
||||
}
|
@ -20,4 +20,6 @@ public class XpackShareProxyRequest implements Serializable {
|
||||
@Schema(description = "密钥", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String ciphertext;
|
||||
private boolean inIframe;
|
||||
|
||||
private String ticket;
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
package io.dataease.api.xpack.share.vo;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class TicketVO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -599110079356725271L;
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
private String uuid;
|
||||
|
||||
private String ticket;
|
||||
|
||||
private Long exp;
|
||||
|
||||
private String args;
|
||||
|
||||
private Long accessTime;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package io.dataease.api.xpack.share.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class TicketValidVO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 2452043685969885580L;
|
||||
|
||||
private boolean ticketValid;
|
||||
|
||||
private boolean ticketExp;
|
||||
|
||||
private String args;
|
||||
}
|
@ -32,4 +32,6 @@ public class XpackShareProxyVO implements Serializable {
|
||||
@Schema(description = "类型")
|
||||
private String type;
|
||||
private boolean inIframeError = true;
|
||||
|
||||
private TicketValidVO ticketValidVO;
|
||||
}
|
||||
|
@ -29,4 +29,6 @@ public class XpackShareVO implements Serializable {
|
||||
private String pwd;
|
||||
@Schema(description = "自动生成密码")
|
||||
private Boolean autoPwd = true;
|
||||
@Schema(description = "ticket必须")
|
||||
private Boolean ticketRequire = false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user