feat(user): 重构用户端竞赛流程,集成后端API并优化交互体验
- 新增 `activityinfo` store 管理活动信息,支持持久化 - 重构 `competition` store,分离数据层与流程控制,新增音效管理 - 新增游戏API模块 (`game.ts`),实现抽题、题目详情、提交结果等接口 - 用户端页面全面对接后端数据:首页轮播展示活动列表,组别/队伍页动态加载,封面页显示题目卡片 - 抽题页改为竹签翻转动画,游戏页集成题目详情与倒计时 - 优化布局组件,支持点击返回首页,统一路由参数传递 - 更新类型定义,支持富文本题目渲染 - 添加 `activityinfo` 拼写检查词条
This commit is contained in:
@ -1,81 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { ActivityNode } from '../types'
|
||||
|
||||
defineProps<{
|
||||
title: string
|
||||
nodes: ActivityNode[]
|
||||
}>()
|
||||
|
||||
defineEmits(['start'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full w-full flex flex-col items-center pt-24">
|
||||
<!-- 标题卷轴 -->
|
||||
<div class="relative mb-20">
|
||||
<!-- 卷轴主体 -->
|
||||
<div class="relative z-10 h-24 min-w-[400px] flex items-center justify-center border-2 border-orange-200 rounded-lg from-orange-100 to-orange-50 bg-gradient-to-b px-12 shadow-lg">
|
||||
<div class="absolute top-1/2 h-28 w-8 border-r-4 border-yellow-600 rounded-l-md bg-teal-700 shadow-md -left-4 -translate-y-1/2">
|
||||
<!-- 卷轴轴头 -->
|
||||
<div class="absolute left-1 top-2 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
<div class="absolute bottom-2 left-1 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
</div>
|
||||
<div class="absolute top-1/2 h-28 w-8 border-l-4 border-yellow-600 rounded-r-md bg-teal-700 shadow-md -right-4 -translate-y-1/2">
|
||||
<!-- 卷轴轴头 -->
|
||||
<div class="absolute right-1 top-2 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
<div class="absolute bottom-2 right-1 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
</div>
|
||||
|
||||
<!-- 飘带装饰 -->
|
||||
<div class="absolute h-12 w-24 rotate-12 transform rounded-full bg-green-200/50 blur-xl -right-12 -top-6 -z-10" />
|
||||
<div class="absolute h-12 w-24 transform rounded-full bg-green-200/50 blur-xl -bottom-6 -left-12 -z-10 -rotate-12" />
|
||||
|
||||
<h1 class="text-4xl text-gray-800 font-bold tracking-widest font-serif">
|
||||
{{ title }}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片列表 -->
|
||||
<div class="grid grid-cols-4 max-w-7xl w-full gap-8 px-12">
|
||||
<div
|
||||
v-for="(node) in nodes.slice(0, 4)"
|
||||
:key="node.nodeId"
|
||||
class="group relative cursor-default"
|
||||
>
|
||||
<!-- 卡片背景 (仿古风) -->
|
||||
<div class="relative aspect-[3/4] w-full flex flex-col items-center justify-center overflow-hidden border-4 border-orange-200 rounded-2xl bg-orange-50/80 shadow-lg transition-transform hover:-translate-y-2">
|
||||
<!-- 内部装饰圈 -->
|
||||
<div class="absolute inset-4 flex items-center justify-center border-2 border-orange-300/50 rounded-xl border-dashed">
|
||||
<!-- 云纹装饰 (CSS模拟) -->
|
||||
<div class="absolute h-12 w-12 rounded-full bg-teal-100/30 blur-md -left-4 -top-4" />
|
||||
<div class="absolute h-12 w-12 rounded-full bg-teal-100/30 blur-md -bottom-4 -right-4" />
|
||||
</div>
|
||||
|
||||
<!-- 文字内容 -->
|
||||
<div class="relative z-10 transform text-center -rotate-2">
|
||||
<div class="text-3xl text-gray-800 font-bold leading-tight font-serif drop-shadow-sm">
|
||||
<!-- 强制换行处理,每两个字换行或根据长度 -->
|
||||
<span class="block">{{ node.moduleName.slice(0, 2) }}</span>
|
||||
<span class="block">{{ node.moduleName.slice(2) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 准备开始按钮 -->
|
||||
<div class="fixed bottom-12 right-12">
|
||||
<button
|
||||
class="border-2 border-red-200 rounded-full from-red-400 to-red-500 bg-gradient-to-r px-10 py-3 text-xl text-white font-bold shadow-lg transition active:scale-95 hover:from-red-500 hover:to-red-600"
|
||||
@click="$emit('start')"
|
||||
>
|
||||
准备开始
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 可以添加一些古风字体或特定样式 */
|
||||
</style>
|
||||
@ -1,148 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { ActivityNode, Question } from '../types'
|
||||
import { computed } from 'vue'
|
||||
import { uiTemplatesMapping } from '../data/mock'
|
||||
import QuestionRenderer from './QuestionRenderer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
node: ActivityNode
|
||||
question: Question
|
||||
subStep: number
|
||||
timeLeft: number
|
||||
}>()
|
||||
|
||||
defineEmits(['back', 'next'])
|
||||
|
||||
const formattedTime = computed(() => {
|
||||
const m = Math.floor(props.timeLeft / 60)
|
||||
const s = props.timeLeft % 60
|
||||
return `${m}:${s < 10 ? `0${s}` : s}`
|
||||
})
|
||||
|
||||
// Mock chart data
|
||||
const chartData = [
|
||||
{ group: '第一组', total: 42, correct: 36 },
|
||||
{ group: '第二组', total: 20, correct: 16 },
|
||||
{ group: '第三组', total: 19, correct: 19 },
|
||||
{ group: '第四组', total: 17, correct: 14 },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative h-full w-full flex flex-col items-center px-12 pt-28">
|
||||
<!-- 顶部栏 -->
|
||||
<div class="relative z-10 mb-8 w-full flex items-center justify-between">
|
||||
<!-- 返回按钮 -->
|
||||
<button
|
||||
class="border-2 border-red-400 rounded-full bg-white px-8 py-2 text-lg text-red-500 font-bold shadow-md transition hover:bg-red-50"
|
||||
@click="$emit('back')"
|
||||
>
|
||||
返回
|
||||
</button>
|
||||
|
||||
<!-- 标题卷轴 -->
|
||||
<div class="absolute left-1/2 top-0 -translate-x-1/2">
|
||||
<div
|
||||
class="relative h-20 min-w-[300px] flex items-center justify-center border-2 border-orange-200 rounded-lg from-orange-100 to-orange-50 bg-gradient-to-b px-12 shadow-lg"
|
||||
>
|
||||
<div
|
||||
class="absolute top-1/2 h-24 w-6 border-r-4 border-yellow-600 rounded-l-md bg-teal-700 shadow-md -left-3 -translate-y-1/2"
|
||||
>
|
||||
<div class="absolute left-1 top-2 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
<div class="absolute bottom-2 left-1 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
</div>
|
||||
<div
|
||||
class="absolute top-1/2 h-24 w-6 border-l-4 border-yellow-600 rounded-r-md bg-teal-700 shadow-md -right-3 -translate-y-1/2"
|
||||
>
|
||||
<div class="absolute right-1 top-2 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
<div class="absolute bottom-2 right-1 h-2 w-full rounded-full bg-teal-600/50" />
|
||||
</div>
|
||||
<h1 class="text-3xl text-gray-800 font-bold tracking-widest font-serif">
|
||||
{{ node.moduleName }}
|
||||
<span class="text-sm text-red-500 font-bold">({{ uiTemplatesMapping[node.uiTemplate] }})</span>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 倒计时 -->
|
||||
<div class="border-2 border-red-400 rounded-full bg-white px-6 py-2 shadow-md">
|
||||
<span class="text-xl text-red-500 font-bold">倒计时 {{ formattedTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 题目说明 -->
|
||||
<div class="m-14 text-2xl text-gray-800 font-medium">
|
||||
{{ node.description }}
|
||||
</div>
|
||||
|
||||
<!-- 题目内容区域 -->
|
||||
<div class="flex-2 mb-4 w-full flex items-center justify-center">
|
||||
<QuestionRenderer
|
||||
:template="node.uiTemplate" :content="question.content"
|
||||
class="origin-center scale-150 transform"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 隐藏的 Next 按钮 (点击题目区域或键盘操作,这里为了演示保留一个透明层或仅通过逻辑触发,或者暂时放一个不易察觉的按钮用于测试) -->
|
||||
<div class="absolute inset-0 z-0" @click="$emit('next')" /> <!-- 点击背景切换下一题,方便演示 -->
|
||||
|
||||
<!-- 底部图表区域 -->
|
||||
<div
|
||||
class="relative z-20 mb-8 h-64 max-w-5xl w-full flex flex-col border-2 border-blue-300 rounded-xl bg-white/90 p-4 shadow-lg backdrop-blur"
|
||||
>
|
||||
<!-- 图表标题栏 -->
|
||||
<div class="mb-4 flex items-center justify-between px-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="h-3 w-3 rotate-45 bg-orange-400" />
|
||||
<span class="text-lg text-blue-800 font-bold">答题进度</span>
|
||||
</div>
|
||||
<div class="flex gap-6 text-sm">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="h-3 w-3 rounded-full bg-blue-400" />
|
||||
<span class="text-gray-600">答题数量</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="h-3 w-3 rounded-full bg-orange-300" />
|
||||
<span class="text-gray-600">正确数量</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 柱状图 -->
|
||||
<div class="flex flex-1 items-end justify-around px-8 pb-2">
|
||||
<div v-for="item in chartData" :key="item.group" class="w-16 flex flex-col items-center gap-2">
|
||||
<div class="h-32 flex items-end gap-2">
|
||||
<!-- Blue Bar -->
|
||||
<div
|
||||
class="relative w-6 rounded-t-md from-blue-500 to-blue-300 bg-gradient-to-t transition-all duration-1000"
|
||||
:style="{ height: `${item.total * 2}px` }"
|
||||
>
|
||||
<span class="absolute left-1/2 text-blue-800 font-bold -top-6 -translate-x-1/2">{{ item.total }}</span>
|
||||
</div>
|
||||
<!-- Orange Bar -->
|
||||
<div
|
||||
class="relative w-6 rounded-t-md from-orange-400 to-orange-200 bg-gradient-to-t transition-all duration-1000"
|
||||
:style="{ height: `${item.correct * 2}px` }"
|
||||
>
|
||||
<span class="absolute left-1/2 text-orange-600 font-bold -top-6 -translate-x-1/2">{{ item.correct
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 text-blue-800 font-bold">
|
||||
{{ item.group }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Question Renderer Override if needed */
|
||||
:deep(.question-content) {
|
||||
font-size: 4rem;
|
||||
color: #ef4444;
|
||||
/* red-500 */
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
@ -1,26 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { ActivityNode } from '../types'
|
||||
|
||||
defineProps<{ node: ActivityNode }>()
|
||||
defineEmits(['back', 'draw'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full w-full flex flex-col items-center pt-44">
|
||||
<div class="mb-20 max-w-4xl text-center">
|
||||
<div class="text-2xl text-gray-800 font-medium leading-relaxed tracking-wide">
|
||||
{{ node.description }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 抽题按钮 (大圆形) -->
|
||||
<div class="group relative">
|
||||
<button
|
||||
class="h-64 w-64 flex flex-col items-center justify-center border-4 border-blue-400 rounded-full bg-gray-200/80 text-3xl text-gray-700 font-bold shadow-xl transition-all active:scale-95 hover:scale-105"
|
||||
@click="$emit('draw')"
|
||||
>
|
||||
<span>抽题</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -9,7 +9,11 @@ const props = defineProps<{
|
||||
|
||||
const pinyinChars = computed(() => {
|
||||
if (props.template === 'TEMPLATE_WORD_DICTATION' && props.content.title) {
|
||||
return props.content.title.split(' ')
|
||||
// 创建临时元素提取HTML文本内容
|
||||
const div = document.createElement('div')
|
||||
div.innerHTML = props.content.title
|
||||
const text = div.textContent || ''
|
||||
return text.trim().split(/\s+/).filter(Boolean)
|
||||
}
|
||||
return []
|
||||
})
|
||||
@ -19,8 +23,12 @@ const pinyinChars = computed(() => {
|
||||
<div class="min-h-[400px] w-full flex items-center justify-center p-6">
|
||||
<!-- 模板A: 汉字听写-提示 (拼音+提示) -->
|
||||
<div v-if="template === 'TEMPLATE_DICTATION_HINT'" class="text-center">
|
||||
<div class="mb-6 inline-block text-5xl text-red-500 font-bold leading-none" style="text-shadow: 2px 2px 4px rgba(0,0,0,0.1);">
|
||||
“{{ content.title }}”
|
||||
<div
|
||||
class="mb-6 inline-block text-5xl font-bold leading-none"
|
||||
style="text-shadow: 2px 2px 4px rgba(0,0,0,0.1);"
|
||||
>
|
||||
<div class="rich-content" v-html="content.title" />
|
||||
<!-- “{{ content.title }}” -->
|
||||
</div>
|
||||
<!-- <div class="text-4xl text-gray-800 font-bold">
|
||||
{{ content.meta?.hint }}
|
||||
@ -29,15 +37,17 @@ const pinyinChars = computed(() => {
|
||||
|
||||
<!-- 模板B: 汉字听写-同音字 (大字) -->
|
||||
<div v-else-if="template === 'TEMPLATE_DICTATION_HOMOPHONE'" class="text-center">
|
||||
<div class="text-[100px] text-red-600 font-bold">
|
||||
“{{ content.title }}”
|
||||
<div class="homophone text-[100px] text-red-600 font-bold">
|
||||
<!-- “{{ content.title }}” -->
|
||||
<div class="rich-content" v-html="content.title" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模板C: 汉字加一加 (提示+部件) -->
|
||||
<div v-else-if="template === 'TEMPLATE_COMPONENT_ADD'" class="text-center">
|
||||
<div class="text-[100px] text-red-600 font-bold">
|
||||
{{ content.title }}
|
||||
<!-- {{ content.title }} -->
|
||||
<div class="rich-content" v-html="content.title" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -45,8 +55,7 @@ const pinyinChars = computed(() => {
|
||||
<div v-else-if="template === 'TEMPLATE_WORD_DICTATION'" class="flex flex-col items-center">
|
||||
<div class="mb-8 flex flex-wrap justify-center gap-6">
|
||||
<div
|
||||
v-for="(char, index) in pinyinChars"
|
||||
:key="index"
|
||||
v-for="(char, index) in pinyinChars" :key="index"
|
||||
class="relative h-32 w-32 flex select-none items-center justify-center border-2 border-red-500 bg-white"
|
||||
>
|
||||
<!-- 米字格背景 -->
|
||||
@ -71,7 +80,8 @@ const pinyinChars = computed(() => {
|
||||
<!-- 模板E: 成语-文字要求 -->
|
||||
<div v-else-if="template === 'TEMPLATE_IDIOM_TEXT_REQ'" class="text-center">
|
||||
<div class="mb-8 text-4xl text-gray-800 font-bold">
|
||||
{{ content.title }}
|
||||
<!-- {{ content.title }} -->
|
||||
<div class="rich-content" v-html="content.title" />
|
||||
</div>
|
||||
<!-- <div class="rounded bg-gray-100 px-4 py-2 text-xl text-gray-500">
|
||||
示例:{{ content.meta?.example }}
|
||||
@ -96,10 +106,7 @@ const pinyinChars = computed(() => {
|
||||
</div>
|
||||
<div class="options-container">
|
||||
<div
|
||||
v-for="(option, index) in content.options"
|
||||
:key="index"
|
||||
class="option-card group"
|
||||
:class="{
|
||||
v-for="(option, index) in content.options" :key="index" class="option-card group" :class="{
|
||||
'is-mixed': !option.renderType || option.renderType === 'mixed' || option.renderType === 'image',
|
||||
'is-text': option.renderType === 'text',
|
||||
}"
|
||||
@ -164,16 +171,21 @@ const pinyinChars = computed(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 0.75rem; /* rounded-xl */
|
||||
padding: 1rem; /* p-4 */
|
||||
border-radius: 0.75rem;
|
||||
/* rounded-xl */
|
||||
padding: 1rem;
|
||||
/* p-4 */
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: #f87171; /* border-red-400 */
|
||||
background-color: #fef2f2; /* bg-red-50 */
|
||||
border-color: #f87171;
|
||||
/* border-red-400 */
|
||||
background-color: #fef2f2;
|
||||
/* bg-red-50 */
|
||||
box-shadow:
|
||||
0 10px 15px -3px rgba(0, 0, 0, 0.1),
|
||||
0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg */
|
||||
0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
/* shadow-lg */
|
||||
}
|
||||
|
||||
&.is-mixed {
|
||||
@ -182,7 +194,8 @@ const pinyinChars = computed(() => {
|
||||
|
||||
&.is-text {
|
||||
flex-direction: row;
|
||||
gap: 1rem; /* gap-4 */
|
||||
gap: 1rem;
|
||||
/* gap-4 */
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,8 +207,10 @@ const pinyinChars = computed(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
border-radius: 0.5rem; /* rounded-lg */
|
||||
padding: 0.5rem; /* p-2 */
|
||||
border-radius: 0.5rem;
|
||||
/* rounded-lg */
|
||||
padding: 0.5rem;
|
||||
/* p-2 */
|
||||
}
|
||||
|
||||
.option-image {
|
||||
@ -211,14 +226,18 @@ const pinyinChars = computed(() => {
|
||||
|
||||
.tianzige-wrapper {
|
||||
position: relative;
|
||||
margin-bottom: 0.75rem; /* mb-3 */
|
||||
height: 8rem; /* h-32 */
|
||||
width: 8rem; /* w-32 */
|
||||
margin-bottom: 0.75rem;
|
||||
/* mb-3 */
|
||||
height: 8rem;
|
||||
/* h-32 */
|
||||
width: 8rem;
|
||||
/* w-32 */
|
||||
display: flex;
|
||||
user-select: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2px solid #ef4444; /* border-red-500 */
|
||||
border: 2px solid #ef4444;
|
||||
/* border-red-500 */
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
@ -236,7 +255,8 @@ const pinyinChars = computed(() => {
|
||||
top: 50%;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
border-top: 1px dashed #f87171; /* border-red-400 */
|
||||
border-top: 1px dashed #f87171;
|
||||
/* border-red-400 */
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
@ -246,7 +266,8 @@ const pinyinChars = computed(() => {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
border-left: 1px dashed #f87171; /* border-red-400 */
|
||||
border-left: 1px dashed #f87171;
|
||||
/* border-red-400 */
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
@ -258,43 +279,73 @@ const pinyinChars = computed(() => {
|
||||
}
|
||||
|
||||
.tianzige-text {
|
||||
font-family: 'KaiTi', 'STKaiti', serif; /* font-kaaiti */
|
||||
font-family: 'KaiTi', 'STKaiti', serif;
|
||||
/* font-kaaiti */
|
||||
z-index: 10;
|
||||
font-size: 3.75rem; /* text-6xl */
|
||||
font-size: 3.75rem;
|
||||
/* text-6xl */
|
||||
font-weight: 700;
|
||||
color: #1f2937; /* text-gray-800 */
|
||||
color: #1f2937;
|
||||
/* text-gray-800 */
|
||||
}
|
||||
|
||||
.option-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem; /* gap-3 */
|
||||
gap: 0.75rem;
|
||||
/* gap-3 */
|
||||
}
|
||||
|
||||
.option-label {
|
||||
height: 2rem; /* h-8 */
|
||||
width: 2rem; /* w-8 */
|
||||
height: 2rem;
|
||||
/* h-8 */
|
||||
width: 2rem;
|
||||
/* w-8 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 9999px; /* rounded-full */
|
||||
background-color: #fee2e2; /* bg-red-100 */
|
||||
color: #dc2626; /* text-red-600 */
|
||||
border-radius: 9999px;
|
||||
/* rounded-full */
|
||||
background-color: #fee2e2;
|
||||
/* bg-red-100 */
|
||||
color: #dc2626;
|
||||
/* text-red-600 */
|
||||
font-weight: 700;
|
||||
|
||||
.group:hover & {
|
||||
background-color: #ef4444; /* bg-red-500 */
|
||||
background-color: #ef4444;
|
||||
/* bg-red-500 */
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.option-text {
|
||||
font-size: 1.25rem; /* text-xl */
|
||||
color: #374151; /* text-gray-700 */
|
||||
font-size: 1.25rem;
|
||||
/* text-xl */
|
||||
color: #374151;
|
||||
/* text-gray-700 */
|
||||
font-weight: 500;
|
||||
|
||||
.group:hover & {
|
||||
color: #b91c1c; /* text-red-700 */
|
||||
color: #b91c1c;
|
||||
/* text-red-700 */
|
||||
}
|
||||
}
|
||||
|
||||
.homophone {
|
||||
:deep(img) {
|
||||
height: 230px !important;
|
||||
width: auto !important;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.rich-content {
|
||||
:deep(img) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user