8 Commits

Author SHA1 Message Date
rjl
e061f46e66 chore(config): 优化Kiro配置并调整UI组件样式
- 更新Kiro AI助手配置,新增强制语言和中文模式设置
- 添加用户排名背景框图片资源
- 优化CompetitionLayout组件标题样式(字体大小和字间距调整)
- 优化用户封面页面卡片布局,根据屏幕尺寸动态调整顶部padding
- 删除联想对对碰题库数据文件
2026-03-19 14:52:36 +08:00
rjl
7d49143ae0 feat(admin): 新增UUID生成工具并优化模板管理
- 新增 uuid.ts 工具函数,提供原生和兼容性 UUID 生成方案
- 更新模板详情页面,使用 generateUUID() 替代 crypto.randomUUID()
- 模板列表新增页码字段显示
- 优化模板列表组件代码格式,改进可读性
- 更新 Git 提交消息规范文档,强制使用中文描述和具体要求
2026-03-19 11:16:01 +08:00
rjl
d1f6044a6c chore(config): 配置 Kiro AI 助手并规范化 Git 提交消息
- 新增 .kiro/settings/kiro.json 配置文件,设置 AI 助手语言为中文
- 新增 .kiro/steering/chinese-commit-messages.md 文档,规范化项目 Git 提交消息格式
- 更新 .vscode/settings.json,添加 Kiro AI 助手和 Git 相关配置
- 优化 QuestionConfigCard.vue 中时间选项的排序逻辑
- 重新启用 cover/index.vue 中的 watch 监听器并优化代码格式
- 优化 teams/index.vue 的代码结构和可读性
2026-03-19 09:35:34 +08:00
rjl
9a80fd9fa1 feat(question-importer): Replace poetry knowledge with association game questions
- Add new association game question bank (联想对对碰.json) with 25 classical poetry matching questions
- Remove outdated poetry knowledge question set (诗词常识.json)
- Update store with new association game data
- Expand question variety to include poetry-based word association challenges
2026-03-18 17:52:44 +08:00
rjl
fe4d8f6d62 chore(admin): Update build configuration and ignore analysis reports
- Add report.html files to .gitignore to exclude analysis reports from version control
- Update build time configuration to include milliseconds for unique timestamps
- Add explanatory comment for build time millisecond precision
- Regenerate bundle analysis report with updated build configuration
2026-03-18 17:22:02 +08:00
rjl
1c8035d935 feat(admin): 优化字典管理界面并更新构建报告
- 优化字典列表页面交互与展示逻辑
- 改进字典类型模态框组件功能
- 更新构建分析报告数据
2026-03-18 17:14:07 +08:00
rjl
2fad025496 feat(admin): 新增品牌logo资源并优化用户界面组件
- 新增重庆、树人、文字logo资源(PNG和WebP格式)
- 新增用户界面背景图片资源(内容背景、对框、主页背景等)
- 优化ActionButton组件样式(自适应宽度、禁用状态样式)
- 更新CompetitionLayout组件header布局,集成新logo资源
- 优化TianZiGe组件功能和交互体验
- 更新竞赛相关页面组件(QuestionConfig、draw、QuestionRenderer等)
- 更新排名列表页面样式和功能
- 更新诗词常识题库数据
- 完善Competition类型定义
2026-03-18 16:58:13 +08:00
rjl
02b4720b34 feat(admin): 优化用户界面组件并新增自定义按钮样式
- 新增按钮背景图片资源(btn-bg.png、progress-title.png、title-bg3.png、title-bg4.png)
- 扩展 ActionButton 组件支持自定义按钮类型,新增 custom 类型用于背景图片驱动的按钮
- 添加 btnBg 和 fontSize 属性到 ActionButton,支持动态背景和字体大小配置
- 重构 ActionButton 样式结构,分离 standard-btn 和 custom-btn 两种按钮样式
- 优化按钮禁用状态的样式处理和交互反馈
- 更新 CompetitionLayout 组件支持新的标题背景类型(titleBg3、titleBg4)
- 新增 titleTextColor 和 fontSize 属性到 CompetitionLayout,增强标题和按钮的定制化能力
- 更新所有用户页面组件(cover、draw、game、groups、rules、teams)以适配新的按钮和布局配置
2026-03-17 17:51:12 +08:00
48 changed files with 659 additions and 451 deletions

4
.gitignore vendored
View File

@ -7,6 +7,10 @@ dist-ssr
apps/*/dist
packages/*/dist
# --- 分析报告文件 ---
report.html
apps/*/report.html
# --- 日志文件 ---
logs
*.log

9
.kiro/settings/kiro.json Normal file
View File

@ -0,0 +1,9 @@
{
"kiro.ai.language": "zh-CN",
"kiro.ai.commitMessage.language": "chinese",
"kiro.ai.commitMessage.forceLanguage": "zh-CN",
"kiro.git.commitMessageLanguage": "zh-CN",
"kiro.assistant.locale": "zh-CN",
"kiro.assistant.language": "chinese",
"kiro.assistant.alwaysUseChinese": true
}

View File

@ -0,0 +1,110 @@
---
inclusion: auto
---
# Git 提交消息规范
**重要:所有提交消息必须使用中文!**
本项目严格遵循 [Conventional Commits](https://www.conventionalcommits.org/) 规范。
## 提交消息格式
```
<type>(<scope>): <subject>
<body>
<footer>
```
### 必需部分
#### Type (类型)
提交的类型必须是以下之一:
- **feat**: 新功能 (feature)
- **fix**: 修复 bug
- **docs**: 仅文档更改
- **style**: 不影响代码含义的更改(空格、格式化、缺少分号等)
- **refactor**: 既不修复 bug 也不添加功能的代码更改
- **perf**: 提高性能的代码更改
- **test**: 添加缺失的测试或更正现有测试
- **build**: 影响构建系统或外部依赖的更改示例范围webpack, npm, vite
- **ci**: 对 CI 配置文件和脚本的更改示例范围GitHub Actions, GitLab CI
- **chore**: 其他不修改 src 或测试文件的更改
- **revert**: 回退之前的提交
#### Subject (主题)
- **必须使用中文描述**
- 使用简洁的语言描述本次提交的更改
- 不超过 50 个字符
- 首字母小写
- 结尾不加句号
### 可选部分
#### Scope (范围)
用于说明提交影响的范围,例如:
- **component**: 组件相关
- **api**: API 相关
- **router**: 路由相关
- **store**: 状态管理相关
- **utils**: 工具函数相关
- **styles**: 样式相关
- **deps**: 依赖项相关
#### Body (正文)
- 详细描述本次提交的动机和更改内容
- 可以分多行
- 应该说明"是什么"和"为什么",而不是"怎么做"
#### Footer (页脚)
- 用于关闭 Issue 或描述破坏性变更
- Breaking Changes 必须在页脚中以 `BREAKING CHANGE:` 开头
- 关闭 Issue 使用 `Closes #issue号`
## 示例(必须使用中文)
### 简单的功能添加
```
feat(article): 添加文章搜索功能
```
### 修复 bug
```
fix(login): 修复登录状态未持久化的问题
```
### 包含详细描述
```
feat(editor): 支持 markdown 实时预览
添加了一个新的编辑器组件,支持 markdown 的实时预览功能。
用户在编辑时可以同时看到渲染后的效果,提升编辑体验。
Closes #123
```
### 破坏性变更
```
feat(api): 重构用户认证 api
BREAKING CHANGE: 用户认证接口从 /api/auth 迁移到 /api/v2/auth
旧接口将在下一个版本中移除。客户端需要更新 API 端点。
```
## 重要规则
1. **严格遵循格式**: `<type>(<scope>): <subject>`
2. **type 必须小写**: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
3. **subject 必须使用中文**: 不要使用英文描述
4. **subject 首字母小写**: 不要大写开头
5. **subject 不加句号**: 结尾不要加标点符号
6. **不超过 50 字符**: subject 部分要简洁
7. **破坏性变更**: 必须在 body 中以 `BREAKING CHANGE:` 开头说明
## 生成提交消息时的要求
- 始终使用中文
- 动词开头(如:添加、修复、更新、优化、重构)
- 描述要具体,避免模糊的表述
- 如果有多个更改,选择最主要的作为 subject

14
.vscode/settings.json vendored
View File

@ -42,5 +42,17 @@
"Echarts",
"Typeit"
],
"kiroAgent.configureMCP": "Disabled" // `
// Kiro AI 助手配置
"kiroAgent.configureMCP": "Disabled",
"kiro.ai.language": "zh-CN",
"kiro.ai.commitMessage.language": "chinese",
"kiro.git.commitMessageLanguage": "zh-CN",
"kiro.assistant.locale": "zh-CN",
// Git 配置
"git.inputValidationLength": 72,
// GitHub Copilot 语言设置(如果安装了)
"github.copilot.chat.localeOverride": "zh-CN"
}

View File

@ -6,7 +6,9 @@ export function getBuildTime() {
dayjs.extend(utc)
dayjs.extend(timezone)
const buildTime = dayjs.tz(Date.now(), 'Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss')
// 添加随机毫秒确保每次构建时间唯一
const now = Date.now()
const buildTime = dayjs.tz(now, 'Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss.SSS')
return buildTime
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
// import { defineProps, defineEmits } from 'vue';
import { computed } from 'vue'
import defaultBtnBg from '@/assets/imgs/user/btn-bg.png'
const props = defineProps({
text: {
@ -15,13 +16,25 @@ const props = defineProps({
default: 'primary',
},
type: {
type: String as () => 'button' | 'text',
type: String as () => 'button' | 'text' | 'custom',
default: 'button',
},
btnBg: {
type: String,
default: defaultBtnBg,
},
fontSize: {
type: Number,
default: 30,
},
})
const emits = defineEmits(['click'])
const isCustom = computed(() => props.type === 'custom')
const customBg = computed(() => `url(${props.btnBg}) no-repeat center / 100% 100%`)
function handleClick() {
if (!props.disabled) {
emits('click')
@ -32,33 +45,52 @@ function handleClick() {
<template>
<button
class="action-btn"
:class="[theme, { 'is-disabled': disabled, 'text-btn': type === 'text' }]"
:class="[
isCustom ? 'custom-btn' : 'standard-btn',
theme,
type,
{ 'is-disabled': disabled },
]"
@click="handleClick"
>
<span v-if="type === 'text'" class="btn-text">{{ text }}</span>
<span v-if="type === 'text' || type === 'custom'" class="btn-text">{{ text }}</span>
<slot v-else />
</button>
</template>
<style lang="scss" scoped>
.action-btn {
width: 50px;
height: 50px;
border-radius: 50%;
border: none;
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
border: none;
outline: none;
font-family: inherit;
&.is-disabled {
cursor: not-allowed;
filter: grayscale(1);
opacity: 0.7;
&:hover,
&:active {
transform: none !important;
box-shadow: inherit !important;
}
}
}
// standard: type="button" | type="text"
.standard-btn {
width: 50px;
height: 50px;
border-radius: 50%;
color: white;
background: #eb5e55;
box-shadow: 0 8px 0 #fcc64f;
.arrow-icon {
font-size: 32px;
}
&:hover {
transform: translateY(-2px);
filter: brightness(1.05);
@ -70,7 +102,17 @@ function handleClick() {
box-shadow: 0 2px 0 #fcc64f;
}
&.text-btn {
&.light {
background: white;
color: #eb5e55;
border: 2px solid #eb5e55;
&:hover {
background-color: #fff;
}
}
&.text {
width: auto;
min-width: 180px;
padding: 0 30px;
@ -82,35 +124,38 @@ function handleClick() {
letter-spacing: 2px;
}
}
&.is-disabled {
cursor: not-allowed;
&:hover {
transform: none;
}
&:active {
transform: none;
}
}
}
.light {
background: white;
color: #eb5e55;
border: 2px solid #eb5e55;
box-shadow: 0 8px 0 #fcc64f;
// custom: type="custom",背景完全由 btnBg 决定
.custom-btn {
background: v-bind(customBg);
background-color: transparent;
min-width: 210px;
width: auto;
height: 60px;
padding: 0 20px;
box-shadow: none;
color: rgb(0, 94, 174);
.btn-text {
font-size: v-bind('`${fontSize}px`');
font-weight: bold;
letter-spacing: 2px;
margin-bottom: 7px;
}
&.is-disabled {
color: #eb5e55;
filter: none;
opacity: 1;
}
&:hover {
background-color: #fff;
transform: translateY(-3px);
box-shadow: 0 10px 0 #fcc64f;
transform: scale(1.05);
}
&:active {
transform: translateY(4px);
box-shadow: 0 2px 0 #fcc64f;
transform: scale(0.95);
}
}
</style>

View File

@ -2,8 +2,13 @@
<script lang="ts" setup>
import VScaleScreen from 'v-scale-screen'
import { computed, onMounted, ref, watch } from 'vue'
import _defaultBg from '@/assets/imgs/user/home-bg.webp'
import cqLogo from '@/assets/imgs/logo/cq-logo.webp'
import srLogo from '@/assets/imgs/logo/qw-logo.webp'
import qwLogo from '@/assets/imgs/logo/text-logo.webp'
import _defaultBg from '@/assets/imgs/user/home-bg1.webp'
import titleBg2 from '@/assets/imgs/user/title-bg2.webp'
import titleBg3 from '@/assets/imgs/user/title-bg3.png'
import titleBg4 from '@/assets/imgs/user/title-bg4.png'
import _defaultTitleBg from '@/assets/imgs/user/title-bg.webp'
import { useRouterPush } from '@/hooks/common/router'
@ -36,6 +41,10 @@ interface Props {
showNextBtn2?: boolean
/** 第二个按钮的文本 */
nextBtnText2?: string
/** title 颜色 */
titleTextColor?: string
/* 按钮字体大小 */
fontSize?: number
}
const props = withDefaults(defineProps<Props>(), {
@ -52,6 +61,8 @@ const props = withDefaults(defineProps<Props>(), {
titleBgType: 1,
showNextBtn2: false,
nextBtnText2: undefined,
titleTextColor: '#000000',
fontSize: 30,
})
const emit = defineEmits<{
@ -63,6 +74,8 @@ const emit = defineEmits<{
const titleBgUrlMapping: Record<number, string> = {
1: _defaultTitleBg,
2: titleBg2,
3: titleBg3,
4: titleBg4,
}
const { routerPushByKey } = useRouterPush()
@ -214,11 +227,22 @@ watch(titleBgUrl, (newUrl) => {
<VScaleScreen width="2048" height="1080">
<div class="competition-layout">
<!-- Header -->
<!-- <header class="page-header flex items-center text-[30px] text-[#333333] font-bold">
<span class="org-name" @click="handleBackHome">重庆市教育学会</span>
<img src="@/assets/imgs/ydzx.png" width="100" height="50" alt="logo" class="logo">
<span class="org-name">树人教育研究院</span>
</header> -->
<header class="page-header flex items-center px-8 text-[30px] text-[#333333] font-bold">
<!-- 左侧logo -->
<div class="flex cursor-pointer items-center" @click="handleBackHome">
<img :src="cqLogo" alt="重庆logo" class="h-20 w-auto">
</div>
<!-- 中间文字 -->
<div class="flex flex-1 justify-center">
<img :src="qwLogo" alt="重庆logo" class="h-14 w-auto">
</div>
<!-- 右侧logo组 -->
<div class="flex items-center justify-end gap-4">
<img :src="srLogo" alt="树人logo" class="h-19 w-auto">
</div>
</header>
<div class="glass-overlay">
<!-- title -->
@ -228,21 +252,14 @@ watch(titleBgUrl, (newUrl) => {
<div class="scroll-bg">
<!-- 预渲染所有背景图 opacity 切换避免加载抖动 -->
<img
v-for="(url, _key) in titleBgUrlMapping"
:key="_key"
:src="url"
class="scroll-bg-img"
:class="{
v-for="(url, _key) in titleBgUrlMapping" :key="_key" :src="url" class="scroll-bg-img" :class="{
active: titleBgUrl === url && imageLoadStatus[url] !== false,
loading: imageLoadStatus[url] === undefined,
}"
:style="{ visibility: imageLoadStatus[url] === false ? 'hidden' : 'visible' }"
aria-hidden="true"
@load="imageLoadStatus[url] = true"
@error="imageLoadStatus[url] = false"
}" :style="{ visibility: imageLoadStatus[url] === false ? 'hidden' : 'visible' }" aria-hidden="true"
@load="imageLoadStatus[url] = true" @error="imageLoadStatus[url] = false"
>
<Transition name="fade-in-delay" appear>
<h1 v-if="showContent" class="main-title">
<h1 v-if="showContent" class="main-title" :style="{ color: titleTextColor }">
{{ title }}
</h1>
</Transition>
@ -260,14 +277,13 @@ watch(titleBgUrl, (newUrl) => {
<!-- Footer Action -->
<footer
v-if="showButton"
class="page-footer w-full flex items-center justify-between px-20"
v-if="showButton" class="page-footer w-full flex items-center justify-between px-20"
:class="[actionPosition, btnTheme]"
>
<div class="left">
<ActionButton
class="back-btn" :style="{ visibility: showBack ? 'visible' : 'hidden' }"
:type="backBtnText ? 'text' : 'button'" :text="backBtnText || ''" :theme="btnTheme" @click="handleBack"
class="back-btn" :style="{ visibility: showBack ? 'visible' : 'hidden' }" type="custom"
:text="backBtnText || ''" :theme="btnTheme" :font-size="fontSize" @click="handleBack"
>
<SvgIcon v-if="!backBtnText" icon="mdi:arrow-left" size="40" class="arrow-icon" />
</ActionButton>
@ -275,8 +291,8 @@ watch(titleBgUrl, (newUrl) => {
<div class="right">
<ActionButton
v-if="showNext" :type="nextBtnText ? 'text' : 'button'" :text="nextBtnText || '下一步'"
:theme="btnTheme" :disabled="nextDisabled" @click="handleNext"
v-if="showNext" type="custom" :text="nextBtnText || '下一步'" :theme="btnTheme"
:disabled="nextDisabled" :font-size="fontSize" @click="handleNext"
>
<SvgIcon v-if="!nextBtnText" icon="mdi:arrow-right" class="arrow-icon" size="40" />
</ActionButton>
@ -301,25 +317,29 @@ watch(titleBgUrl, (newUrl) => {
width: 412px;
height: 165px;
display: flex;
justify-content: center; /* Ensure wrapper stays centered during expansion */
justify-content: center;
/* Ensure wrapper stays centered during expansion */
.title-wrapper {
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
justify-content: center; /* Keep the background image centered */
justify-content: center;
/* Keep the background image centered */
}
.scroll-bg {
width: 400px !important; /* Fixed width to prevent squishing during animation */
width: 400px !important;
/* Fixed width to prevent squishing during animation */
height: 155px !important;
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 10px;
flex-shrink: 0; /* Prevent shrinking */
flex-shrink: 0;
/* Prevent shrinking */
.scroll-bg-img {
position: absolute;
@ -343,12 +363,13 @@ watch(titleBgUrl, (newUrl) => {
}
.main-title {
font-size: 2.5rem;
font-size: 2.4rem;
color: $text-color;
margin: 0;
letter-spacing: 4px;
letter-spacing: 3px;
text-align: center;
white-space: nowrap; /* Prevent text wrapping */
white-space: nowrap;
/* Prevent text wrapping */
position: relative;
z-index: 1;
}
@ -423,7 +444,7 @@ watch(titleBgUrl, (newUrl) => {
.page-header {
position: absolute;
top: 0;
top: -20px;
left: 0;
width: 100%;
display: flex;
@ -477,7 +498,8 @@ watch(titleBgUrl, (newUrl) => {
.fade-in-delay-enter-active {
transition: opacity 0.8s ease;
transition-delay: 1s; /* Wait for scroll to unfold */
transition-delay: 1s;
/* Wait for scroll to unfold */
}
.fade-in-delay-enter-from {

View File

@ -43,6 +43,3 @@ const _props = withDefaults(defineProps<Props>(), {
<slot />
</div>
</template>
<style scoped>
</style>

View File

@ -106,6 +106,8 @@ declare namespace Api {
Image: string
ImageUrl: string
Answer: string
KeyWordsIndex?: number
KeyWord?: string
}
/** get current question params */

View File

@ -0,0 +1,16 @@
/**
* 生成UUID的兼容函数
* 优先使用原生 crypto.randomUUID如果不支持则使用兼容方案
*/
export function generateUUID(): string {
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
return crypto.randomUUID()
}
// 兼容性回退方案 - 生成符合 UUID v4 格式的字符串
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0
const v = c === 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { NButton, NForm, NFormItem, NInputNumber, NModal, NSelect, type SelectOption } from 'naive-ui'
import { onMounted, ref, watch } from 'vue'
import { computed, onMounted, ref, watch } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import { useDict } from '@/hooks/business/useDict'
import { fetchGetQuestionListAll } from '@/service/api/question'
@ -29,7 +29,10 @@ const props = defineProps<{
const { options: roundTypeOptions } = useDict('round_type')
const { options: scoreTypeOptions } = useDict('score_type')
const { options: timeOptions } = useDict('time_out')
const { options: timeOptionsRaw } = useDict('time_out')
const timeOptions = computed(() =>
[...timeOptionsRaw.value].sort((a, b) => Number(a.value) - Number(b.value)),
)
// const { options: uiTypeOptions } = useDict('ui_type', 'string')
const { options: uiTypeOptions } = useDict('question_category_name', 'string')

View File

@ -41,8 +41,10 @@ const modelValue = ref<{
const { options: roundTypeOptions } = useDict('round_type')
const { options: scoreTypeOptions } = useDict('score_type')
const { options: timeOptions } = useDict('time_out')
// const { options: uiTypeOptions } = useDict('ui_type', 'string')
const { options: timeOptionsRaw } = useDict('time_out')
const timeOptions = computed(() =>
[...timeOptionsRaw.value].sort((a, b) => Number(a.value) - Number(b.value)),
)
const { options: uiTypeOptions } = useDict('question_category_name', 'string')
const hookProps = reactive({

View File

@ -23,7 +23,6 @@ function handleAdd() {
}
async function handleCopy(item: Api.Competition.CompetitionItem) {
// TODO: 实现复制逻辑
try {
const { error } = await fetchCopyActivity(item.Id)
if (error) {
@ -163,7 +162,3 @@ onMounted(() => fetchActivityList())
<CompetitionAddModal v-model:show="showAddModal" @success="fetchActivityList" />
</NSpace>
</template>
<style scoped>
/* 针对不同屏幕微调间距 */
</style>

View File

@ -57,6 +57,14 @@ async function fetchData() {
// 列定义
const columns: DataTableColumns<Api.Dictionary.DictionaryItem> = [
{
title: '序号',
key: 'index',
width: 80,
render(_, index) {
return index + 1
},
},
{ title: 'ID', key: 'Id' },
{
title: '字典键 (Key)',

View File

@ -59,6 +59,14 @@ watch(() => props.visible, (val) => {
})
const columns: DataTableColumns<any> = [
{
title: '序号',
key: 'index',
width: 80,
render(_, index) {
return index + 1
},
},
{ title: 'ID', key: 'ID', width: 80 },
{ title: '键 (Key)', key: 'UI_Key' },
{ title: '值 (Value)', key: 'UI_Value', width: 100 },

View File

@ -151,7 +151,7 @@ function edit(item: any) {
<template #header>
<div class="flex items-center justify-between">
<div class="mid-title">
<div class="text-16px font-bold">
<div class="text-2xl font-bold">
{{ rankTitle }}
</div>
<div class="mt-4px text-12px text-gray-500">

View File

@ -241,9 +241,9 @@ async function fetchQuestions() {
}
/**
* 获取当前正在比赛的题目
* 获取当前正在比赛的题目(不触发同步选中逻辑)
*/
async function fetchCurrentQuestion() {
async function fetchCurrentQuestion(shouldSync = true) {
if (!roomId.value)
return
try {
@ -254,8 +254,10 @@ async function fetchCurrentQuestion() {
}
currentQuestion.value = data?.data || {}
console.warn('current question', currentQuestion.value)
// 拉取当前题目信息后尝试同步选中题
syncCurrentQuestionSelection()
// 只在初始化时同步选中题,轮询时不同步
if (shouldSync) {
syncCurrentQuestionSelection()
}
}
catch (error: any) {
message.error(error.message || '获取当前题目失败')
@ -467,8 +469,8 @@ async function handleNexCurrentQuestion() {
function handlePublish() {
const endTimeStr = (currentQuestion.value as any)?.EndTime
if (endTimeStr && Date.now() < new Date(endTimeStr).getTime()) {
window.$message?.warning('倒计时未结束,暂不能发布')
if (endTimeStr && Date.now() < new Date(endTimeStr).getTime() + 5000) {
window.$message?.warning('倒计时未结束需等待5秒延迟,暂不能发布')
return
}
if (currentQuestion.value?.TeamGroupQuestionID) {
@ -583,7 +585,8 @@ const canPublish = computed(() => {
const endTime = (currentQuestion.value as any)?.EndTime
if (!endTime)
return true
const end = new Date(endTime).getTime()
// 结束时间 + 5秒延迟才能发布
const end = new Date(endTime).getTime() + 5000
return nowTs.value >= end
})
@ -593,7 +596,7 @@ function startPolling() {
// 检查是否已经结束
const endTime = (currentQuestion.value as any)?.EndTime
if (endTime) {
// 增加 8s 缓冲时间
// 增加 12s 缓冲时间
const end = new Date(endTime).getTime() + 12000
const now = new Date().getTime()
if (now > end) {
@ -616,7 +619,7 @@ function startPolling() {
// 每次轮询前再次检查是否过期
const currentEndTime = (currentQuestion.value as any)?.EndTime
if (currentEndTime) {
// 增加 8s 缓冲时间
// 增加 12s 缓冲时间
const endTs = new Date(currentEndTime).getTime() + 12000
if (Date.now() > endTs) {
console.log('题目时间已到含12s缓冲停止轮询', currentEndTime)
@ -625,6 +628,9 @@ function startPolling() {
}
}
nowTs.value = Date.now()
// 轮询时同时更新当前题目信息(获取最新的 EndTime但不触发同步
fetchCurrentQuestion(false)
fetchAnswerData()
}, 3000)
}
@ -681,7 +687,7 @@ watch(() => currentQuestionDetailID.value, (newVal) => {
onMounted(async () => {
// 并行拉取分组、题目与当前题目,完成后做一次同步
await Promise.all([fetchGroups(), fetchQuestions(), fetchCurrentQuestion()])
await Promise.all([fetchGroups(), fetchQuestions(), fetchCurrentQuestion(true)])
syncCurrentQuestionSelection()
startPolling()
})

View File

@ -7,6 +7,7 @@ import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { useRouterPush } from '@/hooks/common/router'
import { fetchAddTemplate, fetchTemplateDetail } from '@/service/api/template'
import { generateUUID } from '@/utils/uuid'
import { useUpload } from './hooks/useUpload'
import TemplateCanvas from './modules/TemplateCanvas.vue'
import TemplateSettings from './modules/TemplateSettings.vue'
@ -64,7 +65,7 @@ function handleUploadTrigger() {
* 处理区域生成
*/
function handleGenerate() {
const groupId = crypto.randomUUID()
const groupId = generateUUID()
const newRegions: Region[] = []
// 计算起始编号:查找现有的最大 Qx 编号
@ -85,7 +86,7 @@ function handleGenerate() {
for (let c = 0; c < genSettings.value.cols; c++) {
const index = maxNum + r * genSettings.value.cols + c + 1 // 计算当前区域的编号
newRegions.push({
id: crypto.randomUUID(),
id: generateUUID(),
groupId,
x: currentX + c * (genSettings.value.w + genSettings.value.gapX),
y: currentY + r * (genSettings.value.h + genSettings.value.gapY),

View File

@ -66,6 +66,11 @@ const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagi
title: '模板ID',
align: 'center',
},
{
key: 'PageNo',
title: '页码',
align: 'center',
},
{
key: 'competitionId',
title: '关联比赛',

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { computed, onMounted, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import CompetitionLayout from '@/components/custom/user/CompetitionLayout.vue'
import { PublishStatus } from '@/enum/business'
@ -30,12 +30,12 @@ const activityName = computed(() => activityInfo.value?.ActivityTitle || '星·
const flippedCards = ref<Set<number>>(new Set())
// 计算是否所有卡片都已翻转 (当前显示4张卡片)
// eslint-disable-next-line unused-imports/no-unused-vars
const isAllFlipped = computed(() => flippedCards.value.size === questions.value.length)
// 控制下一步按钮的显示(带延迟)
const showNextButton = ref(true)
// eslint-disable-next-line prefer-const, unused-imports/no-unused-vars
let timer: ReturnType<typeof setTimeout> | null = null
// 获取路由参数
@ -77,21 +77,21 @@ async function getQuestions() {
}
}
// 测试先注释掉
// watch(isAllFlipped, (val) => {
// if (timer) {
// clearTimeout(timer)
// timer = null
// }
watch(isAllFlipped, (val) => {
if (timer) {
clearTimeout(timer)
timer = null
}
// if (val) {
// timer = setTimeout(() => {
// showNextButton.value = true
// }, 1500)
// }
// else {
// showNextButton.value = false
// }
// })
if (val) {
timer = setTimeout(() => {
showNextButton.value = true
}, 1500)
}
else {
showNextButton.value = false
}
})
function handleBack() {
routerBack()
@ -150,6 +150,15 @@ async function initSyncRouteParams() {
const showCards = ref(false)
// 计算每排卡片数量(根据不同屏幕尺寸)
// 默认按最小屏幕2列计算如果超过2排则调整padding
const needCompactPadding = computed(() => {
// 假设最小屏幕每排2个卡片w-[44%]
const cardsPerRow = 2
const totalRows = Math.ceil(questions.value.length / cardsPerRow)
return totalRows > 2
})
// 3D 悬停效果逻辑
const cardStyles = ref<Record<number, any>>({})
@ -196,11 +205,11 @@ onMounted(async () => {
<template>
<CompetitionLayout
:show-back="true" :show-next="showNextButton" next-btn-text="下一步" :title="activityName"
:title-bg-type="2" @back="handleBack" @next="handleNext"
:title-bg-type="2" back-btn-text="返回" @back="handleBack" @next="handleNext"
>
<div class="h-screen w-full overflow-y-auto font-sans">
<div class="relative z-10 min-h-full w-full">
<div class="min-h-full w-full flex flex-col items-center pb-12 pt-24">
<div class="min-h-full w-full flex flex-col items-center pb-12" :class="needCompactPadding ? 'pt-4' : 'pt-24'">
<!-- 卡片列表 -->
<TransitionGroup
tag="div" name="card-anim"

View File

@ -132,16 +132,19 @@ function handleBack() {
const questionMainTitle = computed(() => question.value?.QuestionList?.Name || '')
const questionTitle = computed(() => question.value?.QuestionList?.QuestionContent || question.value?.QuestionList?.Name || '')
const titleBgTypeNum = computed(() => RoundType.value === 0 ? 3 : 4)
</script>
<template>
<CompetitionLayout
:show-back="true" :show-next="true" :title="questionMainTitle || '抽题'" next-btn-text="开始抽题"
:show-back="true" :show-next="true" back-btn-text="返回" :title="questionMainTitle || '抽题'" next-btn-text="开始抽题"
:title-bg-type="titleBgTypeNum || 3" title-text-color="#ffffff"
@next="handleCardClick(question as Api.Competition.CurrentQuestionResponse)" @back="handleBack"
>
<div class="h-full w-full flex flex-col items-center pt-10 font-sans">
<div v-if="question" class="mb-10 max-w-4xl text-center">
<div class="text-2xl text-gray-800 font-medium leading-relaxed tracking-wide">
<div class="text-4xl text-gray-800 font-medium leading-relaxed tracking-wide">
{{ questionTitle || '' }}
</div>
</div>
@ -169,7 +172,10 @@ const questionTitle = computed(() => question.value?.QuestionList?.QuestionConte
}}</span>
</div> -->
<!-- 禁用放大 -->
<NImage :src="drawImg" class="h-full w-full object-cover" width="300" height="300" :preview-disabled="true" />
<NImage
:src="drawImg" class="h-full w-full object-cover" width="300" height="300"
:preview-disabled="true"
/>
</div>
</div>
</div>

View File

@ -20,6 +20,7 @@ const { activityId, groupId, activityInfo, teamId, teamIds } = storeToRefs(activ
const currentQuestionInfo = computed(() => store.currentQuestionInfo)
const currentQuestionDetail = computed(() => store.currentQuestionDetail)
const currentQuestionMainInfo = computed(() => store.currentQuestionMainInfo)
const RoundType = computed(() => store.currentQuestionMainInfo?.Activity_Question?.RoundType)
const loading = ref(false)
@ -246,13 +247,16 @@ async function fetchGetGameStatisticsData(_params: Api.Competition.QuestionAddPa
}
}
}
const titleBgTypeNum = computed(() => RoundType.value === 0 ? 3 : 4) || 3
</script>
<template>
<CompetitionLayout
action-position="top" :show-back="false" :show-next="true" :title="mainTitle || ''"
back-btn-text="返回" :next-btn-text="isStarted ? formattedTime : '开始答题'" :next-disabled="isStarted" btn-theme="light"
@back="handleBack" @next="handleNext"
:title-bg-type="titleBgTypeNum" title-text-color="#ffffff" back-btn-text="返回"
:next-btn-text="isStarted ? formattedTime : '开始答题'" :next-disabled="isStarted" btn-theme="light" @back="handleBack"
@next="handleNext"
>
<div class="relative h-full w-full flex flex-col items-center overflow-hidden px-12 font-sans">
<!-- 题目说明 -->

View File

@ -83,7 +83,7 @@ onMounted(() => {
<template>
<CompetitionLayout
:show-back="true" :show-next="isAllEnd" next-btn-text="查看常规赛结果" next-btn-text2="查看加时赛结果"
:show-back="true" back-btn-text="返回" :show-next="isAllEnd" next-btn-text="查看常规赛结果" font-size="22" next-btn-text2="查看加时赛结果"
:show-next-btn2="hasExtraTime && isAllEnd" :title-bg-type="2" title="展示组别" @back="handleBack" @next="handleNext"
@next2="handleNext2"
>

View File

@ -1,77 +1,65 @@
<script setup lang="ts">
import { computed, watch } from 'vue'
import TianZiGe from '@/components/custom/user/TianZiGe.vue'
import { QuestionCategoryEnum } from '@/enum/business'
import { useCompetitionStore } from '@/store/modules/competition'
const store = useCompetitionStore()
const currentQuestionMainInfo = computed(() => store.currentQuestionMainInfo)
const currentQuestionDetail = computed(() => store.currentQuestionDetail)
// console.log(currentQuestionMainInfo.value, 'currentQuestionMainInfo')
// 题目
const title = computed(() => currentQuestionMainInfo.value?.QuestionList?.QuestionContent)
// 题目内容
const content = computed(() => currentQuestionDetail.value.Name)
// 图片
const ImageUrl = computed(() => currentQuestionDetail.value.ImageUrl)
// 模版类型
const template = computed(() => currentQuestionMainInfo.value?.Activity_Question?.UIType)
/**
* 组合后的标题(用于汉字加一加模板)
* 将 content 插入到 title 的引号中,并拆分以支持不同样式
*/
const parsedComponentAddTitle = computed(() => {
const t = title.value || ''
const c = content.value || ''
// 尝试替换全角空引号
if (t.includes('“”')) {
const [prefix, suffix] = t.split('“”')
return {
type: 'quote_full',
prefix,
content: c,
suffix,
}
}
// 尝试替换半角空引号
if (t.includes('""')) {
const [prefix, suffix] = t.split('""')
return {
type: 'quote_half',
prefix,
content: c,
suffix,
}
}
// 如果没有找到空引号,直接追加
return {
type: 'normal',
prefix: t,
content: c,
suffix: '',
}
})
/** 获取富文本里面的text */
const pinyinChars = computed(() => {
// 汉字听写1按 # 分割内容
const dictationParts = computed(() => {
if (content.value) {
// 创建临时元素提取HTML文本内容
const div = document.createElement('div')
div.innerHTML = content.value
const text = div.textContent || ''
return text.trim().split(/\s+/).filter(Boolean)
return content.value.split('#').filter(Boolean)
}
return []
})
// 联想对对碰:上方词组
const associationWords = computed(() => {
const name = currentQuestionDetail.value?.Name || ''
return name.split(/[,,、]/).filter(Boolean)
})
// 联想对对碰:答案按逗号分行,只保留汉字
const answerLines = computed(() => {
const answer = currentQuestionDetail.value?.Answer || ''
return answer.split(/[,]/)
.map(line => line.split('').filter(char => /[\u4E00-\u9FA5]/.test(char)))
.filter(line => line.length > 0)
})
// 联想对对碰:关键词索引和文字
const keywordInfo = computed(() => ({
index: currentQuestionDetail.value?.KeyWordsIndex ?? -1,
word: currentQuestionDetail.value?.KeyWord || '',
}))
// 计算全局字符索引(用于匹配 KeyWordsIndex
function getGlobalCharIndex(lineIndex: number, charIndex: number) {
let globalIndex = 0
for (let i = 0; i < lineIndex; i++) {
globalIndex += answerLines.value[i].length
}
return globalIndex + charIndex
}
watch(
() => [currentQuestionMainInfo, currentQuestionDetail],
() => {
// eslint-disable-next-line no-console
console.log('Current currentQuestionMainInfo:', currentQuestionMainInfo.value)
// eslint-disable-next-line no-console
console.log('Current currentQuestionMainInfo:', currentQuestionMainInfo)
console.log('Current currentQuestionDetail:', currentQuestionDetail.value)
},
{ deep: true, immediate: true },
)
@ -81,64 +69,59 @@ watch(
<div class="w-full flex p-6">
<!-- <p>template:{{ template }}</p> -->
<!-- 模板A: 汉字听写1-提示 (拼音+提示) -->
<div v-if="template === QuestionCategoryEnum.ChineseCharacterDictation1 || template === QuestionCategoryEnum.ChineseCharacterDictation2" class="text-center">
<div v-if="template === QuestionCategoryEnum.ChineseCharacterDictation1" class="text-center">
<div class="mb-6 inline-block text-5xl font-bold leading-none">
<div class="ptions-container1 mb-2 text-center text-2xl">
{{ title }}
<div class="flex items-center justify-center gap-4">
<div
v-for="(part, index) in dictationParts" :key="`part-${index}`"
class="text-4xl"
:class="index === 0 ? 'short-content-bg' : 'content-with-bg'"
>
{{ part }}
</div>
</div>
<div class="rich-content ml-3 mt-4 flex gap-1 color-red-600">
<!-- <TianZiGe v-for="(char, index) in pinyinChars" :key="index" :char="char" /> -->
</div>
</div>
<!-- 模板D: 汉字听写 2 词语听写 -->
<div
v-else-if="template === QuestionCategoryEnum.ChineseCharacterDictation2 || template === QuestionCategoryEnum.WordDictation"
class="flex flex-col items-center"
>
<div class="mb-1 text-3xl text-gray-800 font-bold leading-relaxed">
<div class="rich-content content-with-bg ml-3 mt-4 flex text-6xl !px-16 !py-10 !tracking-[0.1em]">
{{ content }}
</div>
</div>
</div>
<!-- 模板B: 汉字听写-同音字 (大字) -->
<!-- 暂时未匹配到枚举保持原样或删除 -->
<!-- <div v-else-if="template === 'TEMPLATE_DICTATION_HOMOPHONE'" class="text-center"> -->
<!-- 模板C: 汉字加一加 (提示+部件) -->
<div v-else-if="template === QuestionCategoryEnum.CharacterRadicalAddition" class="text-center">
<div class="text-[50px] font-bold">
<template v-if="parsedComponentAddTitle.type === 'quote_full'">
<span class="text-black">{{ parsedComponentAddTitle.prefix }}</span>
<span class="text-red-600">{{ parsedComponentAddTitle.content }}</span>
<span class="text-black">{{ parsedComponentAddTitle.suffix }}</span>
</template>
<template v-else-if="parsedComponentAddTitle.type === 'quote_half'">
<span class="text-black">{{ parsedComponentAddTitle.prefix }}"</span>
<span class="text-red-600">{{ parsedComponentAddTitle.content }}</span>
<span class="text-black">"{{ parsedComponentAddTitle.suffix }}</span>
</template>
<template v-else>
<span class="text-black">{{ parsedComponentAddTitle.prefix }}</span>
<span class="ml-4 text-red-600">{{ parsedComponentAddTitle.content }}</span>
</template>
<div class="mb-6 inline-block text-5xl font-bold leading-none">
<div class="rich-content ml-3 mt-4 flex gap-1 text-5xl tracking-[0.1em]">
请写出含有 <span class="text-color-red !text-6xl">{{ content }}</span>的汉字书写时间为60秒
</div>
</div>
</div>
<!-- 模板D: 词语听写 (拼音+提示) -->
<div v-else-if="template === QuestionCategoryEnum.WordDictation" class="flex flex-col items-center">
<div class="mb-8 flex flex-wrap justify-center gap-6">
<TianZiGe v-for="(char, index) in pinyinChars" :key="index" :char="char" />
<!-- 模板D: 成语写一写1 (拼音+提示) -->
<div v-else-if="template === QuestionCategoryEnum.IdiomWriting1" class="flex flex-col items-center">
<div class="mb-1 text-gray-800 font-bold leading-relaxed">
<div class="rich-content ml-3 mt-4 flex gap-1 text-4xl">
{{ content }}
</div>
</div>
</div>
<!-- 模板E: 成语-文字要求 -->
<div v-else-if="template === QuestionCategoryEnum.IdiomWriting1 || template === QuestionCategoryEnum.IdiomWriting2" class="text-center">
<div v-else-if="template === QuestionCategoryEnum.IdiomWriting2" class="text-center">
<div class="mb-8 text-4xl text-gray-800 font-bold">
<!-- {{ content }} -->
<div class="rich-content" v-html="content" />
<NImage :src="ImageUrl" preview-disabled width="300" object-fit="contain" />
</div>
</div>
<!-- 模板G: 诗词理解-选择题 (通用选择题模板) -->
<div v-else-if="template === QuestionCategoryEnum.PoetryComprehension" class="w-full flex flex-col items-center">
<div class="options-container text-2xl">
{{ title }}
</div>
<div class="mb-1 text-3xl text-gray-800 font-bold leading-relaxed">
<div class="rich-content" v-html="content" />
</div>
@ -146,57 +129,65 @@ watch(
<!-- 模板ChangeWords: 换字组成语 -->
<div v-else-if="template === QuestionCategoryEnum.ChangeWords" class="w-full flex flex-col items-center">
<div class="options-container text-2xl">
{{ title }}
</div>
<div class="mb-1 text-3xl text-gray-800 font-bold leading-relaxed">
<div class="rich-content" v-html="content" />
<div class="content-with-bg mb-1 mt-10 p-6 text-6xl text-gray-800 font-bold !px-16 !py-8">
{{ content }}
</div>
</div>
<!-- 模板: 场景猜诗句 -->
<div v-else-if="template === QuestionCategoryEnum.SceneBasedPoemGuessing" class="w-full flex flex-col items-center">
<div class="options-container text-2xl">
{{ title }}
</div>
<div class="mb-1 text-3xl text-gray-800 font-bold leading-relaxed">
<div class="mb-1 p-16 text-3xl text-gray-800 font-bold leading-relaxed line-height-20">
<div class="rich-content" v-html="content" />
</div>
</div>
<!-- 模板: 联想对对碰 -->
<div v-else-if="template === QuestionCategoryEnum.AssociationMatching" class="w-full flex flex-col items-center">
<div class="options-container text-2xl">
{{ title }}
<div
v-else-if="template === QuestionCategoryEnum.AssociationMatching"
class="w-full flex flex-col items-center gap-8"
>
<!-- 上方词组 -->
<div class="flex flex-wrap justify-center gap-4">
<div v-for="(word, index) in associationWords" :key="`word-${index}`" class="association-word text-bold">
{{ word }}
</div>
</div>
<div class="mb-1 text-3xl text-gray-800 font-bold leading-relaxed">
<div class="rich-content" v-html="content" />
<!-- 下方答案字符按逗号分行 -->
<div class="flex flex-col items-center gap-3">
<div v-for="(line, lineIndex) in answerLines" :key="`line-${lineIndex}`" class="flex gap-4">
<div
v-for="(char, charIndex) in line" :key="`char-${lineIndex}-${charIndex}`"
class="association-char text-5xl"
>
<span v-if="getGlobalCharIndex(lineIndex, charIndex) === keywordInfo.index">
{{ keywordInfo.word }}
</span>
</div>
</div>
</div>
</div>
<!-- 模板: 字词飞花令 -->
<div v-else-if="template === QuestionCategoryEnum.CharacterWordFlowerDrinkingGame" class="w-full flex flex-col items-center">
<div class="options-container text-2xl">
<div
v-else-if="template === QuestionCategoryEnum.CharacterWordFlowerDrinkingGame"
class="w-full flex flex-col items-center"
>
<div class="options-container text-5xl">
请回答带有{{ content }}的诗词
</div>
</div>
<!-- 模板: 诗词常识 -->
<div v-else-if="template === QuestionCategoryEnum.PoetryCommonKnowledge" class="w-full flex flex-col items-center">
<div class="options-container text-2xl">
{{ title }}
</div>
<div class="mb-1 text-3xl text-gray-800 font-bold leading-relaxed">
<div class="mb-1 p-16 text-3xl text-gray-800 font-bold leading-relaxed line-height-20">
<div class="rich-content" v-html="content" />
</div>
</div>
<!-- 模板: 逆向接诗句 -->
<div v-else-if="template === QuestionCategoryEnum.ReversePoemMatching" class="w-full flex flex-col items-center">
<div class="options-container text-2xl">
{{ title }}
</div>
<div class="mb-1 text-3xl text-gray-800 font-bold leading-relaxed">
<div class="mb-1 mt-20 text-5xl text-gray-800 font-bold leading-relaxed">
<div class="rich-content" v-html="content" />
</div>
</div>
@ -206,7 +197,7 @@ watch(
<div class="ptions-container1 mb-2 text-center text-2xl">
{{ title }}
</div>
<div class="rich-content ml-3 mt-4 flex gap-1 color-red-600">
<div class="rich-content ml-3 mt-4 flex gap-1">
{{ content }}
</div>
</div>
@ -413,5 +404,53 @@ watch(
margin: 0 auto;
vertical-align: middle;
}
:deep(p),
:deep(span),
:deep(div) {
font-size: 2rem; /* text-5xl */
}
}
.content-with-bg {
background: url('@/assets/imgs/user/content-bg.png') no-repeat center;
background-size: 100% 100%;
border-radius: 12px;
padding: 20px 30px;
letter-spacing: 0.4em;
}
.short-content-bg {
background: url('@/assets/imgs/user/short-content-bg.png') no-repeat center;
background-size: 100% 100%;
border-radius: 12px;
padding: 20px 30px;
letter-spacing: 0.1em;
}
.association-word {
background: url('@/assets/imgs/user/dui-kuang.png') no-repeat center;
background-size: 100% 100%;
min-width: 160px;
height: 70px;
display: flex;
align-items: center;
justify-content: center;
font-size: 32px;
font-weight: bold;
color: white;
padding: 0 20px;
}
.association-char {
background: url('@/assets/imgs/user/dui-text-bg.png') no-repeat center;
background-size: 100% 100%;
width: 100px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: white;
}
</style>

View File

@ -83,13 +83,13 @@ async function getUserRankList() {
render(row: TeamData) {
const rank = row.rank
if (rank === 1) {
return <NTag type="warning" size="large" round>🏆</NTag>
return <NTag type="warning" size="large" class="!py-6 !text-3xl" round>🏆</NTag>
}
if (rank === 2) {
return <NTag type="info" size="large" round>🥈</NTag>
return <NTag type="info" size="large" class="!py-6 !text-3xl" round>🥈</NTag>
}
if (rank === 3) {
return <NTag type="success" size="large" round>🥉</NTag>
return <NTag type="success" size="large" class="!py-6 !text-3xl" round>🥉</NTag>
}
return <span>{rank}</span>
},
@ -140,14 +140,17 @@ function rowClassName(row: TeamData) {
<div class="leaderboard-container">
<div class="leaderboard-header">
<NImage :src="title" alt="logo" preview-disabled class="mt--60px" object-fit="contain" />
<p class="mt--20px text-center text-sm text-#6b778d">
<p class="mt--20px text-center text-lg text-#6b778d">
"勤学如春起之苗,不见其增,日有所长"
</p>
<ActionButton v-if="hasExtraTimeBtn" class="position-absolute bottom-20px right-20px" type="text" text="加时赛" @click="handleAddTime" />
<ActionButton
v-if="hasExtraTimeBtn" class="position-absolute bottom-20px right-20px" type="text" text="加时赛"
@click="handleAddTime"
/>
</div>
<div class="leaderboard-content">
<NDataTable
:columns="columns" :data="tableData" :bordered="false" :bottom-bordered="false"
:columns="columns" :data="tableData" :bordered="false" :bottom-bordered="false" size="large"
:row-class-name="rowClassName" class="rank-table"
/>
</div>

View File

@ -49,8 +49,8 @@ function handleNext() {
<template>
<CompetitionLayout
:show-back="true" :show-next="true" :title="activityName" next-btn-text="下一步" @back="handleBack"
@next="handleNext"
:show-back="true" back-btn-text="返回" :show-next="true" :title="activityName" next-btn-text="下一步"
@back="handleBack" @next="handleNext"
>
<div class="items-flex-start h-full w-full flex justify-center font-sans">
<div class="rules-content-wrapper">

View File

@ -87,7 +87,7 @@ onMounted(() => {
</script>
<template>
<CompetitionLayout :show-back="true" :show-next="true" next-btn-text="下一步" :show-title="false" @next="handleNext" @back="handleBack">
<CompetitionLayout :show-back="true" back-btn-text="返回" :show-next="false" next-btn-text="下一步" :show-title="false" @next="handleNext" @back="handleBack">
<!-- Scroll Content -->
<div class="scroll-container">
<!-- 卷轴背景动画容器 -->

View File

@ -1,100 +0,0 @@
{
"question_bank": [
{
"QuestionId": 34,
"Name": "<p>诗人袁枚写的与<strong>美食</strong>有关的书是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.《食经》&nbsp; &nbsp; B.《食珍录》&nbsp; &nbsp; C.《红楼梦》&nbsp; &nbsp; D.《随园食单》</strong></p>",
"Answer": "D",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>“我家洗砚池头树”引用了一位<strong>书法家</strong>的典故,这位书法家是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.王献之&nbsp; &nbsp; B.王羲之&nbsp; &nbsp; C.王冕&nbsp; &nbsp; D.柳公权</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>“诗中有画,画中有诗”评价的是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.杜牧的诗画风格</strong></p><p><strong>&nbsp; &nbsp;B.刘禹锡的诗画风格</strong></p><p><strong>&nbsp; &nbsp;C.苏轼的诗画风格</strong></p><p><strong>&nbsp; &nbsp;D.王维的诗画风格</strong></p>",
"Answer": "D",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>被闻一多称为“<strong>诗中的诗</strong>,顶峰上的顶峰”的诗歌作品是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.刘希夷的《代悲白头翁》</strong></p><p><strong>&nbsp; &nbsp;B.杨广的《春江花月夜》</strong></p><p><strong>&nbsp; &nbsp;C.张若虚的《春江花月夜》</strong></p><p><strong>&nbsp; &nbsp;D.李白的《蜀道难》</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>“<strong>梅妻鹤子</strong>”指的是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.林逋&nbsp; &nbsp; B.梅尧臣&nbsp; &nbsp; C.苏舜钦&nbsp; &nbsp; D.王安石</strong></p>",
"Answer": "A",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>“一门父子三词客,千古文章八大家。”这副对联中提到的“<strong>三父子</strong>”是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.曹操、曹丕、曹植</strong></p><p><strong>&nbsp; &nbsp;B.苏洵、苏轼、苏辙</strong></p><p><strong>&nbsp; &nbsp;C.班彪、班固、班超</strong></p><p><strong>&nbsp; &nbsp;D.阮瑀、阮籍、阮咸</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>诗人刘禹锡被<strong>称</strong>为(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.“诗鬼”&nbsp; &nbsp; B.“诗豪”&nbsp; &nbsp; C.“诗圣”&nbsp; &nbsp; D.“诗仙”</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>有关诗人卢钺的信息,<strong>不正确</strong>的一项是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.别号梅坡</strong></p><p><strong>&nbsp; &nbsp;B.代表作《雪梅》</strong></p><p><strong>&nbsp; &nbsp;C.与辛派词人陈亮是好友</strong></p><p><strong>&nbsp; &nbsp;D.宋朝人</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>诗人王昌龄被<strong>称</strong>为(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.“五言圣手”&nbsp; &nbsp; B.“七绝圣手”&nbsp; &nbsp; C.“七言圣手”&nbsp; &nbsp; D.“七绝诗人”</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>李商隐与杜牧<strong>合称</strong>&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.“李杜”&nbsp; &nbsp; B.“杜李”&nbsp; &nbsp; C.“小李杜”&nbsp; &nbsp; D.“唐诗双杰”</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>“南朝四百八十寺”中,“<strong>南朝</strong>”指的是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.在南方建都的王朝</strong></p><p><strong>&nbsp; &nbsp;B.宋、齐、魏、陈四个朝代的总称</strong></p><p><strong>&nbsp; &nbsp;C.宋、齐、梁、陈四个朝代的总称</strong></p><p><strong>&nbsp; &nbsp;D.在南京建都的王朝</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
},
{
"QuestionId": 34,
"Name": "<p>“<strong>初唐四杰</strong>”是指(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.张若虚、张旭、孔融和贺知章</strong></p><p><strong>&nbsp; &nbsp;B.王勃、杨炯、卢照邻和骆宾王</strong></p><p><strong>&nbsp; &nbsp;C.高适、王昌龄、岑参和王之涣</strong></p><p><strong>&nbsp; &nbsp;D.贺知章、张若虚、张旭和包融</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
"ImageUrl": ""
}
]
}

View File

@ -1,254 +1,254 @@
{
"question_bank": [
{
"name": "重阳、习俗、思念",
"answer": "遥知兄弟登高处,遍插茱萸少一人。",
"imageUrl": "",
"Name": "重阳、习俗、思念",
"Answer": "遥知兄弟登高处,遍插茱萸少一人。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "处",
"KeyWordsIndex": 6,
"questionId": 32
"QuestionId": 32
},
{
"name": "边塞、征战、思乡",
"answer": "秦时明月汉时关,万里长征人未还。",
"imageUrl": "",
"Name": "边塞、征战、思乡",
"Answer": "秦时明月汉时关,万里长征人未还。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "关",
"KeyWordsIndex": 6,
"questionId": 32
"QuestionId": 32
},
{
"name": "军中、饮酒、欢快",
"answer": "葡萄美酒夜光杯,欲饮琵琶马上催。",
"imageUrl": "",
"Name": "军中、饮酒、欢快",
"Answer": "葡萄美酒夜光杯,欲饮琵琶马上催。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "催",
"KeyWordsIndex": 13,
"questionId": 32
"QuestionId": 32
},
{
"name": "初夏、田园、蔬果",
"answer": "梅子金黄杏子肥,麦花雪白菜花稀。",
"imageUrl": "",
"Name": "初夏、田园、蔬果",
"Answer": "梅子金黄杏子肥,麦花雪白菜花稀。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "肥",
"KeyWordsIndex": 6,
"questionId": 32
"QuestionId": 32
},
{
"name": "童趣、追跑、田野",
"answer": "儿童急走追黄蝶,飞入菜花无处寻。",
"imageUrl": "",
"Name": "童趣、追跑、田野",
"Answer": "儿童急走追黄蝶,飞入菜花无处寻。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "蝶",
"KeyWordsIndex": 6,
"questionId": 32
"QuestionId": 32
},
{
"name": "送别、赤诚、朋友",
"answer": "洛阳亲友如相问,一片冰心在玉壶。",
"imageUrl": "",
"Name": "送别、赤诚、朋友",
"Answer": "洛阳亲友如相问,一片冰心在玉壶。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "心",
"KeyWordsIndex": 10,
"questionId": 32
"QuestionId": 32
},
{
"name": "梅花、香气、傲骨",
"answer": "不要人夸好颜色,只留清气满乾坤。",
"imageUrl": "",
"Name": "梅花、香气、傲骨",
"Answer": "不要人夸好颜色,只留清气满乾坤。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "好",
"KeyWordsIndex": 4,
"questionId": 32
"QuestionId": 32
},
{
"name": "遗愿、爱国、失地",
"answer": "死去元知万事空,但悲不见九州同。",
"imageUrl": "",
"Name": "遗愿、爱国、失地",
"Answer": "死去元知万事空,但悲不见九州同。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "悲",
"KeyWordsIndex": 8,
"questionId": 32
"QuestionId": 32
},
{
"name": "水滨、笙乐、忧愁",
"answer": "山外青山楼外楼,西湖歌舞几时休?",
"imageUrl": "",
"Name": "水滨、笙乐、忧愁",
"Answer": "山外青山楼外楼,西湖歌舞几时休?",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "休",
"KeyWordsIndex": 13,
"questionId": 32
"QuestionId": 32
},
{
"name": "祈求、变革、贤能",
"answer": "我劝天公重抖擞,不拘一格降人材。",
"imageUrl": "",
"Name": "祈求、变革、贤能",
"Answer": "我劝天公重抖擞,不拘一格降人材。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "公",
"KeyWordsIndex": 3,
"questionId": 32
"QuestionId": 32
},
{
"name": "深夜、羁客、寒冷",
"answer": "月落乌啼霜满天,江枫渔火对愁眠。",
"imageUrl": "",
"Name": "深夜、羁客、寒冷",
"Answer": "月落乌啼霜满天,江枫渔火对愁眠。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "愁",
"KeyWordsIndex": 12,
"questionId": 32
"QuestionId": 32
},
{
"name": "登科、飞驰、盛景",
"answer": "春风得意马蹄疾,一日看尽长安花。",
"imageUrl": "",
"Name": "登科、飞驰、盛景",
"Answer": "春风得意马蹄疾,一日看尽长安花。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "花",
"KeyWordsIndex": 13,
"questionId": 32
"QuestionId": 32
},
{
"name": "耕地、纺织、协作",
"answer": "昼出耘田夜绩麻,村庄儿女各当家。",
"imageUrl": "",
"Name": "耕地、纺织、协作",
"Answer": "昼出耘田夜绩麻,村庄儿女各当家。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "村",
"KeyWordsIndex": 7,
"questionId": 32
"QuestionId": 32
},
{
"name": "悠闲、放牧、吹奏",
"answer": "牧童归去横牛背,短笛无腔信口吹。",
"imageUrl": "",
"Name": "悠闲、放牧、吹奏",
"Answer": "牧童归去横牛背,短笛无腔信口吹。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "背",
"KeyWordsIndex": 6,
"questionId": 32
"QuestionId": 32
},
{
"name": "童趣、玩耍、敲击",
"answer": "稚子金盆脱晓冰,彩丝穿取当银钲。",
"imageUrl": "",
"Name": "童趣、玩耍、敲击",
"Answer": "稚子金盆脱晓冰,彩丝穿取当银钲。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "脱",
"KeyWordsIndex": 4,
"questionId": 32
"QuestionId": 32
},
{
"name": "欣喜、回家、畅饮",
"answer": "白日放歌须纵酒,青春作伴好还乡。",
"imageUrl": "",
"Name": "欣喜、回家、畅饮",
"Answer": "白日放歌须纵酒,青春作伴好还乡。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "须",
"KeyWordsIndex": 4,
"questionId": 32
"QuestionId": 32
},
{
"name": "雄师、豪迈、跋涉",
"answer": "红军不怕远征难,万水千山只等闲。",
"imageUrl": "",
"Name": "雄师、豪迈、跋涉",
"Answer": "红军不怕远征难,万水千山只等闲。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "怕",
"KeyWordsIndex": 3,
"questionId": 32
"QuestionId": 32
},
{
"name": "中秋、怀人、月亮",
"answer": "今夜月明人尽望,不知秋思落谁家。",
"imageUrl": "",
"Name": "中秋、怀人、月亮",
"Answer": "今夜月明人尽望,不知秋思落谁家。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "思",
"KeyWordsIndex": 10,
"questionId": 32
"QuestionId": 32
},
{
"name": "无畏、高尚、咏物",
"answer": "粉骨碎身浑不怕,要留清白在人间。",
"imageUrl": "",
"Name": "无畏、高尚、咏物",
"Answer": "粉骨碎身浑不怕,要留清白在人间。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "浑",
"KeyWordsIndex": 4,
"questionId": 32
"QuestionId": 32
},
{
"name": "坚韧、勇气、咏物",
"answer": "咬定青山不放松,立根原在破岩中。",
"imageUrl": "",
"Name": "坚韧、勇气、咏物",
"Answer": "咬定青山不放松,立根原在破岩中。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "根",
"KeyWordsIndex": 8,
"questionId": 32
"QuestionId": 32
},
{
"name": "送别、边塞、畅饮",
"answer": "劝君更尽一杯酒,西出阳关无故人。",
"imageUrl": "",
"Name": "送别、边塞、畅饮",
"Answer": "劝君更尽一杯酒,西出阳关无故人。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "关",
"KeyWordsIndex": 10,
"questionId": 32
"QuestionId": 32
},
{
"name": "细雨、嫩绿、朦胧",
"answer": "天街小雨润如酥,草色遥看近却无。",
"imageUrl": "",
"Name": "细雨、嫩绿、朦胧",
"Answer": "天街小雨润如酥,草色遥看近却无。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "街",
"KeyWordsIndex": 1,
"questionId": 32
"QuestionId": 32
},
{
"name": "哭泣、沦陷、期盼",
"answer": "遗民泪尽胡尘里,南望王师又一年。",
"imageUrl": "",
"Name": "哭泣、沦陷、期盼",
"Answer": "遗民泪尽胡尘里,南望王师又一年。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "师",
"KeyWordsIndex": 10,
"questionId": 32
"QuestionId": 32
},
{
"name": "酒菜、好客、乡村",
"answer": "莫笑农家腊酒浑,丰年留客足鸡豚。",
"imageUrl": "",
"Name": "酒菜、好客、乡村",
"Answer": "莫笑农家腊酒浑,丰年留客足鸡豚。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "足",
"KeyWordsIndex": 11,
"questionId": 32
"QuestionId": 32
},
{
"name": "初夏、喧闹、江南",
"answer": "黄梅时节家家雨,青草池塘处处蛙。",
"imageUrl": "",
"Name": "初夏、喧闹、江南",
"Answer": "黄梅时节家家雨,青草池塘处处蛙。",
"ImageUrl": "",
"IsGood": 0,
"IsDisabled": false,
"KeyWord": "池",
"KeyWordsIndex": 9,
"questionId": 32
"QuestionId": 32
}
]
}

View File

@ -2,7 +2,7 @@
"question_bank": [
{
"QuestionId": 34,
"Name": "<p>诗人袁枚写的与<strong>美食</strong>有关的书是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.《食经》&nbsp; &nbsp; B.《食珍录》&nbsp; &nbsp; C.《红楼梦》&nbsp; &nbsp; D.《随园食单》</strong></p>",
"Name": "<p>诗人袁枚写的与<strong>美食</strong>有关的书是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.《食经》&nbsp; &nbsp; B.《食珍录》&nbsp; &nbsp; C.《红楼梦》&nbsp; &nbsp; D.《随园食单》</strong></p>",
"Answer": "D",
"Type": "text",
"IsGood": 0,
@ -10,7 +10,7 @@
},
{
"QuestionId": 34,
"Name": "<p>“我家洗砚池头树”引用了一位<strong>书法家</strong>的典故,这位书法家是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.王献之&nbsp; &nbsp; B.王羲之&nbsp; &nbsp; C.王冕&nbsp; &nbsp; D.柳公权</strong></p>",
"Name": "<p>“我家洗砚池头树”引用了一位<strong>书法家</strong>的典故,这位书法家是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.王献之&nbsp; &nbsp; B.王羲之&nbsp; &nbsp; C.王冕&nbsp; &nbsp; D.柳公权</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
@ -18,7 +18,7 @@
},
{
"QuestionId": 34,
"Name": "<p>“诗中有画,画中有诗”评价的是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.杜牧的诗画风格</strong></p><p><strong>&nbsp; &nbsp;B.刘禹锡的诗画风格</strong></p><p><strong>&nbsp; &nbsp;C.苏轼的诗画风格</strong></p><p><strong>&nbsp; &nbsp;D.王维的诗画风格</strong></p>",
"Name": "<p>“诗中有画,画中有诗”评价的是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.杜牧的诗画风格</strong></p><p><strong>&nbsp; &nbsp;B.刘禹锡的诗画风格</strong></p><p><strong>&nbsp; &nbsp;C.苏轼的诗画风格</strong></p><p><strong>&nbsp; &nbsp;D.王维的诗画风格</strong></p>",
"Answer": "D",
"Type": "text",
"IsGood": 0,
@ -26,7 +26,7 @@
},
{
"QuestionId": 34,
"Name": "<p>被闻一多称为“<strong>诗中的诗</strong>,顶峰上的顶峰”的诗歌作品是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.刘希夷的《代悲白头翁》</strong></p><p><strong>&nbsp; &nbsp;B.杨广的《春江花月夜》</strong></p><p><strong>&nbsp; &nbsp;C.张若虚的《春江花月夜》</strong></p><p><strong>&nbsp; &nbsp;D.李白的《蜀道难》</strong></p>",
"Name": "<p>被闻一多称为“<strong>诗中的诗</strong>,顶峰上的顶峰”的诗歌作品是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.刘希夷的《代悲白头翁》</strong></p><p><strong>&nbsp; &nbsp;B.杨广的《春江花月夜》</strong></p><p><strong>&nbsp; &nbsp;C.张若虚的《春江花月夜》</strong></p><p><strong>&nbsp; &nbsp;D.李白的《蜀道难》</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
@ -34,7 +34,7 @@
},
{
"QuestionId": 34,
"Name": "<p>“<strong>梅妻鹤子</strong>”指的是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.林逋&nbsp; &nbsp; B.梅尧臣&nbsp; &nbsp; C.苏舜钦&nbsp; &nbsp; D.王安石</strong></p>",
"Name": "<p>“<strong>梅妻鹤子</strong>”指的是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.林逋&nbsp; &nbsp; B.梅尧臣&nbsp; &nbsp; C.苏舜钦&nbsp; &nbsp; D.王安石</strong></p>",
"Answer": "A",
"Type": "text",
"IsGood": 0,
@ -42,7 +42,7 @@
},
{
"QuestionId": 34,
"Name": "<p>“一门父子三词客,千古文章八大家。”这副对联中提到的“<strong>三父子</strong>”是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.曹操、曹丕、曹植</strong></p><p><strong>&nbsp; &nbsp;B.苏洵、苏轼、苏辙</strong></p><p><strong>&nbsp; &nbsp;C.班彪、班固、班超</strong></p><p><strong>&nbsp; &nbsp;D.阮瑀、阮籍、阮咸</strong></p>",
"Name": "<p>“一门父子三词客,千古文章八大家。”这副对联中提到的“<strong>三父子</strong>”是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.曹操、曹丕、曹植</strong></p><p><strong>&nbsp; &nbsp;B.苏洵、苏轼、苏辙</strong></p><p><strong>&nbsp; &nbsp;C.班彪、班固、班超</strong></p><p><strong>&nbsp; &nbsp;D.阮瑀、阮籍、阮咸</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
@ -50,7 +50,7 @@
},
{
"QuestionId": 34,
"Name": "<p>诗人刘禹锡被<strong>称</strong>为(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.“诗鬼”&nbsp; &nbsp; B.“诗豪”&nbsp; &nbsp; C.“诗圣”&nbsp; &nbsp; D.“诗仙”</strong></p>",
"Name": "<p>诗人刘禹锡被<strong>称</strong>为(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.“诗鬼”&nbsp; &nbsp; B.“诗豪”&nbsp; &nbsp; C.“诗圣”&nbsp; &nbsp; D.“诗仙”</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
@ -58,7 +58,7 @@
},
{
"QuestionId": 34,
"Name": "<p>有关诗人卢钺的信息,<strong>不正确</strong>的一项是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.别号梅坡</strong></p><p><strong>&nbsp; &nbsp;B.代表作《雪梅》</strong></p><p><strong>&nbsp; &nbsp;C.与辛派词人陈亮是好友</strong></p><p><strong>&nbsp; &nbsp;D.宋朝人</strong></p>",
"Name": "<p>有关诗人卢钺的信息,<strong>不正确</strong>的一项是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.别号梅坡</strong></p><p><strong>&nbsp; &nbsp;B.代表作《雪梅》</strong></p><p><strong>&nbsp; &nbsp;C.与辛派词人陈亮是好友</strong></p><p><strong>&nbsp; &nbsp;D.宋朝人</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
@ -66,7 +66,7 @@
},
{
"QuestionId": 34,
"Name": "<p>诗人王昌龄被<strong>称</strong>为(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.“五言圣手”&nbsp; &nbsp; B.“七绝圣手”&nbsp; &nbsp; C.“七言圣手”&nbsp; &nbsp; D.“七绝诗人”</strong></p>",
"Name": "<p>诗人王昌龄被<strong>称</strong>为(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.“五言圣手”&nbsp; &nbsp; B.“七绝圣手”&nbsp; &nbsp; C.“七言圣手”&nbsp; &nbsp; D.“七绝诗人”</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,
@ -74,7 +74,7 @@
},
{
"QuestionId": 34,
"Name": "<p>李商隐与杜牧<strong>合称</strong>&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.“李杜”&nbsp; &nbsp; B.“杜李”&nbsp; &nbsp; C.“小李杜”&nbsp; &nbsp; D.“唐诗双杰”</strong></p>",
"Name": "<p>李商隐与杜牧<strong>合称</strong>&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.“李杜”&nbsp; &nbsp; B.“杜李”&nbsp; &nbsp; C.“小李杜”&nbsp; &nbsp; D.“唐诗双杰”</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
@ -82,7 +82,7 @@
},
{
"QuestionId": 34,
"Name": "<p>“南朝四百八十寺”中,“<strong>南朝</strong>”指的是(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.在南方建都的王朝</strong></p><p><strong>&nbsp; &nbsp;B.宋、齐、魏、陈四个朝代的总称</strong></p><p><strong>&nbsp; &nbsp;C.宋、齐、梁、陈四个朝代的总称</strong></p><p><strong>&nbsp; &nbsp;D.在南京建都的王朝</strong></p>",
"Name": "<p>“南朝四百八十寺”中,“<strong>南朝</strong>”指的是(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.在南方建都的王朝</strong></p><p><strong>&nbsp; &nbsp;B.宋、齐、魏、陈四个朝代的总称</strong></p><p><strong>&nbsp; &nbsp;C.宋、齐、梁、陈四个朝代的总称</strong></p><p><strong>&nbsp; &nbsp;D.在南京建都的王朝</strong></p>",
"Answer": "C",
"Type": "text",
"IsGood": 0,
@ -90,7 +90,7 @@
},
{
"QuestionId": 34,
"Name": "<p>“<strong>初唐四杰</strong>”是指(&nbsp; &nbsp;)。</p><p><br></p><p><strong>&nbsp; &nbsp;A.张若虚、张旭、孔融和贺知章</strong></p><p><strong>&nbsp; &nbsp;B.王勃、杨炯、卢照邻和骆宾王</strong></p><p><strong>&nbsp; &nbsp;C.高适、王昌龄、岑参和王之涣</strong></p><p><strong>&nbsp; &nbsp;D.贺知章、张若虚、张旭和包融</strong></p>",
"Name": "<p>“<strong>初唐四杰</strong>”是指(&nbsp; &nbsp;)。</p><p><strong>&nbsp; &nbsp;A.张若虚、张旭、孔融和贺知章</strong></p><p><strong>&nbsp; &nbsp;B.王勃、杨炯、卢照邻和骆宾王</strong></p><p><strong>&nbsp; &nbsp;C.高适、王昌龄、岑参和王之涣</strong></p><p><strong>&nbsp; &nbsp;D.贺知章、张若虚、张旭和包融</strong></p>",
"Answer": "B",
"Type": "text",
"IsGood": 0,