feat: 插件管理 消息管理 优化
This commit is contained in:
parent
a0b92c91ec
commit
1403504e2a
@ -34,7 +34,7 @@ export default {
|
|||||||
return backPath || backName || backTo
|
return backPath || backName || backTo
|
||||||
},
|
},
|
||||||
needInnerPadding() {
|
needInnerPadding() {
|
||||||
return ['sys-task-email', 'system-dept', 'system-dept-form', 'system-auth', 'sys-appearance', 'system-param', 'system-template', "sys-task-dataset"].includes(this.$route.name)
|
return ['sys-task-email', 'system-dept', 'system-dept-form', 'system-auth', 'sys-appearance', 'system-param', 'system-template', "sys-task-dataset", "sys-msg-web-all", "system-plugin"].includes(this.$route.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { log } from '@antv/g2plot/lib/utils';
|
||||||
import tableBody from "./tableBody";
|
import tableBody from "./tableBody";
|
||||||
export default {
|
export default {
|
||||||
components: { tableBody },
|
components: { tableBody },
|
||||||
|
|||||||
@ -2169,7 +2169,7 @@ export default {
|
|||||||
i18n_msg_type_ds_invalid: '数据源失效',
|
i18n_msg_type_ds_invalid: '数据源失效',
|
||||||
i18n_msg_type_all: '全部类型',
|
i18n_msg_type_all: '全部类型',
|
||||||
channel_inner_msg: '站内消息',
|
channel_inner_msg: '站内消息',
|
||||||
channel_email_msg: '邮件'
|
channel_email_msg: '邮件提醒'
|
||||||
},
|
},
|
||||||
denumberrange: {
|
denumberrange: {
|
||||||
label: '数值区间',
|
label: '数值区间',
|
||||||
|
|||||||
@ -1,191 +1,328 @@
|
|||||||
<template>
|
<template>
|
||||||
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
|
<de-layout-content
|
||||||
|
:header="$t('消息列表')"
|
||||||
|
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
|
||||||
|
>
|
||||||
|
<div class="organization">
|
||||||
|
<el-tabs v-model="tabActive" @tab-click="changeTab">
|
||||||
|
<el-tab-pane :label="$t('未读消息')" name="unread"> </el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('已读消息')" name="readed"> </el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('全部消息')" name="allMsg"> </el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="tabs-container">
|
||||||
|
<div class="msg-cont">
|
||||||
|
<el-row class="top-operate">
|
||||||
|
<el-col :span="12">
|
||||||
|
<template v-if="tabActive === 'unread'">
|
||||||
|
<deBtn secondary @click="allMarkReaded">{{
|
||||||
|
$t("webmsg.all_mark_readed")
|
||||||
|
}}</deBtn>
|
||||||
|
<deBtn
|
||||||
|
secondary
|
||||||
|
:disabled="multipleSelection.length === 0"
|
||||||
|
@click="markReaded"
|
||||||
|
>{{ $t("webmsg.mark_readed") }}</deBtn
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<deBtn
|
||||||
|
v-if="tabActive === 'readed'"
|
||||||
|
secondary
|
||||||
|
:disabled="multipleSelection.length === 0"
|
||||||
|
@click="deleteBatch"
|
||||||
|
>{{ $t("commons.delete") }}</deBtn
|
||||||
|
>
|
||||||
|
|
||||||
|
</el-col>
|
||||||
|
<el-col class="right-user" :span="12">
|
||||||
|
<el-select
|
||||||
|
class="name-email-search"
|
||||||
|
v-model="selectType"
|
||||||
|
size="small"
|
||||||
|
@change="typeChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in $store.getters.msgTypes.filter(
|
||||||
|
(type) => type.pid <= 0
|
||||||
|
)"
|
||||||
|
:key="index"
|
||||||
|
:label="$t('webmsg.' + item.typeName)"
|
||||||
|
:value="item.msgTypeId"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div class="table-container" :key="tabActive">
|
||||||
|
<grid-table
|
||||||
|
:key="tabActive"
|
||||||
|
:tableData="data"
|
||||||
|
:multipleSelection="multipleSelection"
|
||||||
|
:columns="[]"
|
||||||
|
:pagination="paginationConfig"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="sortChange"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
|
||||||
<el-radio-group v-model="selectType" style="margin-bottom: 15px;" @change="typeChange">
|
<el-table-column prop="content" :label="$t('webmsg.content')">
|
||||||
<el-radio-button v-for="(item,index) in $store.getters.msgTypes.filter(type => type.pid <= 0)" :key="index" class="de-msg-radio-class" :label="item.msgTypeId">{{ $t('webmsg.' + item.typeName) }}</el-radio-button>
|
<template slot-scope="scope">
|
||||||
|
<span style="display: flex; flex: 1">
|
||||||
|
<span>
|
||||||
|
<svg-icon
|
||||||
|
v-if="!scope.row.status"
|
||||||
|
icon-class="unread-msg"
|
||||||
|
style="color: red"
|
||||||
|
/>
|
||||||
|
<svg-icon v-else icon-class="readed-msg" />
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
style="margin-left: 6px"
|
||||||
|
class="de-msg-a"
|
||||||
|
@click="toDetail(scope.row)"
|
||||||
|
>
|
||||||
|
{{ scope.row.content }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
</el-radio-group>
|
<el-table-column
|
||||||
<complex-table
|
prop="createTime"
|
||||||
:data="data"
|
sortable="custom"
|
||||||
:columns="columns"
|
:label="$t('webmsg.sned_time')"
|
||||||
:pagination-config="paginationConfig"
|
width="180"
|
||||||
@select="select"
|
>
|
||||||
@search="search"
|
<template slot-scope="scope">
|
||||||
@sort-change="sortChange"
|
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||||
>
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="content" :label="$t('webmsg.content')">
|
<el-table-column
|
||||||
<template slot-scope="scope">
|
prop="typeId"
|
||||||
|
sortable="custom"
|
||||||
<span style="display: flex;flex: 1;">
|
:label="$t('webmsg.type')"
|
||||||
<span>
|
width="140"
|
||||||
<svg-icon v-if="!scope.row.status" icon-class="unread-msg" style="color: red;" />
|
>
|
||||||
<svg-icon v-else icon-class="readed-msg" />
|
<template slot-scope="scope">
|
||||||
</span>
|
<span>{{ getTypeName(scope.row.typeId) }}</span>
|
||||||
<span style="margin-left: 6px;" class="de-msg-a" @click="toDetail(scope.row)">
|
</template>
|
||||||
{{ scope.row.content }}
|
</el-table-column>
|
||||||
</span>
|
</grid-table>
|
||||||
</span>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</div>
|
||||||
</el-table-column>
|
</div>
|
||||||
|
</de-layout-content>
|
||||||
<el-table-column prop="createTime" sortable="custom" :label="$t('webmsg.sned_time')" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column prop="typeId" sortable="custom" :label="$t('webmsg.type')" width="140">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ getTypeName(scope.row.typeId) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
</complex-table>
|
|
||||||
|
|
||||||
</layout-content>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import DeLayoutContent from "@/components/business/DeLayoutContent";
|
||||||
import LayoutContent from '@/components/business/LayoutContent'
|
import GridTable from "@/components/gridTable/index.vue";
|
||||||
import ComplexTable from '@/components/business/complex-table'
|
import { query, updateStatus, batchRead, allRead, batchDelete } from '@/api/system/msg'
|
||||||
import { query, updateStatus } from '@/api/system/msg'
|
import { msgTypes, getTypeName, loadMsgTypes } from "@/utils/webMsg";
|
||||||
import { msgTypes, getTypeName, loadMsgTypes } from '@/utils/webMsg'
|
import bus from "@/utils/bus";
|
||||||
import bus from '@/utils/bus'
|
import { addOrder, formatOrders } from "@/utils/index";
|
||||||
import { addOrder, formatOrders } from '@/utils/index'
|
import msgCfm from "@/components/msgCfm/index";
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from "vuex";
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
LayoutContent,
|
DeLayoutContent,
|
||||||
ComplexTable
|
GridTable,
|
||||||
},
|
},
|
||||||
|
mixins: [msgCfm],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
multipleSelection: [],
|
||||||
|
tabActive: "unread",
|
||||||
selectType: -1,
|
selectType: -1,
|
||||||
msgTypes: msgTypes,
|
msgTypes: msgTypes,
|
||||||
data: [],
|
data: [],
|
||||||
allTypes: [{ name: 'mysql', type: 'jdbc' }, { name: 'sqlServer', type: 'jdbc' }],
|
allTypes: [
|
||||||
|
{ name: "mysql", type: "jdbc" },
|
||||||
|
{ name: "sqlServer", type: "jdbc" },
|
||||||
|
],
|
||||||
|
|
||||||
columns: [],
|
columns: [],
|
||||||
|
|
||||||
paginationConfig: {
|
paginationConfig: {
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
total: 0
|
total: 0,
|
||||||
},
|
},
|
||||||
orderConditions: []
|
orderConditions: [],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(["permission_routes"]),
|
||||||
'permission_routes'
|
|
||||||
])
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.search()
|
this.search();
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// 先加载消息类型
|
// 先加载消息类型
|
||||||
loadMsgTypes()
|
loadMsgTypes();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
select(selection) {
|
changeTab(val) {
|
||||||
|
this.initSearch();
|
||||||
|
},
|
||||||
|
handleSelectionChange(val) {
|
||||||
|
this.multipleSelection = val;
|
||||||
|
},
|
||||||
|
handleSizeChange(pageSize) {
|
||||||
|
this.paginationConfig.currentPage = 1;
|
||||||
|
this.paginationConfig.pageSize = pageSize;
|
||||||
|
this.search();
|
||||||
|
},
|
||||||
|
handleCurrentChange(currentPage) {
|
||||||
|
this.paginationConfig.currentPage = currentPage;
|
||||||
|
this.search();
|
||||||
|
},
|
||||||
|
initSearch() {
|
||||||
|
this.handleCurrentChange(1);
|
||||||
|
},
|
||||||
|
allMarkReaded() {
|
||||||
|
allRead().then(res => {
|
||||||
|
this.openMessageSuccess('webmsg.mark_success');
|
||||||
|
bus.$emit('refresh-top-notification')
|
||||||
|
this.initSearch()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
markReaded() {
|
||||||
|
const param = this.multipleSelection.map(item => item.msgId)
|
||||||
|
batchRead(param).then(res => {
|
||||||
|
this.openMessageSuccess('webmsg.mark_success');
|
||||||
|
bus.$emit('refresh-top-notification')
|
||||||
|
this.initSearch()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteBatch() {
|
||||||
|
const param = this.multipleSelection.map(item => item.msgId)
|
||||||
|
batchDelete(param).then(res => {
|
||||||
|
this.openMessageSuccess('commons.delete_success');
|
||||||
|
this.initSearch()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
search() {
|
search() {
|
||||||
const param = {}
|
const param = {};
|
||||||
|
|
||||||
if (this.selectType >= 0) {
|
if (this.selectType >= 0) {
|
||||||
param.type = this.selectType
|
param.type = this.selectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.orderConditions.length === 0) {
|
if (this.orderConditions.length === 0) {
|
||||||
param.orders = ['create_time desc ']
|
param.orders = ["create_time desc "];
|
||||||
} else {
|
} else {
|
||||||
param.orders = formatOrders(this.orderConditions)
|
param.orders = formatOrders(this.orderConditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { currentPage, pageSize } = this.paginationConfig
|
if (this.tabActive !== "allMsg") {
|
||||||
query(currentPage, pageSize, param).then(response => {
|
param.status = this.tabActive === "readed";
|
||||||
this.data = response.data.listObject
|
}
|
||||||
this.paginationConfig.total = response.data.itemCount
|
|
||||||
})
|
const { currentPage, pageSize } = this.paginationConfig;
|
||||||
|
query(currentPage, pageSize, param).then((response) => {
|
||||||
|
this.data = response.data.listObject;
|
||||||
|
this.paginationConfig.total = response.data.itemCount;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
getTypeName(value) {
|
getTypeName(value) {
|
||||||
return this.$t('webmsg.' + getTypeName(value))
|
return this.$t("webmsg." + getTypeName(value));
|
||||||
},
|
},
|
||||||
typeChange(value) {
|
typeChange() {
|
||||||
this.search()
|
this.initSearch();
|
||||||
},
|
},
|
||||||
toDetail(row) {
|
toDetail(row) {
|
||||||
const param = { ...{ msgNotification: true, msgType: row.typeId, sourceParam: row.param }}
|
const param = {
|
||||||
|
...{
|
||||||
|
msgNotification: true,
|
||||||
|
msgType: row.typeId,
|
||||||
|
sourceParam: row.param,
|
||||||
|
},
|
||||||
|
};
|
||||||
if (this.hasPermissionRoute(row.router)) {
|
if (this.hasPermissionRoute(row.router)) {
|
||||||
this.$router.push({ name: row.router, params: param })
|
this.$router.push({ name: row.router, params: param });
|
||||||
row.status || this.setReaded(row)
|
row.status || this.setReaded(row);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.$warning(this.$t('commons.no_target_permission'))
|
this.$warning(this.$t("commons.no_target_permission"));
|
||||||
},
|
},
|
||||||
hasPermissionRoute(name, permission_routes) {
|
hasPermissionRoute(name, permission_routes) {
|
||||||
permission_routes = permission_routes || this.permission_routes
|
permission_routes = permission_routes || this.permission_routes;
|
||||||
for (let index = 0; index < permission_routes.length; index++) {
|
for (let index = 0; index < permission_routes.length; index++) {
|
||||||
const route = permission_routes[index]
|
const route = permission_routes[index];
|
||||||
if (route.name && route.name === name) return true
|
if (route.name && route.name === name) return true;
|
||||||
if (route.children && this.hasPermissionRoute(name, route.children)) return true
|
if (route.children && this.hasPermissionRoute(name, route.children))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
},
|
},
|
||||||
// 设置已读
|
// 设置已读
|
||||||
setReaded(row) {
|
setReaded(row) {
|
||||||
updateStatus(row.msgId).then(res => {
|
updateStatus(row.msgId).then((res) => {
|
||||||
bus.$emit('refresh-top-notification')
|
bus.$emit("refresh-top-notification");
|
||||||
this.search()
|
this.search();
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
sortChange({ column, prop, order }) {
|
sortChange({ column, prop, order }) {
|
||||||
this.orderConditions = []
|
this.orderConditions = [];
|
||||||
if (!order) {
|
if (!order) {
|
||||||
this.search()
|
this.search();
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (prop === 'createTime') {
|
if (prop === "createTime") {
|
||||||
prop = 'create_time'
|
prop = "create_time";
|
||||||
}
|
}
|
||||||
if (prop === 'typeId') {
|
if (prop === "typeId") {
|
||||||
prop = 'type_id'
|
prop = "type_id";
|
||||||
}
|
}
|
||||||
addOrder({ field: prop, value: order }, this.orderConditions)
|
addOrder({ field: prop, value: order }, this.orderConditions);
|
||||||
this.search()
|
this.search();
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
};
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.de-msg-radio-class {
|
|
||||||
padding: 0 5px;
|
|
||||||
::v-deep .el-radio-button__inner {
|
|
||||||
border-radius: 4px 4px 4px 4px !important;
|
|
||||||
border-left: 1px solid #dcdfe6 !important;
|
|
||||||
padding: 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-radio-button__orig-radio:checked+.el-radio-button__inner {
|
|
||||||
color: #fff;
|
|
||||||
// background-color: #0a7be0;
|
|
||||||
// border-color: #0a7be0;
|
|
||||||
-webkit-box-shadow: 0px 0 0 0 #0a7be0;
|
|
||||||
box-shadow: 0px 0 0 0 #0a7be0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.de-msg-a:hover {
|
.de-msg-a:hover {
|
||||||
text-decoration: underline !important;
|
text-decoration: underline !important;
|
||||||
color: #0a7be0 !important;
|
color: #0a7be0 !important;
|
||||||
cursor: pointer !important;
|
cursor: pointer !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
height: calc(100% - 50px);
|
||||||
|
}
|
||||||
|
.top-operate {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
.right-user {
|
||||||
|
text-align: right;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.name-email-search {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.organization {
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--MainBG, #f5f6f7);
|
||||||
|
|
||||||
|
.tabs-container {
|
||||||
|
height: calc(100% - 48px);
|
||||||
|
background: var(--ContentBG, #ffffff);
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
.msg-cont {
|
||||||
|
padding: 24px;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,221 +0,0 @@
|
|||||||
<template>
|
|
||||||
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
|
|
||||||
|
|
||||||
<el-radio-group v-model="selectType" style="margin-bottom: 15px;" @change="typeChange">
|
|
||||||
<el-radio-button v-for="(item,index) in $store.getters.msgTypes.filter(type => type.pid <= 0)" :key="index" class="de-msg-radio-class" :label="item.msgTypeId">{{ $t('webmsg.' + item.typeName) }}</el-radio-button>
|
|
||||||
|
|
||||||
</el-radio-group>
|
|
||||||
<complex-table
|
|
||||||
:data="data"
|
|
||||||
:columns="columns"
|
|
||||||
:hide-columns="true"
|
|
||||||
:pagination-config="paginationConfig"
|
|
||||||
:search-config="searchConfig"
|
|
||||||
@select="select"
|
|
||||||
@search="search"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
@sort-change="sortChange"
|
|
||||||
>
|
|
||||||
<template #toolbar>
|
|
||||||
<el-button :disabled="multipleSelection.length === 0" @click="deleteBatch">{{ $t('commons.delete') }}</el-button>
|
|
||||||
</template>
|
|
||||||
<el-table-column
|
|
||||||
type="selection"
|
|
||||||
width="55"
|
|
||||||
/>
|
|
||||||
<el-table-column prop="content" :label="$t('webmsg.content')">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
|
|
||||||
<span style="display: flex;flex: 1;">
|
|
||||||
<span>
|
|
||||||
<svg-icon v-if="!scope.row.status" icon-class="unread-msg" style="color: red;" />
|
|
||||||
<svg-icon v-else icon-class="readed-msg" />
|
|
||||||
</span>
|
|
||||||
<span style="margin-left: 6px;" class="de-msg-a" @click="toDetail(scope.row)">
|
|
||||||
{{ scope.row.content }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column prop="createTime" sortable="custom" :label="$t('webmsg.sned_time')" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column prop="readTime" sortable="custom" :label="$t('webmsg.read_time')" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ scope.row.readTime | timestampFormatDate }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column prop="typeId" sortable="custom" :label="$t('webmsg.type')" width="140">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ getTypeName(scope.row.typeId) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
</complex-table>
|
|
||||||
|
|
||||||
</layout-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import LayoutContent from '@/components/business/LayoutContent'
|
|
||||||
import ComplexTable from '@/components/business/complex-table'
|
|
||||||
import { query, batchDelete } from '@/api/system/msg'
|
|
||||||
import { msgTypes, getTypeName, loadMsgTypes } from '@/utils/webMsg'
|
|
||||||
import { addOrder, formatOrders } from '@/utils/index'
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
LayoutContent,
|
|
||||||
ComplexTable
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectType: -1,
|
|
||||||
msgTypes: msgTypes,
|
|
||||||
data: [],
|
|
||||||
allTypes: [{ name: 'mysql', type: 'jdbc' }, { name: 'sqlServer', type: 'jdbc' }],
|
|
||||||
|
|
||||||
columns: [],
|
|
||||||
orderConditions: [],
|
|
||||||
|
|
||||||
paginationConfig: {
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0
|
|
||||||
},
|
|
||||||
multipleSelection: [],
|
|
||||||
searchConfig: {
|
|
||||||
useQuickSearch: false,
|
|
||||||
useComplexSearch: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'permission_routes'
|
|
||||||
])
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.search()
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 先加载消息类型
|
|
||||||
loadMsgTypes()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
select(selection) {
|
|
||||||
},
|
|
||||||
|
|
||||||
search() {
|
|
||||||
const param = {}
|
|
||||||
param.status = true
|
|
||||||
if (this.selectType >= 0) {
|
|
||||||
param.type = this.selectType
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.orderConditions.length === 0) {
|
|
||||||
param.orders = [' create_time desc ']
|
|
||||||
} else {
|
|
||||||
param.orders = formatOrders(this.orderConditions)
|
|
||||||
}
|
|
||||||
|
|
||||||
const { currentPage, pageSize } = this.paginationConfig
|
|
||||||
query(currentPage, pageSize, param).then(response => {
|
|
||||||
this.data = response.data.listObject
|
|
||||||
this.paginationConfig.total = response.data.itemCount
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getTypeName(value) {
|
|
||||||
return this.$t('webmsg.' + getTypeName(value))
|
|
||||||
},
|
|
||||||
typeChange(value) {
|
|
||||||
this.search()
|
|
||||||
},
|
|
||||||
toDetail(row) {
|
|
||||||
const param = { ...{ msgNotification: true, msgType: row.typeId, sourceParam: row.param }}
|
|
||||||
// this.$router.push({ name: row.router, params: param })
|
|
||||||
if (this.hasPermissionRoute(row.router)) {
|
|
||||||
this.$router.push({ name: row.router, params: param })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$warning(this.$t('commons.no_target_permission'))
|
|
||||||
},
|
|
||||||
hasPermissionRoute(name, permission_routes) {
|
|
||||||
permission_routes = permission_routes || this.permission_routes
|
|
||||||
for (let index = 0; index < permission_routes.length; index++) {
|
|
||||||
const route = permission_routes[index]
|
|
||||||
if (route.name && route.name === name) return true
|
|
||||||
if (route.children && this.hasPermissionRoute(name, route.children)) return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
sortChange({ column, prop, order }) {
|
|
||||||
this.orderConditions = []
|
|
||||||
if (!order) {
|
|
||||||
this.search()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (prop === 'createTime') {
|
|
||||||
prop = 'create_time'
|
|
||||||
}
|
|
||||||
if (prop === 'readTime') {
|
|
||||||
prop = 'read_time'
|
|
||||||
}
|
|
||||||
if (prop === 'typeId') {
|
|
||||||
prop = 'type_id'
|
|
||||||
}
|
|
||||||
addOrder({ field: prop, value: order }, this.orderConditions)
|
|
||||||
this.search()
|
|
||||||
},
|
|
||||||
deleteBatch() {
|
|
||||||
if (this.multipleSelection.length === 0) {
|
|
||||||
this.$warning(this.$t('webmsg.please_select'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const param = this.multipleSelection.map(item => item.msgId)
|
|
||||||
batchDelete(param).then(res => {
|
|
||||||
this.$success(this.$t('commons.delete_success'))
|
|
||||||
this.search()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleSelectionChange(val) {
|
|
||||||
this.multipleSelection = val
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.de-msg-radio-class {
|
|
||||||
padding: 0 5px;
|
|
||||||
::v-deep .el-radio-button__inner {
|
|
||||||
border-radius: 4px 4px 4px 4px !important;
|
|
||||||
border-left: 1px solid #dcdfe6 !important;
|
|
||||||
padding: 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-radio-button__orig-radio:checked+.el-radio-button__inner {
|
|
||||||
color: #fff;
|
|
||||||
/* background-color: #0a7be0;
|
|
||||||
border-color: #0a7be0; */
|
|
||||||
-webkit-box-shadow: 0px 0 0 0 #0a7be0;
|
|
||||||
box-shadow: 0px 0 0 0 #0a7be0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.de-msg-a:hover {
|
|
||||||
text-decoration: underline !important;
|
|
||||||
color: #0a7be0 !important;
|
|
||||||
cursor: pointer !important;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@ -1,13 +1,19 @@
|
|||||||
<template xmlns:el-col="http://www.w3.org/1999/html">
|
<template xmlns:el-col="http://www.w3.org/1999/html">
|
||||||
<layout-content :header="$t('webmsg.receive_manage')">
|
<de-layout-content :header="$t('消息接收管理')">
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-row class="tree-head">
|
<el-row class="tree-head">
|
||||||
<span style="float: left;padding-left: 10px">{{ $t('webmsg.type') }}</span>
|
<span style="float: left;">{{
|
||||||
<span v-for="channel in msg_channels" :key="channel.msgChannelId" class="auth-span">
|
$t("webmsg.type")
|
||||||
|
}}</span>
|
||||||
|
<span
|
||||||
|
v-for="channel in msg_channels"
|
||||||
|
:key="channel.msgChannelId"
|
||||||
|
class="auth-span"
|
||||||
|
>
|
||||||
{{ $t(channel.channelName) }}
|
{{ $t(channel.channelName) }}
|
||||||
</span>
|
</span>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row style="margin-top: 5px">
|
<el-row class="msg-setting" style="margin-top: 5px">
|
||||||
<el-tree
|
<el-tree
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
:data="treeData"
|
:data="treeData"
|
||||||
@ -18,235 +24,281 @@
|
|||||||
>
|
>
|
||||||
<span slot-scope="{ node, data }" class="custom-tree-node">
|
<span slot-scope="{ node, data }" class="custom-tree-node">
|
||||||
<span>
|
<span>
|
||||||
<span style="margin-left: 6px">{{ $t('webmsg.' + data.name) }}</span>
|
<span style="margin-left: 6px">{{
|
||||||
|
$t("webmsg." + data.name)
|
||||||
|
}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span @click.stop>
|
<span @click.stop>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span v-for="channel in msg_channels" :key="channel.msgChannelId" class="auth-span">
|
<span
|
||||||
|
v-for="channel in msg_channels"
|
||||||
<el-checkbox v-if="data.children && data.children.length > 0" v-model="data.check_all_map[channel.msgChannelId]" :indeterminate="data.indeterminate_map[channel.msgChannelId]" @change="parentBoxChange(node, channel)" />
|
:key="channel.msgChannelId"
|
||||||
<el-checkbox v-else v-model="data.check_map[channel.msgChannelId]" @change="childBoxChange(node, channel)" />
|
class="auth-span-check"
|
||||||
|
>
|
||||||
</span>
|
<el-checkbox
|
||||||
</div></span>
|
v-if="data.children && data.children.length > 0"
|
||||||
|
v-model="data.check_all_map[channel.msgChannelId]"
|
||||||
|
:indeterminate="
|
||||||
|
data.indeterminate_map[channel.msgChannelId]
|
||||||
|
"
|
||||||
|
@change="parentBoxChange(node, channel)"
|
||||||
|
/>
|
||||||
|
<el-checkbox
|
||||||
|
v-else
|
||||||
|
v-model="data.check_map[channel.msgChannelId]"
|
||||||
|
@change="childBoxChange(node, channel)"
|
||||||
|
/>
|
||||||
|
</span></div
|
||||||
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-col>
|
</el-col>
|
||||||
</layout-content>
|
</de-layout-content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LayoutContent from '@/components/business/LayoutContent'
|
import DeLayoutContent from "@/components/business/DeLayoutContent";
|
||||||
import { treeList, channelList, settingList, updateSetting, batchUpdate } from '@/api/system/msg'
|
import {
|
||||||
|
treeList,
|
||||||
|
channelList,
|
||||||
|
settingList,
|
||||||
|
updateSetting,
|
||||||
|
batchUpdate,
|
||||||
|
} from "@/api/system/msg";
|
||||||
export default {
|
export default {
|
||||||
name: 'LazyTree',
|
name: "LazyTree",
|
||||||
components: { LayoutContent },
|
components: { DeLayoutContent },
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
treeData: [],
|
treeData: [],
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
children: 'children',
|
children: "children",
|
||||||
label: 'name',
|
label: "name",
|
||||||
id: 'id'
|
id: "id",
|
||||||
},
|
},
|
||||||
highlightCurrent: true,
|
highlightCurrent: true,
|
||||||
|
|
||||||
msg_channels: [],
|
msg_channels: [],
|
||||||
setting_data: {}
|
setting_data: {},
|
||||||
}
|
};
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
computed: {},
|
||||||
|
mounted() {},
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
// this.loadChannelData()
|
// this.loadChannelData()
|
||||||
|
|
||||||
channelList().then(res => {
|
channelList().then((res) => {
|
||||||
this.msg_channels = res.data
|
this.msg_channels = res.data;
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadSettingData(this.loadTreeData)
|
this.loadSettingData(this.loadTreeData);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
// 加载树节点数据
|
// 加载树节点数据
|
||||||
loadTreeData() {
|
loadTreeData() {
|
||||||
treeList().then(res => {
|
treeList().then((res) => {
|
||||||
const datas = res.data
|
const datas = res.data;
|
||||||
datas.forEach(data => this.formatTreeNode(data))
|
datas.forEach((data) => this.formatTreeNode(data));
|
||||||
this.treeData = datas
|
this.treeData = datas;
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
formatTreeNode(node) {
|
formatTreeNode(node) {
|
||||||
if (node.children && node.children.length > 0) {
|
if (node.children && node.children.length > 0) {
|
||||||
node.check_all_map = {}
|
node.check_all_map = {};
|
||||||
node.indeterminate_map = {}
|
node.indeterminate_map = {};
|
||||||
node.indeterminate_number_map = {}
|
node.indeterminate_number_map = {};
|
||||||
const kidSize = node.children.length
|
const kidSize = node.children.length;
|
||||||
node.children.forEach(kid => {
|
node.children.forEach((kid) => {
|
||||||
this.formatTreeNode(kid)
|
this.formatTreeNode(kid);
|
||||||
const isLeaf = !kid.children || kid.children.length === 0
|
const isLeaf = !kid.children || kid.children.length === 0;
|
||||||
const tempMap = isLeaf ? kid.check_map : kid.indeterminate_map
|
const tempMap = isLeaf ? kid.check_map : kid.indeterminate_map;
|
||||||
for (const key in tempMap) {
|
for (const key in tempMap) {
|
||||||
if (Object.hasOwnProperty.call(tempMap, key)) {
|
if (Object.hasOwnProperty.call(tempMap, key)) {
|
||||||
const element = tempMap[key]
|
const element = tempMap[key];
|
||||||
node.indeterminate_number_map[key] = node.indeterminate_number_map[key] || 0
|
node.indeterminate_number_map[key] =
|
||||||
|
node.indeterminate_number_map[key] || 0;
|
||||||
if (element) {
|
if (element) {
|
||||||
node.indeterminate_number_map[key]++
|
node.indeterminate_number_map[key]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.indeterminate_number_map[key] === kidSize && (isLeaf || kid.check_all_map[key])) {
|
if (
|
||||||
node.check_all_map[key] = true
|
node.indeterminate_number_map[key] === kidSize &&
|
||||||
node.indeterminate_map[key] = false
|
(isLeaf || kid.check_all_map[key])
|
||||||
|
) {
|
||||||
|
node.check_all_map[key] = true;
|
||||||
|
node.indeterminate_map[key] = false;
|
||||||
} else if (node.indeterminate_number_map[key] > 0) {
|
} else if (node.indeterminate_number_map[key] > 0) {
|
||||||
node.check_all_map[key] = false
|
node.check_all_map[key] = false;
|
||||||
node.indeterminate_map[key] = true
|
node.indeterminate_map[key] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
node.check_map = {}
|
node.check_map = {};
|
||||||
this.msg_channels.forEach(channel => {
|
this.msg_channels.forEach((channel) => {
|
||||||
node.check_map[channel.msgChannelId] = this.checkBoxStatus(node, channel)
|
node.check_map[channel.msgChannelId] = this.checkBoxStatus(
|
||||||
})
|
node,
|
||||||
|
channel
|
||||||
|
);
|
||||||
|
});
|
||||||
// this.checkBoxStatus(node, )
|
// this.checkBoxStatus(node, )
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 加载消息渠道
|
// 加载消息渠道
|
||||||
loadChannelData() {
|
loadChannelData() {
|
||||||
channelList().then(res => {
|
channelList().then((res) => {
|
||||||
this.msg_channels = res.data
|
this.msg_channels = res.data;
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
// 加载用户设置信息
|
// 加载用户设置信息
|
||||||
loadSettingData(callBack) {
|
loadSettingData(callBack) {
|
||||||
// this.setting_data = {}
|
// this.setting_data = {}
|
||||||
const temp_setting_data = {}
|
const temp_setting_data = {};
|
||||||
settingList().then(res => {
|
settingList().then((res) => {
|
||||||
const lists = res.data
|
const lists = res.data;
|
||||||
lists.forEach(item => {
|
lists.forEach((item) => {
|
||||||
const key = item.typeId + ''
|
const key = item.typeId + "";
|
||||||
if (!Object.keys(temp_setting_data).includes(key)) {
|
if (!Object.keys(temp_setting_data).includes(key)) {
|
||||||
temp_setting_data[key] = []
|
temp_setting_data[key] = [];
|
||||||
}
|
}
|
||||||
temp_setting_data[key].push(item)
|
temp_setting_data[key].push(item);
|
||||||
})
|
});
|
||||||
this.setting_data = temp_setting_data
|
this.setting_data = temp_setting_data;
|
||||||
callBack && callBack()
|
callBack && callBack();
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
checkBoxStatus(node, channel) {
|
checkBoxStatus(node, channel) {
|
||||||
// const nodeId = node.data.id
|
// const nodeId = node.data.id
|
||||||
const nodeId = node.id
|
const nodeId = node.id;
|
||||||
return this.setting_data[nodeId] && this.setting_data[nodeId].some(item => item.channelId === channel.msgChannelId && item.enable)
|
return (
|
||||||
|
this.setting_data[nodeId] &&
|
||||||
|
this.setting_data[nodeId].some(
|
||||||
|
(item) => item.channelId === channel.msgChannelId && item.enable
|
||||||
|
)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
nodeClick(data, node) {
|
nodeClick(data, node) {},
|
||||||
},
|
|
||||||
getAllKidId(node, ids) {
|
getAllKidId(node, ids) {
|
||||||
if (node.children && node.children.length > 0) {
|
if (node.children && node.children.length > 0) {
|
||||||
node.children.forEach(item => this.getAllKidId(item, ids))
|
node.children.forEach((item) => this.getAllKidId(item, ids));
|
||||||
} else {
|
} else {
|
||||||
ids.push(node.id)
|
ids.push(node.id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
parentBoxChange(node, channel) {
|
parentBoxChange(node, channel) {
|
||||||
const typeIds = []
|
const typeIds = [];
|
||||||
this.getAllKidId(node.data, typeIds)
|
this.getAllKidId(node.data, typeIds);
|
||||||
const channelId = channel.msgChannelId
|
const channelId = channel.msgChannelId;
|
||||||
|
|
||||||
const data = node.data
|
const data = node.data;
|
||||||
const enable = data.check_all_map && data.check_all_map[channelId]
|
const enable = data.check_all_map && data.check_all_map[channelId];
|
||||||
node.data.check_all_map[channelId] = enable
|
node.data.check_all_map[channelId] = enable;
|
||||||
node.data.indeterminate_map[channelId] = false
|
node.data.indeterminate_map[channelId] = false;
|
||||||
node.data.children.forEach(item => {
|
node.data.children.forEach((item) => {
|
||||||
item.check_map = item.check_map || {}
|
item.check_map = item.check_map || {};
|
||||||
item.check_map[channelId] = enable
|
item.check_map[channelId] = enable;
|
||||||
})
|
});
|
||||||
|
|
||||||
const param = {
|
const param = {
|
||||||
typeIds: typeIds,
|
typeIds: typeIds,
|
||||||
channelId: channelId,
|
channelId: channelId,
|
||||||
enable
|
enable,
|
||||||
}
|
};
|
||||||
batchUpdate(param).then(res => {
|
batchUpdate(param).then((res) => {
|
||||||
this.loadSettingData(this.loadTreeData)
|
this.loadSettingData(this.loadTreeData);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
childBoxChange(node, channel) {
|
childBoxChange(node, channel) {
|
||||||
const channelId = channel.msgChannelId
|
const channelId = channel.msgChannelId;
|
||||||
const parent = node.parent
|
const parent = node.parent;
|
||||||
if (parent) {
|
if (parent) {
|
||||||
const data = parent.data
|
const data = parent.data;
|
||||||
const kids = data.children
|
const kids = data.children;
|
||||||
const kidSize = kids.length
|
const kidSize = kids.length;
|
||||||
let index = 0
|
let index = 0;
|
||||||
kids.forEach(kid => {
|
kids.forEach((kid) => {
|
||||||
if (kid.check_map[channelId]) {
|
if (kid.check_map[channelId]) {
|
||||||
index++
|
index++;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
if (index === kidSize) {
|
if (index === kidSize) {
|
||||||
node.parent.data.check_all_map[channelId] = true
|
node.parent.data.check_all_map[channelId] = true;
|
||||||
node.parent.data.indeterminate_map[channelId] = false
|
node.parent.data.indeterminate_map[channelId] = false;
|
||||||
} else if (index > 0) {
|
} else if (index > 0) {
|
||||||
node.parent.data.check_all_map[channelId] = false
|
node.parent.data.check_all_map[channelId] = false;
|
||||||
node.parent.data.indeterminate_map[channelId] = true
|
node.parent.data.indeterminate_map[channelId] = true;
|
||||||
} else {
|
} else {
|
||||||
node.parent.data.check_all_map[channelId] = false
|
node.parent.data.check_all_map[channelId] = false;
|
||||||
node.parent.data.indeterminate_map[channelId] = false
|
node.parent.data.indeterminate_map[channelId] = false;
|
||||||
}
|
}
|
||||||
// this.formatTreeNode(node.parent.data)
|
// this.formatTreeNode(node.parent.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
const param = {
|
const param = {
|
||||||
typeId: node.data.id,
|
typeId: node.data.id,
|
||||||
channelId: channelId
|
channelId: channelId,
|
||||||
|
};
|
||||||
|
updateSetting(param).then((res) => {
|
||||||
|
this.loadSettingData(this.loadTreeData);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-tree-node {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 32px;
|
||||||
|
}
|
||||||
|
.tree-main {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.tree-head {
|
||||||
|
height: 46px;
|
||||||
|
line-height: 46px;
|
||||||
|
border-bottom: 1px solid var(--TableBorderColor, #e6e6e6);
|
||||||
|
border-top: 1px solid var(--TableBorderColor, #e6e6e6);
|
||||||
|
background-color: var(--SiderBG, #f7f8fa);
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--TableColor, #3d4d66);
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 0 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-span {
|
||||||
|
float: right;
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-span-check {
|
||||||
|
float: right;
|
||||||
|
margin-left: 64px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.msg-setting {
|
||||||
|
.el-tree-node__content {
|
||||||
|
height: 46px;
|
||||||
|
border-bottom: 1px solid rgba(31, 35, 41, 0.15);
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--deWhiteHover, #3370ff) !important;
|
||||||
|
.custom-tree-node {
|
||||||
|
color: var(--primary, #3370ff);
|
||||||
}
|
}
|
||||||
updateSetting(param).then(res => {
|
|
||||||
this.loadSettingData(this.loadTreeData)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</style>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.custom-tree-node {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: 14px;
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
.tree-main{
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.tree-head{
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-bottom: 1px solid var(--TableBorderColor, #e6e6e6);
|
|
||||||
background-color: var(--SiderBG, #f7f8fa);
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--TableColor, #3d4d66) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-span{
|
|
||||||
float: right;
|
|
||||||
width:50px;
|
|
||||||
margin-right: 30px
|
|
||||||
}
|
|
||||||
.highlights-text {
|
|
||||||
color: #faaa39 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@ -1,229 +0,0 @@
|
|||||||
<template>
|
|
||||||
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
|
|
||||||
|
|
||||||
<el-radio-group v-model="selectType" style="margin-bottom: 15px;" @change="typeChange">
|
|
||||||
<el-radio-button v-for="(item,index) in $store.getters.msgTypes.filter(type => type.pid <= 0)" :key="index" class="de-msg-radio-class" :label="item.msgTypeId">{{ $t('webmsg.' + item.typeName) }}</el-radio-button>
|
|
||||||
|
|
||||||
</el-radio-group>
|
|
||||||
<complex-table
|
|
||||||
:data="data"
|
|
||||||
:columns="columns"
|
|
||||||
:hide-columns="true"
|
|
||||||
:pagination-config="paginationConfig"
|
|
||||||
:search-config="searchConfig"
|
|
||||||
@select="select"
|
|
||||||
@search="search"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
@sort-change="sortChange"
|
|
||||||
>
|
|
||||||
<template #toolbar>
|
|
||||||
<el-button :disabled="multipleSelection.length === 0" @click="markReaded">{{ $t('webmsg.mark_readed') }}</el-button>
|
|
||||||
<el-button @click="allMarkReaded">{{ $t('webmsg.all_mark_readed') }}</el-button>
|
|
||||||
</template>
|
|
||||||
<el-table-column
|
|
||||||
type="selection"
|
|
||||||
width="55"
|
|
||||||
/>
|
|
||||||
<el-table-column prop="content" :label="$t('webmsg.content')">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
|
|
||||||
<span style="display: flex;flex: 1;">
|
|
||||||
<span>
|
|
||||||
<svg-icon v-if="!scope.row.status" icon-class="unread-msg" style="color: red;" />
|
|
||||||
<svg-icon v-else icon-class="readed-msg" />
|
|
||||||
</span>
|
|
||||||
<span style="margin-left: 6px;" class="de-msg-a" @click="toDetail(scope.row)">
|
|
||||||
{{ scope.row.content }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column prop="createTime" sortable="custom" :label="$t('webmsg.sned_time')" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column prop="typeId" sortable="custom" :label="$t('webmsg.type')" width="140">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ getTypeName(scope.row.typeId) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
</complex-table>
|
|
||||||
|
|
||||||
</layout-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import LayoutContent from '@/components/business/LayoutContent'
|
|
||||||
import ComplexTable from '@/components/business/complex-table'
|
|
||||||
import { query, updateStatus, batchRead, allRead } from '@/api/system/msg'
|
|
||||||
import { msgTypes, getTypeName, loadMsgTypes } from '@/utils/webMsg'
|
|
||||||
import bus from '@/utils/bus'
|
|
||||||
import { addOrder, formatOrders } from '@/utils/index'
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
LayoutContent,
|
|
||||||
ComplexTable
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectType: -1,
|
|
||||||
msgTypes: msgTypes,
|
|
||||||
data: [],
|
|
||||||
allTypes: [{ name: 'mysql', type: 'jdbc' }, { name: 'sqlServer', type: 'jdbc' }],
|
|
||||||
|
|
||||||
columns: [],
|
|
||||||
|
|
||||||
paginationConfig: {
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0
|
|
||||||
},
|
|
||||||
searchConfig: {
|
|
||||||
useQuickSearch: false,
|
|
||||||
useComplexSearch: false
|
|
||||||
},
|
|
||||||
multipleSelection: [],
|
|
||||||
orderConditions: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'permission_routes'
|
|
||||||
])
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.search()
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 先加载消息类型
|
|
||||||
loadMsgTypes()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
select(selection) {
|
|
||||||
},
|
|
||||||
|
|
||||||
search() {
|
|
||||||
const param = {}
|
|
||||||
param.status = false
|
|
||||||
if (this.selectType >= 0) {
|
|
||||||
param.type = this.selectType
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.orderConditions.length === 0) {
|
|
||||||
param.orders = [' create_time desc ']
|
|
||||||
} else {
|
|
||||||
param.orders = formatOrders(this.orderConditions)
|
|
||||||
}
|
|
||||||
|
|
||||||
const { currentPage, pageSize } = this.paginationConfig
|
|
||||||
query(currentPage, pageSize, param).then(response => {
|
|
||||||
this.data = response.data.listObject
|
|
||||||
this.paginationConfig.total = response.data.itemCount
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getTypeName(value) {
|
|
||||||
return this.$t('webmsg.' + getTypeName(value))
|
|
||||||
},
|
|
||||||
typeChange(value) {
|
|
||||||
this.search()
|
|
||||||
},
|
|
||||||
toDetail(row) {
|
|
||||||
const param = { ...{ msgNotification: true, msgType: row.typeId, sourceParam: row.param }}
|
|
||||||
if (this.hasPermissionRoute(row.router)) {
|
|
||||||
this.$router.push({ name: row.router, params: param })
|
|
||||||
this.setReaded(row)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$warning(this.$t('commons.no_target_permission'))
|
|
||||||
},
|
|
||||||
hasPermissionRoute(name, permission_routes) {
|
|
||||||
permission_routes = permission_routes || this.permission_routes
|
|
||||||
for (let index = 0; index < permission_routes.length; index++) {
|
|
||||||
const route = permission_routes[index]
|
|
||||||
if (route.name && route.name === name) return true
|
|
||||||
if (route.children && this.hasPermissionRoute(name, route.children)) return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
// 设置已读
|
|
||||||
setReaded(row) {
|
|
||||||
updateStatus(row.msgId).then(res => {
|
|
||||||
bus.$emit('refresh-top-notification')
|
|
||||||
this.search()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
allMarkReaded() {
|
|
||||||
allRead().then(res => {
|
|
||||||
this.$success(this.$t('webmsg.mark_success'))
|
|
||||||
bus.$emit('refresh-top-notification')
|
|
||||||
this.search()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
markReaded() {
|
|
||||||
if (this.multipleSelection.length === 0) {
|
|
||||||
this.$warning(this.$t('webmsg.please_select'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const param = this.multipleSelection.map(item => item.msgId)
|
|
||||||
batchRead(param).then(res => {
|
|
||||||
this.$success(this.$t('webmsg.mark_success'))
|
|
||||||
bus.$emit('refresh-top-notification')
|
|
||||||
this.search()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleSelectionChange(val) {
|
|
||||||
this.multipleSelection = val
|
|
||||||
},
|
|
||||||
sortChange({ column, prop, order }) {
|
|
||||||
this.orderConditions = []
|
|
||||||
if (!order) {
|
|
||||||
this.search()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (prop === 'createTime') {
|
|
||||||
prop = 'create_time'
|
|
||||||
}
|
|
||||||
if (prop === 'typeId') {
|
|
||||||
prop = 'type_id'
|
|
||||||
}
|
|
||||||
addOrder({ field: prop, value: order }, this.orderConditions)
|
|
||||||
this.search()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.de-msg-radio-class {
|
|
||||||
padding: 0 5px;
|
|
||||||
::v-deep .el-radio-button__inner {
|
|
||||||
border-radius: 4px 4px 4px 4px !important;
|
|
||||||
border-left: 1px solid #dcdfe6 !important;
|
|
||||||
padding: 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-radio-button__orig-radio:checked+.el-radio-button__inner {
|
|
||||||
color: #fff;
|
|
||||||
/* background-color: #0a7be0;
|
|
||||||
border-color: #0a7be0; */
|
|
||||||
-webkit-box-shadow: 0px 0 0 0 #0a7be0;
|
|
||||||
box-shadow: 0px 0 0 0 #0a7be0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.de-msg-a:hover {
|
|
||||||
text-decoration: underline !important;
|
|
||||||
color: #0a7be0 !important;
|
|
||||||
cursor: pointer !important;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@ -1,165 +1,361 @@
|
|||||||
<template>
|
<template>
|
||||||
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
|
<de-layout-content
|
||||||
<complex-table
|
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
|
||||||
:data="data"
|
>
|
||||||
:columns="columns"
|
<div class="top-install">
|
||||||
:search-config="searchConfig"
|
<el-input
|
||||||
:pagination-config="paginationConfig"
|
placeholder="通过插件名称搜索"
|
||||||
@search="search"
|
size="small"
|
||||||
>
|
prefix-icon="el-icon-search"
|
||||||
<template #toolbar>
|
v-model="name"
|
||||||
<el-upload
|
clearable
|
||||||
v-permission="['plugin:upload']"
|
@blur="search"
|
||||||
:action="baseUrl+'api/plugin/upload'"
|
>
|
||||||
:multiple="false"
|
</el-input>
|
||||||
:show-file-list="false"
|
<el-upload
|
||||||
:file-list="fileList"
|
v-permission="['plugin:upload']"
|
||||||
accept=".zip"
|
:action="baseUrl + 'api/plugin/upload'"
|
||||||
:before-upload="beforeUpload"
|
:multiple="false"
|
||||||
:on-success="uploadSuccess"
|
:show-file-list="false"
|
||||||
:on-error="uploadFail"
|
:file-list="fileList"
|
||||||
name="file"
|
accept=".zip"
|
||||||
:headers="headers"
|
:before-upload="beforeUpload"
|
||||||
|
:on-success="uploadSuccess"
|
||||||
|
:on-error="uploadFail"
|
||||||
|
name="file"
|
||||||
|
:headers="headers"
|
||||||
|
>
|
||||||
|
<deBtn
|
||||||
|
:icon="!uploading ? 'el-icon-upload2' : 'el-icon-loading'"
|
||||||
|
type="primary"
|
||||||
|
:disabled="uploading"
|
||||||
>
|
>
|
||||||
<el-button size="mini" type="primary" :disabled="uploading">
|
{{ $t(!uploading ? "plugin.local_install" : "dataset.uploading") }}
|
||||||
<span v-if="!uploading" style="font-size: 12px;">{{ $t('plugin.local_install') }}</span>
|
</deBtn>
|
||||||
<span v-if="uploading" style="font-size: 12px;"><i class="el-icon-loading" /> {{ $t('dataset.uploading') }}</span>
|
</el-upload>
|
||||||
</el-button>
|
</div>
|
||||||
</el-upload>
|
<div v-if="!data.length" class="plugin-cont">
|
||||||
</template>
|
<el-empty style="width: 100%" description="没有找到相关内容"></el-empty>
|
||||||
|
</div>
|
||||||
<el-table-column prop="name" :label="$t('plugin.name')" />
|
<div v-else class="plugin-cont">
|
||||||
<!-- <el-table-column prop="free" :label="$t('plugin.free')">
|
<div v-for="ele in data" :key="ele.pluginId" class="de-card-plugin">
|
||||||
<template v-slot:default="scope">
|
<div class="card-info">
|
||||||
<span>{{ scope.row.free ? '是' : '否' }}</span>
|
<div class="info-top">
|
||||||
</template>
|
<img
|
||||||
</el-table-column> -->
|
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
|
||||||
<el-table-column prop="cost" :label="$t('plugin.cost')" />
|
alt=""
|
||||||
|
/>
|
||||||
<el-table-column :show-overflow-tooltip="true" prop="descript" :label="$t('plugin.descript')" />
|
<p class="title">{{ ele.descript }}</p>
|
||||||
<el-table-column prop="version" :label="$t('plugin.version')" />
|
<el-tooltip
|
||||||
<el-table-column prop="creator" :label="$t('plugin.creator')" />
|
class="item"
|
||||||
|
effect="dark"
|
||||||
<el-table-column prop="installTime" :label="$t('plugin.install_time')">
|
:content="ele.descript"
|
||||||
<template v-slot:default="scope">
|
placement="top"
|
||||||
<span>{{ scope.row.installTime | timestampFormatDate }}</span>
|
>
|
||||||
</template>
|
<p class="tips">{{ ele.name }}</p>
|
||||||
</el-table-column>
|
</el-tooltip>
|
||||||
<fu-table-operations :buttons="buttons" :label="$t('commons.operating')" fix />
|
</div>
|
||||||
</complex-table>
|
<div class="info-left">
|
||||||
|
<p class="list name" v-for="item in listName" :key="item">
|
||||||
</layout-content>
|
{{ item }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="info-right">
|
||||||
|
<p class="list value" v-for="item in listValue" :key="item">
|
||||||
|
<template v-if="item === 'cost' && !ele.cost">
|
||||||
|
<el-tag size="mini" type="success">免费</el-tag>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ ele[item] }}
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-method">
|
||||||
|
<el-upload
|
||||||
|
v-permission="['plugin:upload']"
|
||||||
|
:action="baseUrl + 'api/plugin/upload'"
|
||||||
|
:multiple="false"
|
||||||
|
:show-file-list="false"
|
||||||
|
:file-list="fileList"
|
||||||
|
accept=".zip"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:on-success="uploadSuccess"
|
||||||
|
:on-error="uploadFail"
|
||||||
|
name="file"
|
||||||
|
:headers="headers"
|
||||||
|
>
|
||||||
|
<div class="btn-plugin"><i class="el-icon-more"></i>更新</div>
|
||||||
|
</el-upload>
|
||||||
|
<el-divider direction="vertical"></el-divider>
|
||||||
|
<div
|
||||||
|
:class="[{ 'is-disable': btnDisabled(ele) }]"
|
||||||
|
v-show="checkPermission(['plugin:uninstall'])"
|
||||||
|
@click="del(ele)"
|
||||||
|
class="btn-plugin"
|
||||||
|
>
|
||||||
|
<i class="el-icon-more"></i>卸载
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</de-layout-content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LayoutContent from '@/components/business/LayoutContent'
|
import DeLayoutContent from "@/components/business/DeLayoutContent";
|
||||||
import ComplexTable from '@/components/business/complex-table'
|
|
||||||
|
|
||||||
import { checkPermission } from '@/utils/permission'
|
import { checkPermission } from "@/utils/permission";
|
||||||
import { formatCondition, formatQuickCondition } from '@/utils/index'
|
import { formatCondition, formatQuickCondition } from "@/utils/index";
|
||||||
import { pluginLists, uninstall } from '@/api/system/plugin'
|
import { pluginLists, uninstall } from "@/api/system/plugin";
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from "@/utils/auth";
|
||||||
|
import msgCfm from "@/components/msgCfm/index";
|
||||||
export default {
|
export default {
|
||||||
|
components: { DeLayoutContent },
|
||||||
components: { ComplexTable, LayoutContent },
|
mixins: [msgCfm],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
header: '',
|
listName: ["费用", "开发者", "版本", "安装时间"],
|
||||||
columns: [],
|
name: "",
|
||||||
buttons: [
|
listValue: ["cost", "creator", "version", "installTime"],
|
||||||
// {
|
|
||||||
// label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.del,
|
|
||||||
// show: checkPermission(['user:del'])
|
|
||||||
// }
|
|
||||||
{
|
|
||||||
label: this.$t('plugin.un_install'), icon: 'el-icon-delete', type: 'danger', click: this.del,
|
|
||||||
show: checkPermission(['plugin:uninstall']),
|
|
||||||
disabled: this.btnDisabled
|
|
||||||
}
|
|
||||||
],
|
|
||||||
searchConfig: {
|
|
||||||
useQuickSearch: true,
|
|
||||||
quickPlaceholder: this.$t('role.search_by_name'),
|
|
||||||
components: [
|
|
||||||
{ field: 'name', label: this.$t('plugin.name'), component: 'DeComplexInput' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
paginationConfig: {
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0
|
|
||||||
},
|
|
||||||
data: [],
|
data: [],
|
||||||
uploading: false,
|
uploading: false,
|
||||||
baseUrl: process.env.VUE_APP_BASE_API,
|
baseUrl: process.env.VUE_APP_BASE_API,
|
||||||
fileList: [],
|
fileList: [],
|
||||||
headers: { Authorization: getToken() }
|
headers: { Authorization: getToken() },
|
||||||
|
};
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.search()
|
this.search();
|
||||||
|
this.bindKey();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.unBindKey();
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
entryKey(event) {
|
||||||
search(condition) {
|
const keyCode = event.keyCode;
|
||||||
condition = formatQuickCondition(condition, 'name')
|
if (keyCode === 13) {
|
||||||
const temp = formatCondition(condition)
|
this.search();
|
||||||
const param = temp || {}
|
}
|
||||||
const { currentPage, pageSize } = this.paginationConfig
|
},
|
||||||
pluginLists(currentPage, pageSize, param).then(response => {
|
bindKey() {
|
||||||
this.data = response.data.listObject
|
document.addEventListener("keypress", this.entryKey);
|
||||||
this.paginationConfig.total = response.data.itemCount
|
},
|
||||||
})
|
unBindKey() {
|
||||||
|
document.removeEventListener("keypress", this.entryKey);
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
const param = {};
|
||||||
|
if (this.name) {
|
||||||
|
param.conditions = [
|
||||||
|
{
|
||||||
|
field: "name",
|
||||||
|
operator: "like",
|
||||||
|
value: this.name,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
pluginLists(0, 0, param).then((response) => {
|
||||||
|
this.data = response.data.listObject;
|
||||||
|
this.data.forEach((ele) => {
|
||||||
|
if (ele.installTime) {
|
||||||
|
ele.installTime = new Date(ele.installTime).format(
|
||||||
|
"yyyy-MM-dd hh:mm:ss"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (ele.cost) {
|
||||||
|
ele.cost = ele.cost.toLocaleString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
beforeUpload(file) {
|
beforeUpload(file) {
|
||||||
this.uploading = true
|
this.uploading = true;
|
||||||
},
|
},
|
||||||
uploadFail(response, file, fileList) {
|
uploadFail(response, file, fileList) {
|
||||||
const msg = response && response.message || '安装失败'
|
const msg = (response && response.message) || "安装失败";
|
||||||
try {
|
try {
|
||||||
const result = JSON.parse(msg)
|
const result = JSON.parse(msg);
|
||||||
if (result && result.message) {
|
if (result && result.message) {
|
||||||
this.$error(result.message)
|
this.$error(result.message);
|
||||||
this.uploading = false
|
this.uploading = false;
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e);
|
||||||
}
|
}
|
||||||
this.$error(msg)
|
this.$error(msg);
|
||||||
this.uploading = false
|
this.uploading = false;
|
||||||
},
|
},
|
||||||
uploadSuccess(response, file, fileList) {
|
uploadSuccess(response, file, fileList) {
|
||||||
this.uploading = false
|
this.uploading = false;
|
||||||
this.search()
|
this.search();
|
||||||
},
|
},
|
||||||
|
|
||||||
del(row) {
|
del(row) {
|
||||||
this.$confirm(this.$t('plugin.uninstall_confirm'), '', {
|
const options = {
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
title: "确定卸载该插件?",
|
||||||
cancelButtonText: this.$t('commons.cancel'),
|
content: "卸载并重启服务器之后才能生效",
|
||||||
type: 'warning'
|
confirmButtonText: this.$t('卸载'),
|
||||||
}).then(() => {
|
type: "primary",
|
||||||
uninstall(row.pluginId).then(res => {
|
cb: () => {
|
||||||
this.search()
|
uninstall(row.pluginId)
|
||||||
this.$success(this.$t('plugin.un_install_success'))
|
.then((res) => {
|
||||||
}).catch(() => {
|
this.search();
|
||||||
this.$error(this.$t('plugin.un_install_error'))
|
this.openMessageSuccess("plugin.un_install_success");
|
||||||
})
|
})
|
||||||
}).catch(() => {
|
.catch(() => {
|
||||||
this.$info(this.$t('plugin.uninstall_cancel'))
|
this.$error(this.$t("plugin.un_install_error"));
|
||||||
})
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.handlerConfirm(options);
|
||||||
},
|
},
|
||||||
btnDisabled(row) {
|
btnDisabled(row) {
|
||||||
return row.pluginId < 4
|
return row.pluginId < 4;
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.top-install {
|
||||||
|
position: absolute;
|
||||||
|
top: 24px;
|
||||||
|
right: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.el-input {
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
.el-input__inner {
|
||||||
|
background: #ffffff !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
.plugin-cont {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
background-color: var(--MainBG, #f5f6f7);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.de-card-plugin {
|
||||||
|
width: 270px;
|
||||||
|
height: 230px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #dee0e3;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 0 24px 24px 0;
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0px 6px 24px rgba(31, 35, 41, 0.08);
|
||||||
|
}
|
||||||
|
.card-method {
|
||||||
|
border-top: 1px solid #dee0e3;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 9px 30px 10px 30px;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-around;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.btn-plugin {
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
/* identical to box height, or 157% */
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
letter-spacing: -0.1px;
|
||||||
|
|
||||||
|
/* Neutral/600 */
|
||||||
|
|
||||||
|
color: #646a73;
|
||||||
|
i {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-right: 5.33px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-info {
|
||||||
|
width: 100%;
|
||||||
|
height: 188px;
|
||||||
|
padding: 12px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.info-top {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
img {
|
||||||
|
float: left;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #dee0e3;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 190px;
|
||||||
|
height: 22px;
|
||||||
|
float: left;
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #000000;
|
||||||
|
margin: -2px 0 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips {
|
||||||
|
max-width: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
float: left;
|
||||||
|
height: 20px;
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #646a73;
|
||||||
|
margin: 2px 0 0 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list {
|
||||||
|
padding-bottom: 8px;
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 0;
|
||||||
|
color: #646a73;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-left {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
color: #646a73;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info-right {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 12px;
|
||||||
|
.value {
|
||||||
|
color: #1f2329;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user