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.
458 lines
14 KiB
458 lines
14 KiB
<template> |
|
<div class="game-maintenance-container"> |
|
<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"> |
|
<el-option v-for="item in serverCategorize" :key="item.value" :label="item.label" :value="item.value" /> |
|
</el-select> |
|
<el-select v-model="tableData.param.servers" class="m-2" placeholder="选择服务器" size="large" multiple collapse-tags clearable> |
|
<el-option v-for="item in switchServer()" :key="item.id" :label="item.name" :value="item.id" /> |
|
</el-select> |
|
</el-form-item> |
|
</el-form> |
|
<el-form label-width="90px"> |
|
<el-form-item label="类型:" style="max-width: 800px"> |
|
<el-radio-group v-model="tableData.param.popType" style="max-width: 800px"> |
|
<el-radio :label="1">普通弹窗</el-radio> |
|
<el-radio :label="2">强制退到登录</el-radio> |
|
<el-radio :label="3">强制退到公告</el-radio> |
|
<el-radio :label="4">滚动公告</el-radio> |
|
<el-radio :label="5">滚动公告删除</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> |
|
</el-form-item> |
|
<el-form-item label="公告内容:"> |
|
<el-input v-model="tableData.param.content" type="textarea" rows="14" @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> |
|
|
|
<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> |
|
<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="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 { ElMessageBox, ElMessage } from 'element-plus'; |
|
import { gameNoticePop, gameGMNoticeModelGet, gameGMNoticeModelAdd, gameGMNoticeModelDel } from '/@/api/game'; |
|
import { contentReplace, gSwitchServer } from '/@/utils/utils'; |
|
import { ServerCategorize, serverList } from '/@/utils/game'; |
|
|
|
interface TableDataState { |
|
unselsected: string[]; |
|
colorPicker: boolean; |
|
color: string; |
|
selected: string; |
|
urlLink: string; |
|
dbs: object[]; |
|
servers: object[]; |
|
model: number; |
|
editModel: object; |
|
tableData: { |
|
content: string; |
|
param: { |
|
servers: object; |
|
serverId: number; |
|
content: string; |
|
popType: number; |
|
popTo: number; |
|
uids: string; |
|
noticeId: number; |
|
}; |
|
}; |
|
editModelVisible: boolean; |
|
listModelVisible: boolean; |
|
contentVisible: boolean; |
|
serverSwitch: number; |
|
serverCategorize: object[]; |
|
} |
|
|
|
export default defineComponent({ |
|
name: 'apiV1GameNoticePop', |
|
setup() { |
|
const state = reactive<TableDataState>({ |
|
serverSwitch: 0, |
|
unselsected: ['', ''], |
|
colorPicker: false, |
|
editModelVisible: false, |
|
listModelVisible: false, |
|
contentVisible: false, |
|
color: '#000000', |
|
selected: '替换显示内容', |
|
urlLink: '', |
|
tableData: { |
|
content: '', |
|
param: { |
|
servers: [], |
|
serverId: '', |
|
content: '', |
|
uids: '', |
|
popType: 0, |
|
popTo: 1, |
|
noticeId: 0, |
|
}, |
|
}, |
|
dbs: [], |
|
servers: [], |
|
model: '', |
|
editModel: {}, |
|
serverCategorize: ServerCategorize, |
|
}); |
|
const noticePop = () => { |
|
for (let i in state.tableData.param.servers) { |
|
let data = { |
|
serverId: state.tableData.param.servers[i], |
|
content: state.tableData.param.content, |
|
uids: state.tableData.param.uids, |
|
popType: state.tableData.param.popType, |
|
popTo: state.tableData.param.popTo, |
|
noticeId: state.tableData.param.noticeId, |
|
}; |
|
console.log('Notice: ', data); |
|
gameNoticePop(data).then(() => { |
|
ElMessage.success(data.serverId + '发送成功'); |
|
}).finally(() => { |
|
// state.loading = false; |
|
}); |
|
} |
|
}; |
|
onMounted(() => { |
|
serverList().then((value) => { |
|
state.servers = value; |
|
// console.log(" server : ", state.servers); |
|
}); |
|
getModel(); |
|
}); |
|
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 { |
|
switchServer, |
|
showContent, |
|
noticePop, |
|
inputSelect, |
|
inputBig, |
|
inputItalic, |
|
inputUnderline, |
|
inputLink, |
|
inputColor, |
|
buttonColor, |
|
getModel, |
|
useModel, |
|
makeModel, |
|
setModel, |
|
saveModel, |
|
handleClose, |
|
...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--inline .el-form-item { |
|
display: -moz-flex; |
|
vertical-align: middle; |
|
margin-right: 32px; |
|
} |
|
</style>
|
|
|