|
|
@@ -1,7 +1,7 @@
|
|
|
<template>
|
|
|
<div class="game-stage-3">
|
|
|
<div class="top-config">
|
|
|
- <a-collapse :bordered="false">
|
|
|
+ <a-collapse :bordered="false" :activeKey="1">
|
|
|
<a-collapse-panel key="1">
|
|
|
<template #header>
|
|
|
<div class="collapse-header">
|
|
|
@@ -12,7 +12,7 @@
|
|
|
<a-form-item label="按钮音频">
|
|
|
<SelectAudioNew
|
|
|
v-model="touch_keys[0][0].music_name"
|
|
|
- placeholder="请选择队员按钮音频"
|
|
|
+ placeholder="请选择按钮音频"
|
|
|
/>
|
|
|
</a-form-item>
|
|
|
|
|
|
@@ -33,8 +33,8 @@
|
|
|
</a-collapse-panel>
|
|
|
</a-collapse>
|
|
|
</div>
|
|
|
- <div class="step-list" v-if="getBtnRuleByRule === 'multiple'">
|
|
|
- <a-collapse :bordered="false" >
|
|
|
+ <div class="step-list" >
|
|
|
+ <a-collapse :bordered="false" :activeKey="2">
|
|
|
<a-collapse-panel key="2" >
|
|
|
<template #header>
|
|
|
<div class="collapse-header">
|
|
|
@@ -57,10 +57,18 @@
|
|
|
@click="selectStep(element.value)"
|
|
|
>
|
|
|
<div class="step-info">
|
|
|
- <span class="step-number">按钮 {{ index + 1 }}</span>
|
|
|
+ <div class="step-number">按钮 {{getButtonLabel(element.value) }}</div>
|
|
|
<div class="step-details">
|
|
|
- <span>按钮: <strong>{{ getButtonLabel(element.value) }}</strong></span>
|
|
|
- <span>音频: <strong>{{ element.music_name }}</strong></span>
|
|
|
+ <div class="step-detail-row">
|
|
|
+ <span class="detail-label">音频:</span>
|
|
|
+ <strong class="audio-name">{{ element.music_name }}</strong>
|
|
|
+ </div>
|
|
|
+ <div class="step-detail-row break-row">
|
|
|
+ <span class="detail-label">可中止:</span>
|
|
|
+ <div class="break-select">
|
|
|
+ <select-break v-model:value="element.is_break" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="step-actions">
|
|
|
@@ -82,7 +90,7 @@
|
|
|
</a-collapse>
|
|
|
</div>
|
|
|
<div class="step-list" v-if="getBtnRuleByRule === 'multiple'">
|
|
|
- <a-collapse :bordered="false">
|
|
|
+ <a-collapse :bordered="false" :activeKey="3">
|
|
|
<a-collapse-panel key="3">
|
|
|
<template #header>
|
|
|
<div class="collapse-header">
|
|
|
@@ -105,10 +113,22 @@
|
|
|
@click="selectStep(element.value)"
|
|
|
>
|
|
|
<div class="step-info">
|
|
|
- <span class="step-number">按钮 {{ index + 1 }}</span>
|
|
|
+ <div class="step-number">按钮 {{ index + 1 }}</div>
|
|
|
<div class="step-details">
|
|
|
- <span>按钮: <strong>{{ getButtonLabel(element.value) }}</strong></span>
|
|
|
- <span>音频: <strong>{{ element.music_name }}</strong></span>
|
|
|
+ <div class="step-detail-row">
|
|
|
+ <span class="detail-label">按钮:</span>
|
|
|
+ <strong>{{ getButtonLabel(element.value) }}</strong>
|
|
|
+ </div>
|
|
|
+ <div class="step-detail-row">
|
|
|
+ <span class="detail-label">音频:</span>
|
|
|
+ <strong class="audio-name">{{ element.music_name }}</strong>
|
|
|
+ </div>
|
|
|
+ <div class="step-detail-row break-row">
|
|
|
+ <span class="detail-label">可中止:</span>
|
|
|
+ <div class="break-select">
|
|
|
+ <select-break v-model:value="element.is_break" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="step-actions">
|
|
|
@@ -171,16 +191,16 @@
|
|
|
</div>
|
|
|
</a-form-item>
|
|
|
<a-form-item label="选择语音">
|
|
|
- <span
|
|
|
+ <div
|
|
|
style="margin-bottom: 8px;"
|
|
|
:key="item.value"
|
|
|
v-for="item in steps.ok_key"
|
|
|
>
|
|
|
<SelectAudioNew
|
|
|
v-model="item.music_name"
|
|
|
- placeholder="请选择步骤语音"
|
|
|
+ :placeholder="'请选择' + getButtonLabel(item.value) + '音频'"
|
|
|
/>
|
|
|
- </span>
|
|
|
+ </div>
|
|
|
</a-form-item>
|
|
|
</a-form>
|
|
|
<a-form :model="steps.err_key" layout="vertical" v-else>
|
|
|
@@ -198,16 +218,16 @@
|
|
|
</div>
|
|
|
</a-form-item>
|
|
|
<a-form-item label="选择语音">
|
|
|
- <span
|
|
|
+ <div
|
|
|
style="margin-bottom: 8px;"
|
|
|
v-for="item in steps.err_key"
|
|
|
:key="item.value"
|
|
|
>
|
|
|
<SelectAudioNew
|
|
|
v-model="item.music_name"
|
|
|
- placeholder="请选择步骤语音"
|
|
|
+ :placeholder="'请选择' + getButtonLabel(item.value) + '音频'"
|
|
|
/>
|
|
|
- </span>
|
|
|
+ </div>
|
|
|
</a-form-item>
|
|
|
</a-form>
|
|
|
</a-modal>
|
|
|
@@ -219,6 +239,7 @@ import { ref, computed, reactive, watch } from 'vue'
|
|
|
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue'
|
|
|
import { VueDraggableNext } from 'vue-draggable-next'
|
|
|
import SelectAudioNew from './select-audio-new.vue'
|
|
|
+import SelectBreak from './select-break.vue'
|
|
|
import { message } from 'ant-design-vue'
|
|
|
|
|
|
interface Props {
|
|
|
@@ -234,6 +255,7 @@ watch(
|
|
|
},
|
|
|
{ immediate: true }
|
|
|
)
|
|
|
+
|
|
|
watch(
|
|
|
() => props.touch_key,
|
|
|
(newVal) => {
|
|
|
@@ -245,6 +267,12 @@ watch(
|
|
|
const props = defineProps<Props>()
|
|
|
const emits = defineEmits(['update:modelValue', 'step-selected', 'update:touch_key'])
|
|
|
|
|
|
+// 正确按钮
|
|
|
+const ok_key = ref([])
|
|
|
+
|
|
|
+// 错误按钮
|
|
|
+const err_key = ref([])
|
|
|
+
|
|
|
const steps = computed({
|
|
|
get: () => props.modelValue,
|
|
|
set: (value) => emits('update:modelValue', value)
|
|
|
@@ -288,9 +316,9 @@ const buttonMap = new Map<number, string>(buttonOptions.map(opt => [opt.value, o
|
|
|
const getButtonLabel = (value: number) => buttonMap.get(value) || '未知'
|
|
|
|
|
|
const getBtnTypeByKey = (key: number) => {
|
|
|
- if (steps.value.ok_key.some(item => item.value === key)) {
|
|
|
+ if (steps.value.ok_key.some(item => item.value === key) && btnMode.value === 'success') {
|
|
|
return 'primary'
|
|
|
- } else if (steps.value.err_key.some(item => item.value === key)) {
|
|
|
+ } else if (steps.value.err_key.some(item => item.value === key) && btnMode.value === 'error') {
|
|
|
return 'primary'
|
|
|
}
|
|
|
return 'default'
|
|
|
@@ -306,10 +334,20 @@ const selectButton = (btn: { label: string, value: number }) => {
|
|
|
if (getBtnRuleByRule.value === 'single') {
|
|
|
steps.value.ok_key[0] = { value: btn.value, music_name: '', is_break: 1 }
|
|
|
} else {
|
|
|
- steps.value.ok_key.push({ value: btn.value, music_name: '', is_break: 1 })
|
|
|
+ const targetIndex = steps.value.ok_key.findIndex(item => btn.value === item.value)
|
|
|
+ if (targetIndex === -1) {
|
|
|
+ steps.value.ok_key.push({ value: btn.value, music_name: '', is_break: 1 })
|
|
|
+ } else {
|
|
|
+ steps.value.ok_key.splice(targetIndex, 1)
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
- steps.value.err_key.push({ value: btn.value, music_name: '', is_break: 1 })
|
|
|
+ const targetIndex = steps.value.err_key.findIndex(item => btn.value === item.value)
|
|
|
+ if (targetIndex === -1) {
|
|
|
+ steps.value.err_key.push({ value: btn.value, music_name: '', is_break: 1 })
|
|
|
+ } else {
|
|
|
+ steps.value.err_key.splice(targetIndex, 1)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -410,14 +448,13 @@ const handleDeleteButton = (value: number) => {
|
|
|
}
|
|
|
|
|
|
.step-item-wrapper {
|
|
|
- // width: 100%;
|
|
|
margin-bottom: 12px;
|
|
|
}
|
|
|
|
|
|
.step-item {
|
|
|
width: 90%;
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
+ align-items: flex-start;
|
|
|
justify-content: space-between;
|
|
|
padding: 16px;
|
|
|
border: 1px solid #d9d9d9;
|
|
|
@@ -440,34 +477,62 @@ const handleDeleteButton = (value: number) => {
|
|
|
|
|
|
.step-info {
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 24px;
|
|
|
+ flex-direction: column;
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
|
|
|
.step-number {
|
|
|
font-weight: 600;
|
|
|
font-size: 16px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ color: #1890ff;
|
|
|
}
|
|
|
|
|
|
.step-details {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- gap: 4px;
|
|
|
+ gap: 8px;
|
|
|
font-size: 14px;
|
|
|
color: #555;
|
|
|
+ width: 100%;
|
|
|
+ padding-left: 0;
|
|
|
+ }
|
|
|
|
|
|
- span > strong {
|
|
|
- color: #333;
|
|
|
- margin-left: 8px;
|
|
|
- }
|
|
|
+ .step-detail-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 4px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail-label {
|
|
|
+ width: 60px;
|
|
|
+ color: #666;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .audio-name {
|
|
|
+ color: #1890ff;
|
|
|
+ max-width: 200px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .break-row {
|
|
|
+ margin-top: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .break-select {
|
|
|
+ flex: 1;
|
|
|
+ max-width: 300px;
|
|
|
}
|
|
|
|
|
|
.step-actions {
|
|
|
cursor: pointer;
|
|
|
color: #ff4d4f;
|
|
|
font-size: 16px;
|
|
|
+ padding-top: 4px;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
</style>
|
|
|
<style lang="less" scoped>
|
|
|
@@ -527,24 +592,6 @@ const handleDeleteButton = (value: number) => {
|
|
|
margin-top: 4px;
|
|
|
}
|
|
|
|
|
|
-.button-wrapper {
|
|
|
- position: relative;
|
|
|
-}
|
|
|
-
|
|
|
-.delete-icon {
|
|
|
- position: absolute;
|
|
|
- top: -8px;
|
|
|
- right: -8px;
|
|
|
- color: #ff4d4f;
|
|
|
- background-color: #fff;
|
|
|
- border-radius: 50%;
|
|
|
- padding: 2px;
|
|
|
- font-size: 14px;
|
|
|
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
|
|
|
- cursor: pointer;
|
|
|
- z-index: 10;
|
|
|
-}
|
|
|
-
|
|
|
.panel-header {
|
|
|
display: flex;
|
|
|
justify-content: flex-end;
|