|
@@ -1,4 +1,4 @@
|
|
|
-<template>
|
|
|
|
|
|
|
+<template id="asdfasdf">
|
|
|
<!-- <div class="h-full overflow-auto p-4 rounded-lg bg-white dark:bg-neutral-800"> -->
|
|
<!-- <div class="h-full overflow-auto p-4 rounded-lg bg-white dark:bg-neutral-800"> -->
|
|
|
<el-timeline>
|
|
<el-timeline>
|
|
|
<el-timeline-item
|
|
<el-timeline-item
|
|
@@ -65,6 +65,7 @@
|
|
|
<ElButton :loading="loading" @click="onAddCharactor(true)">加入角色生成选择</ElButton>
|
|
<ElButton :loading="loading" @click="onAddCharactor(true)">加入角色生成选择</ElButton>
|
|
|
<ElButton :loading="loading" @click="revert">回退</ElButton>
|
|
<ElButton :loading="loading" @click="revert">回退</ElButton>
|
|
|
</ElButtonGroup>
|
|
</ElButtonGroup>
|
|
|
|
|
+ <ElButton v-if="game.status === 'finished'" :loading="loading" @click="revert">回退</ElButton>
|
|
|
</div>
|
|
</div>
|
|
|
<ElDialog title="详情" v-model="showDetailDialog" width="1000px">
|
|
<ElDialog title="详情" v-model="showDetailDialog" width="1000px">
|
|
|
<ElCollapse :model-value="['1', '2']">
|
|
<ElCollapse :model-value="['1', '2']">
|
|
@@ -143,18 +144,23 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
import { InfoCircle } from '@vicons/tabler'
|
|
import { InfoCircle } from '@vicons/tabler'
|
|
|
import { useTimeFormatter } from '@/utils/formatter'
|
|
import { useTimeFormatter } from '@/utils/formatter'
|
|
|
import SingleUpload from '@/components/SingleUpload.vue'
|
|
import SingleUpload from '@/components/SingleUpload.vue'
|
|
|
|
|
+import { io } from 'socket.io-client'
|
|
|
|
|
+
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
|
|
|
+const roomId = route.params.roomId
|
|
|
|
|
+const gameId = route.params.gameId
|
|
|
const game = ref({})
|
|
const game = ref({})
|
|
|
const history = ref([])
|
|
const history = ref([])
|
|
|
const choice = ref(-1)
|
|
const choice = ref(-1)
|
|
|
|
|
+
|
|
|
const needChoice = computed(() => {
|
|
const needChoice = computed(() => {
|
|
|
return (history.value[history.value.length - 1].options || []).length > 0
|
|
return (history.value[history.value.length - 1].options || []).length > 0
|
|
|
})
|
|
})
|
|
|
async function getData(params) {
|
|
async function getData(params) {
|
|
|
- http.get(`/game/${route.params.id}`, { params }).then((res) => {
|
|
|
|
|
|
|
+ http.get(`/game/${gameId}`, { params }).then((res) => {
|
|
|
game.value = res
|
|
game.value = res
|
|
|
})
|
|
})
|
|
|
- http.get(`/game/${route.params.id}/history`, { params }).then((res) => {
|
|
|
|
|
|
|
+ http.get(`/game/${gameId}/history`, { params }).then((res) => {
|
|
|
res.forEach((i) => {
|
|
res.forEach((i) => {
|
|
|
if (i.options && i.choice) {
|
|
if (i.options && i.choice) {
|
|
|
i.choiceIndex = i.options.findIndex((o) => o.content === i.choice.content)
|
|
i.choiceIndex = i.options.findIndex((o) => o.content === i.choice.content)
|
|
@@ -173,32 +179,92 @@ async function getData(params) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
history.value = res
|
|
history.value = res
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ document
|
|
|
|
|
+ .querySelector('#main-container')
|
|
|
|
|
+ .scrollTo({ top: document.querySelector('#main-container').scrollHeight, behavior: 'smooth' })
|
|
|
|
|
+ }, 500)
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
getData()
|
|
getData()
|
|
|
-const timer = setInterval(() => {
|
|
|
|
|
- getData()
|
|
|
|
|
-}, 2000)
|
|
|
|
|
|
|
+const socket = ref(null)
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ socket.value = io(import.meta.env.VITE_WS_URL)
|
|
|
|
|
+ socket.value.on('connect', () => {
|
|
|
|
|
+ console.log('[websocket] connected')
|
|
|
|
|
+ })
|
|
|
|
|
+ socket.value.on('disconnect', () => {
|
|
|
|
|
+ console.log('[websocket] disconnected')
|
|
|
|
|
+ })
|
|
|
|
|
+ socket.value.on(`${gameId}`, (...args) => {
|
|
|
|
|
+ console.log('[websocket] received message', args[0])
|
|
|
|
|
+ const data = args[0]
|
|
|
|
|
+ switch (data.type) {
|
|
|
|
|
+ case 'timeChange':
|
|
|
|
|
+ if (history.value[history.value.length - 1].id !== -1) {
|
|
|
|
|
+ history.value.push({
|
|
|
|
|
+ id: -1
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ history.value[history.value.length - 1] = {
|
|
|
|
|
+ ...history.value[history.value.length - 1],
|
|
|
|
|
+ ...data.data
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'plot':
|
|
|
|
|
+ if (history.value[history.value.length - 1].id !== -1) {
|
|
|
|
|
+ history.value.push({
|
|
|
|
|
+ id: -1
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ history.value[history.value.length - 1] = {
|
|
|
|
|
+ ...history.value[history.value.length - 1],
|
|
|
|
|
+ plot: data.data
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'options':
|
|
|
|
|
+ if (history.value[history.value.length - 1].id !== -1) {
|
|
|
|
|
+ history.value.push({
|
|
|
|
|
+ id: -1
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ history.value[history.value.length - 1] = {
|
|
|
|
|
+ ...history.value[history.value.length - 1],
|
|
|
|
|
+ options: data.data
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'state':
|
|
|
|
|
+ getData()
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ if (data.type !== 'votes') {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ document
|
|
|
|
|
+ .querySelector('#main-container')
|
|
|
|
|
+ .scrollTo({ top: document.querySelector('#main-container').scrollHeight, behavior: 'smooth' })
|
|
|
|
|
+ }, 500)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ socket.value.connect()
|
|
|
|
|
+})
|
|
|
onBeforeUnmount(() => {
|
|
onBeforeUnmount(() => {
|
|
|
- clearInterval(timer)
|
|
|
|
|
|
|
+ socket.value?.disconnect()
|
|
|
})
|
|
})
|
|
|
function formatDatetime(date, time) {
|
|
function formatDatetime(date, time) {
|
|
|
- return (
|
|
|
|
|
- format(new Date(date), 'MMMdo', { locale: zhCN }) +
|
|
|
|
|
- {
|
|
|
|
|
- morning: '上午',
|
|
|
|
|
- afternoon: '下午',
|
|
|
|
|
- evening: '晚上'
|
|
|
|
|
- }[time]
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ return (
|
|
|
|
|
+ format(new Date(date), 'MMMdo', { locale: zhCN }) +
|
|
|
|
|
+ {
|
|
|
|
|
+ morning: '上午',
|
|
|
|
|
+ afternoon: '下午',
|
|
|
|
|
+ evening: '晚上'
|
|
|
|
|
+ }[time]
|
|
|
|
|
+ )
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return ''
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
-async function start() {
|
|
|
|
|
- loading.value = true
|
|
|
|
|
- await http.post(`/game/${route.params.id}/start`, { date: new Date() })
|
|
|
|
|
- loading.value = false
|
|
|
|
|
- getData()
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
async function continueGame(genChoice = false, newCharactor = null) {
|
|
async function continueGame(genChoice = false, newCharactor = null) {
|
|
|
if (needChoice.value && choice.value < 0) {
|
|
if (needChoice.value && choice.value < 0) {
|
|
@@ -207,7 +273,7 @@ async function continueGame(genChoice = false, newCharactor = null) {
|
|
|
}
|
|
}
|
|
|
loading.value = true
|
|
loading.value = true
|
|
|
try {
|
|
try {
|
|
|
- await http.post(`/game/${route.params.id}/continue`, {
|
|
|
|
|
|
|
+ await http.post(`/game/${gameId}/continue`, {
|
|
|
genChoice: genChoice,
|
|
genChoice: genChoice,
|
|
|
choice: history.value[history.value.length - 1].options[choice.value],
|
|
choice: history.value[history.value.length - 1].options[choice.value],
|
|
|
addCharactor: newCharactor
|
|
addCharactor: newCharactor
|
|
@@ -223,7 +289,7 @@ async function continueGame(genChoice = false, newCharactor = null) {
|
|
|
async function revert() {
|
|
async function revert() {
|
|
|
loading.value = true
|
|
loading.value = true
|
|
|
try {
|
|
try {
|
|
|
- await http.post(`/game/${route.params.id}/revert`)
|
|
|
|
|
|
|
+ await http.post(`/game/${gameId}/revert`)
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
ElMessage.error(error.message)
|
|
ElMessage.error(error.message)
|
|
|
}
|
|
}
|