| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- <template>
- <PagingTable url="/game" :where="where" ref="table">
- <template #filter>
- <ElButton :icon="Plus" @click="onEdit()">添加</ElButton>
- </template>
- <ElTableColumn prop="id" label="#" width="80" />
- <ElTableColumn prop="name" label="名称" min-width="120" />
- <ElTableColumn prop="status" label="状态" :formatter="statusFormatter" width="120" />
- <ElTableColumn prop="createdAt" label="创建时间" :formatter="timeFormatter" width="150" />
- <ElTableColumn label="操作" align="center" width="350">
- <template #default="{ row }">
- <ElButton @click="onPlay(row)" type="primary">进入</ElButton>
- <ElButton @click="onEdit(row)">编辑</ElButton>
- <ElButton @click="bindTwitch(row)" type="success">绑定Twitch</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="roomId" label="房间ID">
- <ElInput v-model="model.roomId" placeholder="请输入房间ID" />
- </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="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>
- </template>
- <script setup>
- import { 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 EnumSelect from '@/components/EnumSelect.vue'
- import { GameStatus } from '@/enums'
- import { http } from '@/plugins/http'
- import { ElMessage, ElMessageBox } from 'element-plus'
- import { useClipboard } from '@vueuse/core'
- import { useRouter } from 'vue-router'
- 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' }],
- roomId: [{ required: true, message: '请输入房间ID', 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 { 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() {
- const { value } = await ElMessageBox.prompt('生成数量:', '生成角色', {
- inputPattern: /^\d{1,2}$/,
- inputErrorMessage: 'Invalid Num'
- })
- generating.value = true
- try {
- const res = await http.post(`/game/${model.value.id}/genCharactor`, { gameId: model.value.id, 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 = {
- 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: {
- id: row.id
- }
- })
- }
- function bindTwitch(row) {
- let u = new URL('https://id.twitch.tv/oauth2/authorize?')
- u.searchParams.append('client_id', '530df6x09eq34be0vjhsezkl2oxap0')
- u.searchParams.append('redirect_uri', 'http://localhost:3000/api/twitch/auth_callback')
- u.searchParams.append('response_type', 'code')
- u.searchParams.append('xxx', 'aaa')
- u.searchParams.append('scope', 'channel:manage:broadcast chat:read chat:edit channel:manage:polls')
- window.open(u.href)
- }
- </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>
|