| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795 |
- <template>
- <div class="six-hat-detail">
- <!-- 头部导航 -->
- <div class="detail-header">
- <div class="back-btn" @click="$emit('back')">
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <path d="M15 18l-6-6 6-6" />
- </svg>
- </div>
- <div class="detail-title">{{ lang.ssSixHatTitle }}</div>
- </div>
- <!-- Banner 区域 -->
- <div class="detail-banner">
- <img :src="sixHat" :alt="lang.ssSixHatTitle" />
- <div class="tool-overly"></div>
- <div class="tool-icon-badge">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <path d="M9 18h6M10 22h4M12 2a7 7 0 00-4 12.7c.6.5 1 1.3 1 2.3h6c0-1 .4-1.8 1-2.3A7 7 0 0012 2z"></path>
- </svg>
- </div>
- </div>
- <!-- 描述与标签 -->
- <div class="detail-desc-row">
- <div class="detail-desc-text">{{ lang.ssSixHatDesc }}</div>
- <div class="help-icon" @mouseenter="showHelp = true" @mouseleave="showHelp = false">
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <circle cx="12" cy="12" r="10" />
- <path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3" />
- <line x1="12" y1="17" x2="12.01" y2="17" />
- </svg>
- <!-- 帮助气泡 -->
- <div v-if="showHelp" class="help-tooltip">
- <div class="help-title">{{ lang.ssSixHatUsageScenario }}</div>
- <div class="help-text">{{ lang.ssSixHatScenarioText }}</div>
- <div class="help-title">{{ lang.ssSixHatSteps }}</div>
- <div class="help-list">
- <div class="help-step"><span class="step-num">1</span><span>{{ lang.ssSixHatStep1 }}</span></div>
- <div class="help-step"><span class="step-num">2</span><span>{{ lang.ssSixHatStep2 }}</span></div>
- <div class="help-step"><span class="step-num">3</span><span>{{ lang.ssSixHatStep3 }}</span></div>
- <div class="help-step"><span class="step-num">4</span><span>{{ lang.ssSixHatStep4 }}</span></div>
- <div class="help-step"><span class="step-num">5</span><span>{{ lang.ssSixHatStep5 }}</span></div>
- <div class="help-step"><span class="step-num">6</span><span>{{ lang.ssSixHatStep6 }}</span></div>
- </div>
- <div class="help-source">{{ lang.ssSixHatSource }}</div>
- <div class="help-purpose">{{ lang.ssSixHatPurpose }}</div>
- </div>
- </div>
- </div>
- <div class="detail-tags">
- <span class="detail-tag">{{ lang.ssSixHatGradeRange }}</span>
- </div>
- <!-- 工具配置区 -->
- <div class="config-section">
- <div class="config-title">{{ lang.ssKwlToolConfig }}</div>
- <div class="config-subtitle">{{ lang.ssKwlConfigSubtitle }}</div>
- </div>
- <!-- 配置项卡片 -->
- <div class="config-card">
- <!-- 工具内容由使用者配置 -->
- <div class="config-row config-row-highlight">
- <div class="form-text-block">
- <div class="form-label">{{ lang.ssSixHatUserConfig }}</div>
- <div class="form-sublabel">{{ lang.ssSixHatUserConfigDesc }}</div>
- </div>
- <div class="toggle-switch" :class="{ active: formData.enableContentConfigurable }"
- @click="formData.enableContentConfigurable = !formData.enableContentConfigurable">
- <div class="toggle-thumb"></div>
- </div>
- </div>
- <!-- 小组合作 -->
- <div class="config-row">
- <div class="form-text-block">
- <div class="form-label">{{ lang.ssSixHatGroupWork }}</div>
- <div class="form-sublabel">{{ lang.ssSixHatGroupWorkDesc }}</div>
- </div>
- <div class="toggle-switch" :class="{ active: formData.enableMemberSelect }"
- @click="formData.enableMemberSelect = !formData.enableMemberSelect">
- <div class="toggle-thumb"></div>
- </div>
- </div>
- <!-- 默认展开操作提示 -->
- <div class="config-row">
- <div class="form-text-block">
- <div class="form-label">{{ lang.ssKwlShowHowTo }}</div>
- <div class="form-sublabel">{{ lang.ssKwlShowHowToDesc }}</div>
- </div>
- <div class="toggle-switch" :class="{ active: formData.autoExpandHowTo }"
- @click="formData.autoExpandHowTo = !formData.autoExpandHowTo">
- <div class="toggle-thumb"></div>
- </div>
- </div>
- <!-- 高级配置 -->
- <div class="advanced-section">
- <div class="advanced-header" @click="showAdvanced = !showAdvanced">
- <span class="advanced-title">{{ lang.ssKwlAdvanced }}</span>
- <svg class="advanced-arrow" :class="{ expanded: showAdvanced }" width="16" height="16" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2">
- <polyline points="6 9 12 15 18 9" />
- </svg>
- </div>
- <div v-if="showAdvanced" class="advanced-body">
- <!-- 显示计时器 -->
- <div class="config-row config-row-borderless">
- <div class="form-text-block">
- <div class="form-label">{{ lang.ssSixHatShowTimer }}</div>
- </div>
- <div class="toggle-switch" :class="{ active: formData.timerEnabled }"
- @click="formData.timerEnabled = !formData.timerEnabled">
- <div class="toggle-thumb"></div>
- </div>
- </div>
- <!-- 计时时长 -->
- <div v-if="formData.timerEnabled" class="timer-duration">
- <div class="duration-label">{{ lang.ssSixHatTimerDuration }}</div>
- <div class="duration-options">
- <div v-for="item in timerOptions" :key="item" class="duration-chip"
- :class="{ active: !customTimerActive && formData.timerDuration === item }"
- @click="selectTimerDuration(item)">
- {{ item }}{{ lang.ssSixHatTimerSeconds }}
- </div>
- <div class="duration-chip" :class="{ active: customTimerActive }" @click="selectCustomTimer">
- {{ lang.ssCustom }}
- </div>
- </div>
- <!-- 自定义时长输入 -->
- <div v-if="customTimerActive" class="custom-timer">
- <input v-model="customTimerInput" type="number" min="10" max="3600" step="10"
- @change="handleCustomTimerInput" @keyup.enter="handleCustomTimerInput" />
- <span class="custom-unit">{{ lang.ssSixHatTimerSeconds }}</span>
- </div>
- </div>
- <!-- 思考帽选择 -->
- <div class="hats-select">
- <div class="duration-label">{{ lang.ssSixHatSelectHats }}</div>
- <div class="hats-options">
- <div v-for="hat in hatList" :key="hat.key" class="hat-chip"
- :class="[`hat-${hat.key}`, { active: formData.hats.includes(hat.key) }]"
- @click="toggleHat(hat.key)">
- <span class="hat-dot"></span>
- {{ hat.label }}
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 添加到幻灯片按钮 -->
- <div class="footer-btn">
- <div class="add-btn" @click="handleAddToSlide">{{ lang.ssKwlAddToSlide }}</div>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, reactive } from 'vue'
- import sixHat from '@/assets/img/sixHatBanner.jpg'
- import { lang } from '@/main'
- const emit = defineEmits<{
- (e: 'back'): void
- (e: 'add', data: any): void
- }>()
- const showHelp = ref(false)
- const showAdvanced = ref(false)
- const timerOptions = [30, 60, 120, 180, 300]
- const customTimerActive = ref(false)
- const customTimerInput = ref<number>(60)
- const hatList = [
- { key: 'white', label: lang.ssSixHatWhite },
- { key: 'red', label: lang.ssSixHatRed },
- { key: 'black', label: lang.ssSixHatBlack },
- { key: 'yellow', label: lang.ssSixHatYellow },
- { key: 'green', label: lang.ssSixHatGreen },
- { key: 'blue', label: lang.ssSixHatBlue }
- ]
- const formData = reactive({
- stage: 'member',
- members: [] as string[],
- scenario: '',
- timerEnabled: true,
- timerDuration: 60,
- timerCustomValue: 60,
- hats: ['white', 'red', 'black', 'yellow', 'green', 'blue'] as string[],
- hatContent: {} as Record<string, string>,
- enableMemberSelect: false,
- enableContentConfigurable: true,
- autoExpandHowTo: false,
- customScenario: '',
- customTimerEnabled: true,
- customTimerDuration: 60,
- customHats: null as string[] | null
- })
- const CUSTOM_TIMER_MIN = 10
- const CUSTOM_TIMER_MAX = 3600
- const selectTimerDuration = (value: number) => {
- customTimerActive.value = false
- formData.timerDuration = value
- formData.timerCustomValue = value
- }
- const selectCustomTimer = () => {
- customTimerActive.value = true
- applyCustomTimer()
- }
- const applyCustomTimer = () => {
- formData.timerCustomValue = customTimerInput.value
- formData.timerDuration = customTimerInput.value
- }
- const handleCustomTimerInput = () => {
- let val = Number(customTimerInput.value)
- if (!val || Number.isNaN(val)) val = 60
- val = Math.round(val)
- val = Math.max(CUSTOM_TIMER_MIN, Math.min(CUSTOM_TIMER_MAX, val))
- customTimerInput.value = val
- applyCustomTimer()
- }
- const toggleHat = (key: string) => {
- const index = formData.hats.indexOf(key)
- if (index > -1) {
- // 至少保留一顶帽子
- if (formData.hats.length === 1) return
- formData.hats.splice(index, 1)
- }
- else {
- // 按固定顺序插入,保持帽子次序
- const order = hatList.map(h => h.key)
- formData.hats.push(key)
- formData.hats.sort((a, b) => order.indexOf(a) - order.indexOf(b))
- }
- }
- const handleAddToSlide = () => {
- emit('add', {
- ...formData,
- members: [...formData.members],
- hats: [...formData.hats],
- hatContent: { ...formData.hatContent }
- })
- }
- </script>
- <style lang="scss" scoped>
- .six-hat-detail {
- display: flex;
- flex-direction: column;
- height: calc(100% - 75px);
- overflow-y: auto;
- overflow-x: hidden;
- padding: 0 0 20px;
- }
- /* 头部 */
- .detail-header {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 0 14px;
- position: sticky;
- top: 0;
- background: #fff;
- z-index: 10;
- margin-bottom: 20px;
- .back-btn {
- width: 32px;
- height: 32px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 8px;
- cursor: pointer;
- color: #6b7280;
- transition: all 0.2s ease;
- &:hover {
- background: #f3f4f6;
- color: #374151;
- }
- }
- .detail-title {
- font-size: 16px;
- font-weight: 600;
- color: #1f2937;
- }
- }
- /* Banner */
- .detail-banner {
- margin: 0 14px 14px;
- border-radius: 12px;
- overflow: hidden;
- height: 140px;
- min-height: 140px;
- position: relative;
- box-sizing: border-box;
- .tool-overly {
- position: absolute;
- inset: 0;
- background-color: #f59e0b;
- opacity: .35;
- pointer-events: none;
- }
- .tool-icon-badge {
- position: absolute;
- top: 10px;
- left: 10px;
- width: 32px;
- height: 32px;
- border-radius: 8px;
- background: rgba(255, 255, 255, 0.95);
- display: flex;
- align-items: center;
- justify-content: center;
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
- svg {
- width: 18px;
- height: 18px;
- color: #f59e0b;
- }
- }
- img {
- width: 100%;
- height: 140px;
- object-fit: cover;
- display: block;
- }
- }
- /* 描述 */
- .detail-desc-row {
- display: flex;
- align-items: flex-start;
- gap: 8px;
- padding: 0 14px;
- .detail-desc-text {
- flex: 1;
- font-size: 13px;
- color: #4b5563;
- line-height: 1.6;
- }
- .help-icon {
- position: relative;
- color: #9ca3af;
- cursor: pointer;
- flex-shrink: 0;
- margin-top: 2px;
- &:hover {
- color: #FF9300;
- }
- .help-tooltip {
- position: absolute;
- top: 100%;
- right: 0;
- margin-top: 8px;
- width: 250px;
- background: #fff;
- border: 1px solid #e5e7eb;
- border-radius: 10px;
- padding: 14px;
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
- z-index: 100;
- .help-title {
- font-size: 13px;
- font-weight: 600;
- color: #1f2937;
- margin-bottom: 4px;
- margin-top: 8px;
- &:first-child {
- margin-top: 0;
- }
- }
- .help-text {
- font-size: 12px;
- color: #6b7280;
- margin-bottom: 4px;
- }
- .help-list {
- font-size: 12px;
- color: #4b5563;
- line-height: 1.6;
- .help-step {
- display: flex;
- align-items: flex-start;
- gap: 8px;
- padding: 3px 0;
- .step-num {
- flex-shrink: 0;
- width: 18px;
- height: 18px;
- margin-top: 1px;
- border-radius: 50%;
- background: #FF9300;
- color: #fff;
- font-size: 11px;
- font-weight: 600;
- line-height: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
- }
- .help-source,
- .help-purpose {
- font-size: 11px;
- color: #9ca3af;
- margin-top: 8px;
- line-height: 1.5;
- }
- }
- }
- }
- .detail-tags {
- display: flex;
- gap: 6px;
- padding: 10px 14px 0;
- .detail-tag {
- display: inline-block;
- padding: 3px 10px;
- font-size: 11px;
- color: #3b82f6;
- background: #eff6ff;
- border-radius: 4px;
- font-weight: 500;
- }
- }
- /* 配置区 */
- .config-section {
- padding: 20px 14px 12px;
- .config-title {
- font-size: 16px;
- font-weight: 600;
- color: #1f2937;
- margin-bottom: 6px;
- }
- .config-subtitle {
- font-size: 12px;
- color: #6b7280;
- line-height: 1.6;
- }
- }
- /* 配置卡片 */
- .config-card {
- margin: 0 14px;
- background: #f8f9fb;
- border-radius: 14px;
- padding: 8px 14px;
- }
- .config-row {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
- padding: 16px 0;
- border-bottom: 1px solid #eceef2;
- &:last-child {
- border-bottom: none;
- }
- .form-label {
- font-size: 14px;
- font-weight: 500;
- color: #374151;
- }
- .form-sublabel {
- font-size: 12px;
- color: #9ca3af;
- margin-top: 3px;
- line-height: 1.5;
- }
- &.config-row-borderless {
- border-bottom: none;
- padding-bottom: 8px;
- }
- }
- /* 使用者配置高亮行 */
- .config-row-highlight {
- background: #fff4e8;
- border-radius: 12px;
- border-bottom: none;
- padding: 16px;
- margin: 6px 0;
- .form-label {
- color: #1f2937;
- font-weight: 600;
- }
- .form-sublabel {
- color: #b0825c;
- }
- }
- /* 开关 */
- .toggle-switch {
- width: 44px;
- height: 24px;
- border-radius: 12px;
- background: #d1d5db;
- position: relative;
- cursor: pointer;
- transition: background 0.25s ease;
- flex-shrink: 0;
- .toggle-thumb {
- width: 20px;
- height: 20px;
- border-radius: 50%;
- background: #fff;
- position: absolute;
- top: 2px;
- left: 2px;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
- transition: transform 0.25s ease;
- }
- &.active {
- background: #FF9300;
- .toggle-thumb {
- transform: translateX(20px);
- }
- }
- }
- /* 高级配置 */
- .advanced-section {
- .advanced-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 12px 0;
- cursor: pointer;
- .advanced-title {
- font-size: 14px;
- font-weight: 600;
- color: #6b7280;
- }
- .advanced-arrow {
- color: #9ca3af;
- transition: transform 0.2s ease;
- &.expanded {
- transform: rotate(180deg);
- }
- }
- }
- .advanced-body {
- display: flex;
- flex-direction: column;
- }
- }
- /* 计时时长 / 帽子选择 */
- .timer-duration,
- .hats-select {
- padding: 4px 0 14px;
- .duration-label {
- font-size: 13px;
- font-weight: 500;
- color: #374151;
- margin-bottom: 10px;
- }
- }
- .duration-options {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- }
- .duration-chip {
- padding: 6px 14px;
- font-size: 12px;
- color: #6b7280;
- background: #fff;
- border: 1px solid #e5e7eb;
- border-radius: 999px;
- cursor: pointer;
- transition: all 0.2s ease;
- &:hover {
- border-color: #FF9300;
- color: #FF9300;
- }
- &.active {
- background: #FF9300;
- border-color: #FF9300;
- color: #fff;
- font-weight: 600;
- }
- }
- /* 自定义时长输入 */
- .custom-timer {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-top: 10px;
- input {
- width: 96px;
- padding: 8px 12px;
- border: 1px solid #e5e7eb;
- border-radius: 10px;
- font-size: 13px;
- color: #374151;
- background: #fff;
- outline: none;
- transition: border-color 0.2s ease;
- box-sizing: border-box;
- &::placeholder {
- color: #9ca3af;
- }
- &:focus {
- border-color: #FF9300;
- }
- // 隐藏 number 输入框的上下箭头
- &::-webkit-outer-spin-button,
- &::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
- &[type='number'] {
- -moz-appearance: textfield;
- appearance: textfield;
- }
- }
- .custom-unit {
- font-size: 13px;
- color: #6b7280;
- }
- }
- .hats-options {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- }
- .hat-chip {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- padding: 6px 12px;
- font-size: 12px;
- color: #9ca3af;
- background: #fff;
- border: 1px solid #e5e7eb;
- border-radius: 999px;
- cursor: pointer;
- transition: all 0.2s ease;
- .hat-dot {
- width: 10px;
- height: 10px;
- border-radius: 50%;
- background: #d1d5db;
- transition: background 0.2s ease;
- }
- &.hat-white.active {
- color: #374151;
- border-color: #d1d5db;
- background: #fff;
- .hat-dot { background: #f3f4f6; border: 1px solid #d1d5db; }
- }
- &.hat-red.active {
- color: #ef4444;
- border-color: #fecaca;
- background: #fef2f2;
- .hat-dot { background: #ef4444; }
- }
- &.hat-black.active {
- color: #fff;
- border-color: #374151;
- background: #4b5563;
- .hat-dot { background: #1f2937; }
- }
- &.hat-yellow.active {
- color: #b45309;
- border-color: #fde68a;
- background: #fffbeb;
- .hat-dot { background: #f59e0b; }
- }
- &.hat-green.active {
- color: #15803d;
- border-color: #bbf7d0;
- background: #f0fdf4;
- .hat-dot { background: #22c55e; }
- }
- &.hat-blue.active {
- color: #1d4ed8;
- border-color: #bfdbfe;
- background: #eff6ff;
- .hat-dot { background: #3b82f6; }
- }
- }
- /* 底部按钮 */
- .footer-btn {
- padding: 16px 14px 0;
- .add-btn {
- width: 100%;
- padding: 14px;
- background: #FF9300;
- color: #fff;
- font-size: 15px;
- font-weight: 600;
- text-align: center;
- border-radius: 12px;
- cursor: pointer;
- transition: all 0.2s ease;
- &:hover {
- background: #f57c00;
- transform: translateY(-1px);
- box-shadow: 0 4px 12px rgba(255, 147, 0, 0.3);
- }
- &:active {
- transform: translateY(0);
- }
- }
- }
- </style>
|