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.
590 lines
19 KiB
590 lines
19 KiB
<template> |
|
<div class="system-edit-post-container"> |
|
<el-form size="default" label-width="80px"> |
|
<el-card shadow="hover" header="战令配置"> |
|
<template #header> |
|
战令配置 |
|
<el-button v-show="item.show === false" @click="item.show = true" class="button-caret" type="text"> |
|
<el-icon> |
|
<ele-CaretBottom /> |
|
</el-icon> |
|
</el-button> |
|
<el-button v-show="item.show === true" @click="item.show = false" class="button-caret" type="text"> |
|
<el-icon> |
|
<ele-CaretTop /> |
|
</el-icon> |
|
</el-button> |
|
</template> |
|
<div v-show="item.show"> |
|
<div class="flex-warp"> |
|
<el-form-item label="期数" prop="periodId"> |
|
<el-select class="m-2" placeholder="选择期数" filterable v-model="props.periodId" @change="onCheckPeriodId"> |
|
<el-option v-for="item in unique(battlePassConfig)" :key="item.PeriodId" :label="item.PeriodId + '期'" :value="item.PeriodId" /> |
|
</el-select> |
|
</el-form-item> |
|
<el-form-item label="时间" prop="beginTime"> |
|
<el-date-picker |
|
id="dateTime" |
|
type="daterange" |
|
size="default" |
|
v-model="props.times" |
|
placeholder="开始时间" |
|
format="YYYY-MM-DD" |
|
value-format="x" |
|
:disabled-date="disabledDate" |
|
/> |
|
</el-form-item> |
|
<el-tooltip :content="query.serverIds.length == 0 ? '勾选下表可✔选项,选择服务器以激活按钮' : '发布'" placement="top" effect="dark"> |
|
<el-button size="default" class="ml10" @click="onSubmit" :disabled="query.serverIds.length == 0"> |
|
<el-icon> |
|
<ele-Promotion /> |
|
</el-icon> |
|
发布 |
|
</el-button> |
|
</el-tooltip> |
|
</div> |
|
<el-divider /> |
|
<div class="flex-warp"> |
|
<el-form-item prop="periodId" label="显示期数"> |
|
<el-select size="default" placeholder="请选择显示期数" filterable v-model="query.periodId" @change="getProp"> |
|
<el-option label="全部" value="" /> |
|
<el-option v-for="item in unique()" :key="item.PeriodId" :label="item.PeriodId + '期'" :value="item.PeriodId" /> |
|
</el-select> |
|
</el-form-item> |
|
<el-form-item prop="showOnly" label="显示全服"> |
|
<el-switch v-model="query.showOnly" class="ml-2" inline-prompt active-text="是" inactive-text="否" @change="getProp" /> |
|
</el-form-item> |
|
</div> |
|
|
|
<div class="flex-warp"> |
|
<el-table ref="tableRef" :data="tableData.data" :span-method="objectSpanMethod" border @selection-change="handleSelectionChange"> |
|
<el-table-column prop="platform" label="平台" width="75"> |
|
<template #default="scope"> |
|
<div v-if="scope.row.sort == 0">其他</div> |
|
<div v-else-if="scope.row.sort == 1">ios</div> |
|
<div v-else-if="scope.row.sort == 2">官服</div> |
|
<div v-else-if="scope.row.sort == 3">渠道</div> |
|
<div v-else>其他</div> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="area" label="区服编号" width="95"> |
|
<template #default="scope"> {{ scope.row.area }}区</template> |
|
</el-table-column> |
|
<el-table-column prop="name" label="服务器名称" width="200"> |
|
<template #default="scope"> |
|
<el-button type="text" style="color: #5f6165" @click="openDialog(scope.row)">{{ scope.row.name }} </el-button> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="PeriodId" label="当前期数" width="95"> |
|
<template #default="scope"> |
|
<div v-if="scope.row.PeriodId">{{ scope.row.PeriodId }}期</div> |
|
<div v-else-if="ignoreSelectList.includes(scope.row.id) && query.periodId">{{ query.periodId }}期</div> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="State" label="状态" width="100"> |
|
<template #default="scope"> |
|
<div v-if="scope.row.State == 2" style="color: red">关闭</div> |
|
<div v-else-if="scope.row.State == 3">永久关闭</div> |
|
<div v-else-if="scope.row.BeginTime > Date.now() / 1000" style="color: #66b7cf">未开启</div> |
|
<div v-else-if="scope.row.State == 1" style="color: green">开启</div> |
|
<div v-else> |
|
{{ scope.row.State }} |
|
<div v-if="ignoreSelectList.includes(scope.row.id) && query.periodId">永久关闭</div> |
|
</div> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="BeginTimeStr" label="开始时间" width="200"> |
|
<template #default="scope"> |
|
<div v-if="!!listVisible && scope.row.id == tableData.edit.id && tableData.edit.BeginTime > Date.now()"> |
|
<el-date-picker |
|
style="width: 180px" |
|
type="date" |
|
size="default" |
|
v-model="tableData.edit.BeginTime" |
|
placeholder="开始时间" |
|
format="YYYY-MM-DD" |
|
value-format="x" |
|
:disabled-date="disabledDate" |
|
/> |
|
</div> |
|
<div v-else> |
|
{{ scope.row.BeginTimeStr }} |
|
</div> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="EndTimeStr" label="结束时间" width="200"> |
|
<template #default="scope"> |
|
<div v-if="!!listVisible && scope.row.id == tableData.edit.id"> |
|
<el-date-picker |
|
style="width: 180px" |
|
type="date" |
|
size="default" |
|
v-model="tableData.edit.EndTime" |
|
placeholder="开始时间" |
|
format="YYYY-MM-DD" |
|
value-format="x" |
|
:disabled-date="disabledDate" |
|
/> |
|
</div> |
|
<div v-else> |
|
{{ scope.row.EndTimeStr }} |
|
</div> |
|
</template> |
|
</el-table-column> |
|
<el-table-column type="selection" width="50" :selectable="selectable" /> |
|
<el-table-column prop="" label="开关" width="200"> |
|
<template #default="scope"> |
|
<div v-if="!!listVisible && scope.row.id == tableData.edit.id"> |
|
<el-button |
|
type="success" |
|
v-if="1 != tableData.edit.State" |
|
@click="onUpdate1({ State: 1, Id: scope.row.StringId, PeriodId: scope.row.PeriodId })" |
|
> |
|
开启 |
|
</el-button> |
|
<el-button |
|
type="danger" |
|
v-if="2 != tableData.edit.State" |
|
@click="onUpdate1({ State: 2, Id: scope.row.StringId, PeriodId: scope.row.PeriodId })" |
|
> |
|
关闭 |
|
</el-button> |
|
<el-button |
|
type="info" |
|
v-if="3 != tableData.edit.State" |
|
@click="onUpdate1({ State: 3, Id: scope.row.StringId, PeriodId: scope.row.PeriodId })" |
|
> |
|
永久关闭 |
|
</el-button> |
|
</div> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="" label="操作" width="200"> |
|
<template #default="scope"> |
|
<div v-if="!!listVisible && scope.row.id == tableData.edit.id"> |
|
<el-button type="primary" @click="onUpdate(1)">确认</el-button> |
|
<el-button @click="onClose(1)">取消</el-button> |
|
</div> |
|
<div v-else> |
|
<el-button size="small" class="ml10" @click="onEdit(scope.row)"> 修改</el-button> |
|
</div> |
|
</template> |
|
</el-table-column> |
|
</el-table> |
|
</div> |
|
</div> |
|
</el-card> |
|
</el-form> |
|
|
|
<EditConfig ref="listDicRef" @countList="getProp" /> |
|
</div> |
|
</template> |
|
<script lang="ts"> |
|
import { defineComponent, onMounted, reactive, ref, toRefs } from 'vue'; |
|
import { gameGMCheckPeriodIdBattlePass, gameGMGetBattlePass, gameGMInsertBattlePass, gameGMUpdateBattlePass } from '/@/api/game/gameConfig'; |
|
import BattlePassConfigCategory from '/@/api/config/BattlePassConfigCategory.json'; |
|
import BattlePassLvConfigCategory from '/@/api/config/BattlePassLvConfigCategory.json'; |
|
import BattlePassTaskConfigCategory from '/@/api/config/BattlePassTaskConfigCategory.json'; |
|
import { ElLoading, ElMessage } from 'element-plus'; |
|
import { uniquePeriodId, zeroFill } from '/@/utils/utils'; |
|
import { serverList } from '/@/utils/game'; |
|
import { showCountdownConfirm } from '/@/utils/countdownMsg'; |
|
import { BATTLE_PASS } from '/@/api/common/consts'; |
|
import EditConfig from '/@/views/serverBattlePass/update/component/listConfig.vue'; |
|
|
|
interface Props { |
|
id: string; |
|
periodId: string; |
|
beginTime: number; |
|
endTime: number; |
|
times: number[]; |
|
} |
|
|
|
interface TableDataState { |
|
props: Props; |
|
query: object; |
|
tableData: { data: object[]; list: object[]; edit: object }; |
|
battlePassList: object[]; |
|
ignoreSelectList: object[]; |
|
listVisible: boolean; |
|
check: boolean; |
|
lastDate: number; |
|
curDate: number; |
|
selectModel: string; |
|
battlePassConfig: object; |
|
servers: object; |
|
} |
|
|
|
interface SpanMethodProps { |
|
row: object; |
|
column: object; |
|
rowIndex: number; |
|
columnIndex: number; |
|
} |
|
|
|
export default defineComponent({ |
|
name: 'apiV1ServerBattlePass', |
|
components: { EditConfig }, |
|
setup: function () { |
|
const tableRef = ref(); |
|
const listDicRef = ref(); |
|
let date = new Date(); |
|
let getBeginTime = (date: number) => { |
|
return new Date(date + 24 * 60 * 60 * 1000).setHours(0, 0, 0); |
|
}; |
|
let getEndTime = (date: number) => { |
|
return new Date(date + 21 * 24 * 60 * 60 * 1000).setHours(0, 0, 0); |
|
}; |
|
const state = reactive<TableDataState>({ |
|
lastDate: 0, |
|
curDate: 0, |
|
check: false, |
|
item: { topShow: true, show: true, giftShow: true }, |
|
query: { |
|
serverIds: [], |
|
periodId: '', |
|
showOnly: true, |
|
}, |
|
props: { |
|
id: '', |
|
periodId: BattlePassConfigCategory[0].PeriodId, |
|
beginTime: getBeginTime(date.getTime()), |
|
endTime: getEndTime(date.getTime()), |
|
times: [getBeginTime(date.getTime()), getEndTime(date.getTime())], |
|
}, |
|
tableData: { data: [], list: [], edit: {} }, |
|
battlePassList: [], |
|
ignoreSelectList: [], |
|
battlePassConfig: BattlePassConfigCategory, |
|
listVisible: false, |
|
selectModel: '', |
|
servers: [], |
|
closeColor: BATTLE_PASS.Close, |
|
openColor: BATTLE_PASS.Open, |
|
unopenedColor: BATTLE_PASS.Unopened, |
|
permanentClosed: BATTLE_PASS.PermanentClosed, |
|
}); |
|
|
|
const onCheckPeriodId = () => { |
|
const loading = ElLoading.service({ |
|
lock: true, |
|
text: 'Loading', |
|
background: 'rgba(0, 0, 0, 0.7)', |
|
}); |
|
|
|
state.tableData.list = []; |
|
gameGMCheckPeriodIdBattlePass({ periodId: state.props.periodId }) |
|
.then((res) => { |
|
console.log('gameGMGetBattlePass: ', res); |
|
if (res.code != 0 || !res.data || !res.data.list) { |
|
return; |
|
} |
|
state.tableData.list = res.data.list; |
|
state.ignoreSelectList = state.tableData.list |
|
.filter((r) => r.PeriodId == state.props.periodId || (r.PeriodId > state.props.periodId && r.BeginTime < Date.now() / 1000)) |
|
.map((item) => item.Server); |
|
console.log('state.ignoreSelectList: ', state.ignoreSelectList); |
|
}) |
|
.finally(() => { |
|
loading.close(); |
|
}); |
|
}; |
|
const onSubmit = () => { |
|
console.log('state.props:', state.props); |
|
if (!state.props.times[0] || !state.props.times[1]) { |
|
ElMessage.error('有未配置完成的部分1,请检查!'); |
|
return; |
|
} |
|
|
|
let lvConfigs = BattlePassLvConfigCategory.filter((r) => r.PeriodId == state.props.periodId); |
|
if (lvConfigs.length === 0) { |
|
ElMessage.error('配置表【BattlePassLvConfig】,期数【' + state.props.periodId + '期】未配置奖励,请检查!'); |
|
return; |
|
} |
|
let taskConfigs = BattlePassTaskConfigCategory.filter((r) => r.PeriodId == state.props.periodId); |
|
if (taskConfigs.length === 0) { |
|
ElMessage.error('配置表【BattlePassTaskConfig】,期数【' + state.props.periodId + '期】未配置奖励,请检查!'); |
|
return; |
|
} |
|
|
|
const loading = ElLoading.service({ |
|
lock: true, |
|
text: 'Loading', |
|
background: 'rgba(0, 0, 0, 0.7)', |
|
}); |
|
state.tableData.total = state.query.serverIds.length; |
|
for (let i in state.query.serverIds) { |
|
let monthly = onState(); |
|
monthly.Server = state.query.serverIds[i]; |
|
console.log('monthly1:', monthly); |
|
insertData(loading, monthly); |
|
} |
|
}; |
|
const insertData = (loading, monthly) => { |
|
gameGMInsertBattlePass(monthly) |
|
.then(() => { |
|
ElMessage.success(monthly.Server + '区活动更新成功'); |
|
state.check = false; |
|
}) |
|
.finally(() => { |
|
loading.close(); |
|
state.tableData.total--; |
|
if (state.tableData.total == 0) { |
|
getProp(); |
|
} |
|
}); |
|
}; |
|
onMounted(() => { |
|
state.props.id = ''; |
|
state.rows = {}; |
|
serverList().then((res) => { |
|
state.servers = res; |
|
console.log('serverList:', res); |
|
getProp(); |
|
}); |
|
}); |
|
const onState = () => { |
|
let data = { |
|
BeginTime: Math.floor(state.props.times[0] / 1000), |
|
EndTime: Math.floor(state.props.times[1] / 1000), |
|
Server: '', |
|
State: 1, |
|
PeriodId: state.props.periodId, |
|
}; |
|
console.log('data: ', data); |
|
return data; |
|
}; |
|
const getProp = () => { |
|
const loading = ElLoading.service({ |
|
lock: true, |
|
text: 'Loading', |
|
background: 'rgba(0, 0, 0, 0.7)', |
|
}); |
|
state.tableData.data = []; |
|
gameGMGetBattlePass({ periodId: state.query.periodId }) |
|
.then((res) => { |
|
console.log('gameGMGetBattlePass: ', res); |
|
if (res.code != 0 || !res.data) { |
|
return; |
|
} |
|
onCheckPeriodId(); |
|
let now = new Date().getTime() / 1000; |
|
console.log('gameGMGetBattlePass: time ', now); |
|
if (!res.data.list) { |
|
res.data.list = []; |
|
} |
|
res.data.list.sort((a, b) => { |
|
return b.BeginTime - a.BeginTime; |
|
}); |
|
if (!state.query.periodId) { |
|
for (let i in state.servers) { |
|
let battle = res.data.list.filter((r) => r.Server == state.servers[i].id && r.BeginTime <= now); |
|
if (battle) { |
|
battle.sort((a, b) => { |
|
return b.PeriodId - a.PeriodId; |
|
}); |
|
} |
|
let data = { |
|
id: state.servers[i].id, |
|
name: state.servers[i].name, |
|
area: state.servers[i].area, |
|
sort: state.servers[i].sort, |
|
}; |
|
if (battle && battle.length > 0) { |
|
data.PeriodId = battle[0].PeriodId; |
|
data.BeginTimeStr = new Date(battle[0].BeginTime * 1000).toLocaleDateString(); |
|
data.BeginTime = battle[0].BeginTime; |
|
data.EndTimeStr = new Date(battle[0].EndTime * 1000).toLocaleDateString(); |
|
data.EndTime = battle[0].EndTime; |
|
data.StringId = battle[0].StringId; |
|
data.State = battle[0].State; |
|
data.Server = battle[0].Server; |
|
} else { |
|
if (!state.query.showOnly) continue; |
|
} |
|
state.tableData.data.push(data); |
|
} |
|
} else { |
|
for (let i in state.servers) { |
|
let battle = res.data.list.find((r) => r.Server == state.servers[i].id && r.PeriodId == state.query.periodId); |
|
let data = { |
|
id: state.servers[i].id, |
|
name: state.servers[i].name, |
|
area: state.servers[i].area, |
|
sort: state.servers[i].sort, |
|
}; |
|
if (battle) { |
|
data.PeriodId = battle.PeriodId; |
|
data.BeginTimeStr = new Date(battle.BeginTime * 1000).toLocaleDateString(); |
|
data.BeginTime = battle.BeginTime; |
|
data.EndTimeStr = new Date(battle.EndTime * 1000).toLocaleDateString(); |
|
data.EndTime = battle.EndTime; |
|
data.StringId = battle.StringId; |
|
data.State = battle.State; |
|
data.Server = battle.Server; |
|
} else { |
|
if (!state.query.showOnly) continue; |
|
} |
|
state.tableData.data.push(data); |
|
} |
|
} |
|
|
|
state.tableData.data.sort((a, b) => a.sort * 100000 + a.id - (b.sort * 100000 + b.id)); |
|
state.rows = {}; |
|
for (let i in state.tableData.data) { |
|
let server = state.tableData.data[i]; |
|
if (!state.rows[server.sort]) { |
|
state.rows[server.sort] = { num: 0, id: server.id }; |
|
} |
|
state.rows[server.sort].num++; |
|
if (state.rows[server.sort].id > server.id) { |
|
state.rows[server.sort].id = server.id; |
|
} |
|
} |
|
|
|
console.log('gameGMGetBattlePass: state.tableData.data', state.tableData.data); |
|
}) |
|
.finally(() => { |
|
loading.close(); |
|
}); |
|
}; |
|
|
|
const unique = () => { |
|
return uniquePeriodId(BattlePassConfigCategory); |
|
}; |
|
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => { |
|
if (columnIndex === 0) { |
|
if (state.rows[row.sort].id == row.id) { |
|
return { |
|
rowspan: state.rows[row.sort].num, |
|
colspan: 1, |
|
}; |
|
} else { |
|
return { |
|
rowspan: 0, |
|
colspan: 0, |
|
}; |
|
} |
|
} |
|
}; |
|
const handleSelectionChange = (selection: any[]) => { |
|
if (state.ignoreSelectList.length > 0) { |
|
selection.forEach((item) => { |
|
if (state.ignoreSelectList.includes(item.id)) { |
|
tableRef.value!.toggleRowSelection(item, false); |
|
} |
|
}); |
|
selection = tableRef.value!.getSelectionRows(); |
|
} |
|
state.query.serverIds = selection.map((item) => item.id); |
|
console.log(state.query.serverId, selection); |
|
}; |
|
const selectable = (row) => !state.ignoreSelectList.includes(row.id); |
|
const disabledDate = (time) => { |
|
return time.getTime() < Date.now(); |
|
}; |
|
const onUpdate = () => { |
|
let data = { |
|
Id: state.tableData.edit.StringId, |
|
PeriodId: state.tableData.edit.PeriodId, |
|
EndTime: Math.floor(state.tableData.edit.EndTime / 1000), |
|
}; |
|
if (state.tableData.edit.BeginTime > Date.now()) { |
|
data.BeginTime = Math.floor(state.tableData.edit.BeginTime / 1000); |
|
} |
|
|
|
showCountdownConfirm( |
|
`此操作将修改:服务器【${state.tableData.edit.name}】第【${state.tableData.edit.PeriodId}】期的时间为[${new Date( |
|
state.tableData.edit.BeginTime |
|
).toLocaleDateString()}]-[${new Date(state.tableData.edit.EndTime).toLocaleDateString()}],是否继续?`, |
|
'提示', |
|
'确认', |
|
'取消', |
|
5 |
|
) |
|
.then((res) => { |
|
if (res) { |
|
update(data); |
|
} |
|
}) |
|
.catch(() => { |
|
state.listVisible = false; |
|
}); |
|
}; |
|
const onUpdate1 = (data) => { |
|
let confirm = ''; |
|
if (data.State == 1) { |
|
confirm = `此操作将<span style="color: green">【开启】</span>第${data.PeriodId}期的战令,是否继续?`; |
|
} |
|
if (data.State == 2) { |
|
confirm = `此操作将<span style="color: red">【关闭】</span>第${data.PeriodId}期的战令,是否继续?`; |
|
} |
|
if (data.State == 3) { |
|
confirm = `此操作将<span style="color: grey">【永久关闭】</span>第${data.PeriodId}期的战令,是否继续?`; |
|
} |
|
showCountdownConfirm(confirm, '提示', '确认', '取消', 3).then((res) => { |
|
console.log('showCountdownConfirm: ', res); |
|
if (res) { |
|
update(data); |
|
} |
|
}); |
|
}; |
|
const update = (data) => { |
|
gameGMUpdateBattlePass(data).then((response) => { |
|
console.log(response); |
|
state.listVisible = false; |
|
getProp(); |
|
state.tableData.edit = {}; |
|
}); |
|
}; |
|
const onEdit = (row) => { |
|
if (!row.StringId) { |
|
ElMessage.error('未定义数据无法修改,请先发布!'); |
|
return; |
|
} |
|
if (row.State == 3) { |
|
ElMessage.error('永久关闭后无法修改!'); |
|
return; |
|
} |
|
state.tableData.edit = { ...row }; |
|
state.tableData.edit.changeState = 0; |
|
state.tableData.edit.EndTime = new Date(row.EndTimeStr + ' 00:00:00').getTime(); |
|
state.tableData.edit.BeginTime = new Date(row.BeginTimeStr + ' 00:00:00').getTime(); |
|
state.listVisible = true; |
|
}; |
|
const onClose = () => { |
|
state.listVisible = false; |
|
state.tableData.edit = {}; |
|
}; |
|
const openDialog = (row) => { |
|
listDicRef.value.openDialog(row.id); |
|
}; |
|
return { |
|
listDicRef, |
|
openDialog, |
|
onClose, |
|
onEdit, |
|
onUpdate1, |
|
onUpdate, |
|
disabledDate, |
|
onCheckPeriodId, |
|
tableRef, |
|
insertData, |
|
selectable, |
|
handleSelectionChange, |
|
objectSpanMethod, |
|
onSubmit, |
|
unique, |
|
getProp, |
|
zeroFill, |
|
...toRefs(state), |
|
}; |
|
}, |
|
}); |
|
</script> |
|
|
|
<style scoped lang="scss"> |
|
::v-deep .el-table .el-table__cell { |
|
padding: 5px; |
|
} |
|
</style>
|
|
|