桃源记客服系统前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

691 lines
21 KiB

<template>
<div class="game-maintenance-container">
<el-card shadow="hover" header="登录公告">
<div class="game-order-search mb15">
<el-form label-width="70px" label-position="right">
<el-form-item label="渠道" prop="channel">
<el-select v-model="tableData.param.channels" multiple collapse-tags class="m-2" placeholder="选择渠道" clearable>
<el-option v-for="item in channels" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-form-item style="margin-left: 20px">
<el-button type="primary" @click="getAllChannel" style="margin-left: 20px">所有渠道</el-button>
</el-form-item>
</el-form-item>
<el-form-item label="发送时间" prop="time">
<el-radio-group v-model="tableData.param.send">
<el-radio :label="1">立即</el-radio>
<el-radio :label="2">定时</el-radio>
</el-radio-group>
<el-form-item prop="now" v-if="tableData.param.send == 2" style="margin-left: 20px">
<el-date-picker
type="datetime"
v-model="tableData.param.sendTime"
placeholder="发送时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="x"
/>
</el-form-item>
<el-form-item style="margin-left: 20px">
<el-button type="primary" @click="noticeLog" style="margin-left: 20px">待发送公告</el-button>
</el-form-item>
</el-form-item>
<el-form-item label="公告模板" prop="model">
<el-select v-model="model" @change="useModel(1)" placeholder="请选择模板">
<el-option v-for="item in dbs" :key="item.id" :label="item.title" :value="item.id"></el-option>
</el-select>
<el-button type="primary" @click="makeModel(1)" style="margin-left: 20px">编辑模板</el-button>
</el-form-item>
<el-form-item>
<el-button size="small" @click="inputBig" style="margin-bottom: -15px">
<span style="font-weight: bold">B</span>
</el-button>
<el-button size="small" @click="inputItalic" style="margin-bottom: -15px">
<span style="font-style: italic">I</span>
</el-button>
<el-button size="small" @click="inputUnderline" style="margin-bottom: -15px">
<span style="text-decoration: underline">U</span>
</el-button>
<el-button size="small" @click="inputLink" style="margin-bottom: -15px; padding: 0; padding-left: 5px">
<el-icon type="text">
<ele-Link />
</el-icon>
</el-button>
<el-button size="small" class="color-picker font-color-picker" style="margin-bottom: -15px; padding: 0">
<el-color-picker size="default" v-model="color" @change="inputColor"></el-color-picker>
</el-button>
<el-form-item style="margin-bottom: -15px; margin-left: 20px">
<el-button type="primary" @click="showContent" style="margin-left: 20px">内容预览</el-button>
</el-form-item>
</el-form-item>
<el-form-item label="公告内容">
<el-input v-model="tableData.param.content" type="textarea" rows="16" @mouseup="inputSelect" @blur="inputSelect" clearable />
</el-form-item>
<el-form-item>
<el-button size="large" type="primary" class="ml10" @click="noticeLogin"> 登录公告发送</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
<el-dialog v-model="listModelVisible" :before-close="handleClose" :close-on-click-modal="false" center>
<div class="my-header">
<el-button type="" @click="saveModel(2)">保存</el-button>
<el-button type="primary" @click="setModel(1)">添加</el-button>
</div>
<el-table :data="dbs" :inline="true" :cell-style="{ padding: '0' }">
<el-table-column>
<template #default="scope">
<div class="flex-warp">
{{ scope.row.title }}
</div>
</template>
</el-table-column>
<el-table-column width="150">
<template #default="scope">
<el-button size="small" type="danger" @click="setModel(3, scope.row.id)" inline="true">删</el-button>
<el-button size="small" type="primary" @click="setModel(2, scope.row.id)" inline="true">改</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<el-dialog v-model="editModelVisible" :close-on-click-modal="false" center>
<el-form label-width="90px">
<el-form-item label="模板名称" prop="title">
<el-input v-model="editModel.title" placeholder="请输入模板名称" />
</el-form-item>
<el-form-item label="模板内容" prop="content">
<el-input v-model="editModel.content" type="textarea" placeholder="请输入内容" rows="25" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="saveModel(1)"> 保存</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="listCronVisible" :close-on-click-modal="false" title="待发送公告列表" center>
<el-table :data="tableData.crons" :inline="true" :cell-style="{ padding: '0' }" stripe>
<el-table-column label="公告类型" width="100">
<template #default="scope">
<div class="flex-warp">
{{ noticeTypes.find((r) => r.Id == scope.row.noticeType).Name }}
</div>
</template>
</el-table-column>
<el-table-column label="公告内容" show-overflow-tooltip>
<template #default="scope">
<div class="flex-warp">
<span @click="alertContent(scope.row.content)">{{ scope.row.content }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="待发送时间" width="200">
<template #default="scope">
<div class="flex-warp">
{{ getDate(scope.row.sendTime) }}
</div>
</template>
</el-table-column>
<el-table-column width="150">
<template #default="scope">
<el-button size="small" type="primary" @click="setCron(1, scope.row.id)" inline="true">修改</el-button>
<el-button size="small" type="danger" @click="setCron(2, scope.row.id)" inline="true">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<el-dialog v-model="editCronVisible" :close-on-click-modal="false" center>
<el-form label-width="90px">
<el-form-item label="发送时间" prop="time">
<el-radio-group v-model="cron.send">
<el-radio :label="1">立即</el-radio>
<el-radio :label="2">定时</el-radio>
</el-radio-group>
<el-form-item prop="now" v-if="cron.send == 2" style="margin-left: 20px">
<el-date-picker type="datetime" v-model="cron.sendTime" placeholder="发送时间" format="YYYY-MM-DD HH:mm:ss" value-format="x" />
</el-form-item>
</el-form-item>
<el-form-item label="公告模板" prop="model">
<el-select v-model="model" @change="useModel(2)" placeholder="请选择模板">
<el-option v-for="item in dbs" :key="item.id" :label="item.title" :value="item.id"></el-option>
</el-select>
<el-button type="primary" @click="makeModel(1)" style="margin-left: 20px">编辑模板</el-button>
</el-form-item>
<el-form-item>
<el-button size="small" @click="inputBig(2)" style="margin-bottom: -15px">
<span style="font-weight: bold">B</span>
</el-button>
<el-button size="small" @click="inputItalic(2)" style="margin-bottom: -15px">
<span style="font-style: italic">I</span>
</el-button>
<el-button size="small" @click="inputUnderline(2)" style="margin-bottom: -15px">
<span style="text-decoration: underline">U</span>
</el-button>
<el-button size="small" @click="inputLink(2)" style="margin-bottom: -15px; padding: 0; padding-left: 5px">
<el-icon type="text">
<ele-Link />
</el-icon>
</el-button>
<el-button size="small" class="color-picker font-color-picker" style="margin-bottom: -15px; padding: 0">
<el-color-picker size="default" v-model="color" @change="inputColor(2)"></el-color-picker>
</el-button>
</el-form-item>
<el-form-item label="公告内容">
<el-input v-model="cron.content" type="textarea" rows="14" @mouseup="inputSelect" @blur="inputSelect" clearable />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="saveCron"> 保存修改</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="contentVisible" :close-on-click-modal="false" center>
<p v-html="tableData.content"></p>
</el-dialog>
</div>
</template>
<script lang="ts">
import { toRefs, reactive, onMounted, defineComponent } from 'vue';
import {
gameGetNotice,
gameGMNoticeModelAdd,
gameGMNoticeModelDel,
gameGMNoticeModelGet,
gameNotice,
gameGMNoticeGetCron,
gameNoticeDel,
} from '/@/api/game';
import { ElMessage, ElMessageBox } from 'element-plus/es';
import { allChannelList } from '/@/utils/game';
import { contentReplace, zeroFill } from '/@/utils/utils';
import { Notice_Type } from '/@/api/common/consts';
interface Data {
title: string;
send: number;
sendTime: number;
channels: string[];
channel: string;
content: string;
noticeType: number;
id: number;
noticeId: number;
}
interface TableDataState {
unselsected: string[];
colorPicker: boolean;
color: string;
selected: string;
urlLink: string;
dbs: Array<Data>;
model: number;
editModel: Data;
tableData: {
content: string;
crons: Array<Data>;
param: Data;
};
editModelVisible: boolean;
listModelVisible: boolean;
listCronVisible: boolean;
editCronVisible: boolean;
contentVisible: boolean;
cron: Data;
channels: object;
noticeTypes: object[];
}
export default defineComponent({
name: 'apiV1GameNoticeLogin',
setup() {
// const {proxy} = getCurrentInstance() as any;
const state = reactive<TableDataState>({
unselsected: ['', ''],
colorPicker: false,
editModelVisible: false,
listModelVisible: false,
listCronVisible: false,
editCronVisible: false,
contentVisible: false,
cron: {
title: '',
send: 1,
sendTime: Date.now(),
content: '',
noticeType: 2,
channel: '',
channels: [],
id: 0,
noticeId: 0,
},
color: '#000000',
selected: '替换显示内容',
urlLink: '',
tableData: {
content: '',
crons: [],
param: {
title: '',
send: 1,
sendTime: Date.now(),
content: '',
noticeType: 2,
channels: [],
channel: '',
id: 0,
noticeId: 0,
},
},
dbs: [],
model: '',
editModel: {},
channels: [],
noticeTypes: Notice_Type,
});
const noticeLogin = () => {
if (state.tableData.param.send == 1) {
state.tableData.param.sendTime = 0;
}
console.log('Notice: ', state.tableData.param);
for (let i in state.tableData.param.channels) {
sendNotice(state.tableData.param.channels[i]);
}
};
const sendNotice = (channel: string) => {
let data = {
title: state.tableData.param.title,
send: state.tableData.param.send,
sendTime: state.tableData.param.sendTime,
content: state.tableData.param.content,
noticeType: state.tableData.param.noticeType,
channel: channel,
id: state.tableData.param.id,
noticeId: state.tableData.param.noticeId,
};
gameNotice(data)
.then(() => {
ElMessage.success(state.channels.find((r) => r.value == channel).label + '发送成功');
})
.finally(() => {
// state.loading = false;
});
};
const saveCron = () => {
if (state.cron.send == 1) {
state.cron.sendTime = 0;
}
console.log('Notice: ', state.cron);
gameNotice(state.cron)
.then(() => {
ElMessage.success('发送成功');
})
.finally(() => {
// state.loading = false;
});
};
const noticeLog = () => {
gameGMNoticeGetCron({})
.then((res) => {
console.log('Notice: ', res);
state.tableData.crons = res.data.noticeLogs;
state.listCronVisible = true;
})
.finally(() => {
// state.loading = false;
});
};
// 初始化表格数据
const initTableData = () => {
getNotice();
};
const getNotice = () => {
gameGetNotice(state.tableData.param).then((res: any) => {
state.tableData.param.content = res.data.content;
state.tableData.param.noticeId = res.data.id;
});
};
// 页面加载时
onMounted(() => {
allChannelList().then((res) => {
state.channels = res;
});
initTableData();
getModel();
console.log('onMounted', document.getElementsByClassName('w-e-droplist'));
if (document.getElementsByClassName('w-e-droplist')[0]) {
document.getElementsByClassName('w-e-droplist')[0].style['width'] = '260px';
}
});
var getDate = (time: string) => {
let date = new Date(time);
return (
date.getFullYear() +
'-' +
zeroFill(date.getMonth() + 1) +
'-' +
zeroFill(date.getDate()) +
' ' +
zeroFill(date.getHours()) +
':' +
zeroFill(date.getMinutes()) +
':' +
zeroFill(date.getSeconds())
);
};
var inputSelect = (res: any) => {
console.log(res, res.target.selectionStart, res.target.selectionEnd);
let selectionStart = res.target.selectionStart;
let selectionEnd = res.target.selectionEnd;
state.unselsected = [res.target.value.slice(0, selectionStart), res.target.value.slice(selectionEnd)];
if (selectionStart == selectionEnd) {
// console.log("same");
state.selected = '替换显示内容';
return;
}
state.selected = res.target.value.slice(selectionStart, selectionEnd);
console.log(state.selected);
};
var changeContent = (type: number) => {
switch (type) {
case 2:
state.cron.content = state.unselsected[0] + state.selected + state.unselsected[1];
break;
default:
state.tableData.param.content = state.unselsected[0] + state.selected + state.unselsected[1];
break;
}
};
var inputBig = (type: number) => {
if (state.unselsected[1].indexOf('[/b]') == 0) {
return;
}
if (state.selected.indexOf('[b]') > -1) {
state.selected = state.selected.replace(/\[b]|\[\/b]/gi, '');
changeContent(type);
return;
}
state.selected = '[b]' + state.selected + '[/b]';
changeContent(type);
// console.log(state.unselsected, state.selected.indexOf("[b]"), state.selected, state.tableData.param.content);
};
var inputItalic = (type: number) => {
if (state.unselsected[1].indexOf('[/i]') == 0) {
return;
}
if (state.selected.indexOf('[i]') > -1 || (state.unselsected[1].indexOf('[i]') == 0 && state.unselsected[1].indexOf('[/i]') > -1)) {
state.selected = state.selected.replace(/\[i]|\[\/i]/gi, '');
changeContent(type);
return;
}
state.selected = '[i]' + state.selected + '[/i]';
changeContent(type);
// console.log(state.unselsected, state.selected, state.tableData.param.content);
};
var inputUnderline = (type: number) => {
if (state.unselsected[1].indexOf('[/u]') == 0) {
return;
}
if (state.selected.indexOf('[u]') > -1) {
state.selected = state.selected.replace(/\[u]|\[\/u]/gi, '');
changeContent(type);
return;
}
state.selected = '[u]' + state.selected + '[/u]';
changeContent(type);
// console.log(state.unselsected, state.selected, state.tableData.param.content);
};
var inputLink = (type: number) => {
if (state.selected.indexOf('[/url]') > -1) {
state.selected = state.selected.replace(/\[url=.*?]|\[\/url]/gi, '');
changeContent(type);
return;
}
ElMessageBox.prompt('请输入Url', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
// inputPattern:
// /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
inputErrorMessage: 'Invalid http request',
}).then(({ value }) => {
state.urlLink = value;
if (state.unselsected[1].indexOf('[/url]') == 0) {
return;
}
state.selected = '[url=' + state.urlLink + ']' + state.selected + '[/url]';
changeContent(type);
state.urlLink = '';
// console.log(state.unselsected, state.selected, state.tableData.param.content);
});
};
var buttonColor = (type: number) => {};
var inputColor = (type: number) => {
if (!state.color) {
if (state.selected.indexOf('[/color]') > -1) {
state.selected = state.selected.replace(/\[color=#.+?]|\[\/color]/gi, '');
changeContent(type);
return;
}
return;
}
if (state.unselsected[1].indexOf('[/color]') == 0) {
return;
}
if (state.selected.indexOf('[/color]') > -1) {
state.selected = state.selected.replace(/\[color=#.+?]|\[\/color]/gi, '');
// changeContent();
// return;
}
state.selected = '[color=' + state.color + ']' + state.selected + '[/color]';
changeContent(type);
// console.log(state.unselsected, state.selected, state.tableData.param.content);
};
// 模板
const getModel = () => {
gameGMNoticeModelGet({ noticeType: 2 }).then((res) => {
if (res.data.noticeModel) {
state.dbs = res.data.noticeModel;
}
console.log(res, state.dbs);
});
};
const useModel = (id: number) => {
switch (id) {
case 1:
let model = state.dbs.find((r) => r.id == state.model);
if (model) {
state.tableData.param.content = model.content;
}
break;
case 2:
let model1 = state.dbs.find((r) => r.id == state.model);
if (model1) {
state.cron.content = model1.content;
}
break;
}
};
const makeModel = () => {
state.listModelVisible = true;
console.log(state);
};
const setModel = (type: number, id: number) => {
switch (type) {
case 1:
state.editModel = {};
state.editModelVisible = true;
break;
case 2:
state.editModel = state.dbs.find((model) => model.id == id);
if (!state.editModel) {
return;
}
state.editModelVisible = true;
break;
case 3:
gameGMNoticeModelDel({
id: id,
})
.then(function () {
getModel();
})
.finally(function () {});
break;
}
};
const saveModel = (type: number) => {
console.log(type, state.editModel);
switch (type) {
case 1:
gameGMNoticeModelAdd({
title: state.editModel.title,
content: state.editModel.content,
noticeType: 2,
id: state.editModel.id,
})
.then(function () {
getModel();
})
.finally(function () {
state.editModelVisible = false;
});
break;
case 2:
state.listModelVisible = false;
break;
}
};
const handleClose = (done: () => void) => {
// ElMessageBox.confirm('确定退出编辑模板页面?').then(() => {
done();
// }).catch(() => {
// // catch error
// })
};
const setCron = (type: number, id: number) => {
switch (type) {
case 1: // 修改
state.cron = state.tableData.crons.find((r) => r.id == id);
console.log(state.cron);
state.editCronVisible = true;
break;
case 2: // 删除
ElMessageBox.confirm('是否确认删除本条待发送公告?,点击确认后删除本条待发送公告。').then(() => {
gameNoticeDel({ id: id })
.then(() => {
ElMessage.success('删除成功');
noticeLog();
})
.finally(() => {
// state.loading = false;
});
});
break;
}
};
const alertContent = (val) => {
console.log(`current page: ${val}`);
ElMessageBox.alert(val, '', { confirmButtonText: 'OK' });
};
const showContent = () => {
state.contentVisible = true;
state.tableData.content = contentReplace(state.tableData.param.content);
console.log(state.tableData.content);
};
const getAllChannel = () => {
state.tableData.param.channels = [];
for (let i in state.channels) {
if (state.channels[i].value == '') {
continue;
}
state.tableData.param.channels.push(state.channels[i].value);
}
};
return {
getAllChannel,
showContent,
getNotice,
noticeLog,
noticeLogin,
inputSelect,
inputBig,
inputItalic,
inputUnderline,
inputLink,
inputColor,
buttonColor,
getModel,
useModel,
makeModel,
setModel,
saveModel,
handleClose,
setCron,
getDate,
alertContent,
saveCron,
...toRefs(state),
};
},
});
</script>
<style scoped lang="scss" src="../../../theme/add.scss"></style>
<style scoped lang="scss">
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
}
.tree-border {
margin-top: 5px;
border: 1px solid #e5e6e7 !important;
background: #fff none !important;
border-radius: 4px;
}
.system-edit-post-container {
.menu-data-tree {
border: var(--el-input-border, var(--el-border-base));
border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
padding: 5px;
}
}
.el-form-item {
display: -moz-flex;
vertical-align: middle;
margin-right: 32px;
}
::v-deep .el-table .cell {
height: 25px;
}
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td {
background: #ffffd5;
}
::v-deep .el-table .el-table--enable-row-hover .el-table__body tr:hover > td {
background: inherit;
}
::v-deep(.el-form-item--large .el-form-item__content) {
line-height: 20px;
}
::v-deep(.el-form-item__content) {
line-height: 20px;
}
::v-deep .w-e-droplist {
width: 260px !important;
}
</style>