Merge pull request #1163 from dataease/pr@dev@feat_完善我的分享

feat: 完善我的分享
This commit is contained in:
fit2cloud-chenyw 2021-11-10 18:05:21 +08:00 committed by GitHub
commit 5cfedd4a44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 437 additions and 20 deletions

View File

@ -2,6 +2,8 @@ package io.dataease.base.mapper.ext;
import io.dataease.base.domain.PanelShare;
import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.controller.request.panel.PanelShareRemoveRequest;
import io.dataease.dto.panel.PanelShareOutDTO;
import io.dataease.dto.panel.PanelSharePo;
import org.apache.ibatis.annotations.Param;
@ -20,6 +22,10 @@ public interface ExtPanelShareMapper {
List<PanelShare> queryWithResource(GridExample example);
List<PanelShareOutDTO> queryTargets(String panelId);
void removeShares(@Param("request") PanelShareRemoveRequest request);
List<Long> queryUserIdWithRoleIds(Map<String, List<Long>> param);
List<Long> queryUserIdWithDeptIds(Map<String, List<Long>> param);

View File

@ -8,6 +8,15 @@
<result column="creator" property="creator" />
</resultMap>
<resultMap id="targetMap" type="io.dataease.dto.panel.PanelShareOutDTO">
<result column="panel_id" property="panelId" />
<result column="share_id" property="shareId" />
<result column="type" property="type" />
<result column="target_Id" property="targetId" />
<result column="target_Name" property="targetName" />
<result column="create_time" property="createTime" />
</resultMap>
<insert id="batchInsert" parameterType="io.dataease.base.domain.PanelShare">
INSERT INTO panel_share (panel_group_id,target_id,granter,create_time,type)
VALUES
@ -61,6 +70,26 @@
</if>
</select>
<select id="queryTargets" resultMap="targetMap">
select
s.share_id,
s.panel_group_id as panel_id,
s.type,
s.target_id,
s.create_time,
(
CASE s.type
WHEN 0 THEN (select nick_name from sys_user where user_id = s.target_id)
WHEN 1 THEN (select name from sys_role where role_id = s.target_id)
WHEN 2 THEN (select name from sys_dept where dept_id = s.target_id)
END
) as target_name
from panel_share s
where s.panel_group_id = #{panelId}
</select>
<select id="queryUserIdWithRoleIds" resultType="java.lang.Long" >
@ -82,6 +111,14 @@
</foreach>
</select>
<delete id="removeShares" parameterType="io.dataease.controller.request.panel.PanelShareRemoveRequest">
delete from panel_share
where panel_group_id = #{request.panelId}
<if test="request.shareId != null">
and share_id = #{request.shareId}
</if>
</delete>

View File

@ -3,12 +3,16 @@ package io.dataease.controller.panel.api;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.base.domain.PanelShare;
import io.dataease.controller.request.panel.PanelShareFineDto;
import io.dataease.controller.request.panel.PanelShareRemoveRequest;
import io.dataease.controller.request.panel.PanelShareRequest;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.dto.panel.PanelShareDto;
import io.dataease.dto.panel.PanelShareOutDTO;
import io.dataease.dto.panel.PanelSharePo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import springfox.documentation.annotations.ApiIgnore;
@ -41,9 +45,20 @@ public interface ShareApi {
@PostMapping("/queryWithResourceId")
List<PanelShare> queryWithResourceId(BaseGridRequest request);
@ApiOperation("查询分享目标")
@PostMapping("/queryTargets/{panelId}")
@ApiImplicitParam(paramType = "path", value = "仪表板ID", name = "panelId", required = true, dataType = "String")
List<PanelShareOutDTO> queryTargets(@PathVariable("panelId") String panelId);
@ApiOperation("创建分享")
@PostMapping("/fineSave")
void fineSave(PanelShareFineDto panelShareFineDto);
@ApiOperation("删除分享")
@PostMapping("/removeShares")
void removeShares(PanelShareRemoveRequest request);
}

View File

@ -3,11 +3,14 @@ package io.dataease.controller.panel.server;
import io.dataease.base.domain.PanelShare;
import io.dataease.controller.panel.api.ShareApi;
import io.dataease.controller.request.panel.PanelShareFineDto;
import io.dataease.controller.request.panel.PanelShareRemoveRequest;
import io.dataease.controller.request.panel.PanelShareRequest;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.dto.panel.PanelShareDto;
import io.dataease.dto.panel.PanelShareOutDTO;
import io.dataease.dto.panel.PanelSharePo;
import io.dataease.service.panel.ShareService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@ -39,10 +42,20 @@ public class ShareServer implements ShareApi {
return shareService.queryWithResource(request);
}
@Override
public List<PanelShareOutDTO> queryTargets(@PathVariable("panelId") String panelId) {
return shareService.queryTargets(panelId);
}
@Override
public void fineSave(@RequestBody PanelShareFineDto panelShareFineDto) {
shareService.fineSave(panelShareFineDto);
}
@Override
public void removeShares(@RequestBody PanelShareRemoveRequest request) {
shareService.removeShares(request);
}
}

View File

@ -0,0 +1,18 @@
package io.dataease.controller.request.panel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel("取消分享参数")
public class PanelShareRemoveRequest implements Serializable {
@ApiModelProperty("仪表板ID")
private String panelId;
@ApiModelProperty("分享ID")
private String shareId;
}

View File

@ -0,0 +1,30 @@
package io.dataease.dto.panel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ApiModel("仪表板分享目标")
@Data
public class PanelShareOutDTO implements Serializable {
@ApiModelProperty("仪表板ID")
private String panelId;
@ApiModelProperty("分享ID")
private Long shareId;
@ApiModelProperty("分享类型{0:用户,1:角色,2:组织}")
private int type;
@ApiModelProperty("目标ID")
private String targetId;
@ApiModelProperty("目标名称")
private String targetName;
@ApiModelProperty("分享时间")
private Long createTime;
}

View File

@ -15,9 +15,11 @@ import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CommonBeanFactory;
import io.dataease.controller.request.panel.PanelShareFineDto;
import io.dataease.controller.request.panel.PanelShareRemoveRequest;
import io.dataease.controller.request.panel.PanelShareRequest;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.dto.panel.PanelShareDto;
import io.dataease.dto.panel.PanelShareOutDTO;
import io.dataease.dto.panel.PanelSharePo;
import io.dataease.service.message.DeMsgutil;
import lombok.Data;
@ -345,5 +347,13 @@ public class ShareService {
return extPanelShareMapper.queryWithResource(example);
}
public List<PanelShareOutDTO> queryTargets(String panelId) {
return extPanelShareMapper.queryTargets(panelId);
}
public void removeShares(PanelShareRemoveRequest removeRequest) {
extPanelShareMapper.removeShares(removeRequest);
}
}

View File

@ -9,6 +9,23 @@ import request from '@/utils/request'
})
} */
export function shareTargets(panelId) {
return request({
url: '/api/share/queryTargets/' + panelId,
method: 'post',
loading: true
})
}
export function removeShares(data) {
return request({
url: '/api/share/removeShares/',
method: 'post',
loading: true,
data
})
}
export function loadShares(data) {
return request({
url: '/api/share/queryWithResourceId',

View File

@ -1225,6 +1225,15 @@ export default {
link_expire: 'Link is expire',
link_share_desc: 'After opening the link, anyone can access the dashboard through this link.',
share: 'Share',
remove_share_confirm: 'Sure removel All share ?',
share_in: 'Share in',
share_out: 'Share out',
who_share: 'Who share',
when_share: 'When share',
share_to: 'Share to',
org: 'Orgnization',
role: 'Role',
user: 'User',
datalist: 'Chart List',
group: 'Catalogue',
panel: 'Dashboard',

View File

@ -1228,6 +1228,15 @@ export default {
link_expire: '鏈接已過期!',
link_share_desc: '開啓鏈接後,任何人可通過此鏈接訪問儀表板。',
share: '分享',
remove_share_confirm: '確認取消當前儀表板所有分享?',
share_in: '分享給我',
share_out: '我分享的',
who_share: '分享人',
when_share: '分享時間',
share_to: '分享對象',
org: '組織',
role: '角色',
user: '用戶',
datalist: '視圖列表',
group: '目錄',
panel: '儀表板',

View File

@ -1236,6 +1236,15 @@ export default {
link_share: '链接分享',
link_share_desc: '开启链接后,任何人可通过此链接访问仪表板。',
share: '分享',
remove_share_confirm: '确认取消当前仪表板所有分享?',
share_in: '分享给我',
share_out: '我分享的',
who_share: '分享人',
when_share: '分享时间',
share_to: '分享对象',
org: '组织',
role: '角色',
user: '用户',
datalist: '视图列表',
group: '目录',
panel: '仪表板',

View File

@ -0,0 +1,156 @@
<template>
<div>
<el-col>
<el-row>
<el-col :span="8" style="text-overflow:ellipsis;overflow: hidden;white-space: nowrap;font-size: 14px">
<span>{{ $t('panel.who_share') + ': ' + $store.getters.user.nickName }}</span>
</el-col>
<el-col :span="8" style="text-overflow:ellipsis;overflow: hidden;white-space: nowrap;font-size: 14px">
<span>{{ $t('panel.when_share') + ': ' + (granterTime ? new Date(granterTime).format('yyyy年-MM月-dd日') : '') }}</span>
</el-col>
<el-col :span="8" style="text-overflow:ellipsis;overflow: hidden;white-space: nowrap;font-size: 14px">
<el-link type="primary" disabled class="share-checked">
<!-- <el-checkbox v-model="checked" disabled>组织</el-checkbox> -->
{{ $t('panel.org') }}
</el-link>
<el-link type="success" disabled class="share-checked">
<!-- <el-checkbox v-model="checked" disabled>角色</el-checkbox> -->
{{ $t('panel.role') }}
</el-link>
<el-link type="info" disabled class="share-checked">
<!-- <el-checkbox v-model="checked" disabled>用户</el-checkbox> -->
{{ $t('panel.user') }}
</el-link>
</el-col>
</el-row>
<el-row style="display: flex;">
<el-col style="text-overflow:ellipsis;overflow: hidden;white-space: nowrap;font-size: 14px; width: 90px;">
<span>{{ $t('panel.share_to') }}</span>
</el-col>
<el-col>
<el-tag
v-for="tag in dynamicTags"
:key="tag.targetName"
:type="tag.tagType"
size="small"
class="selected-tag"
closable
:disable-transitions="false"
@close="handleClose(tag)"
>
{{ tag.targetName }}
</el-tag>
<el-tooltip class="item" effect="dark" :content="$t('commons.edit')" placement="bottom">
<el-button type="primary" circle icon="el-icon-edit" class="button-new-tag" size="mini" @click="showEditPage" />
</el-tooltip>
</el-col>
</el-row>
<el-row />
</el-col>
<el-dialog
v-dialogDrag
:title="authTitle"
:visible.sync="authVisible"
width="800px"
class="dialog-css"
>
<grant-auth v-if="authVisible" :resource-id="authResourceId" @close-grant="closeGrant" />
</el-dialog>
</div>
</template>
<script>
import GrantAuth from '../index'
import { shareTargets, removeShares } from '@/api/panel/share'
export default {
name: 'ShareHead',
components: { GrantAuth },
data() {
return {
granter: '管理员',
granterTime: '2021年11月9日',
dynamicTags: [],
authVisible: false,
authTitle: '',
authResourceId: null,
targetDatas: [],
tagTypes: { 0: 'info', 1: 'success', 2: 'primary' },
checked: false
}
},
computed: {
panelInfo() {
// this.initTagDatas()
return this.$store.state.panel.panelInfo
}
},
watch: {
panelInfo(newVal, oldVla) {
//
this.$nextTick(() => {
this.initTagDatas()
})
}
},
created() {
this.initTagDatas()
},
methods: {
handleClose(tag) {
// this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1)
if (!tag || !tag.shareId) return
const param = {
panelId: this.panelInfo.id,
shareId: tag.shareId
}
removeShares(param).then(res => {
this.initTagDatas()
})
},
showEditPage() {
this.authResourceId = this.panelInfo.id
this.authTitle = '把[' + this.panelInfo.name + ']分享给'
this.authVisible = true
},
closeGrant() {
this.initTagDatas()
this.authResourceId = null
this.authVisible = false
},
initTagDatas() {
shareTargets(this.panelInfo.id).then(res => {
this.targetDatas = res.data
this.dynamicTags = res.data.map(item => {
item.tagType = this.tagTypes[item.type]
this.granterTime = item.createTime
return item
}).sort((a, b) => b.type - a.type)
})
}
}
}
</script>
<style lang="scss" scoped>
.button-new-tag {
margin-left: 10px;
}
.share-checked {
margin-left: 15px;
}
.selected-tag {
margin: 0 2px;
}
</style>

View File

@ -1,11 +1,17 @@
<template>
<el-col style="padding: 0 5px 0 5px;">
<el-row>
<span class="header-title">分享给我</span>
<span class="header-title">{{ $t('panel.share_in') }}</span>
<div class="block" style="margin-top:8px;">
<el-tree :data="datas" :props="defaultProps" node-key="name" :default-expanded-keys="expandNodes" @node-click="handleNodeClick">
<span slot-scope="{ data }" class="custom-tree-node">
<span :class="!!data.msgNode ? 'msg-node-class': ''">
<el-tree :data="datas" :props="defaultProps" :highlight-current="true" node-key="name" :default-expanded-keys="expandNodes" @node-click="handleNodeClick">
<span slot-scope="{ data }" class="custom-tree-node father">
<span style="display: flex; flex: 1 1 0%; width: 0px;" :class="!!data.msgNode ? 'msg-node-class': ''">
<span v-if="!!data.id">
<svg-icon icon-class="panel" class="ds-icon-scene" />
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
</span>
<!-- <span :class="!!data.msgNode ? 'msg-node-class': ''">
<span v-if="!!data.id">
<el-button
icon="el-icon-picture-outline"
@ -13,27 +19,36 @@
/>
</span>
<span style="margin-left: 6px">{{ data.name }}</span>
</span>
</span> -->
</span>
</el-tree>
</div>
</el-row>
<el-row>
<span class="header-title">我分享的</span>
<span class="header-title">{{ $t('panel.share_out') }}</span>
<div class="block" style="margin-top:8px;">
<el-tree :data="outDatas" :props="defaultProps" node-key="name" :default-expand-all="true" @node-click="handleNodeClick">
<span slot-scope="{ data }" class="custom-tree-node">
<span>
<el-tree :data="outDatas" :props="defaultProps" :highlight-current="true" node-key="name" :default-expand-all="true" @node-click="viewMyShare">
<span slot-scope="{ data }" class="custom-tree-node father">
<span style="display: flex; flex: 1 1 0%; width: 0px;">
<span v-if="!!data.id">
<svg-icon icon-class="panel" class="ds-icon-scene" />
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
</span>
<span class="child">
<span class="el-dropdown-link">
<el-button
icon="el-icon-picture-outline"
icon="el-icon-delete"
type="text"
size="small"
@click="removeCurrent(data)"
/>
</span>
<span style="margin-left: 6px">{{ data.name }}</span>
</span>
</span>
</el-tree>
</div>
</el-row>
@ -41,7 +56,7 @@
</template>
<script>
import { loadTree, loadShareOutTree } from '@/api/panel/share'
import { loadTree, loadShareOutTree, removeShares } from '@/api/panel/share'
import { uuid } from 'vue-uuid'
import { get } from '@/api/panel/panel'
import bus from '@/utils/bus'
@ -90,7 +105,16 @@ export default {
this.$store.commit('setCanvasStyle', JSON.parse(response.data.panelStyle))
this.$store.dispatch('panel/setPanelInfo', data)
bus.$emit('set-panel-is-share')
bus.$emit('set-panel-show-type', 1)
})
},
viewMyShare(data) {
get('panel/group/findOne/' + data.id).then(response => {
this.$store.commit('setComponentData', this.resetID(JSON.parse(response.data.panelData)))
this.$store.commit('setCanvasStyle', JSON.parse(response.data.panelStyle))
this.$store.dispatch('panel/setPanelInfo', data)
bus.$emit('set-panel-show-type', 2)
})
},
resetID(data) {
@ -119,6 +143,30 @@ export default {
})
}
})
},
removeCurrent(node) {
console.log(node)
const param = {
panelId: node.id
}
this.$confirm(this.$t('panel.remove_share_confirm'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
removeShares(param).then(res => {
this.initOutData().then(res => {
this.outDatas = res.data
})
this.$success(this.$t('commons.delete_success'))
})
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
})
})
}
}
@ -141,4 +189,29 @@ export default {
color: red;
}
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right:8px;
}
.custom-tree-node-list {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding:0 8px;
}
.father .child {
/*display: none;*/
visibility: hidden;
}
.father:hover .child {
/*display: inline;*/
visibility: visible;
}
</style>

View File

@ -55,6 +55,7 @@ export default {
name: row.name
}
this.$store.dispatch('panel/setPanelInfo', data)
bus.$emit('set-panel-show-type', 0)
})
},
resetID(data) {

View File

@ -647,6 +647,8 @@ export default {
queryPanelJumpInfo(data.id).then(rsp => {
this.$store.commit('setNowPanelJumpInfo', rsp.data)
})
bus.$emit('set-panel-show-type', 0)
})
}
if (node.expanded) {

View File

@ -7,7 +7,13 @@
element-loading-background="rgba(0, 0, 0, 0.8)"
>
<el-col v-if="panelInfo.name.length>0" class="panel-design">
<el-row class="panel-design-head">
<el-row v-if="showType === 2" class="panel-design-head panel-share-head">
<div style="border-bottom: 1px solid #dfe4ed;height: 100%;">
<share-head />
</div>
</el-row>
<el-row v-else class="panel-design-head">
<!--仪表板头部区域-->
<div style="border-bottom: 1px solid #dfe4ed;height: 100%;">
<el-col :span="12" style="text-overflow:ellipsis;overflow: hidden;white-space: nowrap;font-size: 14px">
@ -44,13 +50,13 @@
</el-tooltip>
</span>
<span v-if="!hasStar && panelInfo && !isShare" style="float: right;margin-right: 10px">
<span v-if="!hasStar && panelInfo && showType !== 1" style="float: right;margin-right: 10px">
<el-tooltip :content="$t('panel.store')">
<el-button class="el-icon-star-off" size="mini" circle @click="star" />
</el-tooltip>
</span>
<span v-if="hasStar && panelInfo && !isShare" style="float: right;margin-right: 10px">
<span v-if="hasStar && panelInfo && showType !== 1" style="float: right;margin-right: 10px">
<el-tooltip :content="$t('commons.cancel')">
<el-button class="el-icon-star-on" size="mini" circle @click="unstar" />
</el-tooltip>
@ -115,10 +121,11 @@ import FileSaver from 'file-saver'
import { enshrineList, saveEnshrine, deleteEnshrine } from '@/api/panel/enshrine'
import bus from '@/utils/bus'
import { queryAll } from '@/api/panel/pdfTemplate'
import ShareHead from '@/views/panel/GrantAuth/ShareHead'
export default {
name: 'PanelViewShow',
components: { Preview, SaveToTemplate, PDFPreExport },
components: { Preview, SaveToTemplate, PDFPreExport, ShareHead },
props: {
activeTab: {
type: String,
@ -138,7 +145,7 @@ export default {
fullscreen: false,
pdfExportShow: false,
snapshotInfo: '',
isShare: false,
showType: 0,
dataLoading: false
}
},
@ -155,6 +162,7 @@ export default {
panelInfo(newVal, oldVla) {
//
this.showMain = false
this.$nextTick(() => {
this.showMain = true
this.initHasStar()
@ -170,9 +178,10 @@ export default {
}
},
mounted() {
bus.$on('set-panel-is-share', () => {
this.isShare = true
bus.$on('set-panel-show-type', type => {
this.showType = type || 0
})
this.initPdfTemplate()
},
methods: {
@ -333,6 +342,9 @@ export default {
padding: 0 10px;
line-height: 40px;
}
.panel-share-head {
height: auto !important;
}
.blackTheme .panel-design-head {
color: var(--TextActive);
}