桃源记客服系统前端
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.

450 lines
15 KiB

<template>
<div class="game-maintenance-container">
4 months ago
<el-card shadow="hover" header="弹窗公告">
<el-form label-width="90px">
<el-form-item label="服务器:" prop="serverId">
<el-select v-model="serverSwitch" class="m-2" placeholder="选择服务器" size="large" style="width: 80px">
3 months ago
<el-option v-for="item in serverCategorize" :key="item.value" :label="item.label" :value="item.value"/>
4 months ago
</el-select>
<el-select v-model="tableData.param.serverId" class="m-2" placeholder="选择服务器" size="large" filterable>
3 months ago
<el-option v-for="item in switchServer()" :key="item.id" :label="item.name" :value="item.id"/>
4 months ago
</el-select>
</el-form-item>
</el-form>
<el-form label-width="90px">
<el-form-item label="类型:" style="width: 25%">
<el-radio-group v-model="tableData.param.popType">
<el-radio :label=1>普通弹窗</el-radio>
<el-radio :label=2>强制退到登录</el-radio>
<el-radio :label=3>强制退到公告</el-radio>
<el-radio :label=6>滚动公告</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<el-form label-width="90px" :inline="true">
<el-form-item label="发送对象:" style="width: 25%">
<el-radio-group v-model="tableData.param.popTo">
<el-radio :label=1>全部玩家</el-radio>
<el-radio :label=2>部分玩家</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item style="width: 50%">
<el-tooltip content="uid之间用分号(;)隔开">
<el-input v-show="tableData.param.popTo==2" v-model="tableData.param.uids" placeholder="玩家uid"
clearable/>
</el-tooltip>
</el-form-item>
</el-form>
<el-form label-width="90px">
<el-form-item>
<el-select v-model="model" @change="useModel(1)" placeholder="请选择模板" popper-class="custom-header">
<el-option v-for="item in dbs" :key="item.id" :label="item.title" :value="item.id">
{{ item.title }}
</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>
4 months ago
</el-form-item>
<el-form-item label="公告内容:">
<el-input v-model="tableData.param.content" type="textarea" rows="18" @mouseup="inputSelect"
@blur="inputSelect" clearable/>
</el-form-item>
<el-form-item>
<el-button size="large" type="primary" @click="noticePop">
弹窗公告发送
</el-button>
</el-form-item>
</el-form>
</el-card>
4 months ago
<el-dialog v-model="listModelVisible" :close-on-click-modal="false" :before-close="handleClose" center>
<div class="my-header">
<el-button type="" @click="saveModel(2)">保存</el-button>
<el-button type="primary" @click="setModel(1)">添加</el-button>
</div>
4 months ago
<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>
4 months ago
<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>
4 months ago
<el-dialog v-model="contentVisible" :close-on-click-modal="false" center>
<p v-html="tableData.content"></p>
</el-dialog>
</div>
</template>
<script lang="ts">
4 months ago
import {toRefs, reactive, onMounted, defineComponent,} from 'vue';
import {ElMessageBox, ElMessage} from 'element-plus';
import {gameNoticePop, gameGMNoticeModelGet, gameGMNoticeModelAdd, gameGMNoticeModelDel} from "/@/api/game";
import {contentReplace, gSwitchServer} from "/@/utils/utils";
3 months ago
import {ServerCategorize, serverList} from "/@/utils/game";
interface TableDataState {
4 months ago
unselsected: string[]
colorPicker: boolean
color: string
selected: string
urlLink: string
dbs: object[]
servers: object[]
model: number
editModel: object
tableData: {
4 months ago
content: string,
param: {
4 months ago
serverId: number
content: string
popType: number
popTo: number
uids: string
noticeId: number
};
};
4 months ago
editModelVisible: boolean,
listModelVisible: boolean,
contentVisible: boolean,
serverSwitch: number,
3 months ago
serverCategorize: object[],
}
export default defineComponent({
4 months ago
name: 'apiV1GameNoticePop',
setup() {
const state = reactive<TableDataState>({
4 months ago
serverSwitch: 0,
unselsected: ["", ""],
colorPicker: false,
editModelVisible: false,
listModelVisible: false,
contentVisible: false,
color: "#000000",
selected: "替换显示内容",
urlLink: "",
tableData: {
4 months ago
content: "",
param: {
4 months ago
serverId: "",
content: "",
4 months ago
uids: "",
popType: 0,
popTo: 1,
noticeId: 0
},
4 months ago
},
dbs: [],
servers: [],
model: "",
editModel: {},
3 months ago
serverCategorize: ServerCategorize,
});
4 months ago
const noticePop = () => {
console.log("Notice: ", state.tableData.param);
gameNoticePop(state.tableData.param).then(() => {
ElMessage.success('发送成功');
4 months ago
}).finally(() => {
// state.loading = false;
})
4 months ago
};
onMounted(() => {
4 months ago
serverList().then(value => {
state.servers = value;
// console.log(" server : ", state.servers);
});
getModel();
});
4 months ago
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 = [state.tableData.param.content.slice(0, selectionStart), state.tableData.param.content.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 = () => {
state.tableData.param.content = state.unselsected[0] + state.selected + state.unselsected[1];
};
var inputBig = () => {
if (state.unselsected[1].indexOf("[/b]") == 0) {
return
}
if (state.selected.indexOf("[b]") > -1) {
state.selected = state.selected.replace(/\[b]|\[\/b]/gi, "");
changeContent();
return;
}
state.selected = "[b]" + state.selected + "[/b]";
changeContent();
console.log(state.unselsected, state.selected.indexOf("[b]"), state.selected, state.tableData.param.content);
};
var inputItalic = () => {
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();
return;
}
state.selected = "[i]" + state.selected + "[/i]";
changeContent();
console.log(state.unselsected, state.selected, state.tableData.param.content);
};
var inputUnderline = () => {
if (state.unselsected[1].indexOf("[/u]") == 0) {
return
}
if (state.selected.indexOf("[u]") > -1) {
state.selected = state.selected.replace(/\[u]|\[\/u]/gi, "");
changeContent();
return;
}
state.selected = "[u]" + state.selected + "[/u]";
changeContent();
console.log(state.unselsected, state.selected, state.tableData.param.content);
};
var inputLink = () => {
if (state.selected.indexOf("[/url]") > -1) {
state.selected = state.selected.replace(/\[url=.*?]|\[\/url]/gi, "");
changeContent();
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();
state.urlLink = '';
console.log(state.unselsected, state.selected, state.tableData.param.content);
});
};
var buttonColor = () => {
// if(state.selected.indexOf("[/color]") > -1){
// state.selected = state.selected.replace(/\[color=#.+?]|\[\/color]/gi, "");
// changeContent();
// }
};
var inputColor = () => {
if (!state.color || state.color == "#000000") {
if (state.selected.indexOf("[/color]") > -1) {
state.selected = state.selected.replace(/\[color=#.+?]|\[\/color]/gi, "");
changeContent();
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();
console.log(state.unselsected, state.selected, state.tableData.param.content);
};
// 模板
const getModel = () => {
gameGMNoticeModelGet({noticeType: 1}).then((res) => {
console.log(res);
if (res.data.noticeModel) {
state.dbs = res.data.noticeModel;
}
})
};
const useModel = () => {
let model = state.dbs.find(r => r.id == state.model);
if (model) {
state.tableData.param.content = model.content;
}
};
const makeModel = () => {
state.listModelVisible = true;
console.log(state);
};
const setModel = (type: number, id: number) => {
switch (type) {
case 1:
state.editModelVisible = true;
break;
case 2:
state.editModel = state.dbs.find(model => model.id == id);
state.editModelVisible = true;
break;
case 3:
// state.dbs = state.dbs.filter(model => model.id != id);
// for (let i = 0; i < state.dbs.length; i++) {
// let model = state.dbs[i];
// if (model) {
// model.id = i + 1;
// }
// }
gameGMNoticeModelDel({
id: id,
}).then(function () {
getModel()
}).finally(function () {
});
break;
}
};
const saveModel = (type: number) => {
console.log(type, state.editModel);
switch (type) {
case 1:
gameGMNoticeModelAdd({
id: state.editModel.id,
title: state.editModel.title,
content: state.editModel.content,
noticeType: 1
}).then(function () {
getModel()
}).finally(function () {
state.editModelVisible = false;
});
break;
case 2:
state.listModelVisible = false;
// gameUpdateModel({model: JSON.stringify(state.models)}).then(function(){
// }).finally(function(){
// state.listModelVisible = false;
// });
break;
}
};
const handleClose = (done: () => void) => {
// ElMessageBox.confirm('确定退出编辑模板页面?').then(() => {
done()
// }).catch(() => {
// // catch error
// })
};
const showContent = () => {
state.contentVisible = true;
state.tableData.content = contentReplace(state.tableData.param.content);
console.log(state.tableData.content)
};
const switchServer = () => {
return gSwitchServer(state.serverSwitch, state.servers)
};
return {
4 months ago
switchServer,
showContent,
noticePop,
4 months ago
inputSelect,
inputBig,
inputItalic,
inputUnderline,
inputLink,
inputColor,
buttonColor,
getModel,
useModel,
makeModel,
setModel,
saveModel,
handleClose,
...toRefs(state),
};
},
});
</script>
4 months ago
<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--inline .el-form-item {
display: -moz-flex;
vertical-align: middle;
margin-right: 32px;
}
</style>