消息日志 消息配置 预警设置

This commit is contained in:
caorui 2024-09-13 17:00:40 +08:00
parent c83eb18f48
commit 2eded6d1c9
21 changed files with 4528 additions and 6 deletions

View File

@ -40,6 +40,8 @@
"@babel/parser": "^7.7.4",
"@riophae/vue-treeselect": "0.4.0",
"axios": "^0.24.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^1.0.2",
"babel-polyfill": "^6.26.0",
"clipboard": "2.0.8",
"crypto-js": "^4.1.1",

View File

@ -101,7 +101,8 @@
<i class="el-icon-circle-close" v-if="!row.disabled && ruleForm[row.prop]" @click="elDialogClear(row)"
style="margin-left: 10px"></i>
</div>
<el-select v-model="ruleForm[row.prop]" filterable style="width: 100%"
<el-select v-model="ruleForm[row.prop]" filterable style="width: 100%" :multiple="row.multiple?row.multiple:false"
:collapse-tags="true"
@change="selectChange($event, indexRow, indexRow, row)" :clearable="row.clearable ? row.clearable : true"
:placeholder="!row.placeholder ? '请选择' : row.placeholder" v-if="row.tag === 'elSelect'">
<el-option v-for="(el, elIndex) in row.options" :key="!row.optionValue ? el['value'] : el[row.optionValue]"

View File

@ -104,6 +104,7 @@
</el-select>
<el-select class="w-100" v-model="ruleForm[row.prop]" multiple :disabled="row.disabled?row.disabled:false"
:clearable="row.clearable" :placeholder="!row.placeholder ? '请选择' : row.placeholder"
@change="selectChange($event, index, indexRow, row.options, row)"
v-if="row.tag === 'elMultiple'"
>
<el-option v-for="el in row.options" :key="!row.optionValue ? el['value'] : el[row.optionValue]"
@ -536,7 +537,7 @@ export default {
align-items: center;
justify-content: space-between;
border: 1px solid #DCDFE6;
border-radius: 8px;
border-radius: 4px;
padding: 0 15px;
cursor: pointer;

View File

@ -18,6 +18,7 @@
<span style="font-size: 16px">{{ title }}</span>
<span v-if="footerShow" flex="main:right">
<el-button @click="handleClose" v-if="closeShow"> </el-button>
<slot name="addButton"></slot>
<el-button
type="primary"
@click="handleConfirmClick"

View File

@ -225,6 +225,10 @@ export default {
type: String,
default: "small",
},
currentType: {
type: String,
default: "",
},
//
bottomPlus: {
type: Boolean,
@ -327,7 +331,23 @@ export default {
watch: {},
methods: {
select(selection, row) {
this.$emit("select", selection, row);
//
if(this.currentType == "apiCode"){
let flag = selection.some(item => {
if (item.apiCode === row.apiCode) {
return true
}
})
this.$emit("select", selection, row, flag);
}else{
let flag = selection.some(item => {
if (item.id === row.id) {
return true
}
})
this.$emit("select", selection, row, flag);
}
},
selectAll(selection) {
this.$emit("selectAll", selection);

View File

@ -108,6 +108,12 @@ export default {
icon: "icon-shouye",
show: true,
},
{
title: "消息",
path: "/message",
icon: "el-icon-chat-dot-square",
show: true,
},
{
title: "工作台",
path: "/Workbench",

View File

@ -110,6 +110,15 @@ export const constantRoutes = [{
// affix: true,
}
},
{
path: "message",
component: () => import("@/views/newVersionView/message/index"),
name: "message",
meta: {
title: "消息",
icon: "dashboard",
},
},
{
path: "Workbench",
component: () => import("@/views/newVersionView/Workbench/index"),

View File

@ -37,5 +37,6 @@ const getters = {
conditionDrawer: state => state.flowPath.conditionDrawer,
conditionsConfig: state => state.flowPath.conditionsConfig,
getButtonPre: (state) => state.perButton.buttonObj,
messageCount: state => state.user.messageCount,
}
export default getters

View File

@ -19,6 +19,7 @@ const user = {
info: {},
companyID: "",
companyListAll: [],
messageCount:0
},
mutations: {
@ -46,6 +47,9 @@ const user = {
SET_COMPANYID_LIST_All: (state, companyListAll) => {
state.companyListAll = companyListAll;
},
SET_MESSAGE_COUNT: (state, messageCount) => {
state.messageCount = messageCount
}
},
actions: {

View File

@ -21,9 +21,12 @@ export function openLoading(loadingName) {
case 'del':
loadingText = '删除'
break;
case 'test':
loadingText = '校验数据'
break;
case 'test':
loadingText = '校验数据'
break;
default:
loadingText = loadingName
break;
}
appLoading = Loading.service({
text: "正在" + loadingText + ",请稍候",

View File

@ -0,0 +1,207 @@
<template>
<div>
<base-layout
ref="baseLayout"
:buttonList="buttonList"
@onFuncBtn="onFuncBtn"
:querySwitch="true"
:searchList="requirementList"
@search="handleSearchEvent"
:isPage="true"
@pageChange="handlePageChange"
>
<div slot="main" slot-scope="{ tableHeight }">
<base-table
ref="baseTable"
:showIndex="true"
:funWidth="120"
:funData="funData"
@onFunc="onFunc"
:tabLoading.sync="tabLoading"
:tableHeight="tableHeight"
:tableData="tableData"
:tableColumn="tableColumnData"
>
<template #type="{ row }">
{{ taskStatusDist[row.type] }}
</template>
</base-table>
</div>
</base-layout>
<right-dialog ref="rightDialog" @resetTable="resetTable"></right-dialog>
</div>
</template>
<script>
import baseLayout from "@/components/base/baseLayout";
import baseTable from "@/components/base/baseTable";
import rightDialog from "./rightDialog.vue";
import { getApiModuleApi } from "@/api/apiChunks/index.js";
export default {
components: {
baseLayout,
baseTable,
rightDialog,
},
data() {
return {
buttonList: [
{
menuName: "刷新",
icon: "el-icon-refresh",
btnFunction: "resetLoad",
},
], //
requirementList: [
{
placeholder: "消息内容",
prop: "sendCount",
tag: "elInput",
},
{
placeholder: "发送时间",
prop: "sendDatetime",
tag: "elDatePicker",
},
], //list
tabLoading: false,
tableColumnData: [
{
prop: "type",
label: "消息类型",
tooltip: true,
width: 100,
},
{
prop: "recipientsPersonName",
label: "接收人",
tooltip: true,
width: 120,
},
{
prop: "sendDatetime",
label: "发送时间",
tooltip: true,
width: 170,
},
{
prop: "sendCount",
label: "消息内容",
tooltip: true,
},
{
prop: "sendPersonName",
label: "发送人",
width: 120,
},
{
prop: "resultMessage",
label: "三方系统消息结果",
tooltip: true,
},
// {
// prop: "create_user_name",
// label: "",
// width:120
// },
{
prop: "create_time",
label: "创建时间",
width: 170,
},
], //
funData: [
{
color: "#6a9af1",
text: "查看",
},
],
tableData: [], //
pageModel: {
pageNum: 1,
pageSize: 100,
},
queryModel: {
send_count: "",
send_datetime: "",
},
taskStatusDist: {
1: "系统消息",
2: "单据消息",
3: "钉钉消息",
4: "企业微信消息",
},
};
},
mounted() {
this.GetProductionTableData();
},
methods: {
onCellClick(row) {
this.openLoading("detail");
this.$refs.rightDialog.openDialog("show", row);
},
//
async GetProductionTableData() {
this.tabLoading = true;
let param = {
...this.pageModel,
...this.queryModel,
};
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "queryEntityPage",
},
{
...param,
}
);
this.tabLoading = false;
if (res.status == "200") {
this.tableData = res.attribute.list;
this.$refs.baseLayout.setPageTotal(res.attribute.total);
}
},
//
handlePageChange(val) {
this.pageModel.pageNum = val.pageIndex;
this.pageModel.pageSize = val.pageSize;
this.GetProductionTableData();
},
//
onFuncBtn(btn) {
this.onCellClick();
},
//
onFunc(index, row, item) {
//
if (item.text === "查看") {
this.openLoading("detail");
this.$refs.rightDialog.openDialog("show", row);
}
},
//
resetTable() {
this.pageModel.pageNum = 1;
this.$refs.baseLayout.pageClear();
this.GetProductionTableData();
},
//
handleSearchEvent() {
let data = this.$refs.baseLayout.ruleForm;
this.queryModel = data;
this.resetTable();
},
},
};
</script>
<style scoped>
.clickTitle {
color: #409eff;
cursor: pointer;
}
</style>

View File

@ -0,0 +1,217 @@
<template>
<div>
<base-right-dialog
ref="baseRightDialog"
:footerShow="true"
:dialogVisible.sync="dialogVisible"
:title="dialogTitle + ' 消息日志'"
@handleClose="handleDialogClose"
:type="dialogType"
:submitShow="false"
>
<base-form
ref="basicsForm"
:formRow="formRow"
:isFunBtn="false"
class="dialog_form"
:spanWidth="`120px`"
:loading="vLoading"
></base-form>
</base-right-dialog>
</div>
</template>
<script>
import baseRightDialog from "@/components/base/baseRightDialog";
import baseForm from "@/components/base/baseNewForm";
import baseTable from "@/components/base/baseTable";
import { getApiModuleApi } from "@/api/apiChunks/index.js";
export default {
components: {
baseRightDialog,
baseForm,
baseTable,
},
data() {
return {
dialogVisible: false,
dialogTitle: "",
dialogType: "",
formRow: [],
basicsRules: [],
vLoading: false,
newMarryOptions: [],
submitShow: true,
loadingType: true,
tableVersionData: [],
tableVersionColumn: [],
funData: [],
isEdit: false,
select_dist: {},
};
},
mounted() {},
methods: {
openDialog(type, row) {
//
if (type == "show") {
this.funData = Object.assign([], []);
this.submitShow = false;
this.formRow = [
{
elCol: [
{
label: "消息类型",
prop: "type",
tag: "elRadio",
disabled: true,
options: [
{
label: "系统消息",
value: "1",
},
{
label: "单据消息",
value: "2",
},
{
label: "钉钉消息",
value: "3",
},
{
label: "微信消息",
value: "4",
},
],
span: 24,
},
],
},
{
elCol: [
{
label: "接收人",
prop: "recipientsPersonName",
tag: "elInput",
disabled: true,
},
{
label: "发送时间",
prop: "sendDatetime",
tag: "elInput",
disabled: true,
},
],
},
{
elCol: [
{
label: "消息内容",
prop: "sendCount",
tag: "elInput",
type: "textarea",
disabled: true,
span: 24,
},
],
},
{
elCol: [
{
label: "发送人",
prop: "sendPersonName",
tag: "elInput",
disabled: true,
},
{
label: "创建时间",
prop: "create_time",
tag: "elInput",
disabled: true,
},
],
},
{
elCol: [
{
label: "三方系统消息结果",
prop: "resultMessage",
tag: "elInput",
type: "textarea",
disabled: true,
span: 24,
},
],
},
];
this.dialogTitle = "查看";
this.dialogType = "show";
this.productGetById(row.id);
}
this.dialogVisible = true;
},
//
async productGetById(id) {
let params = {
id: id,
};
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "getEntity",
},
{
...params,
}
);
if (res.status == "200") {
this.$nextTick(() => {
this.$refs.basicsForm.incomingParameters(res.attribute);
});
}
},
//
handleDialogClose() {
this.tableVersionData = Object.assign([], []);
this.$refs.basicsForm.resetFields();
this.dialogVisible = false;
},
},
};
</script>
<style scoped lang="scss">
.dialogList {
padding: 16px 0;
border-top: 1px solid #dcdfe6;
display: flex;
flex-direction: column;
}
.updateBtn {
border: 1px solid #ebedf1;
padding: 5px 0;
border-radius: 3px;
text-align: center;
font-size: 14px;
cursor: pointer;
width: 100px;
}
.updateBtn:hover {
color: #1890ff;
border-color: #badeff;
background-color: #e8f4ff;
}
::v-deep .el-table__body-wrapper.is-scrolling-none {
height: auto !important;
}
::v-deep .app-container {
height: auto !important;
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<div>
<div style="border: 1px solid #ccc; margin-top: 10px" :key="editorKey">
<!-- 工具栏 -->
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" />
<!-- 编辑器 -->
<Editor style="height: 40vh; overflow-y: hidden" :defaultConfig="editorConfig" v-model="html" ref="editor"
@onChange="onChange" @onCreated="onCreated" />
</div>
</div>
</template>
<script>
import {
Editor,
Toolbar
} from "@wangeditor/editor-for-vue";
import {
UploadFilesLocal
} from '@/api/apis/auth.js'
export default {
name: "editorVue",
components: {
Editor,
Toolbar
},
props: {
content: {
type: String,
default: '',
},
htmlContent: {
type: String,
default: '',
},
readOnlys: { //
type: Boolean,
default: false,
},
},
data() {
return {
editorKey:1,
editor: null,
html: '',
toolbarConfig: {
/* 显示哪些菜单,如何排序、分组 */
toolbarKeys: [
'headerSelect',
// '|',
'bold',
'underline',
'italic',
'color',
'bgColor',
// '|',
'indent', //
'delIndent', //
'justifyLeft', //
'justifyRight', //
'justifyCenter', //
'justifyJustify', //
// '|',
'fontSize',
'fontFamily',
'lineHeight',
// '|',
'bulletedList',
'numberedList',
'todo',
'insertLink',
// 'insertTable',
// '|',
'codeBlock',
'divider',
// 'uploadImage',
'undo',
'redo',
],
// excludeKeys: [ ], /* */
},
editorConfig: {
placeholder: "请输入内容",
// autoFocus: false,
// readOnly: true, //
// MENU_CONF
MENU_CONF: {
//
uploadImage: {
customUpload: this.uploaadImg
},
},
},
};
},
watch: {
readOnlys: {
handler(newV) {
if (newV) {
this.editor.disable() //
}
}
},
},
methods: {
changeKey(){
this.editorKey += 1
},
setEditorInnerHTML(content) {
this.html = content
// if(content){
this.changeKey()
// }
// this.setKey()
// this.html= JSON.stringify(content)
// this.html = Object.seal(content);
// this.editor.dangerouslyInsertHtml(content)
},
getbase64(imgfiles) {
let reader = new FileReader();
reader.readAsDataURL(imgfiles);
reader.onload = (e) => {
let imgSrcbase64 = e.target.result;
}
},
uploaadImg(file, insertFn) {
// this.getbase64(file)
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
let url = e.target.result;
this.$emit('uploadImg', file, insertFn, url)
}
return
let url = ''
let formData = new FormData();
formData.append("type", 2)
formData.append("files", file)
formData.append("floadname", '消息模板')
UploadFilesLocal(formData).then(res => {
if (res.success == 'true') {
// this.uploadTx(res.data[0])
url = res.data[1].split('/wwwroot')[1]
this.$emit('uploadImg', file, insertFn, url)
}
})
},
onCreated(editor) {
this.editor = Object.seal(editor);
},
onChange(editor) {
this.$emit('changeData', this.html)
},
},
created() {
this.html = Object.seal(this.content);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // editor
},
};
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>

View File

@ -0,0 +1,498 @@
<template>
<div class="messageContainer">
<div class="messageTopTitle">
<div class="msgTips"> {{ totalMessage || 0 }} 个消息模版</div>
<el-button type="primary" @click="openMessageDialog">新增</el-button>
</div>
<!-- 卡片模式 -->
<div style="height: calc(100% - 100px)">
<div class="messageBox" v-if="messageData.length > 0">
<div v-for="(item, index) in messageData" class="messageItem">
<div class="flowBox">
<div class="IDBOX">
<div class="titlebox">
<div class="title">模板ID</div>
<div class="content" style="color: #1478f6">{{ item.id }}</div>
</div>
</div>
<div class="templateBox" style="align-items: flex-start">
<div
class="titlebox"
style="width: 50%; margin-right: 10px; align-items: flex-start"
>
<div class="title">模板名称</div>
<div class="content">{{ item.templateName }}</div>
</div>
<div class="titlebox" style="width: 49%; margin-right: 10px">
<div class="title">模板类型</div>
<div class="content">{{ item.templateType }}</div>
</div>
</div>
<div class="templateBox">
<div class="titlebox" style="flex: 1">
<div class="title">状态</div>
<div class="content">
{{ item.state == 1 ? "启用" : "停用" }}
</div>
</div>
</div>
<div class="templateBox">
<div class="titlebox" style="align-items: flex-start">
<div class="title">消息标题</div>
<div
class="content"
v-html="item.messageTitle"
:title="item.messageTitle"
></div>
</div>
</div>
<div class="contentBox" style="margin-bottom: 10px">
<div class="title">消息内容</div>
<div class="content" v-html="item.messageContents"></div>
</div>
<div
class="contentBox contentBtnBox"
v-for="(el, elIndex) in item.btns"
:key="elIndex"
v-if="item.btns.length > 0"
>
<div class="title">按钮{{ elIndex + 1 }}</div>
<div class="content boxBtnontent">
<div
v-if="el.pcTitle"
:style="{
backgroundColor: el.pcColor ? el.pcColor : '#409EFF',
borderColor: el.pcColor ? el.pcColor : '#409EFF',
color:
el.pcColor && el.pcColor == '#ffffff'
? '#000000'
: '#ffffff',
}"
class="colorBox"
>
{{ el.pcTitle }}
</div>
<div class="contentBox btnContentBox">
<div class="title" style="margin-bottom: 0">PC按钮配置</div>
<div
class="content"
v-html="el.pcRoute"
style="white-space: pre-wrap; padding: 0 10px"
></div>
</div>
<div
v-if="el.appTitle"
:style="{
backgroundColor: el.appColor ? el.appColor : '#409EFF',
borderColor: el.appColor ? el.appColor : '#409EFF',
color:
el.appColor && el.appColor == '#ffffff'
? '#000000'
: '#ffffff',
}"
class="colorBox"
>
{{ el.appTitle }}
</div>
<div class="contentBox btnContentBox">
<div class="title" style="margin-bottom: 0">
APP按钮配置
</div>
<div
class="content"
v-html="el.appRoute"
style="white-space: pre-wrap; padding: 0 10px"
></div>
</div>
</div>
</div>
</div>
<div class="messageItem_opearte">
<div @click="handleEdit(item)">
<i class="el-icon-edit-outline pointer"></i>
<p class="pointer">编辑</p>
</div>
<div @click="handleDelete(item)">
<i class="el-icon-delete pointer" style="color: #ff3b30"></i>
<p class="pointer">删除</p>
</div>
<div>
<el-switch
v-model="item.state"
:active-value="'1'"
:inactive-value="'0'"
active-color="#13ce66"
style="margin-bottom: 10px"
@change="StopMessageTemplate(item)"
>
</el-switch>
<p class="pointer">启用/停用</p>
</div>
</div>
</div>
</div>
<div v-else style="height: calc(100% - 40px); margin-top: 100px">
<el-empty description="暂无数据"></el-empty>
</div>
</div>
<footer>
<basePage
:pageModel="pageModel"
@update:pageModel="currentChangeHandle"
></basePage>
</footer>
<message-dialog
ref="messageDialog"
:billKindID="billKindID"
@handleConfirmClick="handleConfirmClick"
>
</message-dialog>
</div>
</template>
<script>
import basePage from "@/views/intergrationTask/compoments/basePage.vue";
import messageDialog from "./messageDialog.vue";
import { getApiModuleApi } from "@/api/apiChunks/index.js";
export default {
components: {
messageDialog,
basePage,
},
props: {
billKindID: {
type: [String, Number],
default: null,
},
},
data() {
return {
totalMessage: 0,
messageData: [],
pageModel: {
pageIndex: 1,
total: 10,
limit: 10,
},
};
},
mounted() {
this.initPage();
},
methods: {
initPage() {
this.GetMessageTemplateList();
},
openMessageDialog() {
this.$refs.messageDialog.openDialog("add");
},
handleEdit(item) {
this.$refs.messageDialog.openDialog("edit", item);
},
handleConfirmClick() {
this.GetMessageTemplateList();
},
async GetMessageTemplateList() {
const res = await getApiModuleApi(
{
tl: "sysMessageTemplateService",
as: "",
dj: "queryEntityPage",
},
{
pageNum: this.pageModel.pageIndex,
pageSize: this.pageModel.limit,
}
);
if (res.status == 200 || res.status == "200") {
res.attribute.list.forEach((element) => {
element.btns = element.btns ? JSON.parse(element.btns) : [];
});
this.messageData = res.attribute.list;
this.totalMessage = res.attribute.total;
this.pageModel.total = res.attribute.total;
}
},
//
currentChangeHandle(pageModel) {
this.pageModel = pageModel;
this.GetMessageTemplateList();
},
handleDelete(item) {
this.$confirm("确定删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.deleteMessage(item);
})
.catch(() => {
this.$message({
type: "info",
message: "取消操作",
});
});
},
async deleteMessage(item) {
const res = await getApiModuleApi(
{
tl: "sysMessageTemplateService",
as: "",
dj: "deleteEntity",
},
{
id: item.id,
}
);
if (res.status == 200) {
this.$vmNews("删除成功", "success");
this.GetMessageTemplateList();
}
},
//
StopMessageTemplate(row) {
row.state = row.state == "0" ? "1" : "0";
this.$confirm(
`您确定要${row.state == "1" ? "停用" : "启用"}该消息模版吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
let state = row.state == "1" ? "0" : "1";
let params = {
id: row.id,
state: state,
};
this.changeStage(params);
})
.catch(() => {
this.$message({
type: "info",
message: "取消操作",
});
});
},
async changeStage(params) {
const res = await getApiModuleApi(
{
tl: "sysMessageTemplateService",
as: "",
dj: "enableDisableEntity",
},
{
...params,
}
);
if (res.status == 200) {
this.$message({
type: "success",
message: "操作成功!",
});
this.GetMessageTemplateList();
}
},
},
};
</script>
<style lang="scss" scoped>
.messageContainer {
height: 100%;
background: #ffffff;
padding: 10px 10px 20px 10px;
border-radius: 4px;
}
.messageTopTitle {
width: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
padding-bottom: 10px;
.msgTips {
font-weight: 500;
font-size: 14px;
color: #333333;
text-align: center;
font-style: normal;
margin-right: 10px;
}
}
.messageBox {
height: 100%;
width: 100%;
display: flex;
flex-wrap: wrap;
overflow: auto;
.messageItem {
width: 470px;
// min-width: 600px;
// max-width: 600px;
height: 400px;
background: #ffffff;
border-radius: 8px;
border: 1px solid #dddddd;
position: relative;
margin: 10px;
.flowBox {
padding: 10px;
overflow-y: auto;
height: inherit;
}
.templateBox {
display: flex;
margin-bottom: 10px;
.titlebox {
display: flex;
align-items: center;
font-size: 14px;
// white-space: nowrap;
// /* */
// overflow: hidden;
// /* */
// text-overflow: ellipsis;
/* 使用省略号表示被截断的文本 */
.title {
color: #999999;
text-align: left;
font-style: normal;
}
.content {
color: #333333;
text-align: left;
font-style: normal;
font-weight: 400;
width: calc(100% - 70px);
word-break: break-all;
}
}
}
.contentBox {
display: flex;
flex-direction: column;
font-size: 14px;
.title {
color: #999999;
text-align: left;
font-style: normal;
margin-bottom: 10px;
}
.content {
color: #333333;
text-align: left;
font-style: normal;
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
height: 100px;
overflow-y: auto;
font-weight: 400;
word-break: break-all;
}
}
.contentBtnBox {
.content {
overflow-y: unset;
height: auto;
}
}
&_opearte {
display: none;
// display: flex;
background-color: rgba(0, 0, 0, 0.7);
// display: flex;
justify-content: space-around;
padding: 13px 0;
color: white;
font-size: 12px;
text-align: center;
position: absolute;
width: 100%;
bottom: 0;
left: 0;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
i {
font-size: 24px;
margin-bottom: 10px;
}
}
}
.messageItem:hover {
.messageItem_opearte {
display: flex;
align-items: center;
}
}
.colorBox {
padding: 5px 15px;
font-size: 13px;
border-radius: 3px;
}
}
.btnContentBox {
width: 100%;
display: flex !important;
flex-direction: unset !important;
align-items: flex-start !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
padding: 10px 0;
}
.boxBtnontent {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 15px 10px;
margin-bottom: 10px;
}
.IDBOX {
display: flex;
margin-bottom: 10px;
.titlebox {
display: flex;
align-items: center;
font-size: 14px;
.title {
color: #999999;
text-align: left;
font-style: normal;
}
.content {
color: #333333;
text-align: left;
font-style: normal;
font-weight: 400;
word-break: break-all;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,328 @@
<template>
<base-dialog
:closeEscape="true"
:showClose="true"
:closeModal="false"
@handleConfirmClick="apiConfirmClick"
:dialogVisible.sync="personDialog"
@handleClose="handleClose"
class="userDialog"
title="API配置"
width="1200px"
top="10vh"
:footerShow="true"
>
<div class="organizationBody">
<div style="display: flex">
<base-layout
style="
width: 20%;
border-radius: 5px;
height: calc(100vh - 360px);
overflow: auto;
"
:operateButtonSwitch="false"
:bottonShow="false"
:isPage="false"
:mainColor="mainColor"
>
<div slot="main">
<base-tree
ref="baseTree"
:isCenter="false"
:isSaveBtn="false"
:Allshow="false"
:showCheckbox="false"
:menuData="menuData"
@handleNodeClick="handleNodeClick"
></base-tree>
</div>
</base-layout>
<div style="width: 78%">
<base-table
ref="personpersonCustomtable"
:border="true"
:showIndex="true"
:showSelect="true"
:tabLoading.sync="personLoading"
:tableData="personTableData"
:tableColumn="tableColumn"
:tableHeight="'calc(100vh - 400px)'"
@onSelectionChange="getSelect"
@select="getOneSelectChange"
:currentType="'apiCode'"
>
</base-table>
<basePage
:pageModel="pageModel"
@update:pageModel="currentChangeHandle"
></basePage>
</div>
</div>
<!-- 多选模块-->
<div class="multipleChoice" v-if="selectTableShow.length > 0">
<div class="title">已选</div>
<div
class="checkBoxlist"
style="display: flex; margin-left: 5px; margin-top: 10px"
>
<div
class="chunkItem"
v-for="(item, index) in selectTableShow"
:key="index"
style="display: flex; align-items: center"
>
<div class="name">{{ item.apiName }}</div>
<div class="btn" @click="removeCheckItem(item, index)">x</div>
</div>
</div>
</div>
</div>
</base-dialog>
</template>
<script>
import basePage from "@/views/intergrationTask/compoments/basePage.vue";
import baseDialog from "@/components/base/BaseNewDialog/index.vue";
import baseTree from "@/components/base/BaseMenuTree/index.vue";
import baseLayout from "@/components/base/baseNewLayout";
import baseTable from "@/components/base/baseTable";
import { getApiModuleApi } from "@/api/apiChunks/index.js";
export default {
components: {
baseLayout,
baseTree,
baseDialog,
baseTable,
basePage,
},
data() {
return {
personDialog: false,
mainColor: "#f8f8f8",
personMainHight: "calc(100% - 39px)", //
personHight: "350px", //
personLoading: false, //
personTableHeight: "440px", //
personTableData: [],
pageModel: {
pageIndex: 1,
total: 10,
limit: 100,
appId: "",
},
personData: [],
menuData: [],
tableColumn: [
{
label: "应用编码",
prop: "appId",
tooltip: true,
},
{
label: "应用名称",
prop: "appName",
tooltip: true,
},
{
label: "接口编码",
prop: "apiCode",
tooltip: true,
},
{
label: "接口名称",
prop: "apiName",
tooltip: true,
},
],
selectTableShow: [],
currentresult: [],
};
},
watch: {
personTableData: {
deep: true, // true
handler(newV, oldV) {
this.checkHandle();
},
},
},
methods: {
openDialog(apiStr, menuData = [], result = []) {
this.pageModel.appId = apiStr;
this.personDialog = true;
this.menuData = menuData;
this.currentresult = result;
this.getAPIList("first");
},
//
removeCheckItem(item, index) {
this.selectTableShow.splice(index, 1);
this.checkHandle();
},
//
checkHandle() {
let tempArr = [];
this.personTableData.forEach((item) => {
this.selectTableShow.forEach((ele) => {
if (ele.apiCode === item.apiCode) {
tempArr.push(item);
}
});
});
this.$refs.personpersonCustomtable.clearSelect();
this.$nextTick(() => {
this.$refs.personpersonCustomtable.toggleSelection(tempArr, true);
});
},
//
handleNodeClick(data) {
this.pageModel.appId = data.id;
this.$refs.personpersonCustomtable.clearRadioIndex();
this.$nextTick(() => {
this.getAPIList();
});
},
//
currentChangeHandle(pageModel) {
this.pageModel = pageModel;
this.getAPIList();
},
//
async getAPIList(type = null) {
this.personLoading = true;
setTimeout(() => {
this.personLoading = false;
}, 3000);
const res = await getApiModuleApi(
{
tl: "sysApplicationApiService",
as: "",
dj: "queryMultiAppPage",
},
{
pageNum: this.pageModel.pageIndex,
pageSize: this.pageModel.limit,
appId: this.pageModel.appId,
}
);
if (res.status == 200) {
this.personTableData = res.attribute.list;
this.pageModel.total = res.attribute.total;
this.personLoading = false;
if(type == "first"){
this.$nextTick(() => {
if (this.currentresult.length > 0) {
this.selectTableShow = this.currentresult;
this.checkHandle();
}
});
}
}
},
//
handlePageChange(val) {
this.pageModel.pageIndex = val.pageIndex;
this.pageModel.limit = val.pageSize;
this.getAPIList();
},
//
getSelect(selectTable) {
const mergedData = this.selectTableShow.concat(selectTable);
const uniqueData = Array.from(
new Set(
mergedData.map((item) => {
return item.apiCode;
})
)
)
.filter((apiCode) => apiCode !== undefined)
.map((apiCode) => {
return mergedData.find((item) => {
return item.apiCode == apiCode;
});
});
this.selectTableShow = uniqueData;
},
getOneSelectChange(list, row, flag) {
if (!flag) {
let index = this.selectTableShow.findIndex((item) => {
if (item.apiCode === row.apiCode) {
return true;
}
});
this.selectTableShow.splice(index, 1);
}
},
apiConfirmClick() {
if (this.selectTableShow.length == 0) {
this.$vmNews("请选择数据");
return;
}
this.$emit("apiConfirmClick", this.selectTableShow);
this.handleClose();
},
handleClose() {
this.selectTableShow = [];
this.personTableData = [];
this.$refs.personpersonCustomtable.clearRadioIndex();
this.personDialog = false;
},
},
};
</script>
<style scoped>
.organizationBody {
display: flex;
flex-direction: column;
background-color: #ffffff;
}
::v-deep .tableHeight {
background-color: #ffffff;
}
.multipleChoice {
margin-top: 5px;
width: 100%;
padding-top: 10px;
border-top: 1px solid #eeeeee;
.title {
color: #333;
}
.checkBoxlist {
display: flex !important;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
.chunkItem {
padding: 5px 2px;
margin-right: 10px;
display: flex !important;
justify-content: flex-start;
align-items: center;
background: #f5f5f5;
border-radius: 4px;
margin-bottom: 5px;
.name {
margin-left: 10px;
font-size: 12px;
white-space: nowrap;
}
.btn {
text-align: center;
width: 20%;
cursor: pointer;
margin-left: 5px;
padding-right: 10px;
}
}
}
}
</style>

View File

@ -0,0 +1,341 @@
<template>
<base-dialog
:closeEscape="true"
:showClose="true"
:closeModal="false"
@handleConfirmClick="personConfirmClick"
:dialogVisible.sync="personDialog"
@handleClose="handleClose"
class="userDialog"
title="选择人员"
width="1200px"
top="10vh"
:footerShow="true"
>
<div class="organizationBody">
<div style="display: flex">
<base-layout
style="
width: 20%;
border-radius: 5px;
height: calc(100vh - 360px);
overflow: auto;
"
:operateButtonSwitch="false"
:bottonShow="false"
:isPage="false"
:mainColor="mainColor"
:mainHight="personMainHight"
>
<div slot="main">
<base-tree
ref="baseTree"
:isCenter="false"
:isSaveBtn="false"
:Allshow="false"
:showCheckbox="false"
:menuData="menuData"
@handleNodeClick="handleNodeClick"
></base-tree>
</div>
</base-layout>
<base-layout
style="border-radius: 5px; height: calc(100vh - 360px); flex: 1"
:bottonShow="false"
:operateButtonSwitch="false"
:isPage="false"
:bodyHight="personHight"
>
<div slot="main" style="padding: 10px">
<base-table
ref="personpersonCustomtable"
:border="true"
:showIndex="false"
:showSelect="true"
:tabLoading.sync="personLoading"
:tableHeight="personTableHeight"
:tableData="personTableData"
:tableColumn="tableColumn"
@onSelectionChange="getSelect"
@select="getOneSelectChange"
>
<template #state="{ row }">
<div>{{ row.state == 1 ? "停用" : "启用" }}</div>
</template>
</base-table>
</div>
</base-layout>
</div>
<!-- 多选模块-->
<div class="multipleChoice" v-if="selectTableShow.length > 0">
<div class="title">已选</div>
<div
class="checkBoxlist"
style="display: flex; margin-left: 5px; margin-top: 10px"
>
<div
class="chunkItem"
v-for="(item, index) in selectTableShow"
:key="index"
style="display: flex; align-items: center"
>
<div class="name">{{ item.personName }}</div>
<div class="btn" @click="removeCheckItem(item, index)">x</div>
</div>
</div>
</div>
</div>
</base-dialog>
</template>
<script>
import { authApi } from "@/api/apis/auth";
import baseDialog from "@/components/base/BaseNewDialog/index.vue";
import baseTree from "@/components/base/BaseMenuTree/index.vue";
import baseLayout from "@/components/base/baseNewLayout";
import baseTable from "@/components/base/baseTable";
import { PersonList } from "@/api/apis/personnelSettings";
export default {
components: {
baseLayout,
baseTree,
baseDialog,
baseTable,
},
data() {
return {
personDialog: false,
mainColor: "#f8f8f8",
personMainHight: "calc(100% - 39px)", //
personHight: "350px", //
personLoading: false, //
personTableHeight: "440px", //
personTableData: [],
personModel: {
pageNum: 1,
pageSize: 999,
organId: "",
Sequence: "",
SequenceName: "",
},
personData: [],
menuData: [],
tableColumn: [
{
label: "所属部门",
prop: "organName",
tooltip: true,
},
{
label: "工号",
prop: "personCode",
tooltip: true,
},
{
label: "姓名",
prop: "personName",
tooltip: true,
},
{
label: "入职时间",
prop: "entryTime",
tooltip: true,
},
{
label: "固定电话 ",
prop: "mobilePhone",
tooltip: true,
},
{
label: "电子邮箱",
prop: "email",
tooltip: true,
},
{
label: "出生年月",
prop: "birthDay",
tooltip: true,
},
{
label: "是否用户分配",
prop: "state",
tooltip: true,
width: 150,
},
],
selectTableShow: [],
};
},
watch: {
personTableData: {
deep: true, // true
handler(newV, oldV) {
this.checkHandle();
},
},
},
methods: {
openDialog(result = []) {
this.personDialog = true;
this.getOrganList();
if(result.length > 0){
this.selectTableShow = result
}
},
//
removeCheckItem(item, index) {
this.selectTableShow.splice(index, 1);
this.checkHandle();
},
//
checkHandle() {
let tempArr = [];
this.personTableData.forEach((item) => {
this.selectTableShow.forEach((ele) => {
if (ele.id === item.id) {
tempArr.push(item);
}
});
});
this.$refs.personpersonCustomtable.clearSelect();
this.$nextTick(() => {
this.$refs.personpersonCustomtable.toggleSelection(tempArr, true);
});
},
//
async getOrganList() {
let res = await authApi("sysOrganService", "", "queryEntityTree", "", {
state: 0,
});
this.menuData = res.attribute;
},
//
handleNodeClick(data) {
this.personModel.organId = data.id;
this.$refs.personpersonCustomtable.clearRadioIndex();
this.$nextTick(() => {
this.getPersonList();
});
},
//
async getPersonList() {
this.personLoading = true;
setTimeout(() => {
this.personLoading = false;
}, 3000);
let params = {
...this.personModel,
};
let res = await authApi(
"sysPersonService",
"",
"queryEntity",
"",
params
);
if (res.status == 200) {
this.personTableData = res.attribute;
this.personLoading = false;
}
},
//
getSelect(selectTable) {
const mergedData = this.selectTableShow.concat(selectTable);
const uniqueData = Array.from(
new Set(
mergedData.map((item) => {
return item.id;
})
)
)
.filter((id) => id !== undefined)
.map((id) => {
return mergedData.find((item) => {
return item.id == id;
});
});
this.selectTableShow = uniqueData;
},
getOneSelectChange(list, row, flag) {
if (!flag) {
let index = this.selectTableShow.findIndex((item) => {
if (item.id === row.id) {
return true;
}
});
this.selectTableShow.splice(index, 1);
}
},
personConfirmClick() {
if (this.selectTableShow.length == 0) {
this.$vmNews("请选择数据");
return;
}
this.$emit("personConfirmClick", this.selectTableShow);
this.handleClose();
},
handleClose() {
this.selectTableShow = [];
this.personTableData = [];
this.$refs.personpersonCustomtable.clearRadioIndex();
this.personDialog = false;
},
},
};
</script>
<style scoped>
.organizationBody {
display: flex;
flex-direction: column;
background-color: #ffffff;
}
::v-deep .tableHeight {
background-color: #ffffff;
}
.multipleChoice {
margin-top: 5px;
width: 100%;
padding-top: 10px;
border-top: 1px solid #eeeeee;
.title {
color: #333;
}
.checkBoxlist {
display: flex !important;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
.chunkItem {
padding: 5px 2px;
margin-right: 10px;
display: flex !important;
justify-content: flex-start;
align-items: center;
background: #f5f5f5;
border-radius: 4px;
margin-bottom: 5px;
.name {
margin-left: 10px;
font-size: 12px;
white-space: nowrap;
}
.btn {
text-align: center;
width: 20%;
cursor: pointer;
margin-left: 5px;
padding-right: 10px;
}
}
}
}
</style>

View File

@ -0,0 +1,182 @@
/**
* @desc 预警设置
*/
// 基本信息内容
const formRow = [
{
elCol: [
{
label: '消息模版',
prop: 'messageTemplateId',
tag: 'elSelect',
options: [],
optionValue: 'id',
optionLabel: 'templateName',
},
{
label: '应用',
prop: 'appIdList',
tag: 'elMultiple',
options: [],
optionValue: 'id',
optionLabel: 'name',
}
]
},
{
elCol: [
{
label: '接收人',
prop: 'recipientNameList',
tag: "elDialog",
},
{
label: '推送方式',
prop: 'warningAppId',
tag: 'elMultiple',
options: [],
optionValue: 'id',
optionLabel: 'name',
}
]
},
{
elCol: [
{
label: '消息API',
prop: 'acceptMessageApiCode',
tag: 'elInput',
disabled:true,
placeholder:"选择推送方式自动带出",
span: 24,
}
]
},
{
elCol: [
{
label: '备注',
prop: 'remark',
tag: 'elInput',
type: 'textarea',
span: 24,
}
]
}
]
const formRowShow = [
{
elCol: [
{
label: '消息模版',
prop: 'templateName',
tag: 'elInput',
disabled:true
},
{
label: '应用',
prop: 'appNameList',
tag: 'elInput',
disabled:true
}
]
},
{
elCol: [
{
label: '接收人',
prop: 'recipientNameList',
tag: "elInput",
disabled:true
},
{
label: '推送方式',
prop: 'warningAppNameList',
tag: 'elInput',
disabled:true
}
]
},
{
elCol: [
{
label: '消息API',
prop: 'acceptMessageApiCode',
tag: 'elInput',
disabled:true,
span: 24,
}
]
},
{
elCol: [
{
label: '备注',
prop: 'remark',
tag: 'elInput',
type: 'textarea',
span: 24,
disabled:true
}
]
}
]
const basicsRules = {
code: [{
required: true,
message: '请输入产品编码',
trigger: 'blur'
}],
name: [{
required: true,
message: '请输入产品名称',
trigger: 'blur'
}],
classify: [{
required: true,
message: '请选择产品分类',
trigger: 'blur'
}],
productionCompany: [{
required: true,
message: '请输入出品公司',
trigger: 'blur'
}],
}
const tableChildColumn = [
{
label: "应用名称",
prop: "appName",
tooltip: true,
},
{
label: "API名称",
prop: "apiName",
tooltip: true,
},
{
label: "API编码",
prop: "apiCode",
tooltip: true,
},
{
label: "推送方式",
prop: "pushMethod",
tooltip: true,
},
{
label: "状态",
prop: "status",
tooltip: true,
},
]
export default {
formRow,
basicsRules,
tableChildColumn,
formRowShow
}

View File

@ -0,0 +1,353 @@
<template>
<div>
<base-layout
ref="baseLayout"
:buttonList="buttonList"
@onFuncBtn="onFuncBtn"
:querySwitch="true"
:searchList="requirementList"
@search="handleSearchEvent"
:isPage="true"
@pageChange="handlePageChange"
>
<div slot="main" slot-scope="{ tableHeight }">
<base-table
ref="baseTable"
:showIndex="true"
:funWidth="210"
:funData="funData"
@onFunc="onFunc"
:tabLoading.sync="tabLoading"
:tableHeight="tableHeight"
:tableData="tableData"
:tableColumn="tableColumnData"
>
<template #type="{ row }">
{{ taskStatusDist[row.type] }}
</template>
<template #status="{ row }">
<el-switch
v-model="row.status"
:active-value="'1'"
:inactive-value="'0'"
active-color="#13ce66"
style="margin-bottom: 10px"
@change="StopMessageTemplate(row)"
>
</el-switch>
</template>
</base-table>
</div>
</base-layout>
<right-dialog ref="rightDialog" @resetTable="resetTable"></right-dialog>
</div>
</template>
<script>
import baseLayout from "@/components/base/baseLayout";
import baseTable from "@/components/base/baseTable";
import rightDialog from "./rightDialog.vue";
import { getApiModuleApi } from "@/api/apiChunks/index.js";
export default {
components: {
baseLayout,
baseTable,
rightDialog,
},
data() {
return {
buttonList: [
{
menuName: "新增",
icon: "el-icon-plus",
btnFunction: "handlerAddEvent",
},
{
menuName: "刷新",
icon: "el-icon-refresh",
btnFunction: "resetLoad",
},
], //
requirementList: [
{
placeholder: "请选择消息模版",
prop: "messageTemplateId",
tag: "elSelect",
options: [],
optionValue: "id",
optionLabel: "templateName",
},
{
placeholder: "请选择应用",
prop: "appIdList",
tag: "elSelect",
options: [],
optionValue: "id",
optionLabel: "name",
},
], //list
tabLoading: false,
tableColumnData: [
{
prop: "appIdList",
label: "应用编码",
tooltip: true,
},
{
prop: "appNameList",
label: "应用名称",
tooltip: true,
width:200
},
{
prop: "messageTemplateId",
label: "消息模版编号",
tooltip: true,
},
{
prop: "templateName",
label: "消息模版名称",
tooltip: true,
},
{
prop: "recipientNameList",
label: "接收人",
tooltip: true,
},
{
prop: "warningAppNameList",
label: "推送方式",
tooltip: true,
},
{
prop: "acceptMessageApiCode",
label: "消息API",
tooltip: true,
},
{
prop: "remark",
label: "备注",
tooltip: true,
},
{
prop: "create_time",
label: "创建时间",
tooltip: true,
},
{
prop: "status",
label: "状态",
tooltip: true,
},
], //
funData: [
{
color: "#6a9af1",
text: "编辑",
},
{
color: "#6a9af1",
text: "查看",
},
{
color: "#ff0000",
text: "删除",
},
],
tableData: [], //
pageModel: {
pageNum: 1,
pageSize: 100,
},
queryModel: {
send_count: "",
send_datetime: "",
},
};
},
mounted() {
this.getMessageList()
this.getApplicationList()
this.GetProductionTableData();
},
methods: {
//
async getMessageList() {
const res = await getApiModuleApi(
{
tl: "sysMessageTemplateService",
as: "",
dj: "queryEntity",
},
{}
);
if (res.status == "200") {
this.requirementList[0].options = res.attribute;
}
},
//
async getApplicationList() {
const res = await getApiModuleApi(
{
tl: "sysApplicationService",
as: "",
dj: "queryEntity",
},
{}
);
if (res.status == "200") {
this.requirementList[1].options = res.attribute;
}
},
onCellClick(row) {
this.openLoading("detail");
this.$refs.rightDialog.openDialog("show", row);
},
//
async GetProductionTableData() {
this.tabLoading = true;
setTimeout(() => {
this.tabLoading = false;
}, 5000);
let param = {
...this.pageModel,
...this.queryModel,
};
const res = await getApiModuleApi(
{
tl: "sysWarningConfigService",
as: "",
dj: "queryEntityPage",
},
{
...param,
}
);
this.tabLoading = false;
if (res.status == "200") {
this.tableData = res.attribute.list;
this.$refs.baseLayout.setPageTotal(res.attribute.total);
}
},
//
handlePageChange(val) {
this.pageModel.pageNum = val.pageIndex;
this.pageModel.pageSize = val.pageSize;
this.GetProductionTableData();
},
//
onFuncBtn(btn) {
this[btn.btnFunction]();
},
handlerAddEvent() {
this.$refs.rightDialog.openDialog("add");
},
//
onFunc(index, row, item) {
//
if (item.text === "查看") {
this.openLoading("detail");
this.$refs.rightDialog.openDialog("show", row);
}
//
if (item.text === "编辑") {
this.openLoading("detail");
this.$refs.rightDialog.openDialog("edit", row);
}
//
if (item.text === "删除") {
this.$delConfirm().then(() => {
this.openLoading("del");
this.productionDeleteById(row.id);
});
}
},
async productionDeleteById(id) {
let param = {
id: id,
};
const res = await getApiModuleApi(
{
tl: "sysWarningConfigService",
as: "",
dj: "deleteEntity",
},
{
...param,
}
);
if (res.status == "200") {
this.$vmNews("删除成功", "success");
this.resetTable();
}
},
//
resetTable() {
this.pageModel.pageNum = 1;
this.$refs.baseLayout.pageClear();
this.GetProductionTableData();
},
//
handleSearchEvent() {
let data = JSON.parse(JSON.stringify(this.$refs.baseLayout.ruleForm));
this.queryModel = data;
this.resetTable();
},
//
StopMessageTemplate(row) {
row.status = row.status == "0" ? "1" : "0";
this.$confirm(
`您确定要${row.status == "1" ? "停用" : "启用"}该预警设置吗?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
let status = row.status == "1" ? "0" : "1";
let params = {
id: row.id,
status: status,
};
this.changeStage(params);
})
.catch(() => {
this.$message({
type: "info",
message: "取消操作",
});
});
},
async changeStage(params) {
const res = await getApiModuleApi(
{
tl: "sysWarningConfigService",
as: "",
dj: "enableDisableEntity",
},
{
...params,
}
);
if (res.status == 200) {
this.$message({
type: "success",
message: "操作成功!",
});
this.resetTable();
}
},
},
};
</script>
<style scoped>
.clickTitle {
color: #409eff;
cursor: pointer;
}
</style>

View File

@ -0,0 +1,492 @@
<template>
<div>
<base-right-dialog
ref="baseRightDialog"
:footerShow="true"
:dialogVisible.sync="dialogVisible"
:title="dialogTitle + ' 预警设置'"
@handleClose="handleDialogClose"
:submitShow="submitShow"
@handleConfirmClick="handleConfirmClick"
size="1200px"
>
<base-form
ref="basicsForm"
:formRow="formRow"
:isFunBtn="false"
class="dialog_form"
:spanWidth="`120px`"
@elDialogClick="formDialogClick"
@onSelect="onSelect"
@elDialogClear="elDialogClear"
></base-form>
<el-button
type="primary"
style="margin: 10px 0"
@click="apiSetting"
v-if="dialogTitle != '查看'"
>配置API</el-button
>
<base-table
ref="baseTable"
:showIndex="true"
:tableData="tableData"
:tableColumn="tableColumn"
:fixedTable="'right'"
:funData="funData"
@onFunc="onFunc"
:funWidth="100"
>
<!-- 推送方式 -->
<template v-slot:pushMethod="{ row }">
<div class="w100" v-if="dialogTitle != '查看'">
<el-select v-model="row.pushMethod" clearable>
<el-option
v-for="item in pushMethodList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="w100" v-else>
{{ row.pushMethod }}
</div>
</template>
<!-- 状态 -->
<template v-slot:status="{ row }">
<div class="w100" v-if="dialogTitle != '查看'">
<el-switch
v-model="row.status"
:active-value="'1'"
:inactive-value="'0'"
active-color="#13ce66"
>
</el-switch>
</div>
<div class="w100" v-else>
{{ row.status == "1" ? "启用" : row.status == "0" ? "停用" : "" }}
</div>
</template>
</base-table>
</base-right-dialog>
<base-multiple-person
ref="baseMultiplePerson"
@personConfirmClick="personConfirmClick"
></base-multiple-person>
<base-api ref="baseApi" @apiConfirmClick="apiConfirmClick"></base-api>
</div>
</template>
<script>
import baseRightDialog from "@/components/base/baseRightDialog";
import baseForm from "@/components/base/baseNewForm";
import baseTable from "@/components/base/baseTable";
import { getApiModuleApi } from "@/api/apiChunks/index.js";
import configData from "./configData";
import baseMultiplePerson from "./baseMultiplePerson/index.vue";
import baseApi from "./baseApi/index.vue";
export default {
components: {
baseRightDialog,
baseForm,
baseTable,
baseMultiplePerson,
baseApi,
},
data() {
return {
dialogVisible: false,
dialogTitle: "",
dialogType: "",
formRow: configData.formRow,
basicsRules: {},
submitShow: true,
tableData: [],
tableColumn: configData.tableChildColumn,
funData: [
{
color: "#ff0000",
text: "删除",
handle: "deleteData",
},
],
apiClassificationData: [], //
GolbelApiStr: null,
pushMethodList: [
{
value: "一次",
label: "一次",
},
{
value: "定时",
label: "定时",
},
],
billID: null,
appArrData:[]
};
},
methods: {
openDialog(type, row = {}) {
this.dialogVisible = true;
this.billID = row ? row.id : null;
if (type == "add") {
this.dialogTitle = "新增";
}
if (type == "edit") {
this.dialogTitle = "修改";
}
if (type == "show") {
this.dialogTitle = "查看";
this.formRow = configData.formRowShow;
this.funData = [];
}
if (type != "show") {
this.getMessageList();
this.getApplicationList();
this.getSendMethods();
}
if (row.id) {
this.getDetails(row.id);
}
},
//
async getDetails(id) {
const res = await getApiModuleApi(
{
tl: "sysWarningConfigService",
as: "",
dj: "getEntity",
},
{
id: id,
}
);
if (res.status == "200") {
this.$nextTick(() => {
this.GolbelApiStr = res.attribute.father.appIdList;
let appList = res.attribute.father.appIdList.split(",");
// id
const result = this.appArrData
.filter((item) => appList.includes(item.id)) // id
.map((item) => ({ id: item.id, label: item.name })); // idappName
this.apiClassificationData = [{ id: res.attribute.father.appIdList, label: "全部" }, ...result];
res.attribute.father.appIdList = appList;
res.attribute.father.warningAppId =
res.attribute.father.warningAppId.split(",");
this.$refs.basicsForm.incomingParameters(res.attribute.father);
this.tableData = res.attribute.son;
});
}
},
formDialogClick(row, index) {
if (row.label == "接收人") {
let data = this.$refs.basicsForm.ruleForm;
if (data.recipientNameList && data.recipientIdList) {
const ids = data.recipientIdList.split(",");
const names = data.recipientNameList.split(",");
const result = ids.map((id, index) => ({
id: id,
personName: names[index],
}));
this.$refs.baseMultiplePerson.openDialog(result);
} else {
this.$refs.baseMultiplePerson.openDialog();
}
}
},
personConfirmClick(row) {
let idList = "",
nameList = "";
if (row.length > 0) {
let ids = [],
names = [];
row.forEach((el) => {
names.push(el.personName);
ids.push(el.id);
});
idList = ids.join(",");
nameList = names.join(",");
}
this.$refs.basicsForm.getField("recipientNameList", nameList);
this.$refs.basicsForm.getField("recipientIdList", idList);
},
elDialogClear(row, index) {
if (row.label == "接收人") {
this.$refs.basicsForm.getField("recipientNameList", "");
this.$refs.basicsForm.getField("recipientIdList", "");
}
},
onSelect(val, index, indexRow, obj, options, data, row) {
if (row.label == "推送方式") {
const foundItem = options.filter((item) => val.includes(item.id));
if (foundItem.length > 0) {
let messageStr = "";
let messageApi = [];
foundItem.forEach((el) => {
messageApi.push(el.messageApi);
});
messageStr = messageApi.join(",");
this.$refs.basicsForm.getField("acceptMessageApiCode", messageStr);
} else {
this.$refs.basicsForm.getField("acceptMessageApiCode", "");
}
}
if (row.label == "应用") {
let str = val.join(",");
this.GolbelApiStr = str;
// id
const result = options
.filter((item) => val.includes(item.id)) // id
.map((item) => ({ id: item.id, label: item.name })); // idappName
this.apiClassificationData = [{ id: str, label: "全部" }, ...result];
//
if (this.tableData.length > 0) {
let filteredData = this.tableData.filter((item) =>
val.includes(item.appId)
);
this.tableData = filteredData;
}
}
},
apiSetting() {
if (
this.GolbelApiStr == null ||
this.GolbelApiStr == "" ||
this.GolbelApiStr == undefined
) {
this.$vmNews("请选择应用", "warning");
return;
}
this.$refs.baseApi.openDialog(
this.GolbelApiStr,
this.apiClassificationData,
this.tableData
);
},
apiConfirmClick(rows) {
// tempTable
let tempTable = [];
//incove
let tempArr = [];
this.tableData.forEach((item) => {
tempArr.push(item.apiCode);
});
this.tableData = [];
rows.forEach((item) => {
if (!tempArr.includes(item.apiCode)) {
tempTable.push(item);
} else {
//
this.tableData.push(item);
}
});
//
tempTable.forEach((item) => {
let arr = {
apiCode: item.apiCode,
apiName: item.apiName,
appName: item.appName,
appId: item.appId,
pushMethod: "一次",
status: "0",
};
this.tableData.push(arr);
});
},
//
async getMessageList() {
const res = await getApiModuleApi(
{
tl: "sysMessageTemplateService",
as: "",
dj: "queryEntity",
},
{}
);
if (res.status == "200") {
this.formRow[0].elCol[0].options = res.attribute;
}
},
//
async getApplicationList() {
const res = await getApiModuleApi(
{
tl: "sysApplicationService",
as: "",
dj: "queryEntity",
},
{}
);
if (res.status == "200") {
this.appArrData = res.attribute
this.formRow[0].elCol[1].options = res.attribute;
}
},
//
async getSendMethods() {
const res = await getApiModuleApi(
{
tl: "sysApplicationService",
as: "",
dj: "queryEntity",
},
{
appType: "5DD",
}
);
if (res.status == "200") {
res.attribute.forEach((item) => {
if ((item.id = "7ebc1702511f463d9cf50162973bf935")) {
item.messageApi = "8000430001";
}
});
this.sendMessage = res.attribute;
this.formRow[1].elCol[1].options = res.attribute;
}
},
//
async productGetById(id) {
let params = {
id: id,
};
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "getEntity",
},
{
...params,
}
);
if (res.status == "200") {
this.$nextTick(() => {
this.$refs.basicsForm.incomingParameters(res.attribute);
});
}
},
//
onFunc(index, row, item) {
this[item.handle](index, row, item);
},
//
deleteData(index, row, item) {
this.tableData.splice(row.index, 1);
},
handleConfirmClick() {
this.$refs.basicsForm.$refs["ruleForm"].validate((valid) => {
if (!valid) {
this.$tipConfirm("请输入必填项");
return;
} else {
let data = this.$refs.basicsForm.ruleForm;
let params = {
father: {
...data,
status: "1",
},
son: this.tableData,
};
params.father.appIdList = params.father.appIdList.join(",");
params.father.warningAppId = params.father.warningAppId.join(",");
this.openLoading("submit");
if (
this.billID != "" &&
this.billID != null &&
this.billID != undefined
) {
this.updateWarningSetting(params);
} else {
//
this.saveWarningSetting(params);
}
}
});
},
async saveWarningSetting(param) {
const res = await getApiModuleApi(
{
tl: "sysWarningConfigService",
as: "",
dj: "saveEntity",
},
{
...param,
}
);
this.tabLoading = false;
if (res.status == "200") {
this.$vmNews("新增成功", "success");
this.handleDialogClose();
this.$emit("resetTable");
}
},
async updateWarningSetting(param) {
const res = await getApiModuleApi(
{
tl: "sysWarningConfigService",
as: "",
dj: "updateEntity",
},
{
...param,
}
);
this.tabLoading = false;
if (res.status == "200") {
this.$vmNews("修改成功", "success");
this.handleDialogClose();
this.$emit("resetTable");
}
},
//
handleDialogClose() {
this.GolbelApiStr = null;
this.tableData = Object.assign([], []);
this.$refs.basicsForm.resetFields();
this.dialogVisible = false;
},
},
};
</script>
<style scoped lang="scss">
.dialogList {
padding: 16px 0;
border-top: 1px solid #dcdfe6;
display: flex;
flex-direction: column;
}
.w100 {
width: 100%;
}
.updateBtn {
border: 1px solid #ebedf1;
padding: 5px 0;
border-radius: 3px;
text-align: center;
font-size: 14px;
cursor: pointer;
width: 100px;
}
.updateBtn:hover {
color: #1890ff;
border-color: #badeff;
background-color: #e8f4ff;
}
::v-deep .el-table__body-wrapper {
height: auto !important;
}
::v-deep .app-container {
height: auto !important;
}
</style>

View File

@ -0,0 +1,613 @@
<template>
<div class="messageContainer">
<div class="messageLeft">
<div class="leftMessageTitle">消息</div>
<div class="leftMessageBox">
<div
v-for="(item, index) in leftMessgaeData"
:key="index"
class="leftMessageItem"
:class="currentIndex == index ? 'activeLeftMessage' : ''"
@click="leftMessageClickEvent(item, index)"
>
<img
class="messageLeftIcon"
:src="item.appIcon"
v-if="item.appIcon"
/>
<img class="messageLeftIcon" src="../logo1.png" v-else />
<div class="messageLeftItemBox">
<div class="messageLeftContent">{{ item.name }}</div>
<div class="messageLeftCount" v-if="item.newMessageCount > 0">
{{ item.newMessageCount > 100 ? "99+" : item.newMessageCount }}
</div>
</div>
</div>
</div>
</div>
<div class="messageRight">
<div class="rightMessageTitle">审批消息</div>
<div v-if="isShowScroll" @click="scrollToFirstCard" class="scrollTopTip">
<i class="el-icon-d-arrow-left scrollTopIcon"></i>
{{ rightMessgaeData.newData.length }}条最新消息
</div>
<div
class="rigthMessageBox"
id="container"
ref="container"
@scroll="handleScroll"
>
<div
v-if="
rightMessgaeData.newData.length == 0 &&
rightMessgaeData.oldData.length == 0
"
class="rightEmpty"
>
<el-empty :image-size="200"></el-empty>
</div>
<div v-else>
<div
v-if="rightMessgaeData.oldData.length == oldTotal && oldTotal > 0"
style="padding: 10px 0"
ref="dividerNew"
>
<el-divider>没有更多了</el-divider>
</div>
<div
v-for="(oldItem, oldIndex) in rightMessgaeData.oldData"
:key="`oldIndex${oldIndex}`"
class="item"
ref="oldMessage"
>
<div class="itemAvatar">
<img
:src="currntAppImg"
v-if="currntAppImg"
/>
<img src="../logo1.png" v-else />
</div>
<div class="itemBox">
<div class="itemBoxTitle">
{{ oldItem.appName }}
</div>
<div class="box">
<div class="item-title">
<div v-html="oldItem.messageTitle" style="display: flex"></div>
<div>推送时间{{ oldItem.sendDatetime }}</div>
</div>
<div class="item-content">
<div v-html="oldItem.sendCount"></div>
</div>
</div>
</div>
</div>
<div
v-if="rightMessgaeData.newData.length > 0"
style="padding: 10px 0"
ref="dividerNew"
>
<el-divider>以下是最新消息</el-divider>
</div>
<div
v-for="(newItem, newIndex) in rightMessgaeData.newData"
:key="newIndex"
class="item"
ref="lastNewData"
>
<div class="itemAvatar">
<img
:src="currntAppImg"
v-if="currntAppImg"
/>
<img src="../logo1.png" v-else />
</div>
<div class="itemBox">
<div class="itemBoxTitle">{{ newItem.appName }}</div>
<div class="box">
<div class="item-title">
<div v-html="newItem.messageTitle" style="display: flex"></div>
<div>推送时间{{ newItem.sendDatetime }}</div>
</div>
<div class="item-content">
<div v-html="newItem.sendCount"></div>
</div>
<div class="item-btns">
<!-- <div v-for="(btnList,btnIndex) in JSON.parse(newItem.btns)">
{{111}}
</div> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getApiModuleApi } from "@/api/apiChunks/index.js";
import request from '@/utils/request'
export default {
data() {
return {
leftMessgaeData: [],
currentIndex: null,
rightMessgaeData: {
newData: [],
oldData: [],
},
pageModel: {
pageNum: 1,
pageSize: 10,
},
oldTotal: 0,
firstCardOffsetTop: null,
cardContainerScrollTop: null,
isShowScroll: false,
currentBottomScrollTo: null,
firstLoad: true,
currntAppImg:null
};
},
filters: {
timeDate(row) {
if (!row) {
return;
}
return row.replace("T", " ").slice(0, 19);
},
},
mounted() {
//
this.scrollToBottom();
this.GetMessageCount();
},
methods: {
//
scrollToFirstCard() {
this.$nextTick(() => {
this.isShowScroll = false;
const firstCard = this.$refs["lastNewData"][0];
const cardContainer = this.$refs.container;
const dividerNew = this.$refs.dividerNew;
if (firstCard && cardContainer) {
this.$refs.container.scrollTo(
0,
firstCard.offsetTop -
cardContainer.offsetTop -
dividerNew.offsetHeight -
100
); //
}
});
},
scrollToBottom() {
this.$nextTick(() => {
this.$refs.container.scrollTop = this.$refs.container.scrollHeight;
this.currentBottomScrollTo = this.$refs.container.scrollTop;
});
},
handleScroll() {
const container = this.$refs.container;
//
if (container.scrollTop === 0 && !this.firstLoad) {
if (this.pageModel.pageNum * this.pageModel.pageSize <= this.oldTotal) {
this.pageModel.pageNum++;
this.GetOldMessageList("page");
}
} else {
if (this.rightMessgaeData.newData.length > 5) {
let height = 0;
for (let i = 0; i < 5; i++) {
height += this.$refs["lastNewData"][i].offsetHeight;
}
if (container.scrollTop <= container.clientHeight) {
this.isShowScroll = false;
}
if (container.scrollTop <= this.currentBottomScrollTo - height) {
this.isShowScroll = false;
}
}
}
this.firstLoad = false;
},
async GetMessageCount() {
let that = this
const res = await getApiModuleApi(
{
tl: "sysWarningInterfaceService",
as: "",
dj: "queryWarningAppList",
},
{}
);
if (res.status == "200") {
this.leftMessgaeData = res.attribute ? res.attribute : [];
let count = 0;
res.attribute.forEach((item) => {
count += item.newMessageCount * 1;
that.$set(item, "appIcon", null);
if (item.appLogo) {
that.getLogoUrl(item.appLogo).then((res) => {
let imageUrl =
"data:image/png/jpg;base64," +
btoa(
new Uint8Array(res).reduce(
(data, byte) => data + String.fromCharCode(byte),
""
)
);
that.$set(item, "appIcon", imageUrl);
});
}
});
this.$store.commit("SET_MESSAGE_COUNT", count);
}
},
getLogoUrl(id) {
return request({
url:
"/kangarooDataCenterV3/entranceController/fileDownloadNew?id=" + id,
method: "get",
responseType: "arraybuffer",
}).then((res) => {
return res;
});
},
leftMessageClickEvent(item, index) {
this.currentIndex = index;
this.currentBillKindID = item.id;
this.currntAppImg = item.appIcon
this.rightMessgaeData.newData = [];
this.rightMessgaeData.oldData = [];
this.isShowScroll = false;
this.pageModel.pageNum = 1;
this.firstLoad = true;
this.scrollToBottom();
this.GetOldMessageList("", item);
},
async GetNewMessageList(item) {
let params = {
state: "0", //
appId: this.currentBillKindID,
};
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "queryEntity",
},
{
...params
}
);
if (res.status == "200") {
this.ReadMessage(item);
let data = res.attribute ? res.attribute : [];
//
data.sort(function (a, b) {
return new Date(a.sendDatetime) - new Date(b.sendDatetime);
});
if (data.length > 5) {
this.isShowScroll = true;
}
this.rightMessgaeData.newData = data;
this.scrollToBottom();
}
},
async ReadMessage(item) {
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "markRead",
},
{
appId: this.currentBillKindID, //id
state: "0", //
}
);
if (res.status == "200") {
this.$set(item, "newMessageCount", 0);
let count = 0;
this.leftMessgaeData.forEach((item) => {
count += item.newMessageCount * 1;
});
this.$store.commit("SET_MESSAGE_COUNT", count);
}
},
async GetOldMessageList(type, item) {
let params = {
...this.pageModel,
billKindID: this.currentBillKindID,
};
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "queryEntityPage",
},
{
...this.pageModel,
appId: this.currentBillKindID, //id
state: "1", //
}
);
if (res.status == "200") {
this.oldTotal = res.attribute.total;
let allData = JSON.parse(JSON.stringify(this.rightMessgaeData.oldData));
if (type == "page") {
//
allData.forEach((item) => {
delete item.MarkPosition;
});
//
if (allData.length > 1) {
allData[0].MarkPosition = true;
}
}
let data = res.attribute.list ? res.attribute.list : [];
allData.push(...data);
//
allData.sort(function (a, b) {
return new Date(a.sendDatetime) - new Date(b.sendDatetime);
});
this.rightMessgaeData.oldData = allData;
this.$nextTick(() => {
if (type == "page") {
let index = this.rightMessgaeData.oldData.findIndex(
(item) => item.MarkPosition
);
if (index >= 0) {
this.$refs.container.scrollTo(
0,
this.$refs["oldMessage"][index].offsetTop
); //
}
} else {
this.$nextTick(() => {
this.scrollToBottom();
this.GetNewMessageList(item);
});
}
});
}
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-divider__text {
color: #909399;
font-size: 12px;
}
.messageContainer {
height: 100vh !important;
display: flex;
}
/* 左侧应用消息样式 */
.messageLeft {
width: 278px;
height: 100%;
overflow-y: auto;
background: #fafafa;
padding: 15px;
.leftMessageTitle {
font-size: 18px;
font-weight: 500;
color: #333333;
text-align: left;
margin: 10px 0;
}
.leftMessageBox {
margin-top: 20px;
height: calc(100% - 75px);
.leftMessageItem {
display: flex;
align-items: center;
padding: 12px 10px;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #ebeced;
}
.messageLeftIcon {
width: 42px;
height: 42px;
border-radius: 10px;
}
.messageLeftItemBox {
width: calc(100% - 42px);
display: flex;
align-items: center;
justify-content: space-between;
.messageLeftContent {
margin-left: 8px;
font-size: 14px;
color: #333333;
font-weight: 400;
overflow: hidden;
/* 确保超出容器的内容被裁剪 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 超出部分显示省略号 */
}
.messageLeftCount {
background: #ff3b30;
border-radius: 40px;
font-size: 12px;
line-height: 16px;
color: #ffffff;
text-align: center;
border: 1px solid #ffffff;
width: 35px;
}
}
}
.activeLeftMessage {
background-color: #ebeced;
}
}
}
//
.messageRight {
width: calc(100% - 278px);
height: 100%;
overflow: hidden;
background: #ffffff;
position: relative;
.rightMessageTitle {
font-size: 18px;
font-weight: 500;
color: #333333;
text-align: left;
padding: 25px 15px 15px 15px;
border-bottom: 1px solid #f6f6f6;
position: fixed;
background: #ffffff;
width: 100%;
z-index: 1;
}
.rigthMessageBox {
padding: 0 15px;
margin-top: 70px;
height: calc(100% - 70px);
overflow: scroll;
.rightEmpty {
display: flex;
align-items: center;
justify-content: center;
height: 80%;
}
.item {
display: flex;
margin: 20px 0;
.itemAvatar {
width: 30px;
height: 30px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
img {
height: 100%;
width: 100%;
border-radius: 6px;
}
}
.itemBox {
margin-left: 15px;
.itemBoxTitle {
font-weight: 600;
font-size: 12px;
color: #333333;
line-height: 17px;
text-align: left;
font-style: normal;
margin-bottom: 10px;
}
.box {
width: 546px;
background: #f8f8f8;
border-radius: 12px;
padding: 10px;
margin-bottom: 10px;
.item-title {
font-weight: 600;
font-size: 12px;
font-style: normal;
display: flex;
justify-content: space-between;
padding: 10px 6px;
border-bottom: 1px solid #e8e8e8;
}
.item-title div:first-child {
width: calc(100% - 190px);
color: #333333;
text-align: left;
overflow: hidden;
/* 确保超出容器的内容被裁剪 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 超出部分显示省略号 */
::v-deep p {
overflow: hidden;
/* 确保超出容器的内容被裁剪 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 超出部分显示省略号 */
}
}
.item-title div:last-child {
width: 180px;
color: #1478f6;
text-align: right;
white-space: nowrap;
}
.item-content {
font-weight: 400;
font-size: 12px;
color: #333333;
line-height: 28px;
text-align: left;
font-style: normal;
padding: 10px 6px;
}
}
}
}
}
}
.scrollTopTip {
position: absolute;
top: 30%;
right: 5%;
cursor: pointer;
background: #fbfbfb;
border-radius: 19px;
padding: 3px 15px;
.scrollTopIcon {
transform: rotate(90deg);
}
}
</style>