|
|
@@ -1,318 +0,0 @@
|
|
|
-<template>
|
|
|
- <PagingTable url="/game" :where="where" ref="table">
|
|
|
- <template #filter>
|
|
|
- <ElSelect v-model="where.roomId" clearable placeholder="筛选房间">
|
|
|
- <ElOption v-for="item in rooms" :key="item.id" :label="item.name" :value="item.id" />
|
|
|
- </ElSelect>
|
|
|
- <ElButton :icon="Plus" @click="onEdit()">添加</ElButton>
|
|
|
- </template>
|
|
|
- <ElTableColumn prop="id" label="#" width="80" />
|
|
|
- <ElTableColumn prop="name" label="名称" />
|
|
|
- <ElTableColumn prop="type" label="类型" width="100" />
|
|
|
- <ElTableColumn prop="roomId" label="房间ID" />
|
|
|
- <ElTableColumn prop="status" label="状态" width="150" :formatter="statusFormatter" />
|
|
|
- <ElTableColumn prop="autoReset" label="自动重置" />
|
|
|
- <ElTableColumn prop="resetNum" label="重置次数" />
|
|
|
- <ElTableColumn prop="running" label="运行" width="100" align="center">
|
|
|
- <template #default="{ row }">
|
|
|
- <ElSwitch
|
|
|
- v-if="row.status === 'initialized' || row.status === 'running'"
|
|
|
- :model-value="row.status === 'running'"
|
|
|
- @update:model-value="onActiveChange($event, row)"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </ElTableColumn>
|
|
|
- <ElTableColumn prop="createdAt" label="创建时间" :formatter="timeFormatter" width="150" />
|
|
|
- <ElTableColumn label="操作" align="center" width="350">
|
|
|
- <template #default="{ row }">
|
|
|
- <ElButton @click="onEdit(row)" type="primary">编辑</ElButton>
|
|
|
- <ElButton v-if="row.status === 'created'" @click="onInit(row)" type="primary">初始化</ElButton>
|
|
|
- <ElButton v-if="row.status !== 'created'" @click="onPlay(row)" type="primary">详情</ElButton>
|
|
|
- <ElButton v-if="row.status !== 'created'" @click="reset(row)" type="warning">重置</ElButton>
|
|
|
- <ElButton @click="onDelete(row)" type="danger">删除</ElButton>
|
|
|
- </template>
|
|
|
- </ElTableColumn>
|
|
|
- </PagingTable>
|
|
|
- <EditDialog
|
|
|
- v-model="showEditDialog"
|
|
|
- :model="model"
|
|
|
- :rules="rules"
|
|
|
- :on-submit="submit"
|
|
|
- @success="table.refresh()"
|
|
|
- width="800px"
|
|
|
- >
|
|
|
- <ElFormItem prop="name" label="名称">
|
|
|
- <ElInput v-model="model.name" placeholder="请输入名称" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="type" label="类型">
|
|
|
- <ElSelect v-model="model.type" placeholder="请选择类型">
|
|
|
- <ElOption v-for="item in promptTypes" :key="item" :label="item" :value="item" />
|
|
|
- </ElSelect>
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="roomId" label="房间">
|
|
|
- <ElSelect v-model="model.roomId" placeholder="请选择房间">
|
|
|
- <ElOption v-for="item in rooms" :key="item.id" :label="item.name" :value="item.id" />
|
|
|
- </ElSelect>
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="autoReset" label="自动重置">
|
|
|
- <ElRadioGroup v-model="model.autoReset">
|
|
|
- <ElRadio :label="true">是</ElRadio>
|
|
|
- <ElRadio :label="false">否</ElRadio>
|
|
|
- </ElRadioGroup>
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="background" label="故事背景">
|
|
|
- <ElInput v-model="model.background" type="textarea" placeholder="请输入故事背景" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="charactors" label="初始角色">
|
|
|
- <div class="charactor-form" v-for="(item, i) in model.charactors" :key="i">
|
|
|
- <ElForm :model="item" label-position="top" inline :rules="charactorRules" ref="charactorForms">
|
|
|
- <ElFormItem prop="avatar" label="头像">
|
|
|
- <SingleUpload v-model="item.avatar" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="name" label="角色名称">
|
|
|
- <ElInput v-model="item.name" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="gender" label="性别">
|
|
|
- <ElInput v-model="item.gender" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="age" label="年龄">
|
|
|
- <ElInput v-model="item.age" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="occupation" label="职业">
|
|
|
- <ElInput v-model="item.occupation" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem prop="personality" label="性格">
|
|
|
- <ElInput v-model="item.personality" />
|
|
|
- </ElFormItem>
|
|
|
- <div class="w-full"></div>
|
|
|
- <ElFormItem class="w-full" prop="background" label="背景">
|
|
|
- <ElInput v-model="item.background" type="textarea" />
|
|
|
- </ElFormItem>
|
|
|
- </ElForm>
|
|
|
- <ElButton type="danger" size="small" @click="removeCharactor(i)">删除</ElButton>
|
|
|
- </div>
|
|
|
- <ElButton @click="genCharactor" :loading="generating">生成</ElButton>
|
|
|
- <ElButton @click="onAddCharactor">添加</ElButton>
|
|
|
- </ElFormItem>
|
|
|
- </EditDialog>
|
|
|
- <ElDialog title="初始化" v-model="showInitDialog">
|
|
|
- <ElForm :model="initModel" :rules="initRules" ref="initForm" label-position="right" label-width="80">
|
|
|
- <ElFormItem label="日期" prop="date">
|
|
|
- <ElDatePicker v-model="initModel.date" />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="时间" prop="time">
|
|
|
- <ElSelect v-model="initModel.time">
|
|
|
- <ElOption label="上午" value="morning" />
|
|
|
- <ElOption label="下午" value="afternoon" />
|
|
|
- <ElOption label="晚上" value="evening" />
|
|
|
- </ElSelect>
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="初始剧情" prop="plot">
|
|
|
- <ElInput v-model="initModel.plot" type="textarea" placeholder="不填则自动生成" :rows="3" />
|
|
|
- </ElFormItem>
|
|
|
- </ElForm>
|
|
|
- <template #footer>
|
|
|
- <ElButton @click="showInitDialog = false">取消</ElButton>
|
|
|
- <ElButton type="primary" @click="init">确定</ElButton>
|
|
|
- </template>
|
|
|
- </ElDialog>
|
|
|
-</template>
|
|
|
-<script setup>
|
|
|
-import { onMounted, ref } from 'vue'
|
|
|
-import PagingTable from '@/components/PagingTable.vue'
|
|
|
-import { useEnumFormatter, useTimeFormatter } from '@/utils/formatter'
|
|
|
-import { Plus } from '@vicons/tabler'
|
|
|
-import EditDialog from '@/components/EditDialog.vue'
|
|
|
-import { setupEditDialog } from '@/utils/editDialog'
|
|
|
-import { http } from '@/plugins/http'
|
|
|
-import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
-import { useRouter } from 'vue-router'
|
|
|
-import { ElLoading } from 'element-plus'
|
|
|
-import { GameStatus } from '@/enums'
|
|
|
-
|
|
|
-const router = useRouter()
|
|
|
-const where = ref({})
|
|
|
-const timeFormatter = useTimeFormatter()
|
|
|
-const statusFormatter = useEnumFormatter(GameStatus)
|
|
|
-const table = ref(null)
|
|
|
-const model = ref({})
|
|
|
-const rules = {
|
|
|
- name: [{ required: true, message: '请输入昵称', trigger: 'blur' }],
|
|
|
- type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
|
|
|
- roomId: [{ required: true, message: '请选择房间', trigger: 'blur' }],
|
|
|
- autoReset: [{ required: true, message: '请输入自动重置', trigger: 'blur' }],
|
|
|
- background: [{ required: true, message: '请输入故事背景', trigger: 'blur' }],
|
|
|
- charactors: [
|
|
|
- {
|
|
|
- validator: (rule, value, callback) => {
|
|
|
- if (!value || value.length === 0) {
|
|
|
- callback(new Error('请输入初始角色'))
|
|
|
- } else {
|
|
|
- Promise.all(charactorForms.value.map((form) => form.validate()))
|
|
|
- .then(() => {
|
|
|
- callback()
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- callback(new Error('请输入初始角色'))
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
-}
|
|
|
-
|
|
|
-const rooms = ref([])
|
|
|
-const promptTypes = ref([])
|
|
|
-onMounted(() => {
|
|
|
- http.post('/room').then((res) => {
|
|
|
- rooms.value = res.items
|
|
|
- })
|
|
|
- http.get('/prompt/types').then((res) => {
|
|
|
- promptTypes.value = res
|
|
|
- })
|
|
|
-})
|
|
|
-
|
|
|
-const { showEditDialog, onEdit } = setupEditDialog(model)
|
|
|
-async function submit() {
|
|
|
- await http.put(model.value.id ? `/game/${model.value.id}` : '/game', model.value)
|
|
|
- ElMessage.success('保存成功')
|
|
|
-}
|
|
|
-async function onDelete(row) {
|
|
|
- await ElMessageBox.confirm('确认删除?', '删除', { type: 'warning' })
|
|
|
- await http.delete(`/game/${row.id}`)
|
|
|
- ElMessage.success('删除成功')
|
|
|
- table.value.refresh()
|
|
|
-}
|
|
|
-const generating = ref(false)
|
|
|
-async function genCharactor() {
|
|
|
- if (!model.value.background) {
|
|
|
- ElMessage.error('请先输入故事背景')
|
|
|
- return
|
|
|
- }
|
|
|
- if (!model.value.background) {
|
|
|
- ElMessage.error('请先选择类型')
|
|
|
- return
|
|
|
- }
|
|
|
- const { value } = await ElMessageBox.prompt('生成数量:', '生成角色', {
|
|
|
- inputPattern: /^\d{1,2}$/,
|
|
|
- inputErrorMessage: 'Invalid Num'
|
|
|
- })
|
|
|
- generating.value = true
|
|
|
- try {
|
|
|
- const res = await http.post(`/game/genCharactor`, {
|
|
|
- type: model.value.type,
|
|
|
- background: model.value.background,
|
|
|
- num: value
|
|
|
- })
|
|
|
- generating.value = false
|
|
|
- model.value.charactors = (model.value.charactors || []).concat(res)
|
|
|
- } catch (error) {
|
|
|
- ElMessage.error(error.message)
|
|
|
- generating.value = false
|
|
|
- }
|
|
|
-}
|
|
|
-function onAddCharactor() {
|
|
|
- model.value.charactors = (model.value.charactors || []).concat({})
|
|
|
-}
|
|
|
-const charactorRules = {
|
|
|
- avatar: [{ required: true, message: '请上传头像', trigger: 'blur' }],
|
|
|
- name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
|
|
- gender: [{ required: true, message: '请输入性别', trigger: 'blur' }],
|
|
|
- age: [{ required: true, message: '请输入年龄', trigger: 'blur' }],
|
|
|
- occupation: [{ required: true, message: '请输入职业', trigger: 'blur' }],
|
|
|
- personality: [{ required: true, message: '请输入性格', trigger: 'blur' }],
|
|
|
- background: [{ required: true, message: '请输入背景', trigger: 'blur' }]
|
|
|
-}
|
|
|
-const charactorForms = ref([])
|
|
|
-function removeCharactor(index) {
|
|
|
- model.value.charactors.splice(index, 1)
|
|
|
-}
|
|
|
-function onPlay(row) {
|
|
|
- router.push({
|
|
|
- name: 'play',
|
|
|
- params: {
|
|
|
- gameId: row.id,
|
|
|
- roomId: row.roomId
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-const showInitDialog = ref(false)
|
|
|
-const initForm = ref(null)
|
|
|
-const initModel = ref({})
|
|
|
-const selectedRow = ref(null)
|
|
|
-const initRules = {
|
|
|
- date: [{ required: true, message: '请选择日期', trigger: 'blur' }],
|
|
|
- time: [{ required: true, message: '请选择时间', trigger: 'blur' }]
|
|
|
-}
|
|
|
-async function onInit(row) {
|
|
|
- selectedRow.value = row
|
|
|
- initModel.value = {}
|
|
|
- initForm.value?.clearValidate()
|
|
|
- showInitDialog.value = true
|
|
|
-}
|
|
|
-async function init() {
|
|
|
- await initForm.value.validate()
|
|
|
- const loadingInstance = ElLoading.service({
|
|
|
- fullscreen: true
|
|
|
- })
|
|
|
- try {
|
|
|
- await http.post(`/game/${selectedRow.value.id}/init`, initModel.value)
|
|
|
- ElMessage.success('初始化成功')
|
|
|
- table.value.refresh()
|
|
|
- showInitDialog.value = false
|
|
|
- } catch (error) {
|
|
|
- ElMessage.error(error.message)
|
|
|
- }
|
|
|
- loadingInstance.close()
|
|
|
-}
|
|
|
-async function onActiveChange(e, row) {
|
|
|
- const loadingInstance = ElLoading.service({
|
|
|
- fullscreen: true
|
|
|
- })
|
|
|
- try {
|
|
|
- if (e) {
|
|
|
- await http.post(`/game/${row.id}/startRun`)
|
|
|
- } else {
|
|
|
- await http.post(`/game/${row.id}/stopRun`)
|
|
|
- }
|
|
|
- table.value.refresh()
|
|
|
- } catch (error) {
|
|
|
- ElMessage.error(error.message)
|
|
|
- }
|
|
|
- loadingInstance.close()
|
|
|
-}
|
|
|
-async function reset(row) {
|
|
|
- ElMessageBox.confirm('确认重置?', '重置', {
|
|
|
- type: 'warning',
|
|
|
- beforeClose: (action, instance, done) => {
|
|
|
- if (action === 'confirm') {
|
|
|
- instance.confirmButtonLoading = true
|
|
|
- instance.confirmButtonText = '执行中...'
|
|
|
- http.post(`/game/${row.id}/reset`)
|
|
|
- .then(() => {
|
|
|
- ElMessage.success('重置成功')
|
|
|
- table.value.refresh()
|
|
|
- done()
|
|
|
- })
|
|
|
- .catch((error) => {
|
|
|
- ElMessage.error(error.message)
|
|
|
- done()
|
|
|
- })
|
|
|
- } else {
|
|
|
- done()
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-</script>
|
|
|
-<style lang="less" scoped>
|
|
|
-.charactor-form {
|
|
|
- background-color: var(--el-color-info-light-9);
|
|
|
- padding: 15px;
|
|
|
- border-radius: 8px;
|
|
|
- margin-bottom: 10px;
|
|
|
- .el-form-item {
|
|
|
- margin-bottom: 20px;
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|